物聯(lián)網(wǎng)(三)---WEB下發(fā)命令控制單片機[STM32+OneNET+ESP8266]

物聯(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、ModbusTCP透傳也是可以的,這里只介紹其中一種,其他方法可以去OneNET平臺查找相關(guān)例程。

下面開始進入本節(jié)正文。

1.創(chuàng)建新的產(chǎn)品,使用EDP協(xié)議

這里和前面沒什么不同,唯一不同的就是將HTTP協(xié)議換成了EDP協(xié)議,其他的與之前所介紹的物聯(lián)網(wǎng)(一)---快速上手[STM32+OneNET+ESP8266]是一樣的。

image.png

2.快速實現(xiàn)

硬件電路:

可以直接使用之前的硬件電路,需要稍微改動一下,加入按鍵LED兩個部分,其他硬件電路無需進行改動,也就是只要接好STM32ESP8266相應(yīng)的串口部分就好了。

ESP8266連接方法

按鍵與LED

軟件程序:

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

image.png

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


設(shè)備狀態(tài)

設(shè)備狀態(tài)

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

數(shù)據(jù)流展示 1

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

數(shù)據(jù)流展示 2

3.制作WEB APP

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

控件參數(shù)修改

注:
1.這里不要將按鈕文本控件進行組合,組合后將不是一個按鈕,會導(dǎo)致按鈕只能顯示狀態(tài)而無法點擊,無法正常下發(fā)命令。
2.這里的{LED_RED{V}}中的{V}在命令下發(fā)時會被自動替換為01,最終下發(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的接法相一致才不致邏輯錯誤。

完成后的效果圖如下:


GIF壓縮后的渣畫質(zhì)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容