文章目錄
- 概述
- WIFI8266 通信模組
- WIFI模組也用AT指令?
- ESP8266 內置協議棧?
- 支持的無線網絡模式
- MCU通過串口與模組交互
- Wifi模組做客戶端
- PC-AT接入路由器
- 向本地TCP服務發數據
- 用代碼接入你家路由器
- 已接入AP(你家Wifi)
- 平臺側開發
- 工程配置和編譯
- 工程配置
- 編譯不過
- WIFI連接參數
- 接入AP成功,IoTDA失敗
- 無可用加密套件
- 成功接入平臺
概述
本實驗基于WIFI模組實現智慧農業案例,實現實時數據采集,實現命令下發和響應,實現端云互通。實驗目的包括:
- 掌握Wifi通信方式的配置。
- 掌握智慧農業案例的開發過程。
- 掌握Wifi+DTLS+PSK接入華為云物聯網平臺的方法。
- 了解LiteOS以及DTLS的裁剪,避免板卡Flash不足以存儲編譯結果。
- NB-IoT模組通過串口與主板MCU以AT指令交互,wifi模組也是。
@NOTE
轉載請標明出處,https://blog.csdn.net/quguanxin/category_12929470.html
@HISTORY
從本實驗開始,我將放棄使用LiteOS Stduio集成開發環境,轉而使用新構建的 GitBash+GCC+CortexDebug 集成開發環境。在原本的計劃里頭,本文是要探尋LwM2M/CoAP與AT指令、Wifi、NB-IoT之間的關聯,但實際上并沒有,因為我遇到了其他困難。我原本以為在智慧農業NB-IoT實驗基礎上,Wifi實驗過程會很順利,但事與愿違。在編譯階段,啟用DTLS模塊后,遇到了程序大小超過Flash總額的問題。在平臺接入階段,由于錯把設備ID當做設備標識碼使用,導致接入平臺失敗。為了分析和解決上述問題,延伸多寫了其他幾篇文章。
WIFI8266 通信模組
WIFI8266通信模塊是小熊派開發板用于通過Wi-Fi傳輸數據的通信擴展板,板載樂鑫 ESP8266 Wi-Fi通信模組。
WIFI模組也用AT指令?
從學習華為云物聯網開始,這可能是我給自己挖的最大的坑,我一直以為AT指令是NB-IoT通信下的一種特有的指令,可現在來看,WIFI通信模組也是要使用AT指令的。那么,我們不得不重新來審視什么是AT指令?
AT指令絕非僅限于NB-IoT,而是貫穿各類通信模組(WiFi、4G藍牙等)的通用控制協議,堪稱物聯網設備的 “神經系統語言”。
AT是"Attention"的縮寫,歷史遺留術語,它起源于很久以前,NB-IoT只是其后來的一個受益者而已。它在1981年由Hayes公司設計,用于調制解調器撥號控制(如ATDT撥號),通過文本化命令實現對通信模塊的操控,隔離底層硬件差異,使主控MCU無需理解復雜射頻協議。其本質是通過ASCII字符串控制通信模組的協議,實現設備與模組間的交互。
3GPP TS 27.007,定義基礎指令如 AT+CSQ(信號強度),不是只指針對NB的,而是覆蓋蜂窩網絡,也包含4G/5G 等。但是 Wi-Fi 不在3GPP規范范圍內,其AT指令由各芯片廠商(如樂鑫ESP8266)自行定義。雖無全球統一標準,但廠商也常會參考3GPP語法,采用類似格式,如,AT+CWJAP(連接Wi-Fi)、AT+CWSAP(創建熱點)等指令。只是格式差不多,指令名不一樣,
小熊派社區,擴展板資料中也有 <ESP-12F(ESP8266) AT指令使用示例.pdf> 等可以下載參考。在小熊派開發板這個場景下,AT指令是主板(MCU)與通信模組之間的控制語言,用于操控模組底層行為。
ESP8266 內置協議棧?
ESP8266 模塊是有獨立運行能力的哈,這點一定要提前意識到。
其內部集成Tensilica L106 32位微控制器,自帶Flash存儲,可直接運行固件。該固件包含完整的 LwIP 協議棧,支持 IPv4 的TCP、UDP、HTTP 等常見協議。ESP8266 擴展板僅通過 UART/TX/RX引腳 與主板通信,主板僅需實現串口數據傳輸,不參與任何協議處理。主板(如STM32)僅需通過UART串口發送AT指令控制ESP8266,例如,AT+CIPSTART=“TCP”,“192.168.1.100”,8080 建立TCP連接。
進一步的,這意味著什么呢?我們不需要在主板程序中啟用LWIP協議棧,這將會減少很多的一筆開銷。
需要注意的是,ESP8266模組并不內置LwM2M客戶端,
如前文所述,其內置LwIP TCP/IP協議棧,支持基礎網絡通信,但并無內置LwM2M/CoAP這種更上層的應用層協議。在理論上,Wifi模組可以通過OpenCPU/SDK可集成CoAP/LwM2M,但需開發者手動實現,且資源占用較高。
支持的無線網絡模式
ESP8266 Wi-Fi擴展板(如小熊派開發板所用)支持三種主要無線網絡模式:
Station(STA)模式SoftAP(AP)模式STA+AP混合模式。這些模式決定了模塊如何與其他設備或網絡交互,適用于不同物聯網場景。
Station (STA) 模式 - 客戶端角色,
源自 IEEE 802.11(Wi-Fi)標準術語,指連接到無線網絡的終端設備,如手機、筆記本電腦。你的手機連接家里路由器時,手機(相關通信模組)就是 Station,哈哈,這里的Station其含義車站的乘客,不是車站,AP才是車站,互聯網算是動車高鐵吧。當擴展板處于此工作模式時,它就相當于你的手機一樣,去鏈接你家的路由器。該角色下的設備,會包含掃描可用網絡、發起認證連接(向AP接入點的認證請求)、獲取IP地址(DHCP客戶端)等技術行為。
Access Point (AP) 模式 - 服務端角色,
IEEE 802.11 標準定義的無線網絡接入點,即提供Wi-Fi信號的設備,如,路由器。也就是說擴展板可以像我們家路由器那樣,做為網絡的創建者和服務提供者,主動廣播SSID創建無線網絡、為STA設備分配IP、路由數據,組件本地局域網。該角色下的設備,會有,廣播信標幀、宣告網絡存在,認證連接請求(如WPA2-PSK握手),作為DHCP服務器分配IP地址,等技術行為。SoftAP 區別于硬件AP(專用路由器芯片),其通常是資源受限的,具有臨時性,通常用于特定場景(如配網),在早期家用無線攝像頭配置方案里確實見過。
MCU通過串口與模組交互
在<IoT/透過oc_lwm2m和at源碼,分析NB-IoT通信模組和主板MCU之間的通信過程和工作機制> 文中,我們已經從軟件源碼層級上,分析論證了NB-IoT模組與主板MCU之間是通過串口進行通信的。那么ESP8266同樣依賴UART傳輸AT指令和數據嗎?首先,答案是肯定的。但在本文我們先不急著從軟件實現層次上去分析這個事情。因為看看硬件原理圖,一切就不容狡辯。實錘。
Wifi/ESP8266通信模組原理圖,
NB-IoT通信模組原理圖,
如上,無論是WiFi或NB-IoT通信模組,都具有串口Rx/Tx通信管腳導出,用于和主板進行串口通信,交互AT指令和數據。
Wifi模組做客戶端
在我們的實驗5-Wifi智慧農業,中 ESP8266,其工作在客戶端模式。
PC-AT接入路由器
其實一開始,我不知道ESP8266這東西還能用PC-AT指令接入接力的路由器,我是在看了一會源碼后才發現的。 <ESP-12F(ESP8266) AT指令使用示例.pdf> 等手冊可以從文中連接下載。接下來,我們根據手冊內容,進行些簡單實驗。與NB-IoT-AT指令的PC實踐一樣,撥碼開發要撥到PC側,但是這里的波特率是115200,不與PC-AT一樣了哈。
//設置模組為客戶端模式
AT+CWMODE=3
//固件中是純字符串解析,相當脆弱,一定要注意不要在任何地方不要亂加空格
AT+CWJAP="HUAWEI-IoT","1xxxxxxxxx2+"
建立TCP連接,
這里還鬧騰了烏龍。早期我使用Wifi代碼連接到平臺的實踐中,我連接的是家里凌霄路由器的客人WIFI,當時我是實驗成功的。現如今用PC-AT指令實驗,依據ESP8266的AT指令手冊,使用網絡助手在本地創建TCP服務端,使用AT指令控制ESP8266建立TCP連接,結果總是連接不上。我關閉了防火墻、禁用了所有其他網絡適配器,依然不行。但是當我切換到正常的WIFI網絡時,我就可以ping通了。當然,關閉防火墻或進行更細粒度的策略配置,肯定是必要,否則你肯定是ping不通的。至于為啥客網在PC-AT指令實現時,存在不通,可能這是凌霄Q6獨有策略吧,我沒再深究,沒有那個時間。
向本地TCP服務發數據
//查詢模組的IP地址
AT+CIFSR
//測試從模組到PC主機的可達性
AT+PING="192.168.155.10"
//連接到本地TCP服務
AT+CIPSTART="TCP","192.168.3.7",62100
//數據發送/發多了會被截斷哈
AT+CIPSEND=4
如下圖,我們發送 CSDN_DAHE_QU 多個字符,最終實際發送4個字符成功.
我們前文提到過,ESP8266也是用AT指令與MCU通信的,看到上述CIPSTART、CIPSEND等指令,去源碼里搜一下就豁然開朗了。
用代碼接入你家路由器
首先在.config配置中,修改CONFIG_ESP8266_SSID和CONFIG_ESP8266_PWD的值,為你家的Wifi名稱和密碼。這兩個宏定義會在 ESP8266 驅動程序中使用,并最終作為 esp8266_joinap 函數的輸入參數,具體過程如下,
//宏重命名
#define WIFI_SSID CONFIG_ESP8266_SSID //在.config模式下定義
#define WIFI_PASSWD CONFIG_ESP8266_PWD //在.config模式下定義
//使用上述宏作實參的函數實現
static bool_t esp8266_joinap(char *ssid, char *passwd) {char cmd[64];(void) memset(cmd,0,64);(void) snprintf(cmd,64,"AT+CWJAP_CUR=\"%s\",\"%s\"\r\n",ssid, passwd);return esp8266_atcmd(cmd,"OK");
}
通過上述函數實現可以看出來,底層通過調用擴展板的AT指令,完成擴展板與AP的鏈接過程。這里AT指令,可參見相關手冊。在代碼調試前,可以先基于PC上的AT指令測試上述連接過程。
已接入AP(你家Wifi)
這個過程挺順利的。我在終端中配置的是Q6訪客網的連接信息,在Q6的Web管理頁面中,可以檢索到擴展板連接情況。
平臺側開發
與實驗-5/基于NB-IoT,使用相同產品模型和設備定義也是可以的。我們這里只重點再強調下設備注冊中的設備秘鑰配置問題。為了更好的說明一些問題,我們重新注冊一個新設備,包括密碼設置什么的,截圖上都不打碼,以更好的理解。
密碼設置時,我坑了自己好幾次了,哈哈,還每次都覺得自己理解無誤。
上述紅色告警信息有些不靠譜,自己與左側提示信息就矛盾著。
首先,華為云IoT平臺在創建注冊設備時,似乎無法區分是否為NB設備。其次,你輸入非16進制(0~F)字符,如H、J、Q等字符時,是無法通過輸入檢查的。上圖右側的告警,也很繞人。所謂1個十六進制字符,并不是字符串單字符的概念,如上0x00、0x99、0xAA 都只算是一個字符,即單字節8bit的16進制數據。是字節數據,不是字符數據,以A5為例,它可以使用0xA5這個單字節存儲或傳輸,當然也可以使用0x41(‘A’)和0x35(‘5’)兩個字節來存儲或傳輸。
另外,已經驗證過的一個問題是,
使用Wifi模組進行通信時,我們可以任意但唯一的指定設備標識碼,不必一定是MAC。NB-IoT設備不行哦,只能是IMEI。
工程配置和編譯
工程配置,并不復雜,基本可按照HCIP-IOT實驗手冊進行。編譯過程中倒是遇到了不少的麻煩。
工程配置
修改.config中的串口波特率。將NB-IoT連接模式修改為WIFI模式,詳情可參見具體源碼,點擊此鏈接下載即可。
CONFIG_UARTAT_BAUDRATE=115200
CONFIG_TCPIP_AL_ENABLE=y
CONFIG_ESP8266_ENABLE=y
CONFIG_ESP8266_SSID="HUAWEI-IoT"
CONFIG_ESP8266_PWD="135836xxx02+"
CONFIG_DTLS_AL_ENABLE=y //記得打開
CONFIG_MBEDTLS_ENABLE=y //記得打開
CONFIG_MBEDTLS_PSK=y //記得打開
CONFIG_OCLWM2M_ENABLE=y
CONFIG_OCLWM2MTINY_ENABLE=y
編譯不過
開啟上述DTLS三聯配置后,編譯報錯,說是Flash溢出了,即Flash存不下編譯生成的elf可執行文件了,
小熊派開發板使用的STM32L431RCT6,其片內Flash只有256K,確實不大。通過芯片手冊,或小熊派官網可以查詢到,
為了驗證編譯器報錯是否靠譜,我們先造個假,欺騙下編譯器。我們修改在 LiteOS_Lab_HCIP\targets\STM32L431_BearPi\GCC 目錄下的 os.ld 配置文件,臨時設置Flash為512K,重新編譯。
被欺騙的編譯器是可以通過編譯的。左側是啟用DTLS前的編譯結果,
啟用DTLS后,作為編譯結果的程序大出來68000字節,約合65KB字節,為什么DTLS這么耗費存儲呢?是源碼中開啟的模塊宏,如一些調試和日志模塊。包括底層LiteOS的一些暫時不用的模塊,都開啟了。需要裁減,但是這很費心神,愁得慌啊真是。我當時先的辦法,
0、裁簡DTLS模塊。(LiteOS我還不是特別熟,可能裁減不好,DTLS我試了試,各個細枝末節有關聯,也沒有參考)
1、不使用DTLS,退回到不安全模式。 (后記/應該確實不支持了)
2、是使用外擴展的Flash,來存放程序。(這不簡單啊)
3、放棄使用小熊派開發板,轉而使用Flash更大的芯片或板子。(太貴了)
哎,每個都不簡單啊。好在天無絕人之路,LiteOS中的Wifi示例程序,盡然裁減的不錯,可以滿足編譯呢。使用小熊派提供的示例程序,
…\bearpi-iot_std_liteos-master\targets\STM32L431_BearPi\Demos\oc_wifi_lwm2m_agriculture,結合自己的代碼,結果如下,
WIFI連接參數
基于LiteOS lwM2M_al 的核心封裝實現,在應用層看來,NB-IoT通信或基于Wifi通信是一致的,連設備接入流程的代碼都是一致的,只是在接入參數配置上有所區別,這是真替用戶考慮啊。應用層代碼實現請參考 #<IoT/HCIP實驗-5/基于NB-IoT的智慧農業實驗(平臺側開發+端側編碼+基礎調試分析)>#,本文只簡單說說WIFI通信下的設備接入配置。
#define cn_app_pskid "csdn_dahe_0528"
//#define cn_app_psk "00112233445566778899" //這是錯誤的哈
const unsigned char cn_app_psk[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA};
#define cn_app_psklen 10 //建議使用sizeof(cn_app_psk)static int app_report_task_entry() {...oc_param.app_server.address = CONFIG_APP_SERVERIP;oc_param.app_server.port = CONFIG_APP_SERVERPORT;oc_param.app_server.ep_id = CONFIG_APP_ENDPOIINT_ID;oc_param.boot_mode = en_oc_boot_strap_mode_factory;oc_param.rcv_func = app_msg_deal;#if 1 //CoAPS/DTLS加密oc_param.app_server.ep_id = cn_app_pskid;oc_param.app_server.psk = (char *)cn_app_psk;oc_param.app_server.psk_len = sizeof(cn_app_psk);oc_param.app_server.psk_id = cn_app_pskid;#endifret = oc_lwm2m_config( &oc_param);...
}
特別注意,特別注意,WIFI下的oc_param.app_server.psk,即cn_app_psk定義,與NB-IoT不同,不是使用字符串哈。
接入AP成功,IoTDA失敗
異常分析,小熊派開發板使用Wifi通信擴展板,接入AP成功,但是連接平臺失敗,
[DEBUG][189183][registration_step:1382] [189][registration_step:1382] targetP Status: STATE_REG_PENDING
[DEBUG][189192][transaction_step:505] [189][transaction_step:505] Entering
[DEBUG][189199][lwm2m_step:767] [189][lwm2m_step:767] Final timeoutP: ld
[DEBUG][189206][lwm2m_step:769] [189][lwm2m_step:769] Final state: STATE_REGISTERING
小熊派開發板WiFi接入AP成功后連接華為云平臺失敗(狀態卡在STATE_REG_PENDING和STATE_REGISTERING)。平臺地址或端口配置已經在NB-IoT實驗中進行過實驗(后來發現這是病灶)。因此分析最可能導致上述問題的原因是,DTLS握手失敗。
無可用加密套件
握手失敗錯誤-0x6900通常因未啟用CCM_C或PSK導致。
我在嘗試自己裁減HCIP-IoT-Lab代碼中的DTLS算法庫時,曾經遇到以上問題,關鍵原因是無可用加密套件,或者是PSK與平臺設置不一致,在后續的其他文章中,我們還會單獨針對DTLS采集重新討論。
成功接入平臺
設備側接入日志,
平臺側設備詳情,