• CC2530_ZigBee+华为云IOT:设计一套属于自己的冷链采集系统


    摘要:以CC2530单片机为核心器件,设计一个冷链环境信息采集系统,利用传感器技术对冷藏仓内的环境参数进行采集,上传到华为云物联网云平台,然后通过手机端或移动端进行显示,便于分析,观察冷链环境信息。

    本文分享自华为云社区《基于CC2530_ZigBee+华为云IOT设计的冷链信息采集系统【玩转华为云】》,作者: DS小龙哥 。

    1、前言

    近年来,随着人们消费需求的不断提高,连锁超市、便利店、大卖场等商超不但提供了各种各样的新鲜食品,而且采用统一进货和冷链储藏的方式,从而不但使得商品质量有保证,而且购物环境良好,越来越成为人们购物的主要场所。超市作为冷链物流产品的末端,在分销以及零售过程中都对产品质量、运营成本和功耗等方面有着较高的要求,而冷链系统的压力参数作为保证这一品质的重要参数之一,实现智能压力检测和控制对于时刻掌握冷链的工作状态非常重要,可以保证运营的安全性和经济性。因此,如果能够设计一款针对冷链系统数据采集系统,就可以实现对冷链系统进行实时监控,达到经济性运营的目的,对提高企业经济效益具有非常重要的意义。

    2、设计需求

    以CC2530单片机为核心器件,设计一个冷链环境信息采集系统,利用传感器技术对冷藏仓内的环境参数进行采集,上传到物联网云平台,然后通过手机端或移动端进行显示,便于分析,观察冷链环境信息。

    硬件选型:

    (1)ESP8266-WIFI 用于与上位机进行通信,实现数据传输
    (2)CC2530单片机,本身是51内核,与普通的51单片机编程一样,它内部多了一个ZigBee 模块,能实现ZigBee 组网。
    (3)DHT11 温湿度传感器。这是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度5~95%RH, 温度-20~+60℃。
    (4)蜂鸣器。当设置阀值超出标准时,可以发出警报提醒。

    3、硬件选型

    3.1 CC2530+WIFI模块

    3.2 DHT11温湿度模块

    3.3 蜂鸣器

    4、物联网云端配置与应用

    4.1 华为云IoTDA介绍

    当前的设计中,用的物联网平台服务是华为云的设备接入服务(IoTDA),IoTDA提供海量设备连接上云、设备和云端双向消息通信、批量设备管理、远程控制和监控、OTA升级、设备联动规则等能力,并可将设备数据灵活流转到华为云其他服务。

    使用物联网平台构建一个完整的物联网解决方案主要包括3部分:物联网平台、业务应用和设备。

    物联网平台作为连接业务应用和设备的中间层,屏蔽了各种复杂的设备接口,实现设备的快速接入;同时提供强大的开放能力,支撑行业用户构建各种物联网解决方案。

    设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台,并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台,平台也可以将控制命令下发给设备。

    业务应用通过调用物联网平台提供的API,实现设备数据采集、命令下发、设备管理等业务场景。

    接下来就详细把整个物联网平台的使用流程进行介绍。

    4.2 产品创建

    地址: 共建智能世界云底座-华为云

    查看平台接入地址: 

     点击右上角创建产品:

    根据自己的产品信息填充:

    根据产品的传感器属性创建服务器的属性字段:

    4.3 设备创建

    详细创建流程,看下面的截图:

    保存设备信息,接下来的MQTT登录需要使用。

    1. {
    2. "device_id": "62e732be3a884835598654f7_dev1",
    3. "secret": "12345678"
    4. }

    4.4 MQTT三元组信息生成

    在这里可以使用华为云提供的工具快速得到MQTT三元组进行登录。
    使用MQTT.fx调测_设备接入 IoTDA_开发指南_设备侧开发_使用MQTT Demo接入_华为云

    工具的页面地址:
    Huaweicloud IoTDA Mqtt ClientId Generator工具的页面地址:
    Huaweicloud IoTDA Mqtt ClientId Generator
    根据提示填入信息,然后生成三元组信息即可。 这里填入的信息就是在创建设备的时候生成的信息。

    1. ClientId 62e732be3a884835598654f7_dev1_0_0_2022080102
    2. Username 62e732be3a884835598654f7_dev1
    3. Password 13483ebeadd786ea107527a3c92c5463a8f3c71377cd33276143ffe2fb85c1dc

    4.5 MQTT主题订阅与发布格式

    1. //订阅主题: 平台下发消息给设备
    2. $oc/devices/62e732be3a884835598654f7_dev1/sys/messages/down
    3. //设备上报数据
    4. $oc/devices/62e732be3a884835598654f7_dev1/sys/properties/report
    5. //上报的属性消息 (一次可以上报多个属性,在json里增加就行了)
    6. {"services": [{"service_id": "server_id","properties":{"温度":23.4}},{"service_id": "server_id","properties":{"湿度":80.5}}]}

    4.6 设备模拟登录测试

    4.7 应用侧开发接口介绍

    在设备上云之后,为了能方便管理设备,方便用户设备入网,都需要开发一款手机APP或者微信小程序、桌面软件等,进行数据交互,设备管理。

    华为云IOT提供了应用侧开发的API对接接口,这里就介绍一下使用应用侧开发的流程。这个API接口里常用的接口包括:产品创建、设备创建、设备属性获取、设备删除、查询设备等管理接口,可以通过API主动获取产品下面某个设备的属性,要求设备上报最新的数据过来。整个开发过程,都是基于HTTP协议的API接口进行交互,不依赖开发环境,不依赖开发语言。 不管是桌面软件,还是手机APP、微信小程序、web网页等,核心代码基本都是一样,都是HTTP协议交互。下面的例子里,我是采用C++编写的,采用QT框架库完成整个开发,了解了整个思路,你就可以采用自己熟悉的语言完成相同的功能。

    官方帮助文档: https://support.huaweicloud.com/usermanual-iothub/iot_01_0045.html

    5、CC2530程序设计

    5.1 IAR环境搭建

    完整的安装整个配套环境,需要安装以下的软件,具体的版本型号也介绍了,直接百度搜索就能找到;最简单的办法是,淘宝搜索一下CC2530的开发板,店铺里一般都有配套的资料包下载,里面基本都包含了下面这些软件,直接白嫖就行:

    安装集成开发环境: IAR-EW8051-8.10.1。
    安装仿真器“SmartRF4EB”的驱动程序。
    安装代码烧写工具: Setup_SmartRF_Programmer_1.10.2。
    安装 TI 的 Zigbee 协议栈: ZStack-CC2530-2.5.1a。

    安装过程截图请看另外的文档。

    5.2 硬件原理图

    5.3 IAR程序工程图

    5.4 DHT11.c代码

    1. #include "uart.h"
    2. /*
    3. 函数功能:串口0初始化
    4. */
    5. void Init_Uart0(void)
    6. {
    7. PERCFG&=~(1<<0); //串口0的引脚映射到位置1,即P0_2和P0_3
    8. P0SEL|=0x3<<2; //将P0_2和P0_3端口设置成外设功能
    9. U0BAUD = 216; //32MHz的系统时钟产生115200BPS的波特率
    10. U0GCR&=~(0x1F<<0);//清空波特率指数
    11. U0GCR|=11<<0; //32MHz的系统时钟产生115200BPS的波特率
    12. U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器
    13. U0CSR |= 0x3<<6; //选择UART模式,使能接收器
    14. }
    15. /*
    16. 函数功能:UART0发送字符串函数
    17. */
    18. void UR0SendString(u8 *str)
    19. {
    20. while(*str!='\0')
    21. {
    22. U0DBUF = *str; //将要发送的1字节数据写入U0DBUF
    23. while(UTX0IF == 0);//等待数据发送完成
    24. UTX0IF = 0; //清除发送完成标志,准备下一次发送
    25. str++;
    26. }
    27. }
    28. /*
    29. 函数功能: 模仿printf风格的格式化打印功能
    30. */
    31. char USART0_PRINT_BUFF[200]; //格式化数据缓存数据
    32. void USART0_Printf(const char *format,...)
    33. {
    34. char *str=NULL;
    35. /*1. 格式化转换*/
    36. va_list ap; // va_list---->char *
    37. va_start(ap,format); //初始化参数列表
    38. vsprintf(USART0_PRINT_BUFF,
    39. format,
    40. ap); //格式化打印
    41. va_end(ap); //结束参数获取
    42. /*2. 串口打印*/
    43. str=USART0_PRINT_BUFF;//指针赋值
    44. while(*str!='\0')
    45. {
    46. U0DBUF=*str; //发送一个字节的数据
    47. str++; //指针自增,指向下一个数据
    48. while(UTX0IF == 0);//等待数据发送完成
    49. UTX0IF = 0; //清除发送完成标志,准备下一次发送
    50. }
    51. }

    5.5 ESP8266.c代码

    1. #include "esp8266.h"
    2. uint lenU1 = 0;
    3. uchar tempRXU1;
    4. uchar RecdataU1[MAXCHAR];
    5. //"AT+CIPSEND=0,10\r\n" //长度10
    6. //返回">" 之后就可以正常发送数据了
    7. //发送成功返回 "SEND OK"
    8. //发送数据
    9. void ESP8266_SendData(char *p,int len)
    10. {
    11. int i=0;
    12. char buff[50];
    13. sprintf(buff,"AT+CIPSEND=0,%d\r\n",len);
    14. clearBuffU1();
    15. Uart1_Send_String(buff); //发送指令
    16. DelayMs(1000); //等待
    17. for(i=0;i
    18. {
    19. Uart1_Send_Char(p[i]);
    20. }
    21. //等待发送完成
    22. DelayMs(1000);
    23. RecdataU1[lenU1]='\0';
    24. UR0SendString(RecdataU1);
    25. clearBuffU1();
    26. }
    27. /****************************************************************************
    28. * 名 称: SetWifi()
    29. * 功 能: 设置LED灯相应的IO口
    30. * 入口参数: 无
    31. * 出口参数: 无
    32. ****************************************************************************/
    33. void SetWifi(void)
    34. {
    35. P0DIR |= 0x40; //P0.6定义为输出
    36. IGT = 0; //高电平复位
    37. DelayMs(500);
    38. IGT = 1; //低电平工作
    39. }
    40. /*
    41. 设置WIFI为AP模式+TCP服务器
    42. */
    43. void SetESP8266_AP_TCP_Server()
    44. {
    45. clearBuffU1();
    46. Uart1_Send_String("AT\r\n");
    47. DelayMs(2000);
    48. RecdataU1[lenU1]='\0';
    49. UR0SendString(RecdataU1);
    50. clearBuffU1();
    51. Uart1_Send_String("ATE0\r\n");
    52. DelayMs(2000);
    53. RecdataU1[lenU1]='\0';
    54. UR0SendString(RecdataU1);
    55. clearBuffU1();
    56. Uart1_Send_String("AT+CWMODE=2\r\n");
    57. DelayMs(2000);
    58. RecdataU1[lenU1]='\0';
    59. UR0SendString(RecdataU1);
    60. clearBuffU1();
    61. Uart1_Send_String("AT+RST\r\n");
    62. DelayMs(2000);
    63. DelayMs(2000);
    64. DelayMs(2000);
    65. RecdataU1[lenU1]='\0';
    66. UR0SendString(RecdataU1);
    67. clearBuffU1();
    68. Uart1_Send_String("ATE0\r\n");
    69. DelayMs(2000);
    70. RecdataU1[lenU1]='\0';
    71. UR0SendString(RecdataU1);
    72. clearBuffU1();
    73. Uart1_Send_String("AT+CWSAP=\"wifi_cc2530\",\"12345678\",1,4\r\n");
    74. DelayMs(2000);
    75. DelayMs(2000);
    76. DelayMs(2000);
    77. DelayMs(2000);
    78. RecdataU1[lenU1]='\0';
    79. UR0SendString(RecdataU1);
    80. clearBuffU1();
    81. Uart1_Send_String("AT+CIPMUX=1\r\n");
    82. DelayMs(2000);
    83. DelayMs(2000);
    84. RecdataU1[lenU1]='\0';
    85. UR0SendString(RecdataU1);
    86. clearBuffU1();
    87. Uart1_Send_String("AT+CIPSERVER=1,8089\r\n");
    88. DelayMs(2000);
    89. DelayMs(2000);
    90. RecdataU1[lenU1]='\0';
    91. UR0SendString(RecdataU1);
    92. clearBuffU1();
    93. Uart1_Send_String("AT+CIFSR\r\n");
    94. DelayMs(2000);
    95. DelayMs(2000);
    96. RecdataU1[lenU1]='\0';
    97. UR0SendString(RecdataU1);
    98. }
    99. unsigned char dataRecv;
    100. unsigned char Flag = 0;
    101. /*===================UR1初始化函数====================*/
    102. void Init_Uart1()
    103. {
    104. PERCFG = 0x00;//位置1 P0.4/P0.5口
    105. P0SEL |= 0x30;//P0.4,P0.5用作串口(外部设备功能)
    106. U1CSR |= 0x80;//设置为UART方式
    107. U1GCR |= 11;//BAUD_E
    108. U1BAUD |= 216;//BAUD_M 波特率设为115200
    109. UTX1IF = 0; //UART1 TX中断标志初始置位0
    110. U1CSR |= 0X40; //允许接收
    111. IEN0 |= 0x88; // 开总中断,UART1接收中断
    112. }
    113. void clearBuffU1(void)
    114. {
    115. int j;
    116. for(j=0;j
    117. {
    118. RecdataU1[j]=0x00;
    119. }
    120. lenU1=0;
    121. }
    122. /*******************************************************************************
    123. 串口1发送一个字节函数
    124. *******************************************************************************/
    125. void Uart1_Send_Char(char Data)
    126. {
    127. U1CSR &= ~0x40; //禁止接收
    128. U1DBUF = Data;
    129. while(UTX1IF == 0);
    130. UTX1IF = 0;
    131. U1CSR |= 0x40; //允许接收
    132. }
    133. /*******************************************************************************
    134. 串口1发送字符串函数
    135. *******************************************************************************/
    136. void Uart1_Send_String(char *Data)
    137. {
    138. while(*Data!='\0')
    139. {
    140. Uart1_Send_Char(*Data);
    141. Data++;
    142. }
    143. }
    144. /****************************************************************
    145. 串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,将接收到的数据赋值给变量temp.
    146. ****************************************************************/
    147. #pragma vector = URX1_VECTOR
    148. __interrupt void UART1_ISR(void)
    149. {
    150. if(lenU1<81)
    151. {
    152. tempRXU1 = U1DBUF;
    153. RecdataU1[lenU1]=tempRXU1;
    154. URX1IF = 0; // 清中断标志
    155. lenU1++;
    156. }
    157. }

    6、总结

    随着业务的发展,越来越多的企业选择结合物联网技术来实现自身效益增长。相比企业自建MQTT集群,使用华为云IoT服务低成本构建物联网解决方案,在能力、成本、运维、安全、生态等诸多方面具有突出优势。 广泛支持IoT主流的接入协议及私有协议,满足各类设备和接入场景要求;与主流模组、芯片预集成,实现多网络、多协议接入,简化设备接入难度,实现小时级设备极简接入。

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    数据中心绿色低碳重要趋势下,希捷用创新技术让磁盘“重生”
    java--接口
    Git项目Readme.md文件编写格式与语法
    js函数作用域
    【Linux】一些工具的简单使用,vim/gcc/gdb/make
    查询自己电脑能够支持Win11系统升级的方法分享
    案例成果展 | 灵雀云助力中国人民银行清算总中心构建裸金属容器平台
    Nuxt.js Next.js Nest.js
    [附源码]java毕业设计高校知识产权管理系统论文2022
    【python】python连接Oracle数据库
  • 原文地址:https://blog.csdn.net/devcloud/article/details/126142147