《超圖解物聯網IoT實作入門》第13章「透過OTA更新ESP8266的韌體」一節的程式,採用瀏覽器,用Wi-Fi連線方式更新ESP8266程式,也就是以OTA(Over the Air programming)方式更新軟體。
本文則使用ArduinoOTA程式庫建立直接從Arduino IDE,以Wi-Fi無線方式上傳新檔的ESP8266程式。
ArduinoOTA程式樣版
要完成本單元實作,電腦作業系統須事先安裝Python 2.7(非Python 3.x版,兩者語法不完全相容)。Arduinoi IDE請使用1.6.7以上版本(筆者採用1.8.2版),ESP8266平台套件2.0.0以上版本(筆者採用2.3.0版)。
Arduino IDE的ESP8266平台套件包含OTA範例程式,請先從IDE選擇你的控制板,再開啟BasicOTA範例:
- 從Arduino IDE的「工具→開發板」選單,選擇一款ESP8266控制板,例如,NodeMCU 1.0或WeMos D1 Mini。
- 從主功能表選擇「檔案→範例→ArduinoOTA→BasicOTA」範例檔。
ArduinoOTA採用UDP協定傳送檔案,所以程式開頭引用了WiFiUdp.h程式庫:
#include <ESP8266WiFi.h> #include <ESP8266mDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h>
此範例程式將以STA模式連接Wi-Fi網路,請在setup()函式的這兩行敘述設定Wi-Fi網路名稱和密碼:
const char* ssid = "你的Wi-Fi名稱"; const char* password = "你的Wi-Fi密碼";
選擇性地設定ESP8266的埠號、主機名稱以及OTA連線密碼:
// 埠號預設為8266 // ArduinoOTA.setPort(8266); // 沿用預設值 // 主機名稱預設為"esp8266-晶片ID" ArduinoOTA.setHostname("jarvis"); // 改成"jarvis" // 預設無需驗證密碼 ArduinoOTA.setPassword((const char *)"12345678"); // 密碼設定為"12345678"
其餘程式碼不用改,從「工具→序列埠」選單確認控制板的埠號選擇正確後,上傳此程式到ESP8266控制板。
過一會兒,Arduino IDE的「序列埠」選單,將包含「網路連接埠」以及ESP8266控制板選項。
如果該選項遲遲沒有出現,請嘗試:
- 關閉Arduino IDE再重新啟動。
- 確認執行Arduino IDE的電腦和ESP8266控制板位在相同網域,也就是連接到同一個無線網路基地台。
- 確認有安裝好Python 2.7版,以Windows為例,在「命令提示字元」的任何路徑下,輸入”python -V”(V要大寫),系統將回報Python的版本。
OTA無線上傳Arduino程式檔
選擇好位於無線網路連接埠控制板之後,像平常一樣編譯與上傳程式碼,程式檔將透過Wi-Fi網路上傳到ESP8266控制板。由於此OTA連線程式有設定密碼,所以Arduino IDE將顯示如下的密碼輸入對話方塊:
若密碼輸入錯誤,Arduino IDE底下的訊息欄位將顯示Authentication Failed(驗證錯誤)的訊息:
若密碼輸入正確,則開始上傳程式檔。
底下是setup()函式當中,其他與ArduinoOTA程式庫相關的敘述:
// OTA「開始」的事件處理程式 ArduinoOTA.onStart([]() { Serial.println("Start"); }); // OTA「結束」的事件處理程式 ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); }); // OTA「進行中」的事件處理程式 ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); // OTA「錯誤」的事件處理程式 ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); // 啟用OTA ArduinoOTA.begin(); /* 底下可加入你的自訂程式 */
最後是放在loop()函式裡面,負責聆聽OTA請求的敘述:
void loop() { // 處理OTA請求 ArduinoOTA.handle(); /* 底下可加入你的自訂程式 */ }
如同13-15頁「整合OTA功能與自訂的程式」一節的說明,你可以把這個範例當作樣版,在其中加入自己的程式(如:溫濕度控制),讓你的程式具備OTA更新功能。
有了OTA,玩ESP8266真的方式多了~~~
剛才試了一下,建議上傳完ArduinoOTA,要養成習慣先RESET一下ESP8266再繼續上傳自己的sketch。因為我發現如果沒有先RESET,很容易發生一些很離奇的問題(我遇到的是,我上傳一個沒有加入密碼的sketch,Arduino IDE也顯示update成功,接著我拔除3.3v的電源再重新插上,要再透過WIFI去Upload就會回報Authentication Failed,但有趣的是,它根本沒有出現叫我填密碼)。
後來我變更幾個hostname測試後發現,有時候如果你沒有先RESET,Arduino IDE裡面的Port,只存在舊的網路Port,即使關閉Arduino IDE再重開也是一樣。這個時候只要輕輕的RESET一下,網路Port就會正常了~~~
非常感謝Kevin的經驗分享!
thanks,
jeffrey
如果需要機器RESET
那就失去OTA的便利性了
请教一下,我的Arduino IDE是1.6.9版,ESP 8266库是2.3.0版,win7系统也安装了Python2.7。但是在使用OTA功能,上传固件时,程序能编译成功,Arduino却报出“arduino java.io.IOException:Cannot run program “Python.exe “:CreateProcess error=2,系统找不到指定文件”的错误,请问一下这是什么原因,如何解决?
请问你有将Python路径存入系统Path变量吗?
thanks,
jeffrey
之前的确没有将路径存入系统,在系统环境变量Path后面增加”;C:\Python27\”,问题已解决,谢谢。
感谢告知!
thanks,
jeffrey
請問一下密碼是填那個??
就是上面程式裡的”12345678″
thanks,
jeffrey
始终搞不到,总卡在这个ArduinoOTA.setPassword,Type board password to upload a new sketch,输入了好像没反应
你好 请问不在一个网络内,例如我在办公室,想更新家里的8266,可以通过这种方式更新吗?
請參閱這一篇回應說明。
thanks,
jeffrey