前言:
大四上学期的一门课程设计,主要用到CC2530单片机、WiFi模块:ESP826607、光照强度传感器:BH1750、步进电机等…
现分享给大家,希望对大家有所帮助。
实现功能:
数据采集:
- 采集光照强度的数据到ONENET云平台
- 采集终端设备的工作状态
本地控制:
- 控制照明设备的开关
- 控制照明设备是否进入自动模式
- 控制照明设备是否进入手动模式
自动控制:
- 根据当前的光照强度和设定的光照阈值自动控制照明设备的亮灭
- 自动调节照明设备的亮度
远程控制:
- 远程控制照明设备的亮灭
- 远程调节照明设备的亮度
- 远程控制窗帘的开关
- 远程控制照明设备的自动模式
- 远程设定光照阈值
原理图:
PCB图:
3D模型图:
实物图:
手机应用界面:
自动控制代码:
if(flag1==0&&flag2==1) //本地控制未开启且自动控制开启
{
if(end_temp < LIGHT ) //当光照数值小于设定阈值时开灯
{
P1_4 = 0; //D3灯亮
}
else
{
P1_4 = 1; //D3灯灭
}
}
if(flag1==0&&Remote_self_dimming==1) //本地控制未开启且远程自调光控制开启
{
pwmConfig(100-light2); //自动调光,参数取值0~100
}
else
pwmConfig(Remote_dimming_control); //远程调光参数取值0~100
}
本地控制代码:
extern unsigned char flag = 0; //用于记录光照设备开启/关闭状态
extern unsigned char flag1 = 0; //用于标记是否处于手动控制
void SampleApp_HandleKeys( uint8 shift, uint8 keys )
{
(void)shift;
if ( keys & HAL_KEY_SW_6 ) //按下S1进入/退出手动控制模式
{
if(flag1 == 0)
{
flag1 = 1;
}
else
{
flag1 = 0;
}
}
if ( keys & HAL_KEY_SW_1 ) //在手动模式下按下S2控制D3
{
if(flag == 0)
{
flag = 1;
HalLedSet( HAL_LED_3, HAL_LED_MODE_OFF);
}
else
{
flag = 0;
HalLedSet( HAL_LED_3, HAL_LED_MODE_ON);//D3亮代表开启空调
}
}
}
远程控制代码:
void Ctrl(uint8* cmd) //远程控制函数
{
//LED控制
if(strstr((char *)cmd, "D31")) //搜索"D31"
{
P1_4 = 0; //D3亮
}
else if(strstr((char *)cmd, "D30")) //搜索"D30"
{
P1_4 = 1; //D3灭
}
//如果命令是flag21,代表开启自动控制
else if(strstr((char *)cmd, "flag21")) //搜索"flag21"
{
flag2 = 1;
}
else if(strstr((char *)cmd, "flag20")) //搜索"flag20"
{
flag2 = 0;
}
//如果命令是Remote_self_dimming1,代表开启自动调光
else if(strstr((char *)cmd, "Remote_self_dimming1")) //搜索"Remote_self_dimming1"
{
Remote_self_dimming = 1;
}
else if(strstr((char *)cmd, "Remote_self_dimming0")) //搜索"Remote_self_dimming0"
{
Remote_self_dimming = 0;
}
else if(cmd[0]== 'L') //设置光照阈值命令
{
if(osal_strlen(cmd)==6) //5位数
LIGHT = (cmd[1]-0X30)*10000+(cmd[2]-0X30)*1000+(cmd[3]-0X30)*100+(cmd[4]-0X30)*10+(cmd[5]-0X30)*1;
else if(osal_strlen(cmd)==5) //4位数
LIGHT = (cmd[1]-0X30)*1000+(cmd[2]-0X30)*100+(cmd[3]-0X30)*10+(cmd[4]-0X30)*1;
else if(osal_strlen(cmd)==4) //3位数
LIGHT = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3) //2位数
LIGHT = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2) //1位数
LIGHT = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'A') //设置远程调光命令
{
if(osal_strlen(cmd)==4) //3位数
Remote_dimming_control = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3) //2位数
Remote_dimming_control = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2) //1位数
Remote_dimming_control = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'M') //设置电机命令
{
if(cmd[1]== '0')
{
uint8 on=0; //停止 //无线发送到终端
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
1,
&on,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'F')
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'P') //数据格式MP1.5
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
}
}
终端发送数据到协调器代码:
void SampleApp_Send_P2P_Message( void ) //终端发送数据到协调器
{
byte str[6]={0};
byte str1[5]={0};
int len=0;
unsigned short light=0;
light=get_light(); //读取光照值
wan = light/10000+0x30;
qian = (light/1000)%10+0x30;
bai = (light/100)%10+0x30;
shi = (light/10)%10+0x30;
ge = light %10+0x30;
str[4]=wan;
str[3]=qian;
str[2]=bai;
str[1]=shi;
str[0]=ge;
str[5]=mflag+0x30;
sprintf(str1, "%d", light);
len=osal_strlen(str1);
HalUARTWrite(0, "light: ",7); //串口输出
HalUARTWrite(0, str1,len ); //串口输出
HalUARTWrite(0, "\r\n",2);
//无线发送到协调器
AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
6,
str,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
应用层部分代码:
关于ZigBee协议栈的代码太多,故只能放一部分。
/*********************************************************************
* INCLUDES
*/
#include <stdio.h>
#include <string.h>
#include "AF.h"
#include "OnBoard.h"
#include "OSAL_Tasks.h"
#include "SampleApp.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "hal_drivers.h"
#include "hal_key.h"
#if defined ( LCD_SUPPORTED )
#include "hal_lcd.h"
#endif
#include "hal_led.h"
#include "hal_uart.h"
#include "MT_UART.h"
#include "string.h"
#include "stdio.h"
#ifdef ZDO_COORDINATOR //协调器
#include "stdlib.h"
#include "LocalControl.h"
#include "onenet.h" //协议文件
#include "edpkit.h"
#include "pwm.h"
#else //终端
#include "bh1750.h"
#include "motor.h"
#endif
#if !defined( SAMPLE_APP_PORT )
#define SAMPLE_APP_PORT 0
#endif
// This is the max byte count per OTA message.
#if !defined( SAMPLE_APP_TX_MAX )
#define SAMPLE_APP_TX_MAX 80
#endif
#define SAMPLE_APP_RSP_CNT 4
//定时时长最长为65535MS
#define TO_ONENET_TIME 5000
#define TO_COOR_TIME 5000
uint32 LIGHT = 100; //初始化光照阈值
uint8 Remote_dimming_control = 0; //初始化远程调光值
uint8 Remote_self_dimming=1 ;
// This list should be filled with Application specific Cluster IDs.
const cId_t SampleApp_ClusterList[SAMPLE_MAX_CLUSTERS] =
{
SAMPLEAPP_P2P_CLUSTERID,
SAMPLEAPP_PERIODIC_CLUSTERID,
};
const SimpleDescriptionFormat_t SampleApp_SimpleDesc =
{
SAMPLEAPP_ENDPOINT, // int Endpoint;
SAMPLEAPP_PROFID, // uint16 AppProfId[2];
SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2];
SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4;
SAMPLEAPP_FLAGS, // int AppFlags:4;
SAMPLE_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)SampleApp_ClusterList, // byte *pAppInClusterList;
SAMPLE_MAX_CLUSTERS, // byte AppNumOutClusters;
(cId_t *)SampleApp_ClusterList // byte *pAppOutClusterList;
};
endPointDesc_t SampleApp_epDesc =
{
SAMPLEAPP_ENDPOINT,
&SampleApp_TaskID,
(SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc,
noLatencyReqs
};
/*********************************************************************
* GLOBAL VARIABLES
*/
devStates_t SampleApp_NwkState;
uint8 SampleApp_TaskID;
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8 SampleApp_MsgID; //发送消息序列
afAddrType_t SampleApp_P2P_DstAddr; //点播
afAddrType_t SampleApp_Periodic_DstAddr; //广播
static uint8 SampleApp_TxBuf[SAMPLE_APP_TX_MAX+1]={0};
static uint8 SampleApp_TxLen=0;
uint8 onenet_login_ok=0; //onenet注册成功 0:未注册,1:注册中 2:注册成功
unsigned short end_temp; //终端采集的数据
uint8 ge,shi,bai,qian,wan; //数据的各位
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void SampleApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt );
void SampleApp_CallBack(uint8 port, uint8 event);
static void SampleApp_Send_P2P_Message( void );
void motor(void);
uint8 mflag1 = 0; //窗帘状态标志
/****************************应用层初始化函数**********************************/
void SampleApp_Init( uint8 task_id )
{
SampleApp_TaskID = task_id;
SampleApp_NwkState = DEV_INIT;
MT_UartInit(); //串口初始化
MT_UartRegisterTaskID(task_id); //注册串口任务
afRegister( (endPointDesc_t *)&SampleApp_epDesc );
RegisterForKeys( task_id );
#ifdef ZDO_COORDINATOR //协调器初始化
start_pwm(); //初始化PWM,调光
#else
lightInit(); //初始化光照传感器
initSensorPort(); //电机初始化
#endif
SampleApp_P2P_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; //点播
SampleApp_P2P_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_P2P_DstAddr.addr.shortAddr = 0x0000; //发给协调器
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//广播
SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; //可以发送给终端
}
/****************************事件处理函数**********************************/
UINT16 SampleApp_ProcessEvent( uint8 task_id, UINT16 events )
{
(void)task_id; // 故意不引用参数Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
afIncomingMSGPacket_t *MSGpkt;
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
case AF_INCOMING_MSG_CMD: //无线消息事件
SampleApp_ProcessMSGCmd( MSGpkt );
break;
case KEY_CHANGE: //按键事件
SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case ZDO_STATE_CHANGE: //网络状态改变事件
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( (SampleApp_NwkState == DEV_ZB_COORD)||
(SampleApp_NwkState == DEV_ROUTER)
|| (SampleApp_NwkState == DEV_END_DEVICE) )
{
//连网成功后,启动一个定时器
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
}
else
{
// Device is no longer in the network
}
break;
default:
break;
}
osal_msg_deallocate( (uint8 *)MSGpkt );
}
return ( events ^ SYS_EVENT_MSG );
}
#ifdef ZDO_COORDINATOR
//定时器时间到
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
{
if(onenet_login_ok==2) //如果接入onenet成功,启动心跳和发送数据定旳器
{
P1_1 = 0; //点亮D2
// 启动心跳定时器,15秒一次
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_ONENET_HEART_BEAT_EVT,15000 );
// 启动发送数据定时器,3秒一次
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_ONENET_SEND_DATA_EVT,TO_ONENET_TIME );
}
else //如果没有接入onenet成功,重新发起接入
{
OneNet_DevLink();//接入onenet服务器
onenet_login_ok=1;//onenet注册成功 0:未注册,1:注册中 2:注册成功
HalLedBlink (HAL_LED_2, 5, 50, 500);//LED2闪,表示正在接入onenet
// 每5秒尝试接入一次
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,5000 );
}
return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
}
//心跳定时器时间到
if ( events & SAMPLEAPP_ONENET_HEART_BEAT_EVT )
{
if(onenet_login_ok==2)
{
EDP_PacketPing(); //发送心跳
}
// 启动心跳定时器,15秒一次
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_ONENET_HEART_BEAT_EVT,15000 );
return (events ^ SAMPLEAPP_ONENET_HEART_BEAT_EVT);
}
//发送数据定时器时间到
if ( events & SAMPLEAPP_ONENET_SEND_DATA_EVT )
{
if(onenet_login_ok==2)
{
OneNet_SendTempData(end_temp); //发送光照数据到onenet
OneNet_SendLedAndBuzzerData(LIGHT, flag1, P1_4,mflag1,Remote_dimming_control,Remote_self_dimming);//状态发到云服务器
}
// 启动发送数据定时器,3秒一次
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_ONENET_SEND_DATA_EVT,TO_ONENET_TIME );
return (events ^ SAMPLEAPP_ONENET_SEND_DATA_EVT);
}
#else //终端发数据到协调器
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) //定时器时间到
{
static uint16 msCount=0;
if(msCount++>TO_COOR_TIME) //3s发一次数据到协调器
{
SampleApp_Send_P2P_Message(); //BH1750光照数据采集
msCount=0;
}
motorCtrl();//每1ms执行一次步进电机
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,1 );
return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
}
#endif
return ( 0 ); // Discard unknown events.
}
/****************************无线消息处理函数**********************************/
void SampleApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
switch ( pkt->clusterId )
{
case SAMPLEAPP_P2P_CLUSTERID: // 接收终端上传的光照数据
#ifdef ZDO_COORDINATOR
{
ge = pkt->cmd.Data[0]-0x30; //终端数据
shi = pkt->cmd.Data[1]-0x30;
bai = pkt->cmd.Data[2]-0x30;
qian = pkt->cmd.Data[3]-0x30;
wan = pkt->cmd.Data[4]-0x30;
mflag1 = pkt->cmd.Data[5]-0x30; //窗帘状态标志
end_temp = wan*10000+qian*1000+bai*100+shi*10+ge;
uint16 light2=end_temp;
if(flag1==0&&flag2==1) //本地控制未开启且自动控制开启
{
if(end_temp < LIGHT )//当光照数值小于设定阈值时开灯
{
P1_4 = 0; //D3灯亮
}
else
{
P1_4 = 1; //D3灯灭
}
}
if(flag1==0&&Remote_self_dimming==1)//本地控制未开启且远程自调光控制开启
{
pwmConfig(100-light2); //自动调光,参数取值0~100
}
else
pwmConfig(Remote_dimming_control); //远程调光
// Pwm(Remote_dimming_control);
}
break;
#else //终端收到协调器的电机指令
case SAMPLEAPP_PERIODIC_CLUSTERID:
{
uint8 buff[3];
osal_memcpy(buff,pkt->cmd.Data,sizeof(buff));
motorFlag1=buff[0];//P或F
uint8 a=buff[1]-0x30; //转圈个位
uint8 b=buff[2]-0x30; //转圈小数位
float c=a+(float)b/10; //个位和小数位结合
motorFlag = c; //motorFlag全局变量,将值传出去
}
break;
#endif
default:
break;
}
}
#ifdef ZDO_COORDINATOR
/****************************远程控制函数**********************************/
void Ctrl(uint8* cmd) //远程控制
{
//LED2控制
if(strstr((char *)cmd, "D31")) //搜索"D31"
{
P1_4 = 0; //D3亮
}
else if(strstr((char *)cmd, "D30")) //搜索"D30"
{
P1_4 = 1; //D3灭
}
//如果命令是flag21,代表开启自动控制
else if(strstr((char *)cmd, "flag21")) //搜索"flag21"
{
flag2 = 1;
}
else if(strstr((char *)cmd, "flag20")) //搜索"flag20"
{
flag2 = 0;
}
//如果命令是Remote_self_dimming1,代表开启自动控制
else if(strstr((char *)cmd, "Remote_self_dimming1")) //搜索"Remote_self_dimming1"
{
Remote_self_dimming = 1;
}
else if(strstr((char *)cmd, "Remote_self_dimming0")) //搜索"Remote_self_dimming0"
{
Remote_self_dimming = 0;
}
else if(cmd[0]== 'L') //设置光照阈值命令
{
if(osal_strlen(cmd)==6)//5位数
LIGHT = (cmd[1]-0X30)*10000+(cmd[2]-0X30)*1000+(cmd[3]-0X30)*100+(cmd[4]-0X30)*10+(cmd[5]-0X30)*1;
else if(osal_strlen(cmd)==5)//4位数
LIGHT = (cmd[1]-0X30)*1000+(cmd[2]-0X30)*100+(cmd[3]-0X30)*10+(cmd[4]-0X30)*1;
else if(osal_strlen(cmd)==4)//3位数
LIGHT = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3)//2位数
LIGHT = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2)//1位数
LIGHT = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'A') //设置远程调光命令
{
if(osal_strlen(cmd)==4)//3位数
Remote_dimming_control = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3)//2位数
Remote_dimming_control = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2)//1位数
Remote_dimming_control = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'M') //设置电机命令
{
if(cmd[1]== '0')
{
uint8 on=0;//停止 //无线发送到终端
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
1,
&on,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'F')
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'P')//MP1.5
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
}
}
//0:成功 1失败
int parseOnenetCmd(uint8* cmd)
{
EDP_PACKET_STRUCTURE edpPacket = {NULL, 0, 0, 0}; //协议包
char *cmdid_devid = NULL;
unsigned short cmdid_len = 0;
char *req = NULL;
uint32 req_len = 0;
unsigned char type = 0;
short result = -1;
char *dataPtr = NULL;
char numBuf[10];
int num = 0;
type = EDP_UnPacketRecv(cmd);
switch(type) //判断是pushdata还是命令下发
{
case CMDREQ: //解命令包
result = EDP_UnPacketCmd(cmd, (int8 **)&cmdid_devid, &cmdid_len, (int8 **)&req, &req_len);
if(result == 0) //解包成功,则进行命令回复的组包
{
EDP_PacketCmdResp(cmdid_devid, cmdid_len, req, req_len, &edpPacket);
HalLcdWriteString(req, HAL_LCD_LINE_2); //LCD显示
Ctrl(req); //收到控制命令,控制开发板
}
break;
default:break;
}
if(type == CMDREQ && result == 0) //如果是命令包 且 解包成功
{
EDP_FreeBuffer(cmdid_devid); //释放内存
EDP_FreeBuffer(req);
//回复命令
ESP8266_SendData(edpPacket._data, edpPacket._len); //上传平台
EDP_DeleteBuffer(&edpPacket); //删包
}
return result;
}
/****************************串口回调函数**********************************/
void SampleApp_CallBack(uint8 port, uint8 event)
{
(void)port;
if(0==onenet_login_ok)
{
HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf, SAMPLE_APP_TX_MAX);
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
else if(1==onenet_login_ok)//onenet注册成功 0:未注册,1:注册中 2:注册成功
{
//一个一个字节读
SampleApp_TxLen += HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+SampleApp_TxLen, 1);
//判断是否是注册成功
if(SampleApp_TxLen>=4)
{
if(SampleApp_TxBuf[SampleApp_TxLen-4]==0x20&&SampleApp_TxBuf[SampleApp_TxLen-3]==0x02&&SampleApp_TxBuf[SampleApp_TxLen-2]==0x00&&SampleApp_TxBuf[SampleApp_TxLen-1]==0x00)
{
onenet_login_ok=2;//注册成功
SampleApp_TxLen=0;
}
}
//数组满,清0
if(SampleApp_TxLen>=SAMPLE_APP_TX_MAX)
{
SampleApp_TxLen=0;
}
}
else if(2==onenet_login_ok)
{
//如果是注册成功,读服务器的控制命令
SampleApp_TxLen += HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+SampleApp_TxLen, SAMPLE_APP_TX_MAX-SampleApp_TxLen);
//判断是否是注册成功
if(SampleApp_TxLen>0 && CMDREQ==SampleApp_TxBuf[0])
{
if(0==parseOnenetCmd((uint8*)SampleApp_TxBuf))
{
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
}
else
{
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
//数组满,清0
if(SampleApp_TxLen>=SAMPLE_APP_TX_MAX)
{
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
}
}
#else //终端的
/****************************终端无线发送函数**********************************/
void SampleApp_Send_P2P_Message( void )
{
byte str[6]={0};
byte str1[5]={0};
int len=0;
unsigned short light=0;
light=get_light();//取光照
wan = light/10000+0x30;
qian = (light/1000)%10+0x30;
bai = (light/100)%10+0x30;
shi = (light/10)%10+0x30;
ge = light %10+0x30;
str[4]=wan;
str[3]=qian;
str[2]=bai;
str[1]=shi;
str[0]=ge;
str[5]=mflag+0x30;
sprintf(str1, "%d", light);
len=osal_strlen(str1);
HalUARTWrite(0, "light: ",7); //串口输出
HalUARTWrite(0, str1,len ); //串口输出
HalUARTWrite(0, "\r\n",2);
//无线发送到协调器
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
6,
str,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
void SampleApp_CallBack(uint8 port, uint8 event) //终端的
{
(void)port;
HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf, 1);
}
#endif
/****************************WIFI模块发送数据函数**********************************/
void ESP8266_SendData(char* buff, int len) //协调器的
{
if(len==0) return;
HalUARTWrite(0,buff, len);
}
版权声明:本文为CSDN博主「⁽⁽ଘ晴空万里ଓ⁾⁾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/NICHUN12345/article/details/120407436
前言:
大四上学期的一门课程设计,主要用到CC2530单片机、WiFi模块:ESP826607、光照强度传感器:BH1750、步进电机等…
现分享给大家,希望对大家有所帮助。
实现功能:
数据采集:
- 采集光照强度的数据到ONENET云平台
- 采集终端设备的工作状态
本地控制:
- 控制照明设备的开关
- 控制照明设备是否进入自动模式
- 控制照明设备是否进入手动模式
自动控制:
- 根据当前的光照强度和设定的光照阈值自动控制照明设备的亮灭
- 自动调节照明设备的亮度
远程控制:
- 远程控制照明设备的亮灭
- 远程调节照明设备的亮度
- 远程控制窗帘的开关
- 远程控制照明设备的自动模式
- 远程设定光照阈值
原理图:
PCB图:
3D模型图:
实物图:
手机应用界面:
自动控制代码:
if(flag1==0&&flag2==1) //本地控制未开启且自动控制开启
{
if(end_temp < LIGHT ) //当光照数值小于设定阈值时开灯
{
P1_4 = 0; //D3灯亮
}
else
{
P1_4 = 1; //D3灯灭
}
}
if(flag1==0&&Remote_self_dimming==1) //本地控制未开启且远程自调光控制开启
{
pwmConfig(100-light2); //自动调光,参数取值0~100
}
else
pwmConfig(Remote_dimming_control); //远程调光参数取值0~100
}
本地控制代码:
extern unsigned char flag = 0; //用于记录光照设备开启/关闭状态
extern unsigned char flag1 = 0; //用于标记是否处于手动控制
void SampleApp_HandleKeys( uint8 shift, uint8 keys )
{
(void)shift;
if ( keys & HAL_KEY_SW_6 ) //按下S1进入/退出手动控制模式
{
if(flag1 == 0)
{
flag1 = 1;
}
else
{
flag1 = 0;
}
}
if ( keys & HAL_KEY_SW_1 ) //在手动模式下按下S2控制D3
{
if(flag == 0)
{
flag = 1;
HalLedSet( HAL_LED_3, HAL_LED_MODE_OFF);
}
else
{
flag = 0;
HalLedSet( HAL_LED_3, HAL_LED_MODE_ON);//D3亮代表开启空调
}
}
}
远程控制代码:
void Ctrl(uint8* cmd) //远程控制函数
{
//LED控制
if(strstr((char *)cmd, "D31")) //搜索"D31"
{
P1_4 = 0; //D3亮
}
else if(strstr((char *)cmd, "D30")) //搜索"D30"
{
P1_4 = 1; //D3灭
}
//如果命令是flag21,代表开启自动控制
else if(strstr((char *)cmd, "flag21")) //搜索"flag21"
{
flag2 = 1;
}
else if(strstr((char *)cmd, "flag20")) //搜索"flag20"
{
flag2 = 0;
}
//如果命令是Remote_self_dimming1,代表开启自动调光
else if(strstr((char *)cmd, "Remote_self_dimming1")) //搜索"Remote_self_dimming1"
{
Remote_self_dimming = 1;
}
else if(strstr((char *)cmd, "Remote_self_dimming0")) //搜索"Remote_self_dimming0"
{
Remote_self_dimming = 0;
}
else if(cmd[0]== 'L') //设置光照阈值命令
{
if(osal_strlen(cmd)==6) //5位数
LIGHT = (cmd[1]-0X30)*10000+(cmd[2]-0X30)*1000+(cmd[3]-0X30)*100+(cmd[4]-0X30)*10+(cmd[5]-0X30)*1;
else if(osal_strlen(cmd)==5) //4位数
LIGHT = (cmd[1]-0X30)*1000+(cmd[2]-0X30)*100+(cmd[3]-0X30)*10+(cmd[4]-0X30)*1;
else if(osal_strlen(cmd)==4) //3位数
LIGHT = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3) //2位数
LIGHT = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2) //1位数
LIGHT = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'A') //设置远程调光命令
{
if(osal_strlen(cmd)==4) //3位数
Remote_dimming_control = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3) //2位数
Remote_dimming_control = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2) //1位数
Remote_dimming_control = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'M') //设置电机命令
{
if(cmd[1]== '0')
{
uint8 on=0; //停止 //无线发送到终端
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
1,
&on,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'F')
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'P') //数据格式MP1.5
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
}
}
终端发送数据到协调器代码:
void SampleApp_Send_P2P_Message( void ) //终端发送数据到协调器
{
byte str[6]={0};
byte str1[5]={0};
int len=0;
unsigned short light=0;
light=get_light(); //读取光照值
wan = light/10000+0x30;
qian = (light/1000)%10+0x30;
bai = (light/100)%10+0x30;
shi = (light/10)%10+0x30;
ge = light %10+0x30;
str[4]=wan;
str[3]=qian;
str[2]=bai;
str[1]=shi;
str[0]=ge;
str[5]=mflag+0x30;
sprintf(str1, "%d", light);
len=osal_strlen(str1);
HalUARTWrite(0, "light: ",7); //串口输出
HalUARTWrite(0, str1,len ); //串口输出
HalUARTWrite(0, "\r\n",2);
//无线发送到协调器
AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
6,
str,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
应用层部分代码:
关于ZigBee协议栈的代码太多,故只能放一部分。
/*********************************************************************
* INCLUDES
*/
#include <stdio.h>
#include <string.h>
#include "AF.h"
#include "OnBoard.h"
#include "OSAL_Tasks.h"
#include "SampleApp.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "hal_drivers.h"
#include "hal_key.h"
#if defined ( LCD_SUPPORTED )
#include "hal_lcd.h"
#endif
#include "hal_led.h"
#include "hal_uart.h"
#include "MT_UART.h"
#include "string.h"
#include "stdio.h"
#ifdef ZDO_COORDINATOR //协调器
#include "stdlib.h"
#include "LocalControl.h"
#include "onenet.h" //协议文件
#include "edpkit.h"
#include "pwm.h"
#else //终端
#include "bh1750.h"
#include "motor.h"
#endif
#if !defined( SAMPLE_APP_PORT )
#define SAMPLE_APP_PORT 0
#endif
// This is the max byte count per OTA message.
#if !defined( SAMPLE_APP_TX_MAX )
#define SAMPLE_APP_TX_MAX 80
#endif
#define SAMPLE_APP_RSP_CNT 4
//定时时长最长为65535MS
#define TO_ONENET_TIME 5000
#define TO_COOR_TIME 5000
uint32 LIGHT = 100; //初始化光照阈值
uint8 Remote_dimming_control = 0; //初始化远程调光值
uint8 Remote_self_dimming=1 ;
// This list should be filled with Application specific Cluster IDs.
const cId_t SampleApp_ClusterList[SAMPLE_MAX_CLUSTERS] =
{
SAMPLEAPP_P2P_CLUSTERID,
SAMPLEAPP_PERIODIC_CLUSTERID,
};
const SimpleDescriptionFormat_t SampleApp_SimpleDesc =
{
SAMPLEAPP_ENDPOINT, // int Endpoint;
SAMPLEAPP_PROFID, // uint16 AppProfId[2];
SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2];
SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4;
SAMPLEAPP_FLAGS, // int AppFlags:4;
SAMPLE_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)SampleApp_ClusterList, // byte *pAppInClusterList;
SAMPLE_MAX_CLUSTERS, // byte AppNumOutClusters;
(cId_t *)SampleApp_ClusterList // byte *pAppOutClusterList;
};
endPointDesc_t SampleApp_epDesc =
{
SAMPLEAPP_ENDPOINT,
&SampleApp_TaskID,
(SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc,
noLatencyReqs
};
/*********************************************************************
* GLOBAL VARIABLES
*/
devStates_t SampleApp_NwkState;
uint8 SampleApp_TaskID;
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8 SampleApp_MsgID; //发送消息序列
afAddrType_t SampleApp_P2P_DstAddr; //点播
afAddrType_t SampleApp_Periodic_DstAddr; //广播
static uint8 SampleApp_TxBuf[SAMPLE_APP_TX_MAX+1]={0};
static uint8 SampleApp_TxLen=0;
uint8 onenet_login_ok=0; //onenet注册成功 0:未注册,1:注册中 2:注册成功
unsigned short end_temp; //终端采集的数据
uint8 ge,shi,bai,qian,wan; //数据的各位
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void SampleApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt );
void SampleApp_CallBack(uint8 port, uint8 event);
static void SampleApp_Send_P2P_Message( void );
void motor(void);
uint8 mflag1 = 0; //窗帘状态标志
/****************************应用层初始化函数**********************************/
void SampleApp_Init( uint8 task_id )
{
SampleApp_TaskID = task_id;
SampleApp_NwkState = DEV_INIT;
MT_UartInit(); //串口初始化
MT_UartRegisterTaskID(task_id); //注册串口任务
afRegister( (endPointDesc_t *)&SampleApp_epDesc );
RegisterForKeys( task_id );
#ifdef ZDO_COORDINATOR //协调器初始化
start_pwm(); //初始化PWM,调光
#else
lightInit(); //初始化光照传感器
initSensorPort(); //电机初始化
#endif
SampleApp_P2P_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; //点播
SampleApp_P2P_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_P2P_DstAddr.addr.shortAddr = 0x0000; //发给协调器
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//广播
SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; //可以发送给终端
}
/****************************事件处理函数**********************************/
UINT16 SampleApp_ProcessEvent( uint8 task_id, UINT16 events )
{
(void)task_id; // 故意不引用参数Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
afIncomingMSGPacket_t *MSGpkt;
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
case AF_INCOMING_MSG_CMD: //无线消息事件
SampleApp_ProcessMSGCmd( MSGpkt );
break;
case KEY_CHANGE: //按键事件
SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case ZDO_STATE_CHANGE: //网络状态改变事件
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( (SampleApp_NwkState == DEV_ZB_COORD)||
(SampleApp_NwkState == DEV_ROUTER)
|| (SampleApp_NwkState == DEV_END_DEVICE) )
{
//连网成功后,启动一个定时器
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
}
else
{
// Device is no longer in the network
}
break;
default:
break;
}
osal_msg_deallocate( (uint8 *)MSGpkt );
}
return ( events ^ SYS_EVENT_MSG );
}
#ifdef ZDO_COORDINATOR
//定时器时间到
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
{
if(onenet_login_ok==2) //如果接入onenet成功,启动心跳和发送数据定旳器
{
P1_1 = 0; //点亮D2
// 启动心跳定时器,15秒一次
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_ONENET_HEART_BEAT_EVT,15000 );
// 启动发送数据定时器,3秒一次
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_ONENET_SEND_DATA_EVT,TO_ONENET_TIME );
}
else //如果没有接入onenet成功,重新发起接入
{
OneNet_DevLink();//接入onenet服务器
onenet_login_ok=1;//onenet注册成功 0:未注册,1:注册中 2:注册成功
HalLedBlink (HAL_LED_2, 5, 50, 500);//LED2闪,表示正在接入onenet
// 每5秒尝试接入一次
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,5000 );
}
return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
}
//心跳定时器时间到
if ( events & SAMPLEAPP_ONENET_HEART_BEAT_EVT )
{
if(onenet_login_ok==2)
{
EDP_PacketPing(); //发送心跳
}
// 启动心跳定时器,15秒一次
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_ONENET_HEART_BEAT_EVT,15000 );
return (events ^ SAMPLEAPP_ONENET_HEART_BEAT_EVT);
}
//发送数据定时器时间到
if ( events & SAMPLEAPP_ONENET_SEND_DATA_EVT )
{
if(onenet_login_ok==2)
{
OneNet_SendTempData(end_temp); //发送光照数据到onenet
OneNet_SendLedAndBuzzerData(LIGHT, flag1, P1_4,mflag1,Remote_dimming_control,Remote_self_dimming);//状态发到云服务器
}
// 启动发送数据定时器,3秒一次
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_ONENET_SEND_DATA_EVT,TO_ONENET_TIME );
return (events ^ SAMPLEAPP_ONENET_SEND_DATA_EVT);
}
#else //终端发数据到协调器
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) //定时器时间到
{
static uint16 msCount=0;
if(msCount++>TO_COOR_TIME) //3s发一次数据到协调器
{
SampleApp_Send_P2P_Message(); //BH1750光照数据采集
msCount=0;
}
motorCtrl();//每1ms执行一次步进电机
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,1 );
return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
}
#endif
return ( 0 ); // Discard unknown events.
}
/****************************无线消息处理函数**********************************/
void SampleApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
switch ( pkt->clusterId )
{
case SAMPLEAPP_P2P_CLUSTERID: // 接收终端上传的光照数据
#ifdef ZDO_COORDINATOR
{
ge = pkt->cmd.Data[0]-0x30; //终端数据
shi = pkt->cmd.Data[1]-0x30;
bai = pkt->cmd.Data[2]-0x30;
qian = pkt->cmd.Data[3]-0x30;
wan = pkt->cmd.Data[4]-0x30;
mflag1 = pkt->cmd.Data[5]-0x30; //窗帘状态标志
end_temp = wan*10000+qian*1000+bai*100+shi*10+ge;
uint16 light2=end_temp;
if(flag1==0&&flag2==1) //本地控制未开启且自动控制开启
{
if(end_temp < LIGHT )//当光照数值小于设定阈值时开灯
{
P1_4 = 0; //D3灯亮
}
else
{
P1_4 = 1; //D3灯灭
}
}
if(flag1==0&&Remote_self_dimming==1)//本地控制未开启且远程自调光控制开启
{
pwmConfig(100-light2); //自动调光,参数取值0~100
}
else
pwmConfig(Remote_dimming_control); //远程调光
// Pwm(Remote_dimming_control);
}
break;
#else //终端收到协调器的电机指令
case SAMPLEAPP_PERIODIC_CLUSTERID:
{
uint8 buff[3];
osal_memcpy(buff,pkt->cmd.Data,sizeof(buff));
motorFlag1=buff[0];//P或F
uint8 a=buff[1]-0x30; //转圈个位
uint8 b=buff[2]-0x30; //转圈小数位
float c=a+(float)b/10; //个位和小数位结合
motorFlag = c; //motorFlag全局变量,将值传出去
}
break;
#endif
default:
break;
}
}
#ifdef ZDO_COORDINATOR
/****************************远程控制函数**********************************/
void Ctrl(uint8* cmd) //远程控制
{
//LED2控制
if(strstr((char *)cmd, "D31")) //搜索"D31"
{
P1_4 = 0; //D3亮
}
else if(strstr((char *)cmd, "D30")) //搜索"D30"
{
P1_4 = 1; //D3灭
}
//如果命令是flag21,代表开启自动控制
else if(strstr((char *)cmd, "flag21")) //搜索"flag21"
{
flag2 = 1;
}
else if(strstr((char *)cmd, "flag20")) //搜索"flag20"
{
flag2 = 0;
}
//如果命令是Remote_self_dimming1,代表开启自动控制
else if(strstr((char *)cmd, "Remote_self_dimming1")) //搜索"Remote_self_dimming1"
{
Remote_self_dimming = 1;
}
else if(strstr((char *)cmd, "Remote_self_dimming0")) //搜索"Remote_self_dimming0"
{
Remote_self_dimming = 0;
}
else if(cmd[0]== 'L') //设置光照阈值命令
{
if(osal_strlen(cmd)==6)//5位数
LIGHT = (cmd[1]-0X30)*10000+(cmd[2]-0X30)*1000+(cmd[3]-0X30)*100+(cmd[4]-0X30)*10+(cmd[5]-0X30)*1;
else if(osal_strlen(cmd)==5)//4位数
LIGHT = (cmd[1]-0X30)*1000+(cmd[2]-0X30)*100+(cmd[3]-0X30)*10+(cmd[4]-0X30)*1;
else if(osal_strlen(cmd)==4)//3位数
LIGHT = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3)//2位数
LIGHT = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2)//1位数
LIGHT = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'A') //设置远程调光命令
{
if(osal_strlen(cmd)==4)//3位数
Remote_dimming_control = (cmd[1]-0X30)*100+(cmd[2]-0X30)*10+(cmd[3]-0X30)*1;
else if(osal_strlen(cmd)==3)//2位数
Remote_dimming_control = (cmd[1]-0X30)*10+(cmd[2]-0X30)*1;
else if(osal_strlen(cmd)==2)//1位数
Remote_dimming_control = (cmd[1]-0X30)*1;
}
else if(cmd[0]== 'M') //设置电机命令
{
if(cmd[1]== '0')
{
uint8 on=0;//停止 //无线发送到终端
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
1,
&on,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'F')
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
else if(cmd[1]== 'P')//MP1.5
{
uint8 buff[3];
buff[0]=cmd[1];
buff[1]=cmd[2];
buff[2]=cmd[4];
AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
4,
buff,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
}
}
}
//0:成功 1失败
int parseOnenetCmd(uint8* cmd)
{
EDP_PACKET_STRUCTURE edpPacket = {NULL, 0, 0, 0}; //协议包
char *cmdid_devid = NULL;
unsigned short cmdid_len = 0;
char *req = NULL;
uint32 req_len = 0;
unsigned char type = 0;
short result = -1;
char *dataPtr = NULL;
char numBuf[10];
int num = 0;
type = EDP_UnPacketRecv(cmd);
switch(type) //判断是pushdata还是命令下发
{
case CMDREQ: //解命令包
result = EDP_UnPacketCmd(cmd, (int8 **)&cmdid_devid, &cmdid_len, (int8 **)&req, &req_len);
if(result == 0) //解包成功,则进行命令回复的组包
{
EDP_PacketCmdResp(cmdid_devid, cmdid_len, req, req_len, &edpPacket);
HalLcdWriteString(req, HAL_LCD_LINE_2); //LCD显示
Ctrl(req); //收到控制命令,控制开发板
}
break;
default:break;
}
if(type == CMDREQ && result == 0) //如果是命令包 且 解包成功
{
EDP_FreeBuffer(cmdid_devid); //释放内存
EDP_FreeBuffer(req);
//回复命令
ESP8266_SendData(edpPacket._data, edpPacket._len); //上传平台
EDP_DeleteBuffer(&edpPacket); //删包
}
return result;
}
/****************************串口回调函数**********************************/
void SampleApp_CallBack(uint8 port, uint8 event)
{
(void)port;
if(0==onenet_login_ok)
{
HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf, SAMPLE_APP_TX_MAX);
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
else if(1==onenet_login_ok)//onenet注册成功 0:未注册,1:注册中 2:注册成功
{
//一个一个字节读
SampleApp_TxLen += HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+SampleApp_TxLen, 1);
//判断是否是注册成功
if(SampleApp_TxLen>=4)
{
if(SampleApp_TxBuf[SampleApp_TxLen-4]==0x20&&SampleApp_TxBuf[SampleApp_TxLen-3]==0x02&&SampleApp_TxBuf[SampleApp_TxLen-2]==0x00&&SampleApp_TxBuf[SampleApp_TxLen-1]==0x00)
{
onenet_login_ok=2;//注册成功
SampleApp_TxLen=0;
}
}
//数组满,清0
if(SampleApp_TxLen>=SAMPLE_APP_TX_MAX)
{
SampleApp_TxLen=0;
}
}
else if(2==onenet_login_ok)
{
//如果是注册成功,读服务器的控制命令
SampleApp_TxLen += HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+SampleApp_TxLen, SAMPLE_APP_TX_MAX-SampleApp_TxLen);
//判断是否是注册成功
if(SampleApp_TxLen>0 && CMDREQ==SampleApp_TxBuf[0])
{
if(0==parseOnenetCmd((uint8*)SampleApp_TxBuf))
{
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
}
else
{
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
//数组满,清0
if(SampleApp_TxLen>=SAMPLE_APP_TX_MAX)
{
SampleApp_TxLen=0;
osal_memset(SampleApp_TxBuf, 0, SAMPLE_APP_TX_MAX);
}
}
}
#else //终端的
/****************************终端无线发送函数**********************************/
void SampleApp_Send_P2P_Message( void )
{
byte str[6]={0};
byte str1[5]={0};
int len=0;
unsigned short light=0;
light=get_light();//取光照
wan = light/10000+0x30;
qian = (light/1000)%10+0x30;
bai = (light/100)%10+0x30;
shi = (light/10)%10+0x30;
ge = light %10+0x30;
str[4]=wan;
str[3]=qian;
str[2]=bai;
str[1]=shi;
str[0]=ge;
str[5]=mflag+0x30;
sprintf(str1, "%d", light);
len=osal_strlen(str1);
HalUARTWrite(0, "light: ",7); //串口输出
HalUARTWrite(0, str1,len ); //串口输出
HalUARTWrite(0, "\r\n",2);
//无线发送到协调器
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
6,
str,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
void SampleApp_CallBack(uint8 port, uint8 event) //终端的
{
(void)port;
HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf, 1);
}
#endif
/****************************WIFI模块发送数据函数**********************************/
void ESP8266_SendData(char* buff, int len) //协调器的
{
if(len==0) return;
HalUARTWrite(0,buff, len);
}
版权声明:本文为CSDN博主「⁽⁽ଘ晴空万里ଓ⁾⁾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/NICHUN12345/article/details/120407436
暂无评论