基于Zigbee的SHT10温湿度数据采集系统(已实现控制12个终端节点)——Zigbee协调器主要代码解析

之前实现了基于Zigbee的SHT10温湿度数据采集系统,这里来重新复盘一些主要的知识和代码。

写在前面:

  • 1 功能介绍:使用Zigbee终端节点采集环境的温度和湿度数据,然后将数据无线发送的Zigbee协调器,最后在电脑端显示获得到的数据。
  • 2 我没有让Zigbee终端节点 使用周期定时发送,而是通过电脑端的串口来控制 ,即:当电脑需要数据时,就返回终端节点的数据;不需要时终端节点就不会上传数据。 我这样的做法比较方便,因为选择什么时间上传 和 多久上传一次都可以由自己来决定!
  • 3 我设计的Zigbee协调器和Zigbee终端节点没有采用广播的发送方式,因为我之前要控制12个节点,广播的效果实在不太好,而且对首发时间的要求并不算高,所以我采用“单播轮询”的发送方式。
  • 4关于地址的选择,我没有使用64位的IEEE地址,我用的16位的短地址PANID,当然这些在AF_DataRequest()函数都写得很清楚。
  • 5其余细节在说代码的时候,具体再说。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

下面主要介绍一下,Zigbee协调器的SampleApp.c文件的代码:
首先,我们要配置与电脑通信的串口。
这里别忘了在SampleApp.c头文件引入串口头文件#include “hal_uart.h”,我们的波特率设置为115200.

/*  串口基本定义    */
#define MY_DEFINE_UART_PORT 0     //自定义串口号(0,1);
#define RX_MAX_LENGTH       20    //接收缓冲区最大值: 20个字节;
uint8   RX_BUFFER[RX_MAX_LENGTH]; //接收缓冲区;

void UartCallBackFunction(uint8 port , uint8 event); //回调函数声明,定义在最后面;

/*   配置串口      */
halUARTCfg_t uartConfig; //定义串口配置结构体变量;
void Uart_Config(void); //函数声明;
void Uart_Config(void)  //函数定义;//结构体的定义函数
{ 
  uartConfig.configured            = TRUE;  //允许配置;
  uartConfig.baudRate              = HAL_UART_BR_115200;//波特率;
  uartConfig.flowControl           = FALSE;
  uartConfig.flowControlThreshold  = 64;   //don't care - see uart driver.
  uartConfig.rx.maxBufSize         = 128;  //串口接收缓冲区大小
  uartConfig.tx.maxBufSize         = 128;  //串口发送缓冲区大小
  uartConfig.idleTimeout           = 6;    //don't care - see uart driver.
  uartConfig.intEnable             = TRUE; //使能中断
  uartConfig.callBackFunc          = UartCallBackFunction; //指定回调函数名;
}
  • 下面是我的串口回调函数static void UartCallBackFunction(uint8 port , uint8 event)。
  • 在里面我用osal_set_event自定义了任务事件,SAMPLEAPP_SEND_PERIODIC_MSG_EVT1,即:当接收到的字符为01或者02或者03时,在任务事件处理函数,SampleApp_ProcessEvent里处理相应的事件。
  • 01 控制终端节点1~终端节点4(我试过01,控制6个节点效果也是可以的,很少丢包)
  • 02控制终端节点5~终端节点8
  • 03控制终端节点9~终端节点12
static void UartCallBackFunction(uint8 port , uint8 event)
{
  uint8 shuang[2]={0,0};
  uint16 nlen = 0; //接收到字符串大小;
  
   if(event !=HAL_UART_TX_EMPTY)
    {
      nlen = HalUARTRead(0,shuang,2);
   
    if(nlen > 0) //有数据存在;
    {
              if((shuang[0] ==0x30)&&(shuang[1]==0x31))//01 //1END~4END
              {        
                chose=1;
                x1=1;x2=1;x3=1;x4=1;
               osal_set_event(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT1);            
              }
              
              else if((shuang[0] ==0x30)&&(shuang[1]==0x32))//02 //4END~8END
              {
                chose=2;
                x5=1;x6=1;x7=1;x8=1;//
                osal_set_event(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT1);           
              }
              
              else if((shuang[0] ==0x30)&&(shuang[1]==0x33))//03 //9END~12END
              {
                chose=3;
                x9=1;xa=1;xb=1;xc=1;//9~12
                osal_set_event(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT1);            
              }
        }
    } 
}


下面介绍一下Zigbee协调器的接收消息事件 处理函数SampleApp_MessageMSGCB。

  • 这里有的人会问。为什么你的接收咋就没有short address和endpoint,直接上来就判断clusterId?
  • 因为这个SampleApp_MessageMSGCB( )函数是属于应用层范畴,你的short address和endpoint在NWK层就被解析了我们在APP层就区分一下clusterId就可以了。
  • 接收的数据一共分为两类:其中SAMPLEAPP_P3P1_CLUSTERID是接收1~9号终端节点返回的PANID
  • SAMPLEAPP_P3P2_CLUSTERID是接收10~18号节点返回的PANID.(不是我写错了,因为去年我需要控制18个Zigbee终端节点,当然控制12个这么写也没错)
  • SAMPLEAPP_P2P1_CLUSTERID~SAMPLEAPP_P2PC_CLUSTERID是1到12号Zigbee终端节点返回的SHT10传感器温度和湿度的DATA。
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{

  switch ( pkt->clusterId )
  {
    case SAMPLEAPP_P3P1_CLUSTERID://接受终端  网络ID的镞//ok//1~9
      {
        Addrtable[(pkt->cmd.Data[0]*10)+(pkt->cmd.Data[1])]=(((uint16)pkt->cmd.Data[2])<<8)|(((uint16)pkt->cmd.Data[3])&0x00ff);
       
       //初始化D2
  P1SEL&=0Xfd;//1111 1101
  P1DIR|=0x02;  //P11定义为输出0000 0010
  P1_1 =0;
      }
      break;
      
        case SAMPLEAPP_P3P2_CLUSTERID://接受终端  网络ID的镞//ok//10~18
      {
        Addrtable[(pkt->cmd.Data[0]*10)+(pkt->cmd.Data[1])]=(((uint16)pkt->cmd.Data[2])<<8)|(((uint16)pkt->cmd.Data[3])&0x00ff);
       
       //初始化D2
  P1SEL&=0Xfd;//1111 1101
  P1DIR|=0x02;  //P11定义为输出0000 0010
  P1_1 =0;
      }
      break;
 
        case SAMPLEAPP_P2P1_CLUSTERID:
      {
        if(x1==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x1=0;
        }
      }
      break;
      
              case SAMPLEAPP_P2P2_CLUSTERID:
      {
        if(x2==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
       x2=0;
        }
      }
      break;
      
  case SAMPLEAPP_P2P3_CLUSTERID:
      {
        if(x3==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x3=0;
        }
        }
      break;
      
    case SAMPLEAPP_P2P4_CLUSTERID:
      {
        if(x4==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x4=0;
        } 
        }
      break;
      
          case SAMPLEAPP_P2P5_CLUSTERID:
      {
        if(x5==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x5=0;
        }
        }
      break;
      
               case SAMPLEAPP_P2P6_CLUSTERID:
      {
        if(x6==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x6=0;
        }
        }
      break;
      
                     case SAMPLEAPP_P2P7_CLUSTERID:
      {
        if(x7==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x7=0;
        }
        }
      break;
      
   case SAMPLEAPP_P2P8_CLUSTERID:
      {
        if(x8==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x8=0;
        }
        }
      break;
      
         case SAMPLEAPP_P2P9_CLUSTERID:
      {
        if(x9==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        x9=0;
        }
        }
      break;
      
       case SAMPLEAPP_P2Pa_CLUSTERID://10
      {
        if(xa==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        xa=0;
        }
        }
      break;
      
             case SAMPLEAPP_P2Pb_CLUSTERID://11
      {
        if(xb==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        xb=0;
        }
        }
      break;
      
    case SAMPLEAPP_P2Pc_CLUSTERID://12
      {
        if(xc==1)
        {
        HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
        xc=0;
        }
        }
      break;
  }
}

下面介绍一下Zigbee协调器的数据请求函数void SAMPLEAPP_TO_jiedian_shang(uint16 addr)。

  • 在AF_DataRequest里我选择数据发送形式为单播,16位
  • shortAddr的短地址为各个终端节点的PANID。
  • SAMPLEAPP_ENDPOINT为20。
  • SAMPLEAPP_P2P_CLUSTERID为4
    -这个函数的作用就是依次向终端节点发送数据请求,然后终端节点就会返回温湿度的数据
//数据请求函数
void SAMPLEAPP_TO_jiedian_shang(uint16 addr)
{
 SampleApp_P2P_DstAddr.addr.shortAddr=Addrtable[addr];
 
 char theMessageData[]="DATA";
 
 if ( AF_DataRequest( &SampleApp_P2P_DstAddr, 
                     &SampleApp_epDesc,
                       SAMPLEAPP_P2P_CLUSTERID,//4
                       (byte)osal_strlen( theMessageData )+1,
                       (byte * )&theMessageData,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE,
                       AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
  {
  }
  else
  {
    // Error occurred in request to send.
  }
}

除了SHT10之外,我还加了烟雾传感器,OLED显示屏和一个指示灯,当温度、湿度超过阈值时,指示灯闪烁。后期让好朋友用SolidWorks给Zigbee板子做了一个外壳,看起来更好一看些。
在这里插入图片描述
在这里插入图片描述
下一期,有时间再说一下我程序的Zigbee终端节点相关代码解析。
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值