ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO
ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO
概述
上节 ESP32-Web-Server 实战编程-通过网页控制设备的 GPIO 讲述了如何通过网页控制一个 GPIO。本节实现在网页上控制多个 GPIO。
示例解析
前端设计
前端代码建立了四个 GPIO,如下死 GPIO 2 在前端的定义,注意不同的 GPIO,其对应的 id 不同。前端的每个 GPIO,在状态发生改变时,将触发 toggleCheckbox() 函数。
<div class="card"> <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 2</p><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="2"><span class="slider"></span></label><p class="state">State: <span id="2s"></span></p>
</div>
此外,前端代码还定义了两个 JS 函数:getStates() 和 toggleCheckbox()
window.addEventListener('load', getStates);
// Function to get and update GPIO states on the webpage when it loads for the first timefunction getStates(){}
// Send Requests to Control GPIOsfunction toggleCheckbox (element) {}
getStates() 将在重新加载网页时查询当前所有 GPIO 的状态,并更新到网页上。
toggleCheckbox() 将在网页端的对应 GPIO 状态改变时触发检测 GPIO 的状态。
注意,两个函数中都使用了XML 组件生成的 URL 来设置具体的 http 请求。如
xhr.open("GET", "/states", true);
上述语句将向 /states URL 实际发出一个 的 GET 类型的请求。
此外,在前端代码中还使用了 JSON 字符串,JSON 是一种常用的结构化文本结构,这里不做详细科普,感兴趣的可以搜索相关资料进行了解。json.parse 的相关参考资料参考 javascript-json-parse。
后端设计
后端代码中主要增加两个 handler,“/states” 和 “/update”,它们分别响应对应的上述两个前端的函数 getStates() 、toggleCheckbox()。
{"/states", HTTP_GET, output_states_get_handler, NULL},
{"/update", HTTP_GET, update_state_get_handler, NULL},
为了实现上报多个 GPIO 的状态,我们在后端代码中使用了 JSON 格式,通过 JSON 字符串获取每个 GPIO 对象详细的信息。
为了与前端解析 JSON 的过程相对应,我们需要在后端将信息封装为 JSON 字符串。这需要在文件中增加 JSON 功能的头文件 include "cJSON.h",然后使用 cJSON 的函数制作 JSON 对象。示例演示了常见的用法,并通过 cJSON_Print() 打印最终生成的 JSON 字符串,读者可以尽情封装,在使用中体会 JSON 字符串的使用方法。
cJSON* root = cJSON_CreateObject();
cJSON *gpio_array = cJSON_CreateArray();
最后前端回复的字符串中包含 GPIO 的详细信息,我们通过字符串解析函数 httpd_find_arg() 解析要控制的是哪一个 GPIO,以及要设置该 GPIO 是否输出高电平。
示例效果
点击不同的按钮可以切换网页的显示效果:

在网页端更新 GPIO 状态时,可以看到后端代码对应的响应,如下是对控制 GPIO2 的后端代码响应 log:
I (76050) example_main: req:/update?output=2&state=1
I (76060) example_main: updates:gpio_num=2
I (76060) example_main: updates:gpio[2]_status=1
讨论
-
每个前端的请求都需要在发送完数据后回复一个 OK,或者 error 编码,这在我们前述的 HTML 基础 章节中讲述了 HTTP 传输协议的原理。
void modbus_dtu_web_response_OK(httpd_req_t *req) {httpd_resp_set_type(req, HTTPD_TYPE_JSON);httpd_resp_set_status(req, HTTPD_200);httpd_resp_sendstr(req, "{\"state\": 0}"); }void modbus_dtu_web_response_error(httpd_req_t *req, const char *status) {httpd_resp_set_type(req, HTTPD_TYPE_JSON);httpd_resp_set_status(req, status);httpd_resp_sendstr(req, "{\"state\": 1}"); } -
为了在网页端每次设置 GPIO后都重新加载整个网页的 GPIO 信息,我们增加了一个重定义 handler:
redirect_index_html(req);通过重新加载整个网页,避免网页端显示的 GPIO 状态与设备实际的 GPIO 状态不同步。这显然不是较好的做法,因为重新加载整个网页涉及的传输开销很大。我们将在后续的项目中优化这一点。
-
试想当多个浏览器同时访问该 web 服务器时将发生什么?
因为当前的 web 服务器不能将更新以主动通知的形式通知所有连接的设备,当多个设备同时访问该 web 服务器时,会出现 A 浏览器更改了对应 GPIO 状态,但是 B 浏览器没有主动更新网页的情况下,是无法知道当前 GPIO 状态已经更改了的。因此当前的设计不支持多设备访问。我们将在后面修正这点设计的不足。
总结
1)本节主要是演示最常见的控件-button,以及可以绑定一个事件来描述按钮按下时发生的行为。
2)通过本节的 ESP32 Web Server Mutil GPIOs 的示例,你可以模仿写出一个网友控制多个外部传感器、LED灯的物联网工程。
资源链接
1)ESP32-Web-Server ESP-IDF系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)
3)下一篇:ESP32-Web-Server 实战编程-使用文件系统建立强大的 web 系统
(码字不易感谢点赞或收藏)
相关文章:
ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO
ESP32-Web-Server 实战编程-通过网页控制设备多个 GPIO 概述 上节 ESP32-Web-Server 实战编程-通过网页控制设备的 GPIO 讲述了如何通过网页控制一个 GPIO。本节实现在网页上控制多个 GPIO。 示例解析 前端设计 前端代码建立了四个 GPIO,如下死 GPIO 2 在前端的…...
说一说MySQL中的锁机制
说一说MySQL中的锁机制 按粒度大小从大到小分为 全局锁 全局锁 全局锁是对整个数据库的锁,最常用的全局锁就是读写锁 读锁 阻止其他用户更新数据,允许其他用户读数据写锁 阻止其他用户更新和读数据 修改一些大量的数据,并且不希望其他用户…...
C++笔试训练day_1
文章目录 选择题编程题 选择题 编程题 #include <iostream> #include <algorithm> #include <vector>using namespace std;int main() {int n 0;cin >> n;vector<int> v;v.resize(3 * n);int x 0;for(int i 0; i < v.size(); i){cin >&…...
详解Spring对Mybatis等持久化框架的整合
😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783…...
[Electron] 将应用打包成供Ubuntu、Debian平台下安装的deb包
在使用 electron-packager 工具输出 linux 平台的 electron app 后,可以使用 electron-installer-debian 工具把 app 打包成供Ubuntu平台下安装的 debian 包。 electron-installer-debian是一个用于创建 Debian Linux(.deb)安装包的开发工…...
7.24 SpringBoot项目实战【审核评论】
文章目录 前言一、编写控制器二、编写服务层三、Postman测试前言 我们在 上文 7.23 已经实现了 评论 功能,本文我们继续SpringBoot项目实战 审核评论 功能。逻辑如下: 一是判断管理员权限,关于角色权限校验 在 7.5 和 7.6 分别基于 拦截器Interceptor 和 切面AOP 都实现过…...
Java实现动态加载的逻辑
日常工作中我们经常遇到这样的场景,某某些逻辑特别不稳定,随时根据线上实际情况做调整,比如商品里的评分逻辑,比如规则引擎里的规则。 常见的可选方案有: JDK自带的ScriptEngine 使用groovy,如GroovyClassLoader、Gro…...
数据库的设计规范
文章目录 第一范式(1NF):列不可再分 第二范式 (2NF):所有非主键字段,都必须 完全依赖主键,不能部分依赖 第三范式(3NF):所有非主键字段不能依赖于…...
正则表达式从放弃到入门(2):grep命令详解
正则表达式从放弃到入门(2):grep命令详解 总结 本博文转载自 这是一篇”正则表达式”扫盲贴,如果你还不理解什么是正则表达式,看这篇文章就对了。 如果你是一个新手,请从头阅读这篇文章,如果你…...
用Java写一个王者荣耀游戏
目录 sxt包 Background Bullet Champion ChampionDaji GameFrame GameObject Minion MinionBlue MinionRed Turret TurretBlue TurretRed beast包 Bear Beast Bird BlueBuff RedBuff Wolf Xiyi 打开Eclipse创建图片中的几个包 sxt包 Background package sxt;…...
基于SSM的新闻网站浏览管理实现与设计
基于ssm的新闻网站浏览管理实现与设计 摘要:在大数据时代下,科技与技术日渐发达的时代,人们不再局限于只获取自己身边的信息,而是对全球信息获取量也日渐提高,网络正是打开这新世纪大门的钥匙。在传统方式下ÿ…...
【蓝桥杯软件赛 零基础备赛20周】第6周——栈
文章目录 1. 基本数据结构概述1.1 数据结构和算法的关系1.2 线性数据结构概述1.3 二叉树简介 2. 栈2.1 手写栈2.2 CSTL栈2.3 Java 栈2.4 Python栈 3 习题 1. 基本数据结构概述 很多计算机教材提到:程序 数据结构 算法。 “以数据结构为弓,以算法为箭”…...
CWE/SANS TOP 25 2022
我整理了CWE/SANS TOP25 2022年的这25类缺陷,分类适合的开发语言,其实主要是C/C语言的缺陷相对于Java、PHP、Python、C#等更高级的语言的不同,所以分为适合C/C语言和其它语言。但是大家不要纠结,例如SQL难道C/C语言程序没有吗&…...
Qt 天气预报项目
参考引用 QT开发专题-天气预报 1. JSON 数据格式 1.1 什么是 JSON JSON (JavaScript Object Notation),中文名 JS 对象表示法,因为它和 JS 中对象的写法很类似 通常说的 JSON,其实就是 JSON 字符串,本质上是一种特殊格式的字符串…...
新知识-Tuple元组的使用
文章目录 前言一、tuple元组是什么?二、解决方法总结 前言 这次碰到一个需求,大致需要把表A中的字段1和字段2作为共同的表去查表B,并且一次性需要查多条,一开始是想的是根据字段1和字段2去查然后循环多次,但是这样反复…...
“此应用专为旧版android打造,因此可能无法运行”,问题解决方案
当用户在Android P系统上打开某些应用程序时,可能会弹出一个对话框,提示内容为:“此应用专为旧版Android打造,可能无法正常运行。请尝试检查更新或与开发者联系”。 随着Android平台的发展,每个新版本通常都会引入新的…...
【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】
【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】(3题) 数组的改变、移动453. 最小操作次数使数组元素相等 Medium665. 非递减数列 Medium283. 移动零 Easy 大家好,这里是新开的LeetCode刷题系列&…...
Lag-Llama:基于 LlaMa 的单变量时序预测基础模型
文章构建了一个通用单变量概率时间预测模型 Lag-Llama,在来自Monash Time Series库中的大量时序数据上进行了训练,并表现出良好的零样本预测能力。在介绍Lag-Llama之前,这里简单说明什么是概率时间预测模型。概率预测问题是指基于历史窗口内的…...
vue3 :deep() 深度选择器不生效
vue3 :deep() 深度选择器不生效 问题出在根节点上,如果没有这个根节点,那么:deep()不起作用,我把根节点加上,:deep()样式就生效了。在组件外加个 就生效了 参考: 添加链接描述...
从零构建属于自己的GPT系列1:数据预处理(文本数据预处理、文本数据tokenizer、逐行代码解读)
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:文本数据预处理 从零构建属于自己的GPT系列2:语…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
