使用RT-Thread通過MQTT連接華爲物聯網平臺實驗

硬件環境:

(1)開發板:ST官方的stm32wb55-st-nucleo開發板

(2)wifi模塊:esp8266

(3)溫溼度傳感器:DHT22

(4)單色oled屏:主控ssd1306,分辨率126x64

軟件環境:

(1)開發環境:Keil MDK v5.29

(2)RTOS:RT-Thread 4.0.3

實現目標:將溫度、溼度數據上報到華爲雲物聯網平臺。

 

一、準備工作

(1)安裝ENV工具,參見官方文檔《Env 用戶手冊》:

https://www.rt-thread.org/document/site/#

(2)安裝git下載最新的rt-thread源碼,可到github或碼雲gitee上下載:

git clone https://gitee.com/rtthread/rt-thread.git

(3)查看rt-thread源碼的bsp文件夾內已經適配了stm32wb55-st-nucleo開發板,進入“...\rt-thread\bsp\stm32\stm32wb55-st-nucleo”,打開env運行scons --dist將工程抽離成獨立工程(看個人習慣,喜歡一個項目一個工程文件夾就抽離一下)。

(4)先對工程文件進行編譯,看看有沒有錯誤,理論上官方默認狀態是無錯誤的。打開env再運行:

        pkgs --upgrade

        pkgs --update

        scons --target=mdk5

然後用keil打開工程,編譯0錯誤,0警告。準備工作完成。

二、獲取需要的軟件包

   rt-thread提供非常多的軟件包,主要任務就是怎麼把軟件包利用起來。本次操作需要的軟件包:DHT22驅動、ESP8266驅動、MQTT軟件包、json軟件包,另外把oled屏驅動添加到工程。

1. 添加DHT22驅動

(1)DHT22與開發板連接,電源、地、數據就三根線,數據線我連接到開發板的GPIOB 9引腳上,需要查找一下GPIOB 9在rt-thread系統內對應的引腳號(打開drv_gpio.c文件,看到引腳列表pins[]可見對應編號爲25),後面需要配置到menuconfig內。(注意:新版驅動去掉了pins[]列表,暫時不知道去哪裏查找引腳對應的編號,可能需要在代碼內使用GET_PIN(B,9)獲取了

(2)添加DHTxx驅動軟件包,工程目錄內打開env,執行menuconfig,開啓軟件包和例程,版本選擇最新,引腳號配置爲25:

2. 添加oled顯示屏驅動

(1)在工程目錄內建立user_add_files文件夾,將後期用戶代碼都放在這個文件夾內。並在user_add_files文件夾內新建SConscript文件,內容如下(目的是scons時自動添加文件夾內的所有文件到工程):

import os
from building import *
objs = []
cwd  = GetCurrentDir()
list = os.listdir(cwd)

for item in list:
    if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
        objs = objs + SConscript(os.path.join(item, 'SConscript'))
Return('objs')

(2)在user_add_files文件夾內新建oled_ssd1306_drv文件夾並新建對應的SConscript文件, oled驅動文件放到oled_ssd1306_drv文件夾:

SConscript文件內容:

from building import *
cwd     = GetCurrentDir()
src     = Glob('*.c')
CPPPATH = [cwd]
group   = DefineGroup('oled_ssd1306_drv', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

 

(3)使用scons --target=mdk5重新構建工程,發現oled驅動已添加到工程:

(4)在main.c中添加測試代碼:

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "oled.h"
#include "dhtxx.h"
/* defined the LED1 pin: PB5 */
#define LED_G_PIN    GET_PIN(B, 0)
#define LED_R_PIN    GET_PIN(B, 1)
#define LED_B_PIN    GET_PIN(B, 5)
int main(void)
{
    /* set LED0 pin mode to output */
    rt_pin_write(LED_R_PIN, PIN_LOW);
    rt_pin_write(LED_G_PIN, PIN_LOW);
    rt_pin_write(LED_B_PIN, PIN_LOW);
    rt_pin_mode(LED_R_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_G_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LED_B_PIN, PIN_MODE_OUTPUT);
    dht_device_t sensor = dht_create(PKG_USING_DHTXX_SAMPLE_PIN);
    oled_dev.display_on();
    char disp_str[50];
    for(;;)
    {
        rt_thread_mdelay(3000);
        if(dht_read(sensor))
	{
	    rt_int32_t temp = dht_get_temperature(sensor);
	    rt_int32_t humi = dht_get_humidity(sensor);
	    rt_kprintf("Temp: %d, Humi: %d\n", temp, humi);
	    rt_sprintf(disp_str,"Humi: %d.%d %%",humi/10,humi%10);
	    oled_dev.show_string(0,4,(unsigned char *)disp_str,16,1);  
	    rt_sprintf(disp_str,"Temp: %d.%d C",temp/10,temp%10);
	    oled_dev.show_string(0,24,(unsigned char *)disp_str,16,1); 
	    oled_dev.refresh();
	}
	else
	{
	    rt_kprintf("Read dht sensor failed.\n");
	     rt_pin_write(LED_R_PIN, PIN_HIGH);
	}
    }
    return RT_EOK;
}

編譯燒錄運行:

 3. 添加ESP8266 WIFI模塊驅動

(1)stm32wb55芯片有兩個串口(lpuart1和uart1,正好一個做控制檯、一個連接wifi模塊,配置時注意區分,我將lpuart1作爲控制檯,uart1連接wifi),在menuconfig下面路徑找到esp8266,開啓並根據實際情況配置wifi密碼和串口號:

(2)保存 --> pkgs --update --> scons --target=mdk5

(3)keil打開工程 --> 編譯 --> 燒錄 --> 運行,打開串口工具,查看信息,已經可以發現wifi正常連接上了。

4. 添加MQTT軟件包,當時有4個MQTT軟件包可選,哪個好用不了解,暫時選擇my mqtt。

利用軟件包自帶的sample進行測試,直接編譯燒錄,控制檯輸入mqtt_start:

根據打印信息,可以看出已與服務器連接;之後發佈一個消息試試,內容爲hello!,由於例程已訂閱的默認主題和發佈的默認主題相同,所以如果MQTT運行正常則發佈的內容會被原樣接收到,測試如下,說明my mqtt軟件包初步運行正常。

5.因爲需要使用json串傳輸數據,所以添加json軟件包。

三、在華爲物聯網平臺上創建產品

註冊華爲雲賬號,在華爲物聯網平臺上創建產品、建立產品模型、創建設備,具體過程及傳輸的json字符串格式參見官方指導文件《MQTT設備快速接入》文檔:

(https://support.huaweicloud.com/qs-iothub/iot_05_0006.html)

我的產品截圖:

模型定義截圖(只添加溫度和溼度兩個屬性):

四、上傳溫度和溼度數據到華爲雲

(1)根據my_mqtt軟件包自帶的sample例程的函數,稍作調整,用於上報數據,mqtt_start函數採用rtthread上電自動運行方式INIT_APP_EXPORT(mqtt_start)。

編寫數據上報函數(JSON串格式參見上面華爲MQTT設備快速接入文檔):

/*
 * 函數名稱:user_humiture_send_to_server
 * 輸入參數:temp 溫度數據,單位0.1C
 *          humi 溼度數據,單位0.1%
 * 返回數據:-1 發送失敗
 *           0 發送成功
 */
int8_t user_humiture_send_to_server(int temp,int humi)
{
    cJSON *root_prop;
    cJSON *root_serv;
    cJSON *array_serv;
    cJSON *root;
    char *cjson_str = NULL;
    //檢查mqtt連接狀態
    if(paho_mqtt_is_connected(&client) == 0) return -1;
    //生成json字符串
    root_prop = cJSON_CreateObject();
    cJSON_AddNumberToObject(root_prop, "humidity", (humi/10) + 0.1 * (humi%10));
    cJSON_AddNumberToObject(root_prop, "temperature", (temp/10) + 0.1 * (temp%10));
    //
    root_serv = cJSON_CreateObject();
    cJSON_AddStringToObject(root_serv, "service_id", "humiture");
    cJSON_AddItemToObject(root_serv, "properties", root_prop);
    cJSON_AddStringToObject(root_serv, "event_time", "NULL"); //"20201207T002920Z"
    //
    array_serv = cJSON_CreateArray();
    cJSON_AddItemToArray(array_serv,root_serv);
    //
    root  = cJSON_CreateObject();
    cJSON_AddItemToObject(root, "services", array_serv);
    //發佈數據
    cjson_str = cJSON_PrintUnformatted(root);
    mqtt_publish(cjson_str);
    //釋放內存
    cJSON_Delete(root);
    cJSON_free(cjson_str);
    return 0;
}

 

(2)在main函數內調用數據上報函數,具體見後面我的實驗工程代碼,編譯燒寫運行程序;登錄華爲雲查看設備狀態爲在線,可見雲端已收到數據:

(3)數據上報華爲雲初步測試成功,我的測試工程代碼:

鏈接:https://pan.baidu.com/s/10I-BtE3UVGmxp7F2TpNxHA

提取碼:38sr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章