建设网站的市场分析,无锡找做网站,手机触屏网站,建筑人才网报名平台文章目录 1.什么是 OTA2. ESP32cam HTTP_OTA 本地准备2.1 HTTP OTA 升级原理2.2 开发板本地基准程序#xff08;程序版本#xff1a;1_0_0#xff09;2.3 开发板升级程序#xff08;程序版本#xff1a;1_0_1#xff09;2.4 本地 HTTP_OTA 升级测试2.4.1 本地运行一个 HT… 文章目录 1.什么是 OTA2. ESP32cam HTTP_OTA 本地准备2.1 HTTP OTA 升级原理2.2 开发板本地基准程序程序版本1_0_02.3 开发板升级程序程序版本1_0_12.4 本地 HTTP_OTA 升级测试2.4.1 本地运行一个 HTTP 服务2.4.2 替换远程链接并将要升级的程序打包成 .bin 文件2.4.3 替换远程链接并烧录基准程序版本为1_0_0 的程序测试升级是否成功 3. HTTP_OTA 升级展望3.1 后期版本更新可通过 HTTP_OTA 实现3.2 借助网络云平台实现远程 HTTP_OTA 升级 本教程是 ESP32cam 的系列教程之三使用 Arduino IDE 对 ESP32cam 开发板进行开发。 本教程代码同样使用与其他 ESP32 开发板。 1.什么是 OTA
OTA 即空中下载技术Over-the-Air Technology其可以安全方便地升级设备的固件或软件。远程升级还可以大大降低成本节省资源它已成为物联网设备和产品制造商的关键技术之一。
ESP32 开发板支持 3 种 OTA 方式
Arduino IDE 主要用于软件开发阶段实现不接线固件烧录Web_OTA通过 Web 浏览器手动提供应用程序更新模块HTTP_OTA固件存放到 http 服务器端设备自动判断是否需要联网下载固件升级
本文主要介绍HTTP_OTA 的原理与实现。
2. ESP32cam HTTP_OTA 本地准备
2.1 HTTP OTA 升级原理
本地程序在开机连接 WIFI 后发送 http 请求获取远程服务器中的升级 json 文件。通过对比 json 中的远程版本信息与本地的版本信息判断是否一致。若远程版本信息与本地版本不一致则本地需要更新程序。通过 json 中的版本信息在远程服务器中拉取需要更新的程序的 .bin 文件。依据下载下来的 .bin 自动完成版本的升级然后自动重启开发板。重复第一步获取远程 json 文件判断是否需要更新。
2.2 开发板本地基准程序程序版本1_0_0
本地 1_0_0 版本程序主要内容如下
当前版本非常重要升级依据远程升级的 json 链接与远程固件的文件夹链接获取并解析 json 的函数 httpGETRequest依据 json 判断是否需要更新的函数 isOrNotNeedUpdate以及其他基础信息组成
#include WiFi.h#include HTTPClient.h
#include ESP32httpUpdate.h
#include Arduino_JSON.h/**********根据实际修改**********/
const char* wifi_ssid TP-LINK_1760; // WIFI名称区分大小写不要写错
const char* wifi_password 987654321; // WIFI密码// 特别重要升级依据
// 设置当前代码版本 格式 1_0_0
char* version 1_0_0;//远程固件链接只支持http
const char* baseUpdateUrl http://example.cn/esp32/;
const char* updateJson http://example.cn/esp32/esp32_update.json;// esp32_update.json
// {
// version:1_0_1
// }/**********根据实际修改**********/int need_ota_update 0;
int i 0;
String jsonBuffer;// 获取远程 json 升级文件
String httpGETRequest(const char* serverName) {WiFiClient client;HTTPClient http;String payload ;//连接目标网址http.begin(client, serverName);//发送HTTP站点请求int httpCode http.GET();if (httpCode 0) {Serial.printf([HTTP] GET... code: %d\n, httpCode);payload http.getString();} else {Serial.printf([HTTP] GET... failed, error: %s\n, http.errorToString(httpCode).c_str());}http.end(); //关闭连接//返回获得的数据用于Json处理return payload;
}// 依据json文件中版本号与本地版本号判断是否需要进行更新
void isOrNotNeedUpdate(){// 获取远程的升级 json 判断内部版本与本地是否相同判断是否需要升级jsonBuffer httpGETRequest(updateJson);Serial.println(jsonBuffer);//将解析的Json对象值储存在Jsonu缓冲区中JSONVar myObject JSON.parse(jsonBuffer);Serial.println(myObject);// Serial.println(myObject[version]);const char* ota_version myObject[version];// Serial.println(ota_version);Serial.println(---);Serial.print(远程版本 );Serial.println(ota_version);Serial.print(本地版本 );Serial.println(version);// char * 与 const char * 比较// 判断远程版本与本地版本是否相同if (String(version) String(ota_version)) {need_ota_update 0;Serial.println(无需升级。。。);} else {need_ota_update 1;Serial.println(需要升级。。。);Serial.print(OTA 升级地址为);// 升级的完整链接 例如http://example.cn/esp32/esp32_1_0_1.binString fullUpdateUrl String(baseUpdateUrl) esp32_ ota_version .bin;Serial.println(String(fullUpdateUrl));// 获取远程 bin 文件进行升级t_httpUpdate_return ret ESPhttpUpdate.update(fullUpdateUrl);Serial.println(ret);switch (ret) {case HTTP_UPDATE_FAILED:Serial.printf(HTTP_UPDATE_FAILED Error (%d): %s\n, ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());break;case HTTP_UPDATE_NO_UPDATES:Serial.println(HTTP_UPDATE_NO_UPDATES);break;case HTTP_UPDATE_OK:Serial.println(HTTP_UPDATE_OK);break;default:Serial.println(ret);}// version(char *)ota_version;}need_ota_update 0;
}void setup() {Serial.begin(115200); //波特率115200Serial.print(Connection WIFI);WiFi.begin(wifi_ssid, wifi_password); //连接wifiwhile (WiFi.status() ! WL_CONNECTED) { //等待连接wifidelay(500);Serial.print(.);}Serial.println();// 调用判断是否需要升级函数isOrNotNeedUpdate();
}void loop() {
// 主程序Serial.println(i);i;delay(2000);
}
2.3 开发板升级程序程序版本1_0_1
本测试升级程序如下仅仅在程序版本与主程序中做了调整以便更清楚的看出是否OTA升级成功。
#include WiFi.h#include HTTPClient.h
#include ESP32httpUpdate.h
#include Arduino_JSON.h/**********根据实际修改**********/
const char* wifi_ssid TP-LINK_1760; // WIFI名称区分大小写不要写错
const char* wifi_password 987654321; // WIFI密码// 特别重要升级依据
// 设置当前代码版本 格式 1_0_0
char* version 1_0_1;//远程固件链接只支持http
const char* baseUpdateUrl http://example.cn/esp32/;
const char* updateJson http://example.cn/esp32/esp32_update.json;// esp32_update.json
// {
// version:1_0_1
// }/**********根据实际修改**********/int need_ota_update 0;
int i 0;
String jsonBuffer;// 获取远程 json 升级文件
String httpGETRequest(const char* serverName) {WiFiClient client;HTTPClient http;String payload ;//连接目标网址http.begin(client, serverName);//发送HTTP站点请求int httpCode http.GET();if (httpCode 0) {Serial.printf([HTTP] GET... code: %d\n, httpCode);payload http.getString();} else {Serial.printf([HTTP] GET... failed, error: %s\n, http.errorToString(httpCode).c_str());}http.end(); //关闭连接//返回获得的数据用于Json处理return payload;
}// 依据json文件中版本号与本地版本号判断是否需要进行更新
void isOrNotNeedUpdate(){// 获取远程的升级 json 判断内部版本与本地是否相同判断是否需要升级jsonBuffer httpGETRequest(updateJson);Serial.println(jsonBuffer);//将解析的Json对象值储存在Jsonu缓冲区中JSONVar myObject JSON.parse(jsonBuffer);Serial.println(myObject);// Serial.println(myObject[version]);const char* ota_version myObject[version];// Serial.println(ota_version);Serial.println(---);Serial.print(远程版本 );Serial.println(ota_version);Serial.print(本地版本 );Serial.println(version);// char * 与 const char * 比较// 判断远程版本与本地版本是否相同if (String(version) String(ota_version)) {need_ota_update 0;Serial.println(无需升级。。。);} else {need_ota_update 1;Serial.println(需要升级。。。);Serial.print(OTA 升级地址为);// 升级的完整链接 例如http://example.cn/esp32/esp32_1_0_1.binString fullUpdateUrl String(baseUpdateUrl) esp32_ ota_version .bin;Serial.println(String(fullUpdateUrl));// 获取远程 bin 文件进行升级t_httpUpdate_return ret ESPhttpUpdate.update(fullUpdateUrl);Serial.println(ret);switch (ret) {case HTTP_UPDATE_FAILED:Serial.printf(HTTP_UPDATE_FAILED Error (%d): %s\n, ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());break;case HTTP_UPDATE_NO_UPDATES:Serial.println(HTTP_UPDATE_NO_UPDATES);break;case HTTP_UPDATE_OK:Serial.println(HTTP_UPDATE_OK);break;default:Serial.println(ret);}// version(char *)ota_version;}need_ota_update 0;
}void setup() {Serial.begin(115200); //波特率115200Serial.print(Connection WIFI);WiFi.begin(wifi_ssid, wifi_password); //连接wifiwhile (WiFi.status() ! WL_CONNECTED) { //等待连接wifidelay(500);Serial.print(.);}Serial.println();// 调用判断是否需要升级函数isOrNotNeedUpdate();
}void loop() {
// 主程序Serial.println(i);Serial.println(OTA 升级成功);i;delay(2000);
}2.4 本地 HTTP_OTA 升级测试
2.4.1 本地运行一个 HTTP 服务
这里使用 vscode 进行
用 vscode 打开一个空白文件夹在文件夹中新建目录 esp32文件 index.html 目录下新建文件 esp32_update.jsonesp32_update.json 中内容是 {version:1_0_1} ,表明当前远程的版本为 1_0_1index.html 中为标准html结构文件在 index.html 界面中右键Open with Live Server 打开 替换 127.0.0.1 为本地 192.168.1.XXX 并拼接 /esp32/esp32_update.json ,如下图所示 2.4.2 替换远程链接并将要升级的程序打包成 .bin 文件 将 arduino IDE 中的程序的远程链接替换成本地 HTTP 服务器链接 工具中 开发板和 Partition Scheme 选择如下图 项目中选择导出已编译的二进制文件导出的二进制文件在同级目录下。 将导出的 .bin 文件重命名为 esp32_1_0_x.bin 样式并复制到 2.4.1 节中的 esp32目录中保证使用 http://192.168.1.x/esp32/esp32_1_0_x.bin 能够下载到该文件。
2.4.3 替换远程链接并烧录基准程序版本为1_0_0 的程序测试升级是否成功
将 arduino IDE 中的程序的远程链接替换成本地 HTTP 服务器链接 将 2.4.1 节中的 esp32_update.json 内部版本改为 1_0_0 保证一开始不升级。将程序烧录进 esp32 开发板中。然后打开串口监视器串口调试器中显示不需要升级 将 2.4.1 节中的 esp32_update.json 内部版本改为 1_0_1 然后重启开发板。 由上图可知开发板自动判断是否需要升级并自动OTA升级成功。
3. HTTP_OTA 升级展望
3.1 后期版本更新可通过 HTTP_OTA 实现
通过第二节可知可以通过 HTTP_OTA 实现 esp32 开发板的隔空升级这样可以在一台设备上测试好了程序后上传 .bin 文件到第 2.4.1 节中的 HTTP 服务器文件夹中实现其他开发板批量升级。
3.2 借助网络云平台实现远程 HTTP_OTA 升级
第 2.4 节是使用本地 HTTP 服务器进行升级的我们也可以使用云服务厂商的对象云存储服务将需要升级的 .bin 文件与 esp32_update.json 放到云服务厂商的对象云存储服务中使用提供的公网域名替换程序代码中的远程固件连接真正实现远程 OTA 快速自动升级服务。 注意 本地 HTTP_OTA 升级时本机电脑需要和 esp32 开发板连在同一个网络下否则 esp32 开发板无法访问固件地址。使用云服务厂商的对象云存储服务对象云存储需要设置禁止缓存否则可能会获取之前缓存的版本而不是最新版导致不必要的错误。 本文首发于本人博客https://blog.gitnote.cn/post/esp32cam_http_ota/ 版权信息: CC BY-NC-SA 4.0 (自由转载-非商用-相同方式共享-保持署名)