2017/5/26

便宜的 WiFi Solution - 與 ESP8266 的第一次接觸

Maker終究是希望能跟Lucy一樣能跟夠使用/存取這萬物互聯的「全球心智, 除了連接人、電腦、機器設備、龐大的感測器外, 讓這些彼此相連的事物延展人類的感官與觸角也增強了原本的行動力(例如AR/VR3D列印義肢與機械骨架). 近年來「機器學習(Machine-learning)」技術的普及, 使得穿戴(非侵入)式裝置能夠隨時記錄我們的地理資訊與生物資訊等數據並依此分析/追蹤個人的健康狀況(例如透過分析汗水中的乳酸成分可以預測血糖濃度而免受扎針之苦). 相信再過不久, 像超人般的超距離感官, 例如進一步用腦波控制上述的事物甚至是能理解他人或動物的情緒等, 也都將一一實現.

相信你也跟筆者一樣在尋找用什麼方式來將之前made的東東連上網, 比如把監測器的數值放到雲端以及如何用手機讀取它或透過雲端送指令給我們的終端設備(例如開關或伺服器馬達等). 因此, 很直覺我們會想到學習用WiFi, 至少還想要學會如何用便宜的方法架設伺服器以方便控制/存取我們所連上網的各元件與監測器, 而筆者在經過一番審慎評估後選擇了ESP8266(它很便宜又容易使用).

Maker對於WiFi相關技術產品的推出與開發應用, 是開始的早好呢還是早不如巧呢? 相信大家猶記得「藍芽門」事件吧? 因為成本與一些配套技術問題, 大多早期開發藍芽晶片的公司都還等不到市場成熟就提早退場了. ESP8266為例, 我們起步雖晚, 然而相信我們是相對幸運的, 因為成本與許多相關的技術問題都已獲得改善了. (筆者三年沒當Maker想不到Arduino IDE已經從1.0.5進化到1.8.2了呢!)


ESP8266晶片外觀
ESP8266非常小巧, 筆者買的型號是功能屬於最陽春的ESP-01模組(電子材料行賣台幣150, 掏寶會更便宜), 筆者一個拇指可以完全將其遮蔽, 如下圖.



ESP8266的接腳規格比較特殊(兩排共八支針腳), 不像是直接給Arduino用的, 可能原本是客製化給某大戶的設備做WiFi連接用. 不過這問題不大, 網路上已有許多人分享他們為ESP8266專門自做一個版子來連接Arduino的方法. 不過筆者在prototype階段比較喜歡彈性, 也習慣先買/自做一些排線與接頭備用, 最後視實際需要的接腳數目再拆下來即可(沒用到的接腳也可不拆空著).



所以我們可以先將必須使用到的ESP8266的針腳拉出來, 例如本文案例只須接五支腳, 外觀就如下圖. (藍芽模組也可以用這種方法接)



使用ESP8266需要注意的是, 依照規格它需要獨立的3.3V供電, 而連網時可能消耗超過200mA電流, 但是Arduino 3.3V最大輸出電流只有約150mA. 因此實務上建議先做一個可提供較大電流的3.3V電源轉換電路給ESP8266使用, 如下圖.



然而筆者在開始研究ESP8266, LD1117竟然已經買不到了也找不到SC07821, 電子材料行好像也不打算補貨了怪哉? 只好硬著頭皮用 Arduino提供的3.3V硬幹了! 但幸運的是, 筆者直接拉Arduino3.3V出來給ESP8266使用好像沒遇到太大的問題, 也沒遇到許多網友所提到的韌體問體. 如同之前談論到的, 我們介入的晚, 或許許多韌體、函式庫與相關的驅動程式等都改善了吧? 而最後整個系統連接(硬幹)如下圖.




細部接線
ESP8266(ESP-01)總共有八支腳, 以下圖layout方向來看每支腳定義如下. 其中標示為藍色底的三根信號(RSTGPIO0GPIO2)於本案例中用不到, 我們把它空接.



筆者之前做功課看到許多網友討論到CH_PD這支腳若直接接高電位(3.3V)會有ESP模組耗電量提高的問題, 再加上電路沒有使用LD1117電壓轉換電路來提供適當電流的3.3V電源, 因此心想既然是第一次接觸又是硬幹, 也深怕才剛起頭就出狀況導致後面沒戲, 所以筆者就照著做囉(並沒多加查證). 




Arduino程式
筆者的Arduino IDE開發環境1.8.2 ZIP免安裝版. 程式部份我們用SoftwareSerial函式庫將Pin3Pin2模擬成序列埠(分別接TXRX)ESP-01模組, 之後我們將在序列埠監控視窗傳送AT控制命令到ESP8266並接收其傳回來的信息. 由於筆者購買的ESP-01模組其出廠包鮑率(Baud)是設定在115200bps, 所以將Arduino序列埠也設成一樣直接用, 並沒有做任何韌體更新的動作.

#include <SoftwareSerial.h>

SoftwareSerial ESP(3, 2); // ESP8266 ESP-01: Tx, Rx
 
void setup() {
    Serial.begin(115200);
    ESP.begin(115200);
    delay(3000);
    Serial.println("========START AT CMD========");
}

void loop() {
    // send AT command to ESP-01 form console (serial)
    // !NOTE! console must include \r\n at the end of your command line
    while ( Serial.available() ) {
        ESP.write( Serial.read() );
    }
    // AT+GMR     : ESP-01 will return firmware version
    // AT+CWMODE? : ESP-01 will return the configuration mode
    // AT+CIFSR   : ESP-01 will return the IP
    while ( ESP.available() ) { // receive message from ESP-01
        char ch = ESP.read();
        Serial.write( ch );
    }
}



迴圈內主要有兩部份: 一個是監看Arduino本身序列埠是否有資料(由序列埠監控視窗下指令), 若有則將資料直接照抄(write)給我們軟體模擬給ESP-01模組的序列埠(傳送指令給ESP-01). 另一個是反過來監看ESP-01模組的序列埠是否有資料傳進來, 若有則將資料直接照抄(write)Arduino序列埠(ESP-01傳進來的資料透過Arduino序列埠監控視窗顯示出來).



AT Command ESP-01溝通
接下來我們由Ardunio序列埠監控視窗下達AT指令(AT+開頭的字串), 並透過序列埠監控視窗顯示ESP-01模組的回傳值. 整個過程像是用通信軟體在跟機器人對話, 只是對像是ESP-01模組. 請將序列埠監控視窗鮑率(Baud)設為115200bps, 並選擇在命令列尾端自動加上\r\n字元.



舉例來說: 我們可以在序列埠監控視窗的命令列(command line)打上AT+GMR按傳送, 可以看到ESP-01模組傳回韌體的版本. 若打上AT+CWMODE?按傳送, ESP-01模組回傳WiFi的組態, 例如1STA(Station, 終端模式), 2AP(Access Point, 接入點模式).


常用AT命令表列
下表為常用的AT命令說明, 自己玩玩看囉!

AT Command
說明
AT+RST
硬體重置
AT+CWMODE?
WiFi 組態查詢
AT+CWMODE={1,2 or 3}
WiFi 組態設定
1: STA (Station)
2: AP (Access Point)
3: STA+AP
AT+CWLAP
讓模組列出當前環境下存在無線路由器的列表
AT+CWJAP="xxx.xxx.xxx","password"
讓模組連上自己的路由器
AT+CWJAP?
檢測模組是否連上自己的路由器
AT+CIPMUX=1
啟動模組允許多重連線
AT+CIPSTART=4,"TCP"," X1.X2.X3.X4",9999
讓模組連接ID4的連上我們遠端TCP伺服器
X1.X2.X3.X4
IP位址9999為埠讓模組列出當前環境下存在無線路由器的列表
AT+CIPSEND=4,15
"I can hear you!"
發送15個字元"I can hear you!"ID4的連接
AT+CIPSERVER=1,80
開啟模組本地的TCP 伺服器(其中1為開啟, 0則關閉)
80
為監聽埠
AT+CIFSR=?
檢查模組的IP位址