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);
}
评论
查看更多