Zigbee项目总结

目前只是实现了6个下行及上行命令

链路质量探测模块

PC->协调器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static void SerialApp_CallBack(uint8 port,uint8 event)
{

uint8 sBuf[50];
uint16 nLen=0;
if(event!=HAL_UART_TX_EMPTY)
{
nLen=HalUARTRead(SERIAL_APP_PORT,sBuf,50);
if(nLen>0)
{
//处理从Pc至协调器的相关命令
uint8 messageType = sBuf[0];
uint8 msgSubtype = sBuf[1];
uint8 *rcvBuf=sBuf;
if(msgSubtype ==NetID)
{
switch(messageType)
{
case COLLECT_SETTING_CMD: // 感知节点采集参数设置
cmdCollectSet(rcvBuf);
//设置响应超时时间
osal_stop_timerEx(Coord_TaskID,COLLECT_SETTING_CMD_OUTTIME_EVT);

osal_start_timerEx(Coord_TaskID,COLLECT_SETTING_CMD_OUTTIME_EVT,MAX_CLK_TIME);
HalLedSet(HAL_LED_1,HAL_LED_MODE_BLINK);
break;

case NEIGHBOR_DETECT_CMD: //邻居探测(发现节点的邻居)
break;

case LINK_TEST_CMD: //链路探测(测试包接收成功率)
cmdLinkTest(rcvBuf);
//设置响应超时时间
osal_stop_timerEx(Coord_TaskID,LINK_TEST_CMD_OUTTIME_EVT);
osal_start_timerEx(Coord_TaskID,LINK_TEST_CMD_OUTTIME_EVT,MAX_CLK_TIME);
HalLedSet(HAL_LED_1,HAL_LED_MODE_BLINK);
break;

协调器串口从PC机接收到字符命令,判断是否为链路质量探测命令?是进入相应模块 cmdLinkTest进行处理

协调器->路由/终端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

/******************************************************/
//链路测试命令下发
void cmdLinkTest(byte *Msg)
{

byte LinkTest[4];
byte DestAddr[2];
byte DestNodeId;
byte Send_Source_NodeId;
int i;
/*HalLedBlink(HAL_LED_1,2,50,500);*/
for(i=0;i<4;i++)
{
LinkTest[i]=Msg[i];

}
//获取到源节点ID
Send_Source_NodeId=LinkTest[2];
//获取到目的节点ID号
DestNodeId=LinkTest[3];
DestAddr[0]=(byte)((g_AddrTable[DestNodeId]>>8) & 0x00FF);
DestAddr[1]=(byte)(g_AddrTable[DestNodeId]&0x00FF);

Coord_DstAddr.addrMode=(afAddrMode_t)afAddr16Bit;
Coord_DstAddr.endPoint=ENDPOINT;
//节点Id号对应的网络地址
Coord_DstAddr.addr.shortAddr=g_AddrTable[Send_Source_NodeId];

AF_DataRequest(//目的地址为命令中目的节点ID号对应的网络地址
&Coord_DstAddr,
//端点描述符
&Coord_epDesc,
//簇ID
LINK_TEST_CLUSTERID,
//发送字节长度
2,
//发送数据
DestAddr,
//发送序列:q
&Coord_TransID,
//设备为路由发现
AF_DISCV_ROUTE,
//路由半径
AF_DEFAULT_RADIUS);

}

此模块功能:
(20-21):将要发送的源节点ID通过网络地址与节点号表 (g_AddrTable)转换Zigbee网络地址发送到源节点;
26Line: 当然目的节点号也要转换成网络地址。

源节点收到无线数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/******************链路质量测试命令*****************/
//即协调器发送到源节点的链路质量探测命令,后源节点到目的节点
//发送源节点ID号到目的节点
void LinkTest_To_Dest(afIncomingMSGPacket_t *msg)
{

HalLedSet(HAL_LED_1,HAL_LED_MODE_BLINK);
uint16 shortAddr;
byte DestAddr[2];
byte SourceNodeInf[3]; //要发送的源节点ID号
uint8 sendNumber=0;
byte send_PacketComplect=0;
osal_memcpy(DestAddr,msg->cmd.Data,2);
/*将8位数组的目的地址转换16位地址的变量*/
shortAddr=DestAddr[0];
shortAddr=(shortAddr<<8)|(DestAddr[1]);
RouterEnd_DstAddr.addrMode=(afAddrMode_t)afAddr16Bit;
RouterEnd_DstAddr.endPoint=ENDPOINT;
RouterEnd_DstAddr.addr.shortAddr=shortAddr;
//读取到源节点ID号
osal_nv_read(NODEID_NV,0,1,&NodeID);
SourceNodeInf[0]=NodeID;
for(;send_PacketComplect<PacketNumber_LinkTest;send_PacketComplect++)
{
Onboard_wait(50000);
SourceNodeInf[1]=sendNumber;
SourceNodeInf[2]=send_PacketComplect;
if( AF_DataRequest( &RouterEnd_DstAddr,
//端点描述符
&RouterEnd_epDesc,
//簇ID
LINK_NODE_CLUSTERID,
//发送字节长度
3,
//发送数据
SourceNodeInf,
//发送序列号
&RouterEnd_TransID,
//设备为路由发现
AF_DISCV_ROUTE,
//路由半径
AF_DEFAULT_RADIUS)==afStatus_SUCCESS)
{
sendNumber++;
}

}
return;
}

功能:
将协调器发来的目的节点ID号的网络地址取出,以此为地址发送数据到目的节点。后面加了测试PRR的,所以统计了发送包成功数及接收包个数。

目的节点无线接收数据后反馈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**********************链路质量测试反馈命令****************************/
//将自身节点ID与网络ID打包发送
void LinkTest_Rsp(afIncomingMSGPacket_t *msg)
{

HalLedSet(HAL_LED_2,HAL_LED_MODE_BLINK);
byte SourceNodeId,DestNodeId;
byte send_LinkTestPacket[6];
//从flash中读取节点ID
osal_nv_read(NODEID_NV,0,1,&NodeID);
DestNodeId=NodeID;
SourceNodeId=(byte)msg->cmd.Data[0];

send_LinkTestPacket[0]=SourceNodeId;
send_LinkTestPacket[1]=DestNodeId;
send_LinkTestPacket[2]=msg->rssi;
send_LinkTestPacket[3]=msg->LinkQuality;
/*send_LinkTestPacket[4]=g_ReceiveNumber;*/
send_LinkTestPacket[4]=g_ReceiveNumber;
send_LinkTestPacket[5]=msg->cmd.Data[1]+1;

RouterEnd_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
RouterEnd_DstAddr.endPoint = ENDPOINT;
RouterEnd_DstAddr.addr.shortAddr= 0x0000;

//发送探测包反馈消息至协调器
AF_DataRequest(//目的地址为协调器短地址0x0000
&RouterEnd_DstAddr,
//端点描述符
&RouterEnd_epDesc,
//簇ID
RELINK_TEST_CLUSTERID,
//发送字节长度
6,
//发送数据
send_LinkTestPacket,
//发送序列号
&RouterEnd_TransID,
//设备为路由发现
AF_DISCV_ROUTE,
//路由半径
AF_DEFAULT_RADIUS);

g_ReceiveNumber=0;
return;

}

功能:将LQI 、RSSI等数据组包发送至协调器。

协调器接收到反馈数据包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*****************上报命令函数定义*****************/
void ReLinkTest_Rsp(afIncomingMSGPacket_t *msg)
{

byte recev[6];
halIntState_t intState;
osal_memcpy(recev,msg->cmd.Data,6);
byte reLinkTest_Msg[10];
//byte sourceNodeID;
osal_nv_read(NETID_NV,0,1,&NetID);
reLinkTest_Msg[0]=RELINK_TEST_MSG; //消息类型
reLinkTest_Msg[1]=Coord_TransID; //消息序列
reLinkTest_Msg[2]=NetID; //子网ID
reLinkTest_Msg[3]=recev[0]; //源节点ID
reLinkTest_Msg[4]=recev[1]; //目的节点ID
reLinkTest_Msg[5]=recev[2]; //rssi
reLinkTest_Msg[6]=recev[3]; //LQI
// reLinkTest_Msg[7]=recev[4];
//reLinkTest_Msg[8]=recev[5];
reLinkTest_Msg[7]=recev[4]/recev[5];
reLinkTest_Msg[8]=(recev[4]%recev[5])*10/recev[5];
reLinkTest_Msg[9]=(recev[4]%recev[5])*10%recev[5];
HAL_ENTER_CRITICAL_SECTION(intState);
HalUARTWrite(SERIAL_APP_PORT,reLinkTest_Msg,10);
HAL_EXIT_CRITICAL_SECTION(intState);
}

功能:将数据重新组包发送至PC机