摘要:以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 産品建立
位址: https://www.huaweicloud.com/
檢視平台接入位址:
點選右上角建立産品:
根據自己的産品資訊填充:
根據産品的傳感器屬性建立伺服器的屬性字段:
4.3 裝置建立
詳細建立流程,看下面的截圖:
儲存裝置資訊,接下來的MQTT登入需要使用。
{
"device_id": "62e732be3a884835598654f7_dev1",
"secret": "12345678"
}
4.4 MQTT三元組資訊生成
在這裡可以使用華為雲提供的工具快速得到MQTT三元組進行登入。
https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112
工具的頁面位址:
https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
根據提示填入資訊,然後生成三元組資訊即可。 這裡填入的資訊就是在建立裝置的時候生成的資訊。
ClientId 62e732be3a884835598654f7_dev1_0_0_2022080102
Username 62e732be3a884835598654f7_dev1
Password 13483ebeadd786ea107527a3c92c5463a8f3c71377cd33276143ffe2fb85c1dc
4.5 MQTT主題訂閱與釋出格式
//訂閱主題: 平台下發消息給裝置
$oc/devices/62e732be3a884835598654f7_dev1/sys/messages/down
//裝置上報資料
$oc/devices/62e732be3a884835598654f7_dev1/sys/properties/report
//上報的屬性消息 (一次可以上報多個屬性,在json裡增加就行了)
{"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代碼
#include "uart.h"
/*
函數功能:序列槽0初始化
*/
void Init_Uart0(void)
{
PERCFG&=~(1<<0); //序列槽0的引腳映射到位置1,即P0_2和P0_3
P0SEL|=0x3<<2; //将P0_2和P0_3端口設定成外設功能
U0BAUD = 216; //32MHz的系統時鐘産生115200BPS的波特率
U0GCR&=~(0x1F<<0);//清空波特率指數
U0GCR|=11<<0; //32MHz的系統時鐘産生115200BPS的波特率
U0UCR |= 0x80; //禁止流控,8位資料,清除緩沖器
U0CSR |= 0x3<<6; //選擇UART模式,使能接收器
}
/*
函數功能:UART0發送字元串函數
*/
void UR0SendString(u8 *str)
{
while(*str!='\0')
{
U0DBUF = *str; //将要發送的1位元組資料寫入U0DBUF
while(UTX0IF == 0);//等待資料發送完成
UTX0IF = 0; //清除發送完成标志,準備下一次發送
str++;
}
}
/*
函數功能: 模仿printf風格的格式化列印功能
*/
char USART0_PRINT_BUFF[200]; //格式化資料緩存資料
void USART0_Printf(const char *format,...)
{
char *str=NULL;
/*1. 格式化轉換*/
va_list ap; // va_list---->char *
va_start(ap,format); //初始化參數清單
vsprintf(USART0_PRINT_BUFF,
format,
ap); //格式化列印
va_end(ap); //結束參數擷取
/*2. 序列槽列印*/
str=USART0_PRINT_BUFF;//指針指派
while(*str!='\0')
{
U0DBUF=*str; //發送一個位元組的資料
str++; //指針自增,指向下一個資料
while(UTX0IF == 0);//等待資料發送完成
UTX0IF = 0; //清除發送完成标志,準備下一次發送
}
}
5.5 ESP8266.c代碼
#include "esp8266.h"
uint lenU1 = 0;
uchar tempRXU1;
uchar RecdataU1[MAXCHAR];
//"AT+CIPSEND=0,10\r\n" //長度10
//傳回">" 之後就可以正常發送資料了
//發送成功傳回 "SEND OK"
//發送資料
void ESP8266_SendData(char *p,int len)
{
int i=0;
char buff[50];
sprintf(buff,"AT+CIPSEND=0,%d\r\n",len);
clearBuffU1();
Uart1_Send_String(buff); //發送指令
DelayMs(1000); //等待
for(i=0;i<len;i++)
{
Uart1_Send_Char(p[i]);
}
//等待發送完成
DelayMs(1000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
}
/****************************************************************************
* 名 稱: SetWifi()
* 功 能: 設定LED燈相應的IO口
* 入口參數: 無
* 出口參數: 無
****************************************************************************/
void SetWifi(void)
{
P0DIR |= 0x40; //P0.6定義為輸出
IGT = 0; //高電平複位
DelayMs(500);
IGT = 1; //低電平工作
}
/*
設定WIFI為AP模式+TCP伺服器
*/
void SetESP8266_AP_TCP_Server()
{
clearBuffU1();
Uart1_Send_String("AT\r\n");
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("ATE0\r\n");
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("AT+CWMODE=2\r\n");
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("AT+RST\r\n");
DelayMs(2000);
DelayMs(2000);
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("ATE0\r\n");
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("AT+CWSAP=\"wifi_cc2530\",\"12345678\",1,4\r\n");
DelayMs(2000);
DelayMs(2000);
DelayMs(2000);
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("AT+CIPMUX=1\r\n");
DelayMs(2000);
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("AT+CIPSERVER=1,8089\r\n");
DelayMs(2000);
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
clearBuffU1();
Uart1_Send_String("AT+CIFSR\r\n");
DelayMs(2000);
DelayMs(2000);
RecdataU1[lenU1]='\0';
UR0SendString(RecdataU1);
}
unsigned char dataRecv;
unsigned char Flag = 0;
/*===================UR1初始化函數====================*/
void Init_Uart1()
{
PERCFG = 0x00;//位置1 P0.4/P0.5口
P0SEL |= 0x30;//P0.4,P0.5用作序列槽(外部裝置功能)
U1CSR |= 0x80;//設定為UART方式
U1GCR |= 11;//BAUD_E
U1BAUD |= 216;//BAUD_M 波特率設為115200
UTX1IF = 0; //UART1 TX中斷标志初始置位0
U1CSR |= 0X40; //允許接收
IEN0 |= 0x88; // 開總中斷,UART1接收中斷
}
void clearBuffU1(void)
{
int j;
for(j=0;j<MAXCHAR;j++)
{
RecdataU1[j]=0x00;
}
lenU1=0;
}
/*******************************************************************************
序列槽1發送一個位元組函數
*******************************************************************************/
void Uart1_Send_Char(char Data)
{
U1CSR &= ~0x40; //禁止接收
U1DBUF = Data;
while(UTX1IF == 0);
UTX1IF = 0;
U1CSR |= 0x40; //允許接收
}
/*******************************************************************************
序列槽1發送字元串函數
*******************************************************************************/
void Uart1_Send_String(char *Data)
{
while(*Data!='\0')
{
Uart1_Send_Char(*Data);
Data++;
}
}
/****************************************************************
序列槽接收一個字元: 一旦有資料從序列槽傳至CC2530, 則進入中斷,将接收到的資料指派給變量temp.
****************************************************************/
#pragma vector = URX1_VECTOR
__interrupt void UART1_ISR(void)
{
if(lenU1<81)
{
tempRXU1 = U1DBUF;
RecdataU1[lenU1]=tempRXU1;
URX1IF = 0; // 清中斷标志
lenU1++;
}
}
6、總結
随着業務的發展,越來越多的企業選擇結合物聯網技術來實作自身效益增長。相比企業自建MQTT叢集,使用華為雲IoT服務低成本建構物聯網解決方案,在能力、成本、運維、安全、生态等諸多方面具有突出優勢。 廣泛支援IoT主流的接入協定及私有協定,滿足各類裝置和接入場景要求;與主流模組、晶片預內建,實作多網絡、多協定接入,簡化裝置接入難度,實作小時級裝置極簡接入。
點選關注,第一時間了解華為雲新鮮技術~