背景:
隨著科技的發展,物聯網設備的普及和應用越來越廣泛,該系統基于ONENET的多區域溫濕度監控系統是一套用于實時監測和管理不同地區溫濕度的智能解決方案。該系統由一組分布在多個區域的傳感器節點組成,采集環境數據并通過無線網絡傳輸至云平臺。借助云端分析和處理,用戶可以遠程監控各個區域的溫濕度情況,并及時獲取警報和報告。同時,該系統還具備數據存儲和分析功能,為用戶提供科學決策依據,助力業務優化和資源調配。
設計方案:
該項目的方案方案是通過RT-Thread操作系統和ONENET云平臺實現物聯網設備實時監控多個區域的溫濕度,并顯示在HMI_Board開發板中。為了實現一個設備同時監控多個設備發來的數據,一個HMI_Board開發板作為接收節點,剩余三個的作為發送節點,接收節點通過訂閱ONENET上的多個產品,等待發送節點向ONENET上的每個特有的產品發送數據,接收節點通過數據解析是那個設備發過來的,然后顯示在HMI_board開發板上,同時在ONENET云端這可以看到數據,實現多區域溫濕度監控。
開發環境
1.開發板:HMI_Board
2.開發環境:RT-Thread studio V2.2.6
3.RT-Thread版本:4.1.0
4.I2C外設資源:P202—SCL P203—SDA
5.傳感器:AHT10,RW007
6.云平臺:ONENET
系統設計流程
重要代碼設計
發送節點:(下面僅展示一個發送節點的代碼,其他同理,只是發送的幀頭不一樣,方便接收節點解析)
hal_entry.c //包括系統的wifi的連接,mqtt初始化,aht10線程的初始化,mqtt發送線程的初始化
#include
#include "hal_data.h"
#include
#include
#include "my_aht10.h"
#include "my_onenet.h"
#define LED_PIN BSP_IO_PORT_02_PIN_09 /* Onboard LED pins */
void AHT10_read(void *parameter);
void onenet_onenet_mqtt_publish(void *parameter);
rt_mailbox_t temp_msg_mb;
rt_mp_t temp_msg_mp;
rt_sem_t my_sem1;
#define mb_len 32
#define mp_len 32
struct dht_htemp
{
int humi;
int temp;
};
void hal_entry(void)
{
temp_msg_mb = rt_mb_create("temp_mb", mb_len, RT_IPC_FLAG_FIFO);
temp_msg_mp = rt_mp_create("temp_mp", mp_len, sizeof(struct dht_htemp));
my_sem1 = rt_sem_create("my_sem1", 0, RT_IPC_FLAG_FIFO);
rt_wlan_connect("WWWW", "123456789zxc"); //連接wifi
onenet_mqtt_init(); //mqtt //mqtt初始化
my_aht10_init(); //aht10 //啟動aht10線程
My_Onenet_Send(); //Onenet //啟動講數據上傳ONENET上
}
my_aht10.c //讀取溫濕度線程,然后通過郵箱和內存池實現和mqtt上傳數據線程進行交流
#include "my_aht10.h"
extern rt_mailbox_t temp_msg_mb;
extern rt_mp_t temp_msg_mp;
extern rt_sem_t my_sem1;
extern struct dht_htemp
{
int humi;
int temp;
};
static rt_thread_t aht10_tid = RT_NULL;
void AHT10_read(void *parameter)
{
struct dht_htemp *msg;
aht10_device_t dev;
const char *i2c_bus_name = "i2c1";
rt_thread_mdelay(500);
dev = aht10_init(i2c_bus_name);
if(dev == RT_NULL)
{
rt_kprintf("The sensor init failed.rn");
return ;
}
rt_sem_take(my_sem1, RT_WAITING_FOREVER);
while(1)
{
msg = rt_mp_alloc(temp_msg_mp, RT_WAITING_FOREVER);
msg->temp = (int)aht10_read_temperature(dev);
msg->humi = (int)aht10_read_humidity(dev);
rt_mb_send(temp_msg_mb, (rt_ubase_t)msg);
rt_kprintf("temp:[%d], humi:[%d],location:Nanyangn" ,msg->temp, msg->humi);
msg = RT_NULL;
rt_thread_mdelay(1000);
}
}
void my_aht10_init(void)
{
aht10_tid = rt_thread_create("aht10_thread", AHT10_read, RT_NULL, 2048, 17, 10);
if (aht10_tid)
{
rt_thread_startup(aht10_tid);
rt_kprintf("aht10_tid_init success!rn");
}
}
my_onenet.c //將數據上傳到云端,并下發給接收節點
#include "my_onenet.h"
extern rt_mailbox_t temp_msg_mb;
extern rt_mp_t temp_msg_mp;
extern struct dht_htemp
{
int humi;
int temp;
};
static rt_thread_t onenet_tid = RT_NULL;
void onenet_onenet_mqtt_publish(void *parameter)
{
struct dht_htemp msg;
uint8_t tbuf[64] = {0};
size_t len = 0;
while(1)
{
if(rt_mb_recv(temp_msg_mb, (rt_ubase_t ) &msg, RT_WAITING_FOREVER) == RT_EOK)
{
rt_sprintf((char *) tbuf, "temp:[%d], humi:[%d],location:Nanyang", msg->temp, msg->humi);
len = strlen(tbuf);
// rt_kprintf("%dn",len);
if (onenet_mqtt_publish("classA", &tbuf, len) < 0)
{
rt_kprintf("upload string has an error!n");
}
else
{
onenet_mqtt_upload_digit("temperature", msg->temp);
onenet_mqtt_upload_digit("humidity", msg->humi);
rt_mp_free(msg);
msg = RT_NULL;
}
}
}
}
void My_Onenet_Send(void)
{
onenet_tid = rt_thread_create("Onenet_humi_temp",onenet_onenet_mqtt_publish,RT_NULL,2048,16,10);
if (onenet_tid)
{
rt_thread_startup(onenet_tid);
rt_kprintf("mqtt_thread_init success!rn");
}
}
接收節點
主要就是接收onenet每個產品上下發的數據進行解析并顯示到顯示屏上
對發來得數據進行解析:
int onenet_onenet_mqtt_subscribe(void)
{
if (onenet_mqtt_subscribe("classA") < 0)
{
LOG_E("upload string has an error!n");
}
if (onenet_mqtt_subscribe("classB") < 0)
{
LOG_E("upload string has an error!n");
}
if (onenet_mqtt_subscribe("classC") < 0)
{
LOG_E("upload string has an error!n");
}
return 0;
}
rt_err_t onenet_mqtt_subscribe(const char *topic)
{
RT_ASSERT(topic);
if ( MQTTSubscribe(&mq_client, topic, QOS0) < 0)
{
return -1;
}
return 0;
}
LCD顯示:
static void lvgl_thread_entry(void parameter)
{
#if LV_USE_LOG
lv_log_register_print_cb(lv_rt_log);
#endif / LV_USE_LOG /
lv_init();
lv_port_disp_init();
lv_port_indev_init();
lv_obj_t label1 = lv_label_create(lv_scr_act());
lv_obj_t* label2 = lv_label_create(lv_scr_act());
lv_obj_t* label3 = lv_label_create(lv_scr_act());
lv_label_set_text(label1, "1");
lv_label_set_text(label2, "2");
lv_label_set_text(label3, "3");
lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0); //設置對象字體樣式居中
lv_obj_align(label1, LV_ALIGN_CENTER, 0, lv_pct(20)); //設置對象居中
lv_obj_set_style_text_align(label2, LV_TEXT_ALIGN_CENTER, 0); //設置對象字體樣式居中
lv_obj_align(label2, LV_ALIGN_CENTER, 0,0); //設置對象居中
lv_obj_set_style_text_align(label3, LV_TEXT_ALIGN_CENTER, 0); //設置對象字體樣式居中
lv_obj_align(label3, LV_ALIGN_CENTER, 0, lv_pct(-20)); //設置對象居中
/* handle the tasks of LVGL */
while(1)
{
lv_task_handler();
rt_thread_mdelay(500);
if(my_flag == 1)
{
lv_label_set_text(label1, str);
my_flag = 0;
}
if(my_flag == 2)
{
lv_label_set_text(label2, str1);
my_flag = 0;
}
if(my_flag == 3)
{
lv_label_set_text(label3, str2);
my_flag = 0;
}
}
}
效果展示
接收節點的顯示屏顯示:(顯示三個不同組員采集到的數據,在不同地方,南陽,周口,長沙)
云平臺設備在線情況以及傳輸數據顯示
發送節點:
節點一:
節點二:
節點三:
評論