优良网站,专业网站建设设计公司,陕西采购与招标网官方,北京软件开发外包公司ESP32-Web-Server编程综合项目1-结合 Web Server 实现 WiFi 配网和网页 OTA 更新
概述
前述的内容多是一个个小功能的演示#xff0c;本章节讲述一些实际项目中使用到的综合项目。
首先要讲述的案例是通过ESP32 上的 Web Server 实现对 ESP32 的 WiFi 配网和网页 OTA 更新功…ESP32-Web-Server编程综合项目1-结合 Web Server 实现 WiFi 配网和网页 OTA 更新
概述
前述的内容多是一个个小功能的演示本章节讲述一些实际项目中使用到的综合项目。
首先要讲述的案例是通过ESP32 上的 Web Server 实现对 ESP32 的 WiFi 配网和网页 OTA 更新功能。
需求及功能解析
项目的主要功能有
通过菜单控制多网页的切换在多网页中分别实现 WiFi 配网、控制设备重启、通过网页下发 OTA 更新需要的新固件的功能。
WiFi 配网
当用户初次使用设备时设备完全不知道要连接的路由器信息此时可以通过建立一个 SoftAP 什么是 SoftAP 参考AP、STA的概念以及APSTA的实现,让用户向连接路由器一样连接该默认的 AP然后打开配网网页让 ESP32 连接指定的路由器最终使得 ESP32 设备能够正常上网。
设备重启
设备配网信息下发后可以通过网页或者设备的按钮重启设备重新上电也行设备将在重启后检测到已经下发的配网信息网络名称和密码然后使用该配网信息进行联网。
此外当设备 OTA 结束时也需要设备重启以加载新的固件。
OTA 更新
OTA 是更新设备固件的技术可以认为是通过网络的方式传输固件进行软件更新的一种方法。
在路由器设计中经常看到路由器的本地网页上支持通过网页上的输入框选中一个新的固件下发给路由器对路由器的固件进行更新。 示例解析
目录结构
├── CMakeLists.txt
├── main
│ ├── CMakeLists.txt
│ └── main.c User application
├── components
│ └── fs_image└── index.html└── ...
| └── url_handlers└── url_handlers.c└── ...
└── README.md This is the file you are currently reading目录结构主要包含主目录 main以及组件目录 components.其中组件目录components中包含了用于存储网页文件的 fs_image 目录即前端文件。
前端代码
多网页菜单设计
在 components/fs_image/web_image/index.html 中设计三个子菜单wifimanager、ota、Home
div classtopnav-righta hrefwifimanagerWiFi Manager/aa hrefotaOTA/aa href/Home/a
/div当点击对应的 href 时浏览器会向 ESP32 Web Server 发送对该 href 的 Get 请求。
SoftAP 配网界面
在 components/fs_image/web_image/wifimanager_softap.html 中设计 SoftAP 配网的界面
form action/wifi_config methodPOSTplabel forssidSSID/labelinput typetext id ssid namessidbrlabel forpassPassword/labelinput typetext id pass namepassbrlabel foripIP Address/labelinput typetext id ip nameip value192.168.1.xxxinput type submit value Submit/p
/form上述配网界面非常简单提供了输入路由器 WiFi 名称和密码的输入框。
当用户输入 WiFi 名称和密码后将通过 http 的 POST 方法向 /wifi_config 推送配网信息。
WiFi Manager 界面
在配网成功设备连接路由器后我们可以像往常一样。让手机或者电脑连接到同一个路由器然后通过局域网打开 ESP32 设备上的控制网页。
在 components/fs_image/web_image/wifimanager.html 界面我们可以重新下发设备要连接的路由器的信息
form action/wifi_config methodPOSTplabel forssidSSID/labelinput typetext id ssid namessidbrlabel forpassPassword/labelinput typetext id pass namepassbr!-- label foripIP Address/labelinput typetext id ip nameip value192.168.1.200 --input type submit value Submit/p
/formOTA 更新界面
可以通过子菜单跳转到 OTA 更新的网页。
在 components/fs_image/web_image/ota.html 中建立了一个 input file 的输入框。并设置了一个 submit 按钮
h2ESP32 Firmware Update Page/h2h4 idlatest_firmware/h4input typefile idselectedFile accept.bin styledisplay: none; onchangemyFunction() /
input typebutton valueBrowse... onclickdocument.getElementById(selectedFile).click(); /
h3 idfile_info/h3
input typesubmit idupload_button valueUpdate Firmware onclickupdateFirmware()br
p
button onclickrebootButton()Reboot/button
/p选中文件后通过ota.html 中的 updateFirmware() 实现向 /update 以 POST 方法推送新固件数据
function updateFirmware() {// Form Datavar formData new FormData();var fileSelect document.getElementById(selectedFile);if (fileSelect.files fileSelect.files.length 1) {var file fileSelect.files[0];formData.set(file, file, file.name);document.getElementById(status).innerHTML Uploading file.name , Please Wait...;// Http Requestvar request new XMLHttpRequest();request.upload.addEventListener(progress, updateProgress);request.open(POST, /update);request.responseType blob;request.send(formData);} else {window.alert(Select A File First)}
}此外为了反映 OTA 更新过程的进度在 ota.html 中的 script 中添加了更新进度的函数
// progress on transfers from the server to the client (downloads)
function updateProgress(oEvent) {if (oEvent.lengthComputable) {getstatus();} else {window.alert(total size is unknown)}
}后端代码
后端代码除建立前述基于 spiffs 的 Web Server 外重点是设计对应前端文件的各个 URL 的 handlers.
这里的 URL 分为两组一组是还未进行 WiFi 配网比如设备刚出厂用户首次使用时时手机通过连接 ESP32 的 SoftAP 时打开的网页 httpd_uri_array_softap_only[]、一组是配网后ESP32 设备连接到路由器后用户通过手机或者电脑连接至同一个路由器时通过局域网打开的网页httpd_uri_array[]
httpd_uri_t httpd_uri_array_softap_only[] {{/wifi_config, HTTP_POST, wifi_config_post_handler, rest_context},{/*, HTTP_GET, softap_wifi_html_get_handler,rest_context}};httpd_uri_t httpd_uri_array[] {{/wifimanager, HTTP_GET, wifi_manage_html_get_handler, rest_context},{/ota, HTTP_GET, ota_html_get_handler, rest_context},{/wifi_config, HTTP_POST, wifi_config_post_handler, rest_context},{/update, HTTP_POST, OTA_update_post_handler, rest_context},{/status, HTTP_POST, OTA_update_status_handler, rest_context},{/reboot, HTTP_GET, reboot_html_get_handler, rest_context},{/*, HTTP_GET, rest_common_get_handler,rest_context}//Catch-all callback function for the filesystem, this must be set to the array last one
};if (!s_sta_connected) { // 首次配网时uris httpd_uri_array_softap_only;uris_len sizeof(httpd_uri_array_softap_only)/sizeof(httpd_uri_t);
} else { // 已经配过网时uris httpd_uri_array;uris_len sizeof(httpd_uri_array)/sizeof(httpd_uri_t);
}for(int i 0; i uris_len; i){if (httpd_register_uri_handler(server, uris[i]) ! ESP_OK) {ESP_LOGE(TAG, httpd register uri_array[%d] fail, i);}
}配网处理
配网处理在 main/main.c 中的 wifi_config_post_handler() 中接收网页端 POST 的路由器 WiFi 的名称和密码并使用 wifi_config_store() 将其存储在设备上。设备重新上电后将检测到已经存储了WiFi 的名称和密码然后触发向该路由器的 WiFi 连接。
if (recv_post_data(req, buf) ! ESP_OK) {ESP_LOGE(TAG, recv post data error);return ESP_FAIL;
}str_len httpd_find_arg(buf, PARAM_INPUT_1, temp_str, sizeof(temp_str));
if ((str_len ! -1) (strlen((char *)temp_str) ! 0)) {// snprintf((char *)wifi_config.sta.ssid, 32, %s, temp_str);memcpy((char *)wifi_config.sta.ssid, temp_str, 32);ESP_LOGI(TAG, ssid:%s, (char *)wifi_config.sta.ssid);
}memset(temp_str, \0, sizeof(temp_str));str_len httpd_find_arg(buf, PARAM_INPUT_2, temp_str, sizeof(temp_str));
if ((str_len ! -1) (strlen((char *)temp_str) ! 0)) {memcpy((char *)wifi_config.sta.password, temp_str, 64);ESP_LOGI(TAG, pwd:%s, (char *)wifi_config.sta.password);
}
if(!wifi_config_store(wifi_config)) {return ESP_FAIL;
}关于 WiFi Manager
WiFI 管理主要是负责管理 WiFi 的工作模式WiFi 配网信息。
默认情况下设备将建立一个名称为 IoT_Old_Wang、密码为 123456789 、IP 地址默认为 192.168.4.1的 SoftAP用户可以通过手机或者电脑搜索该热点然后连接到该默认 AP并使用浏览器打开 192.168.4.1 网址查看配网界面。
如果需要更改默认 SoftAP 的信息可以在编译程序时通过 idf.py menuconfig 打开配置菜单配置下述信息 OTA 的后端处理
OTA 更新的后端处理在 main/web_ota.c 中在 OTA_update_post_handler() 内主要是接收从网页下发的固件数据
if (esp_ota_end(ota_handle) ESP_OK)
{// Lets update the partitionif(esp_ota_set_boot_partition(update_partition) ESP_OK) {const esp_partition_t *boot_partition esp_ota_get_boot_partition();// Webpage will request status when complete // This is to let it know it was successfulflash_status 1;ESP_LOGI(OTA, Next boot partition subtype %d at offset 0x%x, boot_partition-subtype, boot_partition-address);ESP_LOGI(OTA, Please Restart System...);}else{ESP_LOGI(OTA, \r\n\r\n !!! Flashed Error !!!);}
}接收完固件将设置标志位 flash_status1当网页端重新请求固件的 status 时将在 OTA_update_status_handler()中触发创建一个定时重启设备的定时器
if (flash_status 1)
{// We cannot directly call reboot here because we need the // browser to get the ack back. Send message to another task or create a create_a_restart_timer();// xEventGroupSetBits(reboot_event_group, REBOOT_BIT);
}示例效果
连接 SoftAP 执行配网
下图分别为连接对应热点浏览器输入 192.168.4.1 打开配网界面: 注意 AP 模式下打不开网页就关闭手机的其他网络通路比如 4G 网络。 AP 配网这里配网成功可以通过 GPIO 控制 LED灯闪烁来提示用户或者在网页端跳出弹窗提示配置成功示例这里以 Log 提示用户。
重启设备后连接电脑到同一个路由器打开多网页菜单
设备连接到路由器后登录路由器查看 ESP32 设备的 IP 地址如下该设备的 IP 地址为 192.168.47.100: 打开 wifi manager 界面
点击菜单栏的 WiFi Manager 打开wifi manager 界面 打开 OTA 界面
点击菜单栏的 OTA 打开 OTA 界面 OTA 完成后重启设备
点击 OTA 更新界面的 Browse 按钮选择需要上传的 OTA 新固件然后点击 Updata Firmware开始 OTA 更新。OTA 更新后可以重启设备以便于在下次重启设备时加载新的固件。 流程示意图 讨论
1示例程序中有 version.txt 文件该文件可以用于控制固件的版本信息。读者可以更改该文件的内容记录固件的版本信息。
2示例使用的 ota APIs 可以参考 ESP-IDF OTA 开发指南。
总结
1本节主要是介绍基于 ESP-IDF 的原始 API实现综合项目1- 通过Web Server 实现 WiFi 配网和网页 OTA 更新。
2示例设计了多网页子菜单实现管理 WiFi 配网、OTA 固件更新、设备重启的功能。更多综合项目敬请期待。
资源链接
1ESP32-Web-Server ESP-IDF系列博客介绍 2对应示例的 code 链接 点击直达代码仓库
3下一篇
(码字不易感谢点赞或收藏)