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

基于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 <rtthread.h>
#include <rtdevice.h>
#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 <stdlib.h>
/*DHT11相关头文件*/
#include "sensor.h"
#include "sensor_dallas_dht11.h"
#include "drv_gpio.h"

#include <onenet.h>

#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 <rtdbg.h>

#ifdef FINSH_USING_MSH
#include <finsh.h>

/* 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软件包配置文档
只是对软件包部分代码进行了修改。详情参考官方文档。

发布了1 篇原创文章 · 获赞 4 · 访问量 31

猜你喜欢

转载自blog.csdn.net/weixin_42741090/article/details/105674454