之前分享了基於LiteOS的智慧農業案例實驗分享基於LiteOS的智慧農業案例實驗分享,閱讀量挺不錯,看樣子大家都挺喜歡這種實驗。那咱們就再來一個類似的實驗:基於RT-Thread的智慧路燈案例實驗。
實驗框圖
實驗說明:設備終端不斷採集光強數據並上傳至雲端進行監控,同時也會把當前LED(路燈)的狀態上傳。LED的狀態會根據光照值進行打開、關閉。比如當光照值低於(夜晚)我們設置的光照閾值時就會打開LED,當光照高於(白天)光照閾值時就會熄滅LED燈。除此之外,雲端可以遠程控制LED的亮滅,達到一個遠程控制的作用。
創建RTT工程
- 硬件:小熊派開發板。
- 軟件:STM32+RT-Thread。
- 開發工具:RT-Thread Studio V1.1.0。
本實驗我們需要用到RT-Thread的BH1750軟件包、OneNet軟件包及at_device軟件包等。這些軟件包的使用已經在前兩篇筆記中有寫到:
本次實驗也只是把它們融合在一起來使用。
1、添加相關軟件包、配置:
添加完之後的RT-Thread Settings
文件如:
添加軟件包及軟件包的一些詳細配置可查閱上兩篇筆記。這裏也大概提一下要點:
(1)設置WiFi信息:
(2)設置OneNET信息
(3)配置I2C對接BH1750
這裏我用的是RT-Thread Studio V1.1.0
,這裏的I2C的範例配置有點問題,其它版本的RT-Thread Studio
應該可以按範例配置那麼配,如果按範例配置編譯不通過的話可以按照I2C2那樣配置。
2、應用代碼
(1)測試函數
int onenet_upload_example(void)
{
rt_thread_t tid;
/* onenet初始化 */
onenet_mqtt_init();
/* 綁定led命令響應回調函數 */
onenet_set_cmd_rsp_cb(onenet_ledcmd_rsp_cb);
/* 創建onenet數據上傳任務 */
tid = rt_thread_create("onenet_upload",
onenet_upload_entry,
RT_NULL,
2048,
10,
5);
if (tid)
rt_thread_startup(tid);
return 0;
}
MSH_CMD_EXPORT(onenet_upload_example, send data to OneNET cloud cycle);
先進行一個onenet初始化,這個初始化接口時onenet軟件包提供的。接着進行一個led命令響應回調函數的綁定,回調函數onenet_ledcmd_rsp_cb裏進行的就是接收到onenet下發的led命令之後進行地一些操作。最後就是創建一個onenet數據上傳的線程。最後把這個函數以命令的形式導出,以便我們可以在命令行輸入onenet_upload_example
命令進行測試。
(2)led命令響應回調函數
static void onenet_ledcmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
{
char res_buf[20] = {0};
char recv_buf[5] = {0};
LOG_D("recv data is %.*s\n", recv_size, recv_data);
if (!strncmp((char*)recv_data, "ledon", 5))
{
rt_pin_write(SC1_LED_PIN, SC1_LED_ON);
rt_snprintf(res_buf, sizeof(res_buf), "led is on");
rt_kprintf("led is on\n");
}
else if(!strcmp((char*)recv_data, "ledoff", 5))
{
rt_pin_write(SC1_LED_PIN, SC1_LED_OFF);
rt_snprintf(res_buf, sizeof(res_buf), "led is off");
rt_kprintf("led is off\n");
}
else
{
rt_kprintf("ledcmd ERROR!\n");
}
/* user have to malloc memory for response data */
*resp_data = (uint8_t *) rt_malloc(strlen(res_buf));
strncpy((char *)*resp_data, res_buf, strlen(res_buf));
*resp_size = strlen(res_buf);
}
我們收到onenet下發的命令之後,所需要做的操作放在這裏面。比如當我們的設備接收到ledon
字符串時,打開led,並打印提示信息。最後再把led is on
信息應答給onenet。
(3)上傳數據的任務
/* 上傳數據至onenet */
static void onenet_upload_entry(void *parameter)
{
rt_device_t dev = RT_NULL;
struct rt_sensor_data data;
rt_size_t res;
char led_status = SC1_LED_OFF;
char send_buf[32] = {0};
/* 設置高亮LED的引腳爲輸出模式 */
rt_pin_mode(SC1_LED_PIN, PIN_MODE_OUTPUT);
/* 查找bh1750傳感器 */
dev = rt_device_find("li_bh1750");
if (dev == RT_NULL)
{
rt_kprintf("Can't find device:li_bh1750\n");
return;
}
/* 以只讀模式打開bh1750 */
if (rt_device_open(dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK)
{
rt_kprintf("open device failed!");
return;
}
while (1)
{
/* 從傳感器讀取一個數據 */
res = rt_device_read(dev, 0, &data, 1);
if (1 != res)
{
rt_kprintf("read data failed!size is %d", res);
}
else
{
rt_kprintf("light:%4d.%d lux\n", data.data.light / 10, data.data.light % 10);
rt_sprintf(send_buf,"%4d.%d", data.data.light / 10, data.data.light % 10);
}
/* 高亮LED燈根據光照值自動打開、熄滅 */
if (data.data.light / 10 <= 40)
{
rt_pin_write(SC1_LED_PIN, SC1_LED_ON);
led_status = SC1_LED_ON;
rt_kprintf("led_status = ON\n");
}
else
{
rt_pin_write(SC1_LED_PIN, SC1_LED_OFF);
led_status = SC1_LED_OFF;
rt_kprintf("led_status = OFF\n");
}
/* 上傳光照數據至onenet */
if (onenet_mqtt_upload_string("light", (const char*)send_buf) < 0)
{
LOG_E("upload has an error, stop uploading");
break;
}
/* 上傳高亮led燈的狀態至onenet */
if (onenet_mqtt_upload_string("led_status", (const char*)ledsta_str[led_status]) < 0)
{
LOG_E("upload has an error, stop uploading");
break;
}
rt_thread_delay(rt_tick_from_millisecond(3 * 1000));
}
rt_device_close(dev);
}
這是我們的上傳任務:讀取BH1750傳感器採集的光照值,通過onenet軟件包給我們提供的onenet_mqtt_upload_string接口上傳至onenet;同時,led的狀態根據光照值的結果自動打開/關閉,led的狀態也是通過onenet_mqtt_upload_string接口傳至onenet。
3、OneNET雲端web應用
(1)創建一個web應用
爲了能更好地、更直觀的展示我們的數據,我們創建一個web應用來管理:
onenet構建web應用的方式與之前我們分享的基於LiteOS的智慧農業案例實驗分享中華爲雲構建web應用的方式類似,都是通過拖控件的方式。我們創建好的應用如下:
實驗結果
若覺得文章不錯,轉發分享、在看,也是我們繼續更新的動力。
在公衆號內回覆更多資源,可免費獲取嵌入式資料。期待你的關注~
加ZhengN爲好友,回暗號【嵌入式大雜燴】,進微信羣