網頁最後修改時間:2018/08/01
延續前一篇說明如何以手動輸入的方式建立 ESP8266 的透傳模式後,這一篇將以此做為依據撰寫 MCU 程式操作 ESP8266 進入 UDP 透傳模式,並同時與電腦和另一顆 ESP8266 進行 UDP 透傳通訊。
*********************************************************************************
此網頁所用的材料可自行準備,或選用新版本的升級套件
- V2.1 版 { 萬物皆聯網-ESP8266 IoT(Internet of Things)入門學習套件 }
- Arduino UNO + ESP8266 (Wi-Fi) 二合一開發板 ( 可選擇獨立與偕同開發 )
*********************************************************************************
雖然 AT 指令透傳模式下,ESP8266 不支援多連接,但這是表示:
- 做為 TCP Client 時,ESP8266 只能接收來自單一 TCP Server 的回傳的資料,但可以跳轉到其他同一區域網路下的其他 TCP Server。
不過 ESP8266 處於 TCP 透傳模式下,必須要有 TCP Server 存在,否則 AT+CIPSTART 指令一下就會返回失敗;但 UDP 則不會。 - UDP 透傳通訊下,只能接收來自指定的 RemoteIP 回傳的資料,但不限定要傳送資料給哪一個 UDP 網路裝置 ( 上述限定 AT+CIPSTART 最後一個參數設定為 0 )。
用戶可以指定要傳送資料到任一個 UDP 裝置,但此時除非雙方裝置已互相設定對方,否則是收不到其回傳的資料的。
架構說明:
整個 ESP8266 UDP 透傳模式的測試架構,如下圖所示。
ESP8266 UDP 透傳模式測試架構圖 |
電腦使用 TCP-UDP 軟體設置 UDP 通訊 |
TCP-UDP 軟體下載 (Windows Store),也可使用 USR-TCP232 (前一篇有下載網址)
上面簡單的說明了整個 ESP8266 UDP 透傳模式的測試架構,至於詳細的過程請參考下面各節的說明:
- 電腦的 UDP 通訊設定
- 電腦端的 ESP8266 (ESP-01S) UDP 透傳通訊 (AT 指令)
- Arduino UNO + ESP8266 (WiFi) 開發板的程式撰寫與模式選擇開關操作說明
電腦的 UDP 通訊設定:
打開 TCP-UDP 軟體切換到 "Settings" 頁面。選擇 "UDP" 傳輸,並根據架構圖 "電腦" Remote 欄位的資訊,輸入資料到相對應 (紅色框框) 的欄位,最後按下 "Connect" 進行 UDP 連線;再提醒一次,這時被連線的裝置並不需要事先建立好 UDP 連線。畫紅線的部分則是說明此軟體 (TCP-UDP) 所代表的 IP 地址,是電腦網路介面卡的。
TCP-UDP Settings 頁面 |
不過有個東西可能需要注意一下!就是傳送的資料字串必須以換行符號 (LF, \n, ASII 10) 作結尾,所以 "Format of Send Data" 欄位必須選擇 "Mix" 才能輸入 16 進位的字元碼;如下圖輸入欄位所示。
TCP-UDP Terminal 頁面 |
/*--*//**---/*///**---*-*////***--*/*///***----*///--*/*///**--*/*//**--**/*//
** 使用命令列變更電腦 IP:
有時會特別需要將電腦指定為特定的 IP 地址。以管理者權限開啟命令提示字元視窗,輸入畫面上的指令,就能手動變更。
首先,輸入 netsh int ip show interface 可得到網路介面卡的名稱。
由於電腦端使用無線網路,因此要變更的是網路介面卡是 "Wi-Fi"、IP 地址 192.168.11.3、Netmask 255.255.255.0 和 Getway 192.168.11.1,將這些資料引用到下一個指令變更 IP 地址
netsh int ip set address "Wi-Fi" static 192.168.11.3 255.255.255.0 192.168.11.1 1
參考網址
若之後要變回 DHCP,則改用下面指令恢復
netsh int ip set address "Wi-Fi" dhcp
參考網址
給特定網路介面指定靜態 IP |
電腦端的 ESP8266 (ESP-01S) UDP 透傳通訊 (AT 指令):
這一部分主要是架構圖中間偏左的 ESP8266 (ESP-01S) 藉由 UART 通訊底接到電腦,使用串口調試助手發送 AT 指令建立與架構圖最右邊開發板的 UDP 透傳通訊。這也是最主要的通訊部分,所有傳送到開發板的資料都會轉發到此處。
下面是建立與開發板的 UDP 透傳通訊的 AT 指令集。大致與前一篇的指令差不多,只多了步驟 5 (下面會特別說明)。若之前已經恢復 ESP8266 (ESP-01S) 參數回預設值,則從步驟 3 開始執行即可,詳細的操作過程可參考前一篇網頁。
AT 指令集 - ESP8266 (station mode), UDP 透傳模式 |
/*--*//**---/*///**---*-*////***--*/*///***----*///--*/*///**--*/*//**--**/*//
* 設定 Station 的 MAC 地址 :
AP 和 Station 的 MAC 地址在 ESP8266 無線模組中不可以設定相同,但是有可能兩個 ESP8266 擁有相同的 MAC 地址嗎 ? 這是有可能的,但箇中原由請自行 Google,這裡只討論怎麼解決!
當出現兩顆 ESP8266 擁有相同的 Station MAC 地址時,同時連線到同一個無線路由器時會產生衝突,連線就會產生問題,因此事先透過 AT 指令查詢是否測試的 ESP8266 無線模組擁有相同的 MAC 地址,就可事先預防此問題;別懷疑!就是會發生,所以才有這一小節。
修改 Station MAC 地址可使用下表的 AT 指令,但請提別留意注意事項裡面的最後一點。如此,才能事先確認,避免後面無謂的程式除錯與時間浪費!
AT+CIPSTAMAC |
Arduino UNO + ESP8266 (WiFi) 開發板的程式撰寫與模式選擇開關操作說明:
這個網頁的 MCU 測試程式,除了可用所提到的二合一開發板之外,也可單獨使用 Arduino 開發板再自行加上 ESP8266 (ESP-01/01S) 無線模組也行。關於二合一開發板的部分,請繼續往下看各小節的說明。
/*--*//**---/*///**---*-*////***--*/*///***----*///--*/*///**--*/*//**--**/*//
* Arduino UNO + ESP8266 (WiFi) 開發板開關操作說明:
如下圖所示,各方塊內號碼代表開關,通訊元件 CH340 與 ATmega328 (MCU, 微控制器) 和 ESP8266 (WiFi) 經由不同的號碼組合,可使二合一開發板處於不同的開發或通訊模式下。
二合一開發板模式選擇開關示意圖 |
二合一開發板接腳說明 |
- 插拔開發板上的 MicroUSB 埠時,要先用手按住MicroUSB 埠之後再插拔,避免施力方向或動作不對易造成損傷
- 同時使用 Arduino UNO 和 ESP8266 功能時 ( 1-2 ON ),勿直接使用電腦 USB 供電 (電流不夠,開發板會一直重置),要使用大電流 ( 至少 1A 以上 ) 的 5V 電源供應器 ( MicroUSB 埠供電 ) 或外部電源供電
Arduino 程式要上傳的時候,3-4 ON 其餘 OFF。成功上傳之後,退出電腦 USB 埠,1-2 ON 其餘 OFF,接著變換使用外部電源供電;除非電腦 USB 埠能提供足夠的電流,否則請務必使用外部電源,再次提醒!
二合一開發板模式選擇開關實體圖 |
/*--*//**---/*///**---*-*////***--*/*///***----*///--*/*///**--*/*//**--**/*//
* Arduino 程式碼:
下面的程式碼與影片中使用相同,當中移除一些冗長的註解並採分段說明,用前請自行整理。
先從主程式的部分看起。
setup()
- line 2: UART 通訊速率設為 115200 bps
- line 3: 等待 ESP8266 開機穩定
- line 5: 設定 Arduino 板載的 LED (D13, L) 為輸出
- line 8 ~ 9: 單獨重置 Arduino 開發板時,若 ESP8266 沒有一起重置,會導致 ESP8266 一直處於 UDP 透傳狀態無法輸入 AT 指令,所以需在程式開始執行前讓其跳出透傳模式,也能同時確認 ESP8266 已連接且可接受 AT 指令。當此處出現錯誤時,板載 LED 每秒閃一次。
- line 11 ~ 12: 建立 UDP 透傳通訊。當此處出現錯誤時,板載 LED 每秒閃二次。
- line 15: 建立 UDP 透傳通訊若沒有出現任何問題,則讓板載 LED 常亮;否則在 line 8 - line 12 出現錯誤時,此燈會以每秒閃爍幾次來指示錯誤發生的地方。
ESP8266UDPPassthrough_Demo00, (01/07), setup()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void setup() { Serial.begin( 115200 ); delay( 3000 ); // wait pinMode( _builtin_led, OUTPUT ); // 退出透傳模式與 UDP 傳輸,回到 AT 指令下 if( !exitPassthroughMode() ) ledErrorIndicator( 1 ); if( !station_createUDPPassthrough() ) ledErrorIndicator( 2 ); digitalWrite( _builtin_led, HIGH ); } |
loop()
- line 3 ~ 4: 接收來自 UART 的字元,並且將其存入到 rcv[] 字元陣列中
- line 7: 接收到換行符號,表示已接收到一完整字串,可以準備回傳
- line 8: 加入字串結束字元
- line 9 ~ 10: 回傳接收到的字串之前,先輸出頭行 ">>> reply from ESP8266" 再輸出接收到的字串;藉此可用來區分出是從哪一個裝置回傳的資料
- line 12 ~ 16: 確認字元陣列範圍沒有溢出,如超出範圍則將設為 0。所以輸入的字元再多,也只會輸出字串最後面的部分
ESP8266UDPPassthrough_Demo00, (02/07), loop()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | void loop() { if( Serial.available() ) { rcv[ rcvIndex ] = Serial.read(); //--** 收到換行字元,準備輸出**--// if( rcv[ rcvIndex ] == '\n' ) { rcv[ rcvIndex + 1 ] = 0; Serial.print( ">>> reply from ESP8266\n" ); Serial.print( rcv ); rcvIndex = 0; } else { //--** 確認範圍,避免溢出 **--// if( rcvIndex < ( CHARBUFFER - 2 ) ) rcvIndex++; else rcvIndex = 0; } } } |
再來的是程式用到的標頭檔與變數宣告和定義。
ESP8266UDPPassthrough_Demo00, (03/07)
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> // 常亮表示 AT 指令執行正常,閃爍就是出現錯誤! #define _builtin_led 13 #define CHARBUFFER 102 static char rcv[CHARBUFFER]; // 暫存接收到的字元 static uint8_t rcvIndex; // 字元暫存位置 bool checkOK( uint16_t m = 0, uint8_t e = 0 ); |
最後是其他函式的部分。
checkOK 檢查 AT 指令回傳是否正確。
- line 2: 等待 ms 時間之後再確認 AT 指令回傳的訊息
- line 4: 確認 AT 指令回傳是否包含 "OK"
- line 5: 若沒有回傳 "OK" 表示指令執行出現錯誤,依照參數 e 的設定,指定每秒 LED 閃爍的次數 (此函式不返回,會一直重複執行)
- line 7: 若沒有出現錯誤,返回 true
ESP8266UDPPassthrough_Demo00, (04/07), checkOK()
1 2 3 4 5 6 7 8 | bool checkOK( uint16_t ms, uint8_t e ) { if( ms > 0 ) delay(ms); if( !Serial.find( "OK" ) ) if( e > 0 ) ledErrorIndicator( e ); return true; } |
ledErrorIndicator 使用 LED 閃爍的方式顯示錯誤;當程式出現錯誤時,會一直留在此函式。
- line 2: 儲存 LED OFF 的時間值
- line 7 ~ 11: 重複執行 LED 閃爍的動作
ESP8266UDPPassthrough_Demo00, (05/07), ledErrorIndicator()
1 2 3 4 5 6 7 8 9 10 11 12 | void ledErrorIndicator( uint8_t times ) { static uint16_t offms[] = {900, 400, 250, 150, 100}; while(1) { for( int i = 0; i < times; i++ ) { digitalWrite( _builtin_led, HIGH ); delay( 100 ); digitalWrite( _builtin_led, LOW ); delay( offms[times - 1] ); } delay( 1000 ); } } |
exitPassthroughMode 避免 ESP8266 停留在透傳模式,使其回到可輸入 AT 指令的模式下。
ESP8266UDPPassthrough_Demo00, (06/07), exitPassthroughMode()
1 2 3 4 5 6 7 8 9 10 11 12 | bool exitPassthroughMode() { Serial.println( "AT" ); if( !checkOK() ) { Serial.print( "+++" ); // 退出透傳傳送數據 delay( 1000 ); // 延遲 1 秒後才能繼續傳送 AT 指令 Serial.println( "AT" ); if( !checkOK() ) return false; } return true; } |
station_createUDPPassthrough 建立 UDP 透傳通訊。
這部分參考前一篇 - ESP8266 (station mode), UDP 透傳模式這一小節裡的 AT 指令集。所不同的是,將所有會自動儲存到 flash user parameters 區域裡的 AT 指令,全部在指令尾部加上 _CUR 讓這些指令只生效在當下。
由於相關 AT 指令在前篇網頁與下面程式碼中都有說明,所以就不再贅述!
ESP8266UDPPassthrough_Demo00, (07/07), station_createUDPPassthrough()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | bool station_createUDPPassthrough() { // station // 建立 station Serial.println( "AT+CWMODE_CUR=1" ); // station mode if( !checkOK(0, 1) ) return false; // 連線到 ROUTER Serial.println( "AT+CWJAP_CUR=\"Proteus-WiFi\",\"asdfghjkl\"" ); if( !checkOK( 5000, 3 ) ) return false; // 指定 station 的 IP、Gateway 和 Netmask Serial.println( "AT+CIPSTA_CUR=\"192.168.11.11\",\"192.168.11.1\",\"255.255.255.0\"" ); if( !checkOK( 0, 3) ) return false; // Establish UDP Transmission Serial.println( "AT+CIPSTART=\"UDP\",\"192.168.11.12\",8888,8889,0" ); if( !checkOK( 0, 4 ) ) return false; // 設定傳輸模式為透傳模式 Serial.println( "AT+CIPMODE=1" ); if( !checkOK() ) return false; // 開始傳送資料 Serial.println( "AT+CIPSEND" ); if( checkOK(0, 5) ) if( !Serial.find( ">" ) ) return false; return true; } |
在程式上傳之前,請確認程式碼編譯沒有問題,以及至少執行過一次 ESP8266 AT 指令 AT+RESTORE,否則執行上很大可能會出現錯誤!
另外,有可能是因為 Arduino 關電的當下沒有以適當的方法退出透傳模式 ( +++ ) 和退出 UDP 傳輸 ( AT+CIPCLOSE ),因此系統重置之後要再馬上重新建立 UDP 透傳通訊,會連不上!若出現此問題時,先全部關電等待至少 15 ~ 30 秒後再重新開電即能正常運行。若還是不行,再延長時間至 1 分鐘,讓無線路由器反應過來再作連線,就會恢復正常運作!
照著網頁中的步驟逐步完成相關的設置之後,就能做到與下面影片相同展示的動作。
結論:
經過連續兩篇網頁說明 ESP8266 AT 指令下透傳通訊的介紹,對比於一般傳輸模式,透傳通訊有著如下的方便之處:
- 資料傳送之前,( AT+CIPSEND ) 不需指定網路連接 ID 號碼 <link ID> 和字串長度 <length>
- 資料接收時,不需處理 +IPD 指令
- 連接斷開時,普通傳輸模式不會重連,直接提示斷開 [,<link ID>] CLOSE;透傳傳輸模式會一直嘗試重連,直到接收到 +++ 退出傳輸,停止重連
經過此篇網頁中實際範例的操作,展示了同樣使用 AT 指令操作的兩顆 ESP8266 無線模組的透傳通訊,也同時展示了如何在電腦端與 ESP8266 透傳通訊的方法,希望對於 ESP8266 透傳通訊說的還算清楚,也能起到幫助的作用!
<< 部落格相關文章 >>
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 07 } - 結合 Arduino + ESP8266 實現 MQTT 主題訂閱與接收
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 06 } - 了解 MQTT 協議,學習如何訂閱 MQTT 主題與接收 MQTT 發佈消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 05 } - 結合 ESP8266 發佈 MQTT 消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 04 } - 了解 MQTT 協議,學習如何發佈 MQTT 消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 04 } - 了解 MQTT 協議,學習如何發佈 MQTT 消息
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 03 } - 使用 Arduino + ESP8266 上傳 SHT31 溫溼度數據
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 02 } - 設備感測數據讀取與 (JSON) 解析
- 當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 01 } - 如何使用 ESP8266 利用 AT 指令取回中華電信 IoT 智慧聯網大平台上的設備感測器數據
- ESP8266 AT 指令下的透傳模式
- 如何使用 AT 指令讓同在 AP+STA 模式下的 ESP8266 互相通訊 ?
- 操控 ESP8266 無線模組 - 經由 AP、STA 和 AP+STA 三種模式,學習 ESP8266 AT 指令
沒有留言:
張貼留言
留言屬名為"Unknown"或"不明"的用戶,大多這樣的留言都會直接被刪除掉,不會得到任何回覆!
發問問題,請描述清楚你(妳)的問題,別人回答前不會想去 "猜" 問題是什麼?
不知道怎麼發問,請看 [公告] 部落格提問須知 - 如何問問題 !