2016年11月5日 星期六

ESP8266 Arduino IDE 開發問與答 Q&A ( 1 )

網頁最後修改時間:2016/11/26 

接觸 ESP8266 也有一段不算短的時間,期間的學習以及遇到的網友提問的問題也不少,其中也包含大量重複的問題 ! 希望大家若有問題詢問前:
  1.  看一下該網頁的問與答是否已經有答案
  2. 發問問題前先看過這篇公告,知道如何詢問問題及提供需要的輔助資料
反正不管怎樣,有問就盡量回覆 !

所以我整理了一些關於 ESP8266 的問題。如果在使用 ESP8266 到了撞牆期,或是常撞牆 !
或許接下來的網頁中的內容會有所幫助,釐清一些人關於 ESP8266 在學習上的一些疑惑 !
  • ESP8266 / 模組 / 開發板2016/11/05
  • Web of Thing (WoT, 萬物網)】2016/11/07
  • 聰明連線的方法:WPS / Smart Config】2016/11/25
網頁內容若與程式撰寫有關,都是指 Arduino IDE 環境。
在使用與學習 ESP8266 一段不算短的時間中,發現這塊小東西真的超乎想像中的好用和好玩 ! 除去自我周邊的接腳功能 ( GPIO / PWM / I2C / SPI / I2S ... ),最重要的一點:就是擁有無線網路通訊的能力 !

溫溼度感測器、光強度感測器、風速計、紫外線感測器 ... 都是單一功能電子周邊,需要另一個能夠讀取這些感測器資料的裝置,將資料讀取回來並經過轉換可閱讀的資料這個裝置,在這篇網頁中指的是微控制器 (例如,單晶片(51)、AVR、Arduino ... 類等等)。
這類裝置要有網路功能,大多需要加外掛 (Shield) 模組,而且對於網路部分的程式碼也是望之卻步 (會寫程式,不代表就會網路!術業有專攻,不熟的東西都是需要時間做籌碼去學的 !),而 ESP8266 卻是結合微控制器與網路的功能。注意 ! 這裡所指的網路是 "無線網路",的 !

在繼續之前,先跳一下解釋 ESP8266 這個名詞。

ESP8266 / 模組 / 開發板

ESP8266 應該說是晶片名稱 (有這兩種 晶片版本ESP8266 和 ESP8266EX),只不過已經將包含此片晶片做成的無線模組統稱為 ESP8266,只不過少了模組這兩個字

Link:ESP8266, wikipedia

ES8266 模組 (晶片模組開發)廠商利用這塊晶片開發成無線模組,也就是現在看到的 ESP-01, 01S, 02, ...07, 07S 12E, 12F, 13 ... 類等等,這其中也不乏其他廠商所開發的無線模組,但是基本電路架構都是一樣的,主要是根據在不同環境之下因應各種不同使用情況,所以做出不同的模組以供選擇 !

不管哪一種 ESP8266 模組,怎麼變化,都是使用 ESP8266(EX) 晶片,使用上只要關注接腳名稱對應的功能即可,因為撰寫程式與燒錄方式都是一樣的。
ESP8266 晶片與模組對應腳位
接腳上面的 GPIO # 就是 ESP8266(EX) 晶片上面的接腳名稱,也是 ESP8266 Arduino 程式撰寫時 Generic ESP8266 所定義的接腳號碼

static const uint8_t BUILTIN_LED = 2;//new ESP-12E GPIO2

原則上,若是該模組沒有釋出的接腳就不要在程式碼裡面寫到,除非你 (妳) 知道你 (妳) 要做什麼 !

再者,ESP8266(EX) 晶片沒有內建 SPI Flash (除了 ESP8285 有內建 1Mbyte Flash),所以 ESP8266 模組都會外接,作為儲存 user programs 之用。不同的 ESP8266 模組配置不同大小的 Flash,具體多大可以直接看上面的晶片型號,若是有裝設遮蔽外殼就要找一下資料或是詢問製造商貨零售商。
型號類似 25Q80 或是 25Q32B:最後面的 0 與 B 都是表示 MBit。除以 8 後,前者為 1 MByte;後者為 4MByte。這就代表 ESP8266 模組上的 SPI Flash 的大小;要注意單位。

SPI Flash 晶片位置
若是模組可以進行燒錄,那可以載入 {Arduino IDE}/Examples/ESP8266/CheckFlashConfig 這個範例程式,編譯後上傳再打開 Serail Monitor 看輸出訊息,裡面就有 SPI Flash 晶片的識別碼 (id)、大小( in Bytes)、SPI 速度和 SPI 模式相關訊息
取得 ESP8266 SPI Flash 相關訊息
ES8266 開發板 以 ESP8266 模組做為中心,在其外部加入其他電路方便開發稱之。

這就像是 Arduino UNO、Nano、Duemilanove、Mini、Pro 和 Pro Mini ... 等,大多使用 ATMEL ATMega328 作為微控制器,只要燒錄進去程式,基本上就可以運作 (ESP8266 模組也是一樣 )。
但為了開發上的方便,至少加入基本啟動電路、燒錄電路、USB 轉 TTL UART 電路和其他方便使用者開發時的其他電子週邊 (例如 LED、按鍵和其他感測器...等) 的整合電路板,方便使用。

開發板的種類很多,但是上面有說到,只要注意它所釋出的接腳作為使用即可 ! 也就是在 Arduino IDE 的板型 (Tools/Boards:) 選擇上,不管開發板是哪一種,都可以選擇 Generic ESP8266 Module 來用,但是會因為開發板使用的 ESP8266 模組不一樣,這時就需要特別的去設定好上傳的參數,要不就會上傳韌體時出現問題。
另外,開發板廠商為了方便使用者在寫程式的時候定義接腳名稱,板子上面都會特別有標示 ( 如Arduino 板上的 D1、D2...,A1、A2... );這些定義也可以從開發板電路圖找到 (如下所示)。
GPIO Number to Board Number
有了這些接腳對應之後,開發板廠商就會根據這個資料撰寫 Arduino IDE 開發上所需要的定義檔案。有了這個定義檔,使用者就可以直接使用類似下面的語法作定義

#define myLED D4    // 對應到 GPIO 2

直接將板上的接腳名稱對應到 ESP8266 模組的 GPIO 號碼。
最後,開發板廠商也會根據板載的 ESP8266 模組,撰寫上傳韌體所需要的 (Tools) 參數設定;除了可供選擇的項目可以做選擇之外,其他固定的參數就變成預設值不需要使用者額外做選擇。
這部分可以實際到 Tools/Board: 選單直接去做 Gereric ESP8266 Module NodeMCU 1.0 (ESP-12E Module) ,就可以看到其中的變化。

更多詳細的資訊,可參考 Github:ESP8266 core for Arduino

*********************************************************************************
延續跳轉之前的討論。

結合微控制器與網路的功能,使用 ESP8266 進入物聯網的世界就變得容易許多,但是這還只是基本的一小步 ! 這麼大物聯網世界,分布和散布的一些隨手可得的資料之後,如何蒐集和分析和應用這些資料讓它為其所用,就是另一個可以再進入研究的東西 (Web of Things, WoT, 萬物網) !

Web of Thing (WoT, 萬物網)
個人覺得,這是物聯網的重點,也是應該注重的部分,要不把資料丟到網路上去幹嘛,只是為了自己看 ? 還是少數人用 ? 這都是浪費 ! 只不過,若沒有一個準則或是標準來做遵循,即便有這些分享的資料可以用,也會有所侷限 ! 因此就有人提出了一個想法。據我所知到目前為止 (2016/11/07) 這部分已經進入到審核階段 ,一但通過就會是以後的標準。

但是或許又有人想:這只是規格,離真實應用還有一段時間 !

錯 ! 提出這個規格的時候,就已經實作完成了 ! 作者利用樹莓派連接一些電子週邊,以提出的 WoT 標準撰寫程式,而這個網頁就是個範例,只要懂得這個標準的人,就可以從任何地點控制、讀值、寫值...等樹莓派連接的電子週邊的動作和狀態。每個電子週邊分門別類,可以受控制、釋出狀態資料...等,這些都可以自己做設定。如此,遵循著這個可以說是近期 W3C 會通過的 WoT 規格,我們將會跟這些現在分散在世界各地的 IoT 裝置更加地接近 !

但是,要進入 WoT 的世界,這些資料還是需要讀一下的 ! ! !

WEB OF THINS AT W3C

...///

撇開終極應用,再回到 ESP8266 Arduino IDE 開發上。

一般使用 ESP8266 很少單獨使用而不開啟 WiFi 功能 ! WiFi 的功能很強大,有 Access Point (AP) 、Station (STA) 和混合的三種模式可供使用,可作為 WebServer、HTTP Server、OTA (over-the-air) 韌體上傳、DNS ... 等很多種應用,除非實務應用上只是為了讓內部使用,若是要與外界作溝通 (外部網路)就需要將 ESP8266 (Station) 連上 Access Point (例如路由器,每一個路由器可以設定多個不同的 SSID 名稱與連線密碼)。

對於家中網路連線名稱 ( SSID ) 與連線密碼 (Password) 相信大家都知道 ! 但是若今天的使用環境是在一個陌生的地方,總不可能打開電腦  -> 打開程式編輯器 -> 獲知網路連線名稱與密碼後 -> 編譯上傳 ... 完成 !!!! @#$%^&*&^%$# 這也太蛋疼了吧 !!!!!

【 聰明連線的方法:WPS / Smart Config 】
為了解決這種問題,也避免在使用者在開發完成之後,在不需要修改韌體的情形之下,可以快速的連上非預先定義的網路 Access Point,提供了兩種方法:
兩種方式在使用的時候必須要將 WiFi 模式設定為 Station 模式

WiFi.mode(WIFI_STA);

其他兩種模式都不可以 ! 若是需要其他模式,等連線成功之後再做切換。

WPS 是相對簡單許多的方法,只要在 ESP8266 開機之後 (1),按下支援 WPS 功能的路由器上面的按鈕 (通常標示為 WPS),就可以在不需要輸入任何資料下直接連線 (2);但現在只支援 push-button configuration。對於需要安全性的考量,使用 WPS 要特別注意 !
WPS 連線方式
WPS 測試程式碼下載

Smart Config 相對於第一種方法,就顯得繁瑣一點點 !

首先,先上 Google Play 安裝 ESP8266 SmartConfig (使用 ESP-TOUCH 通訊協議) 手機程式,接著上傳下面的程式到 ESP8266
程式上傳與輸出畫面
開啟手機上的 ESP8266 Smart Config,如果手機已經連上無線網路的話,APP 會直接將連線的 SSID 顯示出來 (沒有的話,先手動連接上),接著輸入連線密碼在下圖橙色文字中,按下 "CONFIGRM" 按鈕,就會將這些資料經由 UDP 的方式廣播出去
ESP8266 Smart Config GUI-01
APP 畫面就會變成下圖
ESP8266 Smart Config GUI-02
此時若 ESP8266 接收到相關訊息,就會開行進行連線,完成連線之後就會出現 Done!,接著將分配到的 Local IP 顯示出來,同在一個網路的裝置就可以利用這個 Local IP 互相傳遞訊息。
Smart config 測試程式碼下載
ESP8266 ESP-TOUCH 中文指導書下載

*********************************************************************************
[ NOTE ]
ESP8266 SmartConfig 軟體即使在 ESP8266 這一端真正連線上之後,也有可能出現 Fail 的訊息,但並不表示 ESP8266 連線是失敗的,這一點實際測試時可以自己確認 !
*********************************************************************************

不管使用的方法是哪一種,獲得的 SSID 與密碼資料,只會存在電源存在的當下 ! 當重置 ESP8266 之後,上面的流程就全部要再來一次,方便 ?! 但也不方便 !

「存起來不就好了 !」

沒錯 ! ESP8266 的確有這個功能,可以將不經常變動的資料直接儲存在 Flash 中,而且也提供了相對應的指令與函式庫可以直接使用。當深入對 Flash 操作的方法以及指令的熟悉之後,更可以自由操控 Flash 存儲應用,充分利用與劃分這些未開發之空間,作為私用 !

為了避免 Q&A 網頁內容太過攏長,所以決定幾個 Q&A 就跳轉一個網頁,Flash 這部分就請到另一個 Q&A ( 2 ) 去看吧 !


<< 相關網頁與連結 >>

13 則留言:

  1. 請教您 有沒有 關於 DeepSleep 與 WIFI Direct 的 範例與說明 , 謝謝

    回覆刪除
  2. deepSleep() 可參考 File/Examples/RTCUseMemory 這個範例;注意最上面的接線提示。
    因為 Wifi Direct 現在在 non-OS SDK 中此功能不可用,所以在 Arudino IDE 也不可用。

    回覆刪除
    回覆
    1. 請教您, 若是要做一個類似 鐵門遙控器 的裝置, ESP8266 開機連網後就待機(deepsleep) , 不預期何時會按下按鈕然後將資料送出 , 再回到待機(deepsleep) 等待下一次按鈕 , 有辦法做到這樣嗎?
      謝謝

      刪除
    2. [更正]
      睡眠模式大多就是用在這種方式! 接收來自外部的訊號喚醒,工作之後再次進入睡眠模式;對於 Arduino 板子可以這樣做。
      但是據我所知,ESP8266 deepSleep(us) 觸發之後就會進入睡眠狀態,等待 us 時間後再重新啟動
      ,程式是重頭執行到尾,而不是從進入睡眠的那裏。而觸發的當下,需要 RST 與 GPIO 16 連接才能重啟 ESP8266;所以要使用 deepSleep() 要先確認這個硬體現是否已完成!
      所以要使用按鈕啟動 ESP8266 就是要將相關電路加在這個地方,按下按鈕時如同按下 RST 一樣,重啟在睡眠中的 ESP8266。

      這裡是個例子,你可以參考一下,但不一定適用你的想法,需要自己再改一下
      https://goo.gl/JQ74uf

      刪除
    3. [補充]
      關於 ESP8266 低功號的解決方案,可以參考這篇文件的說明
      https://espressif.com/sites/default/files/documentation/9b-esp8266_low_power_solutions_cn.pdf

      刪除
  3. 不好意思 請問您這程式可以讓感測器透過Arduino跟ESP8266傳給手機嗎? 謝謝

    回覆刪除
    回覆
    1. Arduino + ESP8266 或是 ESP8266 獨立運行之下都可以透過 WiFi 通訊傳送資料出去,只要支援 WiFi 通訊就可以接收到資料。

      刪除
  4. 大大請問
    我本來是用esp8266傳送數據給資料庫
    但是我在夜晚不需要傳送資料只需要白天時傳送
    esp8266可以整個晚上休眠?
    休眠模式能夠持續一整晚的時間嗎?

    回覆刪除
    回覆
    1. 照本宣科來說是不行,因為根據 ESP8266 Arduino Core 裡面的函式描述,一次最多休眠 (2^32 - 1) us,大概近似 71 分鐘
      void deepSleep(uint32_t time_us, RFMode mode = RF_DEFAULT);

      deepSleep() 的動作並不是真的休眠被叫起來然後繼續未完成的程式碼往下作,是整個系統 RESET 重新執行 !
      如果要達到你要的功能,就必須在每次 RESET 之後,由程式裡取得系統時間 (可使用RTC晶片) 再進行比對是否要上傳資料到 DB,這樣會是比較接近你要的功能。

      ps. 要使用 ESP8266 的 deepSleep() 函式,GPIO16 必須要與 RESET pin 接在一起 ! 若對於上述說明有問題的話,可以再自己 Google 相關資料 !

      刪除
  5. 大大您好:經常看您的技術文章,獲益良多,是這樣的請教大大一個問題,最近用esp8266做了一個家電控制電路,不過業主要求要加AES 128,上網爬文了一下,好像是關於資料傳輸加密,想請問大師,有這方面的經驗可以分享嗎?是要用硬體加密,還是可以用純軟體加密,意思是說,esp8266架了一個server家電控制,Android app控制送出以下網址網址可能是192.168.0.11/ledON , 熄滅是 192.168.0.11/ledOFF, 要如何把網址變亂(加密動作),然後esp8266收到,要解密網址,讓受控家電作動.意思應該是這樣吧,能力不夠,網路上找不到答案,所以特來拜訪,還請賜教!

    回覆刪除
    回覆
    1. 加密網址可能不行 (GET),但是若是加密 POST 裡面的 MESSAGE 是可行的 (AES 編碼訊息然後收到之後再解碼)[https://github.com/kakopappa/arduino-esp8266-aes-encryption-with-nodejs]。

      我不清楚你的程式架構是如何,但這裡有一篇值得一讀的網頁,作者為了怕它的 IoT 裝置被攻擊做了很多重的安全認證,你可以上去看看
      http://jjssoftware.github.io/esp8266-rfc6238-totp/

      刪除
  6. 波特哥你很! 我想請問您, 我用 smart config連線後,想把SSID name & password記錄到flash,供給下次開機連線時,請問有沒有類似的範例,或是有函式可以把RAM紀錄的東西拉到flash去存? 謝謝波特哥賜教!

    回覆刪除
  7. 這篇網頁最下面不是就有儲存資料到 ESP8266 的連結嗎 ? 簡單說,存到 EEPROM 就可以了;若是搞得懂另一篇網頁說的 SPIFFS,那就當成檔案系統來用 (開檔案,寫入資料,關閉;開檔案,讀取資料,關閉)。

    要在 smartconfig 取得 SSID 和密碼,如果 Google 找不到,應該要去查 STA 相關的函式,直接去看程式碼裡面的 Class 宣告試試 ! 有兩個函式您可以試試 ( WiFi.??? 下面用,自己試試)

    // STA WiFi info
    String SSID() const;
    String psk() const;

    回覆刪除