赞
踩
本文着重于ESP32与网页的交互,并没有针对网页进行UI优化,也不会对HTM5的组件进行详细介绍,只讲解一些关键的JS函数。
代码以Arduino框架进行开发,使用ESPAsyncWebServer库实现WebServer,通过JS代码配合库文件的回调函数进行使用,只讲交互部分,文章内容不关注数据的来源以及控制。
首先需要一些基础框架,对库文件的引用,并设置好端口号和网站的首页
- #include <ESPAsyncWebServer.h> // 包含异步Web服务器库文件
-
- AsyncWebServer server(80); // 创建WebServer对象, 端口号80
- // 使用端口号80可以直接输入IP访问,使用其它端口需要输入IP:端口号访问
- // 一个储存网页的数组
- const char index_html[] PROGMEM = R"rawliteral(
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <h2>ESP32 网页</h2>
- </body>
- <script>
-
- </script>)rawliteral";
- void setup()
- {
- // 你需要再此处添加WiFi操作代码,开启热点或者连接到热点
- // 添加HTTP主页,当访问的时候会把网页推送给访问者
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/html", index_html); });
- server.begin(); // 初始化HTTP服务器
- }
-
-
- void loop()
- {
- }
当你添加上WiFi操作代码,把这个程序烧录入ESP32,并通过浏览器访问ESP32的IP地址时,浏览器会显示这个画面:
以显示温度和湿度为例,需要将温湿度打包为HTML代码块
- String Merge_Data(void)
- {
- int Humidity = 50;// 此处应为获取温度代码
- int Temperature = 26;// 此处应为获取湿度代码
- // 将温湿度打包为一个HTML显示代码
- String dataBuffer = "<p>";
- dataBuffer += "<h1>传感器数据 </h1>";
- dataBuffer += "<b>温度: </b>";
- dataBuffer += String(Temperature);
- dataBuffer += "<br/>";
- dataBuffer += "<b>湿度: </b>";
- dataBuffer += String(Humidity );
- dataBuffer += "<br /></p>";
- // 最后要将数组返回出去
- return dataBuffer;
- }
然后在setup中,server初始化前添加响应代码,把数据返回出去。
- void setup()
- {
- // 你需要再此处添加WiFi操作代码,开启热点或者连接到热点
- // 添加HTTP主页,当访问的时候会把网页推送给访问者
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/html", index_html); });
- // 设置反馈的信息,在HTML请求这个Ip/dht这个链接时,返回打包好的传感器数据
- server.on("/dht", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/plain", Merge_Data().c_str()); });
- server.begin(); // 初始化HTTP服务器
- }
数据打包好了,也返回给HTML了,这个时候我们就需要HTML定时去请求数据,所以我们要在HTML中使用JS代码的定时器,来定时采集数据。
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <h2>ESP32 网页</h2>
- <!-- 创建一个ID位dht的盒子用于显示获取到的数据 -->
- <div id="dht">
- </div>
- </body>
- <script>
- // 设置一个定时任务, 1000ms执行一次
- setInterval(function () {
- var xhttp = new XMLHttpRequest();
- xhttp.onreadystatechange = function () {
- if (this.readyState == 4 && this.status == 200) {
- // 此代码会搜索ID为dht的组件,然后使用返回内容替换组件内容
- document.getElementById("dht").innerHTML = this.responseText;
- }
- };
- // 使用GET的方式请求 /dht
- xhttp.open("GET", "/dht", true);
- xhttp.send();
- }, 1000)
- </script>
当代码请求到结果的时候,就会使用结果替换ID为dht的组件内容(此处为DIV盒子)。所以,我们在打包数据的时候就要提前对数据加上HTML代码进行美化,如果不加以美化,返回的就只会是单纯的一串字符串,可读性极差。烧录代码后,显示效果如下:
温湿度显示效果
以按钮为例,我们需要在HTML中添加一个按钮
<button onclick="set()"> 发送数据 </button>
按钮需要绑定onclick运行JS函数
- // 按下按钮会运行这个JS函数
- function set() {
- var payload = "ESP32"; // 需要发送的内容
- // 通过get请求给 /set
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/set?value=" + payload, true);
- xhr.send();
- }
当我们按下按钮的时候,触发onclick事件,进而运行JS中的函数 set。
运行JS函数后,会将payload已GET的方式提交到/set。
上面的HTML发送过来的数据,通用需要添加对应的响应来获取内容z
- // 下发处理回调函数
- void Config_Callback(AsyncWebServerRequest *request)
- {
- if (request->hasParam("value")) // 如果有值下发
- {
- String HTTP_Payload = request->getParam("value")->value(); // 获取下发的数据
- Serial.printf("[%lu]%s\r\n", millis(), HTTP_Payload.c_str()); // 打印调试信息
- }
- request->send(200, "text/plain", "OK"); // 发送接收成功标志符
- }
-
- void setup()
- {
- // 你需要再此处添加WiFi操作代码,开启热点或者连接到热点
- // 添加HTTP主页,当访问的时候会把网页推送给访问者
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/html", index_html); });
- // 设置反馈的信息,在HTML请求这个Ip/dht这个链接时,返回打包好的传感器数据
- server.on("/dht", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/plain", Merge_Data().c_str()); });
- server.on("/set", HTTP_GET, Config_Callback); // 绑定配置下发的处理函数
- server.begin(); // 初始化HTTP服务器
- }
这样,数据就从HTML到了ESP32,接下来就是对HTTP_Payload 字符串内的数据进行处理即可,在此不再赘述。
-
- #include <ESPAsyncWebServer.h> // 包含异步Web服务器库文件
-
- AsyncWebServer server(80); // 创建WebServer对象, 端口号80
- // 使用端口号80可以直接输入IP访问,使用其它端口需要输入IP:端口号访问
- // 一个储存网页的数组
- const char index_html[] PROGMEM = R"rawliteral(
- <!DOCTYPE HTML>
- <html>
- <head>
- <meta charset="utf-8">
- </head>
- <body>
- <h2>ESP32 网页</h2>
- <!-- 创建一个ID位dht的盒子用于显示获取到的数据 -->
- <div id="dht">
- </div>
- <button onclick="set()"> 发送数据 </button>
- </body>
- <script>
- // 按下按钮会运行这个JS函数
- function set() {
- var payload = "ESP32"; // 需要发送的内容
- // 通过get请求给 /set
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "/set?value=" + payload, true);
- xhr.send();
- }
- // 设置一个定时任务, 1000ms执行一次
- setInterval(function () {
- var xhttp = new XMLHttpRequest();
- xhttp.onreadystatechange = function () {
- if (this.readyState == 4 && this.status == 200) {
- // 此代码会搜索ID为dht的组件,然后使用返回内容替换组件内容
- document.getElementById("dht").innerHTML = this.responseText;
- }
- };
- // 使用GET的方式请求 /dht
- xhttp.open("GET", "/dht", true);
- xhttp.send();
- }, 1000)
- </script>)rawliteral";
- String Merge_Data(void)
- {
- int Humidity = 50;// 此处应为获取温度代码
- int Temperature = 26;// 此处应为获取湿度代码
- // 将温湿度打包为一个HTML显示代码
- String dataBuffer = "<p>";
- dataBuffer += "<h1>传感器数据 </h1>";
- dataBuffer += "<b>温度: </b>";
- dataBuffer += String(Temperature);
- dataBuffer += "<br/>";
- dataBuffer += "<b>湿度: </b>";
- dataBuffer += String(Humidity );
- dataBuffer += "<br /></p>";
- // 最后要将数组返回出去
- return dataBuffer;
- }
-
- // 下发处理回调函数
- void Config_Callback(AsyncWebServerRequest *request)
- {
- if (request->hasParam("value")) // 如果有值下发
- {
- String HTTP_Payload = request->getParam("value")->value(); // 获取下发的数据
- Serial.printf("[%lu]%s\r\n", millis(), HTTP_Payload.c_str()); // 打印调试信息
- }
- request->send(200, "text/plain", "OK"); // 发送接收成功标志符
- }
-
- void setup()
- {
- // 你需要再此处添加WiFi操作代码,开启热点或者连接到热点
- // 添加HTTP主页,当访问的时候会把网页推送给访问者
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/html", index_html); });
- // 设置反馈的信息,在HTML请求这个Ip/dht这个链接时,返回打包好的传感器数据
- server.on("/dht", HTTP_GET, [](AsyncWebServerRequest *request)
- { request->send_P(200, "text/plain", Merge_Data().c_str()); });
- server.on("/set", HTTP_GET, Config_Callback); // 绑定配置下发的处理函数
- server.begin(); // 初始化HTTP服务器
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。