物聯(lián)網(wǎng)(一)---快速上手[STM32+OneNET+ESP8266]
物聯(lián)網(wǎng)(二)---原理分析[STM32+OneNET+ESP8266]
物聯(lián)網(wǎng)(三)---WEB下發(fā)命令控制單片機[STM32+OneNET+ESP8266]
物聯(lián)網(wǎng)(四)---搭建自己的TCP服務(wù)器[ESP8266]
物聯(lián)網(wǎng)(五)---搭建自己的云平臺[ESP8266+Django]
前面已經(jīng)介紹了怎么將單片機連入互聯(lián)網(wǎng),使單片機能夠?qū)⒉杉降臄?shù)據(jù)上傳到互聯(lián)網(wǎng)上,可以直接通過網(wǎng)頁來進行查看,以及對其中的原理進行了相應(yīng)的介紹說明。本文將對如何從網(wǎng)頁上下發(fā)命令來控制單片機作相應(yīng)的講解。
前面已經(jīng)介紹過,使用由于HTTP協(xié)議是無狀態(tài),短連接,只能由客戶端向服務(wù)端發(fā)出請求,所以使用HTTP協(xié)議是無法從平臺上下發(fā)命令給單片機的。這里采用另外一種協(xié)議EDP來對進行通信,當然,OneNET平臺上使用MQTT、Modbus和TCP透傳也是可以的,這里只介紹其中一種,其他方法可以去OneNET平臺查找相關(guān)例程。
下面開始進入本節(jié)正文。
1.創(chuàng)建新的產(chǎn)品,使用EDP協(xié)議
這里和前面沒什么不同,唯一不同的就是將HTTP協(xié)議換成了EDP協(xié)議,其他的與之前所介紹的物聯(lián)網(wǎng)(一)---快速上手[STM32+OneNET+ESP8266]是一樣的。

2.快速實現(xiàn)
硬件電路:
可以直接使用之前的硬件電路,需要稍微改動一下,加入按鍵和LED兩個部分,其他硬件電路無需進行改動,也就是只要接好STM32和ESP8266相應(yīng)的串口部分就好了。


軟件程序:
下載程序,修改程序源碼中的
DEVICEID和APIKEY已經(jīng)相應(yīng)的WIFI名稱和密碼,編譯下載至單片機中程序就可正常運行了。但此時還是只能完成數(shù)據(jù)上傳的工作,無法完成平臺給單片機下達命令的操作,要讓平臺能夠控制單片機,還需要一個WEB APP才能完成命令的下發(fā)工作。

將程序下載進入單片機中后,等待1min左右,就可以從網(wǎng)頁上看到有設(shè)備在線了。


在數(shù)據(jù)流展示這里可以看到有數(shù)據(jù)上傳過來,時間也在不斷更新。

當按下開發(fā)板上的按鍵之后,面包中相對應(yīng)的狀態(tài)也會隨之改變(需要開啟實時刷新)。

3.制作WEB APP
制作WEB APP來做相應(yīng)的控制,這里我們只用到兩個控件,分別是文本控件和按鈕控件,直接拖出來,然后修改相應(yīng)的數(shù)據(jù),如下圖。這里要注意的就是命令的格式不餓能出錯,否則
STM32的程序中無法完成對命令的解析工作。

注:
1.這里不要將按鈕和文本控件進行組合,組合后將不是一個按鈕,會導(dǎo)致按鈕只能顯示狀態(tài)而無法點擊,無法正常下發(fā)命令。
2.這里的{LED_RED{V}}中的{V}在命令下發(fā)時會被自動替換為0或1,最終下發(fā)的命令是{LED_RED0}或{LED_RED1}。

制作好WEB APP后,稍微調(diào)整下布局,使之美觀點就好了。

需要注意的是,這里的數(shù)據(jù)流名字需要與STM32程序中解析出來待比對的命令相一致才行,否則STM32是無法對命令進行解析了,也就無法完成控制功能了。
下面的
USART2_IRQHandler()中斷服務(wù)函數(shù)是對服務(wù)器端傳來的命令進行解析的。
/*串口中斷函數(shù)對服務(wù)器返回回來的命令進行解析*/
void USART2_IRQHandler(void)
{
unsigned int data;
if(USART2->SR & 0x0F)
{
// See if we have some kind of error
// Clear interrupt (do nothing about it!)
data = USART2->DR;
}
else if(USART2->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART2->DR;
usart2_rcv_buf[usart2_rcv_len++]=data;
if(data=='{') //約定平臺下發(fā)的控制命令以'{'為開始符,‘}’為控制命令結(jié)束符,讀者可以自定義自己的開始符合結(jié)束符
{
rcv_cmd_start=1;
}
if(rcv_cmd_start==1)
{
usart2_cmd_buf[usart2_cmd_len++]=data;
if((data=='}')||(usart2_cmd_len>=MAX_CMD_LEN-1))
{
rcv_cmd_start=0;
LED_CmdCtl();
memset(usart2_cmd_buf,0,usart2_cmd_len);
usart2_cmd_len=0;
}
}
}
else
{
;
}
}
使用
LED_CmdCtl()函數(shù)對接收到的命令做出判斷,以控制相應(yīng)的LED的亮滅。
/**
* @brief 分析平臺下發(fā)的LED控制命令
**/
void LED_CmdCtl(void)
{
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_RED_1"))) //約定平臺控制命令"LED_RED_1"為打開紅色LED燈
{
LED_RED_ON;
red_value=1;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_GREEN_1"))) //約定平臺控制命令"LED_GREEN_1"為打開綠色LED燈
{
LED_GREEN_ON;
green_value=1;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_YELLOW_1"))) //約定平臺控制命令"LED_YELLOW_1"為打開黃色LED燈
{
LED_YELLOW_ON;
yellow_value=1;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_BLUE_1"))) //約定平臺控制命令"LED_BLUE_1"為打開藍色LED燈
{
LED_BLUE_ON;
blue_value=1;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_RED_0"))) //約定平臺控制命令"LED_RED_0"為關(guān)閉紅色LED燈
{
LED_RED_OFF;
red_value=0;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_GREEN_0"))) //約定平臺控制命令"LED_GREEN_0"為關(guān)閉綠色LED燈
{
LED_GREEN_OFF;
green_value=0;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_YELLOW_0"))) //約定平臺控制命令"LED_YELLOW_0"為關(guān)閉黃色LED燈
{
LED_YELLOW_OFF;
yellow_value=0;
}
if((NULL != strstr((const char *)usart2_cmd_buf, "LED_BLUE_0"))) //約定平臺控制命令"LED_BLUE_0"為關(guān)閉藍色LED燈
{
LED_BLUE_OFF;
blue_value=0;
}
}
到這里,如果按鍵程序編寫正確,LED也能正常驅(qū)動的話,程序基本上就沒有什么太大的問題了,這里注意理一下邏輯,就是WEB APP上開關(guān)的開值和關(guān)值要與程序里的LED的亮滅相一致,程序里的LED亮滅又要與硬件電路的LED的接法相一致才不致邏輯錯誤。
完成后的效果圖如下:

最后再回顧以下本文重點:
1.不可使用前面的HTTP協(xié)議了,HTTP協(xié)議是無狀態(tài)、短連接(一次會話完成后即結(jié)束)、只能由客戶端就發(fā)起請求,所以不可用于命令下發(fā);于是本文選用了EDP協(xié)議,當然還有其他類型的通信協(xié)議可供選擇,文中也有提及,但未展開敘述。
2.WEB端APP的命令格式十分重要,WEB端APP的命令格式需與STM32中的命令格式相一致,否則STM32可能無法對數(shù)據(jù)進行解析。