通过浏览器连接 ESP32 板





5.00/5 (6投票s)
基于板的自动化和环境控制
引言
本文探讨了如何与 Arduino 或 ESP32 等单片机开发板交互,以控制实际过程的功能。
这些设备可以通过多种方式与外部世界交互:通过串口、LCD、蓝牙和 Wi-Fi 等通信协议。
串口需要连接到 PC 或手机的电缆;LCD 是一种输出设备,因此需要一些输入设备;蓝牙和 Wi-Fi 是双向的,并且不需要电缆。
要通过蓝牙访问开发板,我们需要在检查设备上安装一个程序;通过将 Wi-Fi 用作 WEB 服务器,我们可以通过浏览器访问开发板,该浏览器是从开发板下载的 HTML 页面,其中包含 JavaScript 指令,充当控制程序。
在本文中,我展示了一个基于运行在 ESP32 开发板上的 WiFi WEB 服务器的解决方案,该开发板使用 Arduino IDE 1.8.12 开发。 我尝试创建一个并非微不足道的应用程序,以突出连接的显著特征:该应用程序可以显示由三线传感器 DHT22 读取的温度和湿度,并且可以修改内部时钟。
从 WiFi 开始
可以编程 WiFi 在现有的 WiFi 网络中运行,或者像这里所关注的那样,作为接入点运行。 在所有情况下,我们都需要两个库: *WiFi.h* 库用于设置 WiFi 部分,*WebServer.h* 库用于构建网页。
在这里,我简要地讨论了实现服务器所需的指令,互联网上有很多页面非常详细地说明了它们,相反,我将专注于那些允许创建有效应用程序而又不过分关注美学的功能。 无论如何,您可以参考所附的源代码,我希望它是自我解释的。
...
#include <WiFi.h>
#include <WebServer.h>
...
// SSID & Password ******************************************************
const char* ssid = "Sermig_Condor";
const char* password = "";
// IP Address ***********************************************************
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WebServer server(80); // Object of WebServer(HTTP port, 80 is default)
...
有趣的部分从 `setup` 函数开始
void setup() {
...
// Create SoftAP
WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
...
server.on("/", handle_root);
server.onNotFound([](){server.send(404, "text/plain", "The content was not found.");
});
server.begin();
...
}
`WebServer` 模拟了一个事件驱动的应用程序,即 `server.on("/", handle_root)` 将一个函数附加到一个请求,在上面的例子中,获取根页面 `"/"` 的请求将由函数 `handle_root` 满足。 我们可以将函数附加到服务器最终必须提供的每个“页面”,还可以将函数附加到未知的请求:`server.onNotFound([](){server.send(...);});`。
与 WiFi 交互
在循环函数中,有 `listen` 指令和一个延迟,用于模拟开发板的功能,例如,对控件、传感器等的定时循环。
串行通信用于模拟中断来激活 WiFi,它需要不断地监听(注意小的 `delay(10)`)
void loop() {
while (Serial.available() > 0) {
char cmd = Serial.read();
if (cmd == 115) listen = !listen; // s start/stop listening
Serial.println(listen?"WEB on":"WEB off");
}
if(listen) server.handleClient();
else delay(1980);
delay(10);
}
管理请求的函数(在右侧)不是特别有趣。 URL 中存在的参数数量(通过方法 `args()` 获得)区分请求,即,如果数量为 `0`,则发送包含 JavaScript 的根页面(参见下面的 HTML 页面和以更易读形式编写的 JavaScript 代码),否则,它(可能)是一个 Ajax 请求,并通过方法 `arg("c")`,该函数检索并执行所需的命令。 | void handle_root() {
if (server.args() == 0) {
server.send(200, "text/html", H+T); // Handle root url (/)
} else {
char command = server.arg("c").charAt(0);
char answer[50];
switch (command) {
case 104: // h set time
setTime(server.arg("n").toInt());
sprintf(answer,"%s","New time");
break;
case 116: // t temperature and humidity
getTemperature();
strcpy (answer,workBuffer);
break;
}
sprintf(workBuffer, "%s %s", getTime(),answer);
Serial.println(workBuffer);
server.send(200, "text/html",workBuffer);
}
}
|
<!DOCTYPE html>
<html>
<meta name='viewport' content='width=device-width, initial-scale=1' />
<body>
<h1>Condor Web Server with ESP32 - AP Mode</h1>
<input type=button value='Set time' onClick='ajx("c=h&n="+$("n").value)'/>
<input type=number id=n value='36000'/>
<p><input type=button value='Get temp.' onClick='ajx("c=t")'/>
<pre id='f'></pre>";
</body>
</html>
<script type='text/javascript'>
$=i=>document.getElementById(i);
ajx=u=>{
var x = new XMLHttpRequest();
x.onreadystatechange = () => {
if (x.readyState == 4) {
if (x.status == 200) $('f').innerHTML += '\\n'+x.responseText;
else $('f').innerHTML = 'Err: ' + x.status;
}
};
x.open('GET', '?'+u, true);
x.send(null)
}
</script>
`meta` 标签告诉浏览器适应客户端大小,因此在手机上,该页面是可以接受的。 该页面包含两个按钮,带有相关的 `onClick` 事件,一个文本输入数字和一个 `pre` 格式化的标签,用于接收答案。
Ajax 函数在接收到数据时,直接将其添加到 `pre` 格式化的标签中。
访问开发板
检查设备必须连接 WiFi 开发板(通过 `网络和互联网` 部分中的 App `设置`),并在浏览器中插入 IP,在此示例中为 `192.168.1.1`;它应该出现一个页面,用户可以在其中请求温度和湿度或设置时钟输入自午夜以来的秒数。
最后的 remarks
我是自动化领域的新手,因此欢迎任何问题、批评或建议。
历史
- 2020年6月17日:初始版本