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

2023-11-12

之前实现了基于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终端节点相关代码解析。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Java 集合根据条件进行拆分

    创建测试集合 List
  • typescript学习(四)——泛型

    泛型 泛型 软件工程中 不仅要创建一致的定义良好的API 同时也要考虑可重用性 组件不仅能够支持当前的数据类型 同时也能支持未来的数据类型 这在创建大型系统时提供了十分灵活的功能 在像c 和java这样的语言中 可以使用泛型来创建可重用的组

随机推荐

  • 从C语言出发新角度内核剖析C++函数重载(千字精品,附带大厂面试问题回答)

    目录 C角度引入 函数重载 1 什么是函数重载 2 函数重载的优点 3 函数重载的特性 剖析函数重载 最后做一个小补充 大厂面试题 C角度引入 首先在进行C 讲解之前我们照例先来谈谈C语言是如何做的 在C语言中是没有函数重载存在的 每一个函
  • hibernate 关系映射文件配置

  • 1、Java实现队列(Queue)的方式

    编程题目 1 请用Java实现队列 Queue 队列实现的三种方式 1 通过数组实现一个队列 2 通过集合实现一个对列 3 通过两个堆栈实现一个队列 示例代码 1 通过数组实现一个队列 package program stack array
  • conda更新失败--更新后版本号不变

    我们通常使用下面的命令更新conda conda update n base c defaults conda 然而 这个命令有时候失效 如在我电脑上 4 10 0版本的conda一直无法升级为最新的23 3 1版本 失效情况 在更新前的状
  • vue 数字变星号 过滤器_Vue自定义过滤器格式化数字三位加一逗号实现代码

    前端处理一些金额 数字类的数据要求按照固定的格式显示 比如9 527 025 或者带有小数 如1 587 23 仍要三位一断 有些话也不必多说 既然要求如此 实现呗 作为前端主流框架之一的Vue 类似的功能肯定都有人写的很完善了 我呢 最讨
  • React Hooks 学习笔记

    大家好 小编最近在梳理 React Hook 的相关内容 由于看视频 看书 自己做项目总觉得缺点什么 总觉得看过了 内容太简单 有啥好写的 但是过了一段时间 感觉有些东西又模糊了 同时又觉得怕简单 写了也不一定有人看 但是想想 还是整理成文
  • iOS开发之第三方支付支付宝支付教程,史上最新最全第三方支付宝支付方式实现、支付宝集成教程,支付宝实现流程

    本章项目demo https github com zhonggaorong alipayDemo 支付宝支付大致流程为 1 公司与支付宝进行签约 获得商户ID partner 和账号ID seller 和私钥 privateKey 开发中
  • 【自然语言处理】主题建模:Top2Vec(理论篇)

    主题建模 Top2Vec 理论篇 Top2Vec 是一种用于 主题建模 和 语义搜索 的算法 它自动检测文本中出现的主题 并生成联合嵌入的主题 文档和词向量 算法基于的假设 许多语义相似的文档都可以由一个潜在的主题表示 首先 创建文档和词向
  • 没有头的猫在笛卡尔坐标系上随机漫步(未完成)

    想用python模拟随机运动 布朗运动 BROWNIAN MOTION 英国科学家布朗在两百年前第一次观察到水分子推动花粉颗粒在水面做不规则运动 现在我们也想用电脑模拟 在无外力作用下 花粉颗粒在水面的随机运动 如何实现呢 详细解释直接写在
  • LSTM 和 Bi-LSTM

    承上启下 承接上文介绍过的 SimpleRNN 这里介绍它的改进升级版本 LSTM RNN 和 LSTM 比较 RNN 的记忆很短 容易产生梯度消失的长依赖问题 而 LSTM 可以解决这个问题 它有更长的记忆 RNN 模型比较简单 只有一个
  • c++处理数据

    处理数据 简单变量 const限定符 类型转换和auto声明 整型 char类型 字符和小整数 成员函数cout put 通用字符名 signed char和unsigned char wchar t 浮点数 bool类型 c 算术运算符
  • Python入门笔记(1)

    纯小写的就是python的BIF 内置函数 dir builtins ArithmeticError AssertionError AttributeError BaseException BlockingIOError BrokenPip
  • 避免Unity错误剥离代码

    开启ProjectSettings里的Strip Engine Code项目后 Unity会尝试剥离未使用的引擎代码 以降低包体大小和运行时内存占用 但是某些运行时需要的组件会被错误剥离
  • Hibernate之关于多对多单向关联映射

    Hibernate 之关于多对多单向关联映射 老师和学生 最典型的多对多关联 Teacher和Student 所谓单向意思就是说 老师知道自己的教的是哪些学生而学生不知道是哪些老师教 也可以这么说 在查询的时候 通过老师可以级联查询出学生
  • 有些话,只说给懂的人听

    生活中最 孤独的时候 往往不是因为孤身一人 而是即使身边有很多人 有些心事依旧无人能懂 以前的时候 我们常常会把所有的喜怒悲欢 都说与别人听 后来渐渐变得沉默了 不是因为学会了独自消化 只是明白了 有些话只能说给懂的人听 人与人之间 只有彼
  • mybatis+mysql insert时返回自增主键

    mybatis mysql insert时返回自增主键 mysqlmybatisinsert返回自增主键 使用mybatis执行insert操作时 需要返回自增主键 网上清一色的答案 useGeneratedKeys设置为true keyP
  • qt开发使用camera类获取摄像头信息并拍照保存

    首先是UI布局 在pro文件中添加两个类 QT multimedia QT multimediawidgets 然后我们需要包含几个摄像头使用的头文件并创建摄像头的对象 include
  • win10远程桌面的坑

    win10的远程桌面的确是清晰度非常好 操作非常流程的 但是还是有坑的 举两个踩坑例子 1 录屏软件在远程桌面退出后无效了 无法录制屏幕了 2 监控客户端在退出远程桌面后 再进去远程桌面 打圈圈卡死 因此一些应用不适合在win10远程桌面办
  • GNS3 配置GRE

    1 简述 GRE Generic Routing Encapsulation GRE是一种最传统的隧道协议 其根本功能就是要实现隧道功能 以实现异地网络之间可以通过内部私网相互访问 以上图为例 假设IP地址为10 1 1 1的XP1想访问I
  • 基于Zigbee的SHT10温湿度数据采集系统(已实现控制12个终端节点)——Zigbee协调器主要代码解析

    之前实现了基于Zigbee的SHT10温湿度数据采集系统 这里来重新复盘一些主要的知识和代码 写在前面 1 功能介绍 使用Zigbee终端节点采集环境的温度和湿度数据 然后将数据无线发送的Zigbee协调器 最后在电脑端显示获得到的数据 2