CC2530_NODERED平台控制LED灯实验
实验内容
- NODERED平台创建按键应用。
- 在NODERED平台控制LED模块上的LED亮灭。
实验目的
- NODERED平台应用创建。
实验环境
实验所需硬件
序号 | 名称 | 数量 | 备注 |
---|---|---|---|
1 | 电脑 | 1台 | 系统Windows7及以上 |
2 | CC2530底座模块 | 2个 | · |
3 | LED模块 | 1个 | · |
4 | WIFI模块 | 1个 | · |
5 | CC Debugger 仿真器和连接线 | 1套 | · |
6 | USB线 | 1根 | · |
7 | 实验代码 | 1份 | · |
实验所需软件
- IAR 驱动安装步骤
-
CC Debugger 驱动安装步骤
-
NODE RED平台安装应用手册
- Git软件下载(可选)
CC Debugger 仿真器和连接线
USB线
实验原理
ZigBee基本通信方式
ZigBee的通讯方式主要有三种点播、组播、广播。点播顾名思义就是点对点通信,也是2个设备之间的通讯,不允许有第三个设备收到信息;组播就是把网络中的节点分组,每一个组员发出的信息只有相同组号的组员才能收到。广播最广泛的也就是1个设备上发出的信息所有设备都能接收到。这也是ZigBee通信的基本方式。
ZigBee网络地址类型
序号 | 地址类型 | 说明 |
---|---|---|
1 | AddrNotPresent | 依照绑定表 |
2 | Addr16Bit | 16位地址,常用于点播 |
3 | Addr64Bit | Addr64Bit |
4 | AddrGroup | 组播 |
5 | AddrBroadcast | 广播 |
以上的的地址类型均保存在afAddrMode_t。在实际使用过程中考虑功耗,常用使用16位地址,原因16位地址是通过路由算法计算出来的,在传输路径上通过的节点较少最大的节省了网络功耗。16位地址可分成如下几类如表。
序号 | 地址类型 | 说明 |
---|---|---|
1 | 0xFFFF | 对所有设备广播,包括睡眠 |
2 | 0xFFFE | 间接传输,通过绑定表寻找网络短地址 |
3 | 0xFFFD | 对没休眠的设备广播 |
4 | 0xFFFC | 给协调器和路由器广播 |
5 | 0x0000 | 给协调器通信 |
6 | 0x0001-0xFFFB | 用户自设定的目标地址 |
WIFI技术基本概念
WIFI英语全称是Wireless Fidelity,中文译成无线保真。WIFI是建立连接和进行通讯的手段,它对应一套通讯的规则,保证让两个节点能互相连接,设备连接建立后,通过TCP/IP和UDP等协议,传输数据,连接互联网络。WIFI模块的STA模式和AP模式。
AP模式:Access Point,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下。AP和AP之间允许相互连接。Sta模式(SP模式):Station类似于无线终端,sta本身并不接受无线的接入,它可以连接到AP,一般无线网卡即工作在该模式。对照表如下:
分类 | AP模式 | SP模式 |
---|---|---|
接入网络 | 接受 | 不接受 |
网卡 | 需要 | 不需要 |
终端 | 有线 | 无线 |
WiFi模块原理图
实验步骤
① 将WIFI模块、LED模块分别安装CC2530底座上,CC Debugger连接电脑与协调器节点底座,如下图所示:
② 轻按CCDebugger复位按键,指示灯变绿,表示连接正常。如下图:
③ 访问github,进入github界面后点击Code,Clone HTTPS安全链接,如下图所示:
④ 打开电脑终端,进入工作目录workspace (workspace 为工程文件夹所在目录):
$ cd workspace
⑤ 运行clone
命令:
$ git clone https://github.com/aiotcom/eps.git
下载目录至指定文件夹下。
如果提示“command not found”表示电脑没有安装Git,请至Git官网下载。
如果电脑没有安装 Git 软件,也可以进入Github,点击 Code
-> DownLoad ZIP
下载所有工程代码。如下图所示:
如果电脑没有公网,可以进:D盘\实验教程与代码选择相应的代码。
④ 打开已经安装NODERED的电脑:
D:\> ipconfig /all //查看本机IP
本机IP
D:\> NODE-RED //启动本机nodered服务
启动NODE RED服务
⑤ 打开浏览器,输入地址127.0.0.1:1880 打开本机node red 主页:
导入本次试验的NODE RED流程
部署本次试验NODE RED流程
打开本次试验的UI界面(输入地址127.0.0.1:1880/ui)
⑥ 打开 IAR Embedded Workbench
工程软件,点击工具栏: File
-> Open
-> Workspace
,选择工程文件:基于CC2530 NODERED实验\6.NODERED平台控制LED灯实验\Projects\zstack\Samples\SampleApp\CC2530DB\SampleApp.eww
并打开。
⑦ 待工程启动完毕,修改PANID或者信道防止与他人网络冲突,终端与协调器代码共用该配置文件如图:
⑧ 设置工程配置为CoordinatorEB
。
⑨ 打开WiFiGate.h
,修改WIFI热点的名字与密码,以及根据自己的NODE RED服务器的IP地址和端口,修改connect_IP,如下图:
⑩ 点击Make
按钮,重新编译文件,显示没有错误。
⑪ 点击Download and Debug
按钮,将程序下载到模块中。
⑫ 点击X
退出仿真模式。
⑬ 将CCDebugger连接到终端节点,选择工程的配置为EndDeviceEB
,如图:
⑭ 点击Make
按钮,重新编译文件,显示没有错误。
⑮ 点击Download and Debug
按钮,将程序下载到模块中。
⑯ 点击X
退出仿真模式。
⑰ 移除CC Debugger
仿真器,采用USB线供电,接协调器节点的底座。
⑱ 观察WIFI模块状态灯—长亮表示已经连接到路由器:
⑲ NODERED平台显示实验数据。(脚本位于:基于CC2530 NODERED实验\6.NODERED平台控制LED灯实验\LED控制.json
)。具体操作参考node red平台应用手册。
代码讲解
终端节点
① 程序目录结构,源代码文件如下图。代码中有大量ZigBee底层的代码,我们只要主要关心下图中标出的文件代码,ZigBee底层的代码会使用即可。
② EndDevice.c
->SampleApp_Init()
函数是应用代码的入口函数,对LED模块初始化、初始化Point_To_Point_DstAddr
结构,注册端点。
void SampleApp_Init( uint8 task_id )
{
SampleApp_TaskID = task_id;
SampleApp_NwkState = DEV_INIT;
SampleApp_TransID = 0;
UartInit(HAL_UART_PORT_1,HAL_UART_BR_115200);//用于调试
LED_Init();//初始化按键模块LED控制管脚,按键控制管脚
printf("i am end device\r\n");//串口打印
// 点对点通讯定义
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; //点播
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000;//发给协调器
// 填写端点
EndDevice_epDesc.endPoint = SAMPLEAPP_ENDPOINT;
EndDevice_epDesc.task_id = &SampleApp_TaskID;
EndDevice_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&EndDevice_SimpleDesc;
EndDevice_epDesc.latencyReq = noLatencyReqs;
// 注册端点
afRegister( &EndDevice_epDesc );
}
EndDevice.c
->SampleApp_ProcessEvent()
函数是任务处理函数。在该函数中调用SampleApp_MessageMSGCB()
处理无线信道的指令。
switch ( MSGpkt->hdr.event )
{
// Received when a messages is received (OTA) for this endpoint
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB( MSGpkt );
break;
// Received whenever the device changes state in the network
case ZDO_STATE_CHANGE:
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ((SampleApp_NwkState == DEV_ROUTER)
||(SampleApp_NwkState == DEV_END_DEVICE))
{
printf("connect coordinator\r\n");
}
break;
default:
break;
}
协调器节点
① 程序目录结构,源代码文件如下图。代码中有大量ZigBee底层的代码,我们只要主要关心下图中标出的文件代码,ZigBee底层的代码会使用即可。
② Coordinator.c
->SampleApp_Init()
函数是应用代码的入口函数,注册端点。
void SampleApp_Init( uint8 task_id )
{
SampleApp_TaskID = task_id;
SampleApp_NwkState = DEV_INIT;
SampleApp_TransID = 0;
UartInit(HAL_UART_PORT_1,HAL_UART_BR_115200);//初始化串口用于调试
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; //点播
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0;
//广播通信定义
Boardcast_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
Boardcast_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Boardcast_DstAddr.addr.shortAddr = 0Xffff;
// 填写端点
Coordinator_epDesc.endPoint = SAMPLEAPP_ENDPOINT;
Coordinator_epDesc.task_id = &SampleApp_TaskID;
Coordinator_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&Coordinator_SimpleDesc;
Coordinator_epDesc.latencyReq = noLatencyReqs;
// 注册端点
afRegister( &Coordinator_epDesc );
osal_start_timerEx( SampleApp_TaskID, READ_KEY_MSG_EVT,3000);
}
WiFiGate.c
中WiFiGate_Init()
函数初始化WIFI模块的IO及模块的通信串口。
void WiFiGate_Init( uint8 task_id )
{
WiFiGate_TaskId = task_id;
osal_start_timerEx( WiFiGate_TaskId, WIFI_PROCESS_PRODIC,2000);
UartInit(HAL_UART_PORT_0,HAL_UART_BR_115200);
P1SEL &= ~(BV(5)|BV(6));
P1DIR |= BV(5)|BV(6);
P1_5 = 1;
P1_6 = 0;
printf("wifi connect start\r\n");
}
WiFiGate.c
中WiFiGate_ProcessEvent()
,调用WiFiGate_InitProcess()
初始化WIFI模块。初始化完成WiFiModeInitDone
置1。WiFi_ReadCommand()
,获取OneNET下发的指令。解析指令调用Send_LEDCtrl()
函数发送到LED节点。
case 13:
len = GET_RECV_LENGHT();
if(len){
if((WiFiRecvLenght+len) >= (WIFI_RECV_DATA_BUFFER_LEN-1)){
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
printf("overflow\r\n");
}
GET_RECV_DATA(&WiFiRecvDataBuffer[WiFiRecvLenght],len);
WiFiRecvLenght = WiFiRecvLenght + len;
}
if((WiFiRecvLenght)&&(!strstr((const char*)WiFiRecvDataBuffer,(const char*)"$"))){//没有~这个符号
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED1,1");
if(cptr){
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
Send_LEDCtrl(1,1);
printf("~LED_ON_1");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED1,0");
if(cptr){
Send_LEDCtrl(1,0);
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
printf("~LED_OFF_1");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED2,1");
if(cptr){
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
Send_LEDCtrl(2,1);
printf("~LED_ON_2");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED2,0");
if(cptr){
Send_LEDCtrl(2,0);
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
printf("~LED_OFF_2");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED3,1");
if(cptr){
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
Send_LEDCtrl(3,1);
printf("~LED_ON_3");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED3,0");
if(cptr){
Send_LEDCtrl(3,0);
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
printf("~LED_OFF_3");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED4,1");
if(cptr){
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
Send_LEDCtrl(4,1);
printf("~LED_ON_4");
}
cptr = (uint8*)strstr((const char*)WiFiRecvDataBuffer,(const char*)"$LED4,0");
if(cptr){
Send_LEDCtrl(4,0);
WiFiRecvLenght = 0;
memset((void*)WiFiRecvDataBuffer,0,WIFI_RECV_DATA_BUFFER_LEN);
printf("~LED_OFF_4");
}
break;
常见问题
-
弹出警告窗口,不能下载程序。
- 请确认CCDebugger驱动否安装。
- 轻按CCDebugger仿真器的按键,指示灯不是绿色连接有问题。
- CCDebugger仿真器是否正常接入到底座,参考实验步骤第一步。
-
下载代码后程序没观察到实验现象。
- 请重新上电,或者按下底座上的复位按键。
- 模块没有安装稳妥。
- 两个节点的PANID、信道是否相同。
-
NODERED平台设备没有上线。
- WIFI名字、WIFI密码、NODERED服务器IP和端口等信息是否正确。
实验思考
- 在NODERED平台增加一个按键控制LED的全部亮/灭。