使用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时自动添加文件夹内的所有文件到工程):

  1.  
    import os
  2.  
    from building import *
  3.  
    objs = []
  4.  
    cwd = GetCurrentDir()
  5.  
    list = os.listdir(cwd)
  6.  
     
  7.  
    for item in list:
  8.  
    if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
  9.  
    objs = objs + SConscript(os.path.join(item, 'SConscript'))
  10.  
    Return('objs')

(2)在user_add_files文件夹内新建oled_ssd1306_drv文件夹并新建对应的SConscript文件, oled驱动文件放到oled_ssd1306_drv文件夹:

SConscript文件内容:

  1.  
    from building import *
  2.  
    cwd = GetCurrentDir()
  3.  
    src = Glob('*.c')
  4.  
    CPPPATH = [cwd]
  5.  
    group = DefineGroup('oled_ssd1306_drv', src, depend = [''], CPPPATH = CPPPATH)
  6.  
    Return('group')

 

(3)使用scons --target=mdk5重新构建工程,发现oled驱动已添加到工程:

(4)在main.c中添加测试代码:

  1.  
    #include <rtthread.h>
  2.  
    #include <rtdevice.h>
  3.  
    #include <board.h>
  4.  
    #include "oled.h"
  5.  
    #include "dhtxx.h"
  6.  
    /* defined the LED1 pin: PB5 */
  7.  
    #define LED_G_PIN GET_PIN(B, 0)
  8.  
    #define LED_R_PIN GET_PIN(B, 1)
  9.  
    #define LED_B_PIN GET_PIN(B, 5)
  10.  
    int main(void)
  11.  
    {
  12.  
    /* set LED0 pin mode to output */
  13.  
    rt_pin_write(LED_R_PIN, PIN_LOW);
  14.  
    rt_pin_write(LED_G_PIN, PIN_LOW);
  15.  
    rt_pin_write(LED_B_PIN, PIN_LOW);
  16.  
    rt_pin_mode(LED_R_PIN, PIN_MODE_OUTPUT);
  17.  
    rt_pin_mode(LED_G_PIN, PIN_MODE_OUTPUT);
  18.  
    rt_pin_mode(LED_B_PIN, PIN_MODE_OUTPUT);
  19.  
    dht_device_t sensor = dht_create(PKG_USING_DHTXX_SAMPLE_PIN);
  20.  
    oled_dev.display_on();
  21.  
    char disp_str[50];
  22.  
    for(;;)
  23.  
    {
  24.  
    rt_thread_mdelay(3000);
  25.  
    if(dht_read(sensor))
  26.  
    {
  27.  
    rt_int32_t temp = dht_get_temperature(sensor);
  28.  
    rt_int32_t humi = dht_get_humidity(sensor);
  29.  
    rt_kprintf("Temp: %d, Humi: %d\n", temp, humi);
  30.  
    rt_sprintf(disp_str,"Humi: %d.%d %%",humi/10,humi%10);
  31.  
    oled_dev.show_string(0,4,(unsigned char *)disp_str,16,1);
  32.  
    rt_sprintf(disp_str,"Temp: %d.%d C",temp/10,temp%10);
  33.  
    oled_dev.show_string(0,24,(unsigned char *)disp_str,16,1);
  34.  
    oled_dev.refresh();
  35.  
    }
  36.  
    else
  37.  
    {
  38.  
    rt_kprintf("Read dht sensor failed.\n");
  39.  
    rt_pin_write(LED_R_PIN, PIN_HIGH);
  40.  
    }
  41.  
    }
  42.  
    return RT_EOK;
  43.  
    }

编译烧录运行:

 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设备快速接入文档):

  1.  
    /*
  2.  
    * 函数名称:user_humiture_send_to_server
  3.  
    * 输入参数:temp 温度数据,单位0.1C
  4.  
    * humi 湿度数据,单位0.1%
  5.  
    * 返回数据:-1 发送失败
  6.  
    * 0 发送成功
  7.  
    */
  8.  
    int8_t user_humiture_send_to_server(int temp,int humi)
  9.  
    {
  10.  
    cJSON *root_prop;
  11.  
    cJSON *root_serv;
  12.  
    cJSON *array_serv;
  13.  
    cJSON *root;
  14.  
    char *cjson_str = NULL;
  15.  
    //检查mqtt连接状态
  16.  
    if(paho_mqtt_is_connected(&client) == 0) return -1;
  17.  
    //生成json字符串
  18.  
    root_prop = cJSON_CreateObject();
  19.  
    cJSON_AddNumberToObject(root_prop, "humidity", (humi/10) + 0.1 * (humi%10));
  20.  
    cJSON_AddNumberToObject(root_prop, "temperature", (temp/10) + 0.1 * (temp%10));
  21.  
    //
  22.  
    root_serv = cJSON_CreateObject();
  23.  
    cJSON_AddStringToObject(root_serv, "service_id", "humiture");
  24.  
    cJSON_AddItemToObject(root_serv, "properties", root_prop);
  25.  
    cJSON_AddStringToObject(root_serv, "event_time", "NULL"); //"20201207T002920Z"
  26.  
    //
  27.  
    array_serv = cJSON_CreateArray();
  28.  
    cJSON_AddItemToArray(array_serv,root_serv);
  29.  
    //
  30.  
    root = cJSON_CreateObject();
  31.  
    cJSON_AddItemToObject(root, "services", array_serv);
  32.  
    //发布数据
  33.  
    cjson_str = cJSON_PrintUnformatted(root);
  34.  
    mqtt_publish(cjson_str);
  35.  
    //释放内存
  36.  
    cJSON_Delete(root);
  37.  
    cJSON_free(cjson_str);
  38.  
    return 0;
  39.  
    }

 

(2)在main函数内调用数据上报函数,具体见后面我的实验工程代码,编译烧写运行程序;登录华为云查看设备状态为在线,可见云端已收到数据:

(3)数据上报华为云初步测试成功,我的测试工程代码:

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

提取码:38sr

posted @ 2020-12-30 09:03  CNBlackICE  阅读(1498)  评论(0编辑  收藏  举报