*基于RT-Thread的战舰开发板连接Onenent云平台(学习笔记)**

Connie ·
更新时间:2024-11-13
· 706 次阅读

基于RT-Thread的战舰开发板连接Onenent云平台(学习笔记)
摘要:本文主要是我在使用正点原子开发板在rt_thread框架下连接onenet云平台的学习笔记。此文主要介绍配置步骤和开发过程中遇到的问题,写本文的主要目的是为了强化自己的学习过程,第一次发文,希望对他人有所帮助,也希望大佬勿喷。
配置用的硬件主要是正点原子战舰开发板、正点原子ESP8266模块、DHT11温湿度传感器。通过运行rt_thread并加入相关的软件包连接云平台。软件有MDK5、MobaXterm串口调试助手。
准备工作:将ESP266WiFi模块连接到串口3、DHT11使用单总线通信数据传输,模块与开发板连接如下图在这里插入图片描述
一、登录Onenet云平台创建产品和设备产品的联网方式为
WIFI

设备接入协议为
MQTT

在这里插入图片描述
在产品下创建设备,按照要求填写即可。

二、使用ENV工具添加软件包,需要添加的软件包主要有三个分别为:ESP8266软件包、DHT11软件包、onenet软件包,建议全部开启软件包示例sample,这样方便根据示例代码编写自己的工程
这是onenet软件包的使能选项
device id :为设备ID
auth info: 为鉴权信息
api key : API秘钥
product id :产品ID
master/product key:产品秘钥
以上信息按照你创建的产品和设备的信息如实填写,保证准确,当然你也可以在配置完成后在工程中的rtconfig.h中修改相关信息。
在AT DEVICE中使能ESP8266,并开启Enable sample
在这里插入图片描述
同理,还需要打开DHT11软件包,并Enable sample。
还需要打开串口3因为DHT11连接到了串口3上。
****注意在rtconfig.h中修改软件包相关参数会在下次更新软件包时,自动更新为软件包配置时的参数,所以建议在ENV中修改软件包相关参数。
退出ENV配置,输入scons --target=mdk5生成新的工程。
三、代码的修改
1、如果你没有在ENV中配置软件包参数则可以在rtconfig.h中修改

#define PKG_USING_AT_DEVICE #define AT_DEVICE_USING_ESP8266 #define AT_DEVICE_ESP8266_SAMPLE #define ESP8266_SAMPLE_WIFI_SSID "WiFi账号" #define ESP8266_SAMPLE_WIFI_PASSWORD "WiFi密码" #define ESP8266_SAMPLE_CLIENT_NAME "uart3" #define ESP8266_SAMPLE_RECV_BUFF_LEN 512 #define PKG_USING_AT_DEVICE_V202 #define PKG_AT_DEVICE_VER_NUM 0x20002 /* IoT Cloud */ #define PKG_USING_ONENET #define PKG_USING_ONENET_SAMPLE #define ONENET_USING_MQTT #define ONENET_INFO_DEVID "设备ID" #define ONENET_INFO_AUTH "鉴权信息" #define ONENET_INFO_APIKEY "设备的APIkey" #define ONENET_INFO_PROID "产品ID" #define ONENET_MASTER_APIKEY "产品APIkey" #define PKG_USING_ONENET_LATEST_VERSION /* On-chip Peripheral Drivers */ #define BSP_USING_GPIO #define BSP_USING_UART #define BSP_USING_UART1 #define BSP_UART1_RX_USING_DMA #define BSP_USING_UART3

2、在宏定义中打开串口3,编译工程下载后可能会导致死机,原因可能是没有在硬件层打开串口3导致系统初始化失败,下面是我修改的代码,仅供参考
该函数在是stm32f1xx_hal_msp.c中

void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(huart->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } if(huart->Instance==USART3) { /* USER CODE BEGIN USART3_MspInit 0 */ /* USER CODE END USART3_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_USART3_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**USART3 GPIO Configuration PB10 ------> USART3_TX PB11 ------> USART3_RX */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN USART3_MspInit 1 */ /* USER CODE END USART3_MspInit 1 */ } }

修改完成后,可以尝试编译代码,并下载到开发板中,输入相关命令检查硬件是否能够正常工作。
打开MobaXterm串口调试助手(由于正点原子开发板带有一键下载电路,建议先重启开发板在打开串口,否则可能会导致串口打开失败)
输入命令dht11_read_temp_sample查看串口1是否打印DHT11温湿度数据。
3、完成上述过程后添加温湿度数据到MQTT协议中准备上传给Onenet云平台
首先,注释掉dht11_sample.c 中的DHT11温湿度读取线程,修改代码到onenet_sample.c中读取温湿度数据。

#include #include #include "sensor.h" #include "sensor_dallas_dht11.h" #include "drv_gpio.h" /* Modify this pin according to the actual wiring situation */ #define DHT11_DATA_PIN GET_PIN(G, 11) /*DHT11的数据读取在onenet_sample中完成*/ #if 0 static void read_temp_entry(void *parameter) { rt_device_t dev = RT_NULL; struct rt_sensor_data sensor_data; rt_size_t res; rt_uint8_t get_data_freq = 1; /* 1Hz */ dev = rt_device_find("temp_dht11"); if (dev == RT_NULL) { return; } if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) { rt_kprintf("open device failed!\n"); return; } rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq)); while (1) { res = rt_device_read(dev, 0, &sensor_data, 1); if (res != 1) { rt_kprintf("read data failed! result is %d\n", res); rt_device_close(dev); return; } else { if (sensor_data.data.temp >= 0) { uint8_t temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp uint8_t humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi rt_kprintf("temp:%d, humi:%d\n" ,temp, humi); } } rt_thread_delay(1000); } } static int dht11_read_temp_sample(void) { rt_thread_t dht11_thread; dht11_thread = rt_thread_create("dht_tem", read_temp_entry, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX / 2, 20); if (dht11_thread != RT_NULL) { rt_thread_startup(dht11_thread); } return RT_EOK; } MSH_CMD_EXPORT(dht11_read_temp_sample,sample); #endif /*DHT11相关设备注册和初始化*/ static int rt_hw_dht11_port(void) { struct rt_sensor_config cfg; cfg.intf.user_data = (void *)DHT11_DATA_PIN; rt_hw_dht11_init("dht11", &cfg); return RT_EOK; } INIT_COMPONENT_EXPORT(rt_hw_dht11_port);

注意:DHT11的引脚需要修改为PG11

其次,修改onenet_sample.c中的代码
数据上传函数为onenet_mqtt_upload_digit()

#include /*DHT11相关头文件*/ #include "sensor.h" #include "sensor_dallas_dht11.h" #include "drv_gpio.h" #include #define DBG_ENABLE #define DBG_COLOR #define DBG_SECTION_NAME "onenet.sample" #if ONENET_DEBUG #define DBG_LEVEL DBG_LOG #else #define DBG_LEVEL DBG_INFO #endif /* ONENET_DEBUG */ #include #ifdef FINSH_USING_MSH #include /* upload random value to temperature*/ static void onenet_upload_entry(void *parameter) { /*DHT11相关参数定义*/ rt_device_t dev = RT_NULL; struct rt_sensor_data sensor_data; rt_size_t res; rt_uint8_t get_data_freq = 1; /* 1Hz */ uint8_t temp; uint8_t humi; /*DHT11设备查找并打开*/ dev = rt_device_find("temp_dht11"); if (dev == RT_NULL) { return; } if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) { rt_kprintf("open device failed!\n"); return; } rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq)); while (1) { res = rt_device_read(dev, 0, &sensor_data, 1); if (res != 1) { rt_kprintf("read data failed! result is %d\n", res); rt_device_close(dev); return; } else { if (sensor_data.data.temp >= 0) { /*从传感器读取温湿度*/ temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi /*上传温度*/ if (onenet_mqtt_upload_digit("temperature", temp) < 0) { LOG_E("upload has an error, stop uploading"); break; } else { LOG_D("buffer : {\"temperature\":%d}", temp); } /*延时,为湿度上传提供时间*/ rt_thread_mdelay(100); /*上传湿度*/ if (onenet_mqtt_upload_digit("humidity", humi) < 0) { LOG_E("upload has an error, stop uploading"); break; } else { LOG_D("buffer : {\"humidity\":%d}", humi); } } } rt_thread_delay(rt_tick_from_millisecond(5 * 1000)); } } int onenet_upload_cycle(void) { rt_thread_t tid; tid = rt_thread_create("onenet_send", onenet_upload_entry, RT_NULL, 2 * 1024, RT_THREAD_PRIORITY_MAX / 3 - 1, 5); if (tid) { rt_thread_startup(tid); } return 0; } MSH_CMD_EXPORT(onenet_upload_cycle, send data to OneNET cloud cycle); int onenet_publish_digit(int argc, char **argv) { if (argc != 3) { LOG_E("onenet_publish [datastream_id] [value] - mqtt pulish digit data to OneNET."); return -1; } if (onenet_mqtt_upload_digit(argv[1], atoi(argv[2])) < 0) { LOG_E("upload digit data has an error!\n"); } return 0; } MSH_CMD_EXPORT_ALIAS(onenet_publish_digit, onenet_mqtt_publish_digit, send digit data to onenet cloud); int onenet_publish_string(int argc, char **argv) { if (argc != 3) { LOG_E("onenet_publish [datastream_id] [string] - mqtt pulish string data to OneNET."); return -1; } if (onenet_mqtt_upload_string(argv[1], argv[2]) < 0) { LOG_E("upload string has an error!\n"); } return 0; } MSH_CMD_EXPORT_ALIAS(onenet_publish_string, onenet_mqtt_publish_string, send string data to onenet cloud); /* onenet mqtt command response callback function */ static void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size) { char res_buf[] = { "cmd is received!\n" }; LOG_D("recv data is %.*s\n", recv_size, recv_data); /* user have to malloc memory for response data */ *resp_data = (uint8_t *) ONENET_MALLOC(strlen(res_buf)); strncpy((char *)*resp_data, res_buf, strlen(res_buf)); *resp_size = strlen(res_buf); } /* set the onenet mqtt command response callback function */ int onenet_set_cmd_rsp(int argc, char **argv) { onenet_set_cmd_rsp_cb(onenet_cmd_rsp_cb); return 0; } MSH_CMD_EXPORT(onenet_set_cmd_rsp, set cmd response function); #endif /* FINSH_USING_MSH */

注意:在上传温度和湿度的中间需要加入延时函数,因为数据时不断循环上传的,如果不加延时会导致湿度数据来不及上传。
四、运行调试
编译工程下载到开发板
输入命令onenet_mqtt_init进行MQTT初始化
输入命令onenet_upload_cycle进行温湿度循环上报
WiFi连接超时时间到达前请耐心等待开发板连接WiFi
在这里插入图片描述
查看云平台数据和上报数据是否一致,数据正常上报则说明实验成功。

**总结:**配置过程参考了rt_thread的官方文档说明
RT-Thread Onenet软件包配置文档
只是对软件包部分代码进行了修改。详情参考官方文档。


作者:简。郭



学习笔记 rt-thread 学习

需要 登录 后方可回复, 如果你还没有账号请 注册新账号