这里使用的是RT-Thread studio中的mqtt连接阿里云和dht11自带的例程进行修改融合完成的
1.dht11例程:
依赖包:
使能dht11例程:
本人外接的dht11模块,数据引脚用的GPIOH_2 所以例程中初始化引脚改为H,2
#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(H, 2)
具体参照自己实际情况:
2.Ali例程参照本人另一篇文章:
3.代码整合:
简单粗暴的将两个例程的代码合并到一个里面,然后再慢慢修改代码位置。(直接合并起来也能跑,但是都是各跑各的,所以需要修改一下逻辑,达到将温湿度数据传输上云的目的)
首先就是获取温湿度数据,本人通过定义全局变量然后再通过赋值的方式获取的。(全局变量相信都会,就不做解释)
例程中 获取温湿度函数
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
tempT=temp;
humiT=humi;
//rt_kprintf("temp:%d, humi:%d\n" ,temp, humi);
}
}
rt_thread_delay(3000);
}
}
在该函数中本人就只添加了两行代码,并将窗口打印温湿度的代码注释掉,rt_thread_delay();函数的参数例程中给的是1000也就是延时1s 我改成了3s。其他的没动。
tempT=temp;
humiT=humi;
//rt_kprintf("temp:%d, humi:%d\n" ,temp, humi);
其中 tempT和humiT就是我定义的全局变量。
然后就是修改消息发布的函数了
static int example_publish(void *handle)
{
int res = 0;
const char *fmt = "/%s/%s/user/temperature"; //订阅消息
char *topic = NULL;
int topic_len = 0;
char *payload="";
char *Str1="{\"data\":{\"temperature\":\"";
char *Str2="\",\"humidity\":\"";
char *Str3="\",\"alarm\":\"0\"}}";
char *Str01 = (char *) malloc(strlen(Str1) + strlen(tempT));
sprintf(Str01, "%s%d", Str1, tempT);
char *Str02 = (char *) malloc(strlen(Str2) + strlen(humiT));
sprintf(Str02, "%s%d", Str2, humiT);
char *Str0102 = (char *) malloc(strlen(Str01) + strlen(Str02));
sprintf(Str0102, "%s%s", Str01, Str02);
char *StrNum = (char *) malloc(strlen(Str0102) + strlen(Str3));
sprintf(StrNum, "%s%s", Str0102, Str3);
payload=StrNum;
rt_kprintf("%s\n" ,payload);
topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
topic = HAL_Malloc(topic_len);
if (topic == NULL) {
EXAMPLE_TRACE("memory not enough");
return -1;
}
memset(topic, 0, topic_len);
HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, strlen(payload));
if (res < 0) {
EXAMPLE_TRACE("publish failed, res = %d", res);
HAL_Free(topic);
return -1;
}
HAL_Free(topic);
return 0;
}
订阅消息要和自己的topic一致:
const char *fmt = "/%s/%s/user/temperature"; //订阅消息
修改例程中的payload值
因为阿里云收的数据是JSON格式的所以需要按照格式修改。
本人添加的代码:
char *payload="";
char *Str1="{\"data\":{\"temperature\":\"";
char *Str2="\",\"humidity\":\"";
char *Str3="\",\"alarm\":\"0\"}}";
char *Str01 = (char *) malloc(strlen(Str1) + strlen(tempT));
sprintf(Str01, "%s%d", Str1, tempT);
char *Str02 = (char *) malloc(strlen(Str2) + strlen(humiT));
sprintf(Str02, "%s%d", Str2, humiT);
char *Str0102 = (char *) malloc(strlen(Str01) + strlen(Str02));
sprintf(Str0102, "%s%s", Str01, Str02);
char *StrNum = (char *) malloc(strlen(Str0102) + strlen(Str3));
sprintf(StrNum, "%s%s", Str0102, Str3);
payload=StrNum;
rt_kprintf("%s\n" ,payload);
将自己想要的字符串使用sprintf函数进行拼接。其中的温适度数据(tempT,humiT),之前使用strcat和strcpy函数,但是拼接后会乱码,因为tempT和humiT本质上还是uint_8类型的数据。所以使用sprintf进行拼接时需要用%d而不是%s,其他的根据自己需求改写就行。
最后编译下载 运行阿里例程就大功告成啦。