OTA(空中下載)編程是任何支持 WiFi 的微控制器(如 ESP32 和 ESP8266)的一項功能,它允許這些設備在無需任何物理訪問的情況下無線升級其固件或軟件。此功能可用于對固定在屋頂或任何其他難以連接電纜的地方的設備進行重新編程。使用 OTA,您可以將更新發送到同一網絡上的多個微控制器或設備。例如,此功能可用于向多個微控制器、手機、計算機、機頂盒等發送解決錯誤的更新、添加一些功能等。OTA 更新在物聯網中也發揮著重要作用。它用于使用新設置、軟件和固件遠程更新聯網設備。在本教程中,我們將使用Arduino IDE 中的 OTA Web Updater對 ESP32 進行無線 (OTA) 編程。
所需組件
ESP32
Arduino IDE
OTA 編程如何工作?
要使用無線 (OTA) 編程功能,首先,您需要通過串行端口上傳一個草圖。此草圖包含用于創建 OTA Web 更新程序的 HTML 代碼,以便您稍后可以使用瀏覽器上傳代碼。當代碼通過串口上傳時,它會創建一個網絡服務器,您可以在其中通過網絡瀏覽器選擇和上傳新草圖。
要上傳第一個代碼,請將 ESP32 連接到筆記本電腦并打開 Arduino IDE,將 Board Type 選擇為 ESP32 Dev Kit,然后選擇正確的串口。
然后轉到文件》示例》ArduinoOTA》 OTAWebUpdater
更改原始代碼中的 Wi-Fi 名稱和密碼。
const char* ssid = “你的 WiFi 名稱”;
const char* 密碼 = “密碼”;
將代碼上傳到您的 ESP32 開發板。成功上傳代碼后,打開串口監視器。更改串行監視器上的波特率 115200,然后按 ESP32 上的重置按鈕,它應該打印 ESP32 IP 地址。
現在打開默認瀏覽器并粘貼 ESP32 IP 地址。它應該打開用于無線編程的 Web 服務器,如下圖所示:
默認用戶名和密碼是admin。
然后輸入用戶名和密碼并單擊登錄頁面,將打開一個新選項卡。這是您可以上傳代碼的地方。
在這里,我們將上傳一個簡單的 LED 閃爍代碼。您通過無線方式上傳的每個代碼都應該有一個 OTA 代碼。所以在原始OTA代碼中加入blink部分。完整的代碼在頁面末尾給出。
無效循環(無效){
server.handleClient();
延遲(1);
數字寫入(領導,高);
延遲(600);
數字寫入(領導,低);
延遲(600);
}
用新名稱保存您的代碼,然后轉到S ketch 》 Export compiled Binary。這將在您的草圖文件夾中創建一個新的.bin文件。
現在轉到 OTA 網頁,然后單擊“選擇文件”按鈕并選擇.bin文件。在此之后,單擊“更新”按鈕上傳草圖。
?
#include
#include
#include
#include
#include <更新.h>
const char* host = "esp32";
const char* ssid = "銀河-M20";
const char* 密碼 = "ac312129";
//無延遲閃爍的變量:
常量 int led = 2;
WebServer服務器(80);
/*
* 登錄頁面
*/
const char* loginIndex =
“功能檢查(表格)”
“{”
“如果(form.userid.value=='admin' && form.pwd.value=='admin')”
“{”
“window.open('/serverIndex')”
“}”
“別的”
“{”
" alert('Error Password or Username')/*顯示錯誤信息*/"
“}”
“}”
"";
/*
* 服務器索引頁
*/
const char* serverIndex =
""
“<腳本>”
"$('form').submit(function(e){"
“e.preventDefault();”
“var 形式 = $('#upload_form')[0];”
“var data = new FormData(form);”
" $.ajax({"
“網址:'/更新',”
“類型:'POST',”
“數據:數據”
“內容類型:假,”
“過程數據:假”,
“xhr:函數(){”
“var xhr = 新窗口.XMLHttpRequest();”
"xhr.upload.addEventListener('progress', function(evt) {"
“如果(evt.lengthComputable){”
“var per = evt.loaded / evt.total;”
"$('#prg').html('進度:' + Math.round(per*100) + '%');"
“}”
“}, 錯誤的);”
“返回 xhr;”
"},"
“成功:函數(d,s){”
“console.log('成功!')”
"},"
“錯誤:函數(a,b,c){”
“}”
"});"
"});"
"";
/*
* 設置功能
*/
無效設置(無效){
pinMode(LED,輸出);
序列號.開始(115200);
// 連接到 WiFi 網絡
WiFi.begin(ssid, 密碼);
序列號.println("");
// 等待連接
而(WiFi.status()!= WL_CONNECTED){
延遲(500);
序列號.print(".");
}
序列號.println("");
Serial.print("連接到");
序列號.println(ssid);
Serial.print("IP地址:");
Serial.println(WiFi.localIP());
/*使用mdns進行主機名解析*/
if (!MDNS.begin(host)) { //http://esp32.local
Serial.println("設置 MDNS 響應者時出錯!");
而(1){
延遲(1000);
}
}
Serial.println("mDNS 響應器啟動");
/*返回存儲在serverIndex中的索引頁*/
server.on("/", HTTP_GET, []() {
server.sendHeader("連接", "關閉");
server.send(200, "text/html", loginIndex);
});
server.on("/serverIndex", HTTP_GET, []() {
server.sendHeader("連接", "關閉");
server.send(200, "text/html", serverIndex);
});
/*處理上傳固件文件*/
server.on("/update", HTTP_POST, []() {
server.sendHeader("連接", "關閉");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& 上傳 = server.upload();
如果(上傳.status == UPLOAD_FILE_START){
Serial.printf("更新:%s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //從最大可用大小開始
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* 刷固件到 ESP*/
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true 設置大小為當前進度
Serial.printf("更新成功:%u\nRebooting...\n", upload.totalSize);
} 別的 {
Update.printError(Serial);
}
}
});
server.begin();
}
無效循環(無效){
server.handleClient();
延遲(1);
數字寫入(領導,高);
延遲(600);
數字寫入(領導,低);
延遲(600);
}
?
評論
查看更多