ESP32作为服务器,使用网页控制LED小灯
项目描述
ESP32-S开发板加入局域网,使用platformIO编写好ESP32的代码后,编译下载到ESP32中,访问ESP32的IP地址,使用网页控制连接着的LED小灯
项目准备:
ESP32-S开发板 一根数据线 电脑 LED小灯
原理剖析
这个ESP32作为服务器,浏览器作为客户端,这是一个简单的B/S架构。
- 在这个项目中我们说为什么要电脑和ESP32加入同一个局域网?
从前面的有关于Linux网络管理中我们知道了,两台服务器要想实现简单通信,是要在同一网段之下才能进行的(比如说:192.168.3.87和192.168.3.51)。那么在验证通信的时候,我们说要先把自己ping通,再去ping通另一台服务器,这样两台主机就可以通信了。
- 假设电脑和ESP32之间可以正常通信,那么这样的基于B/S的架构是怎么工作的呢?
第一步:个人计算机要想从浏览器上获取一个网页,首先在浏览器中输入要访问的域名(比如:www.baidu.com),输入的域名会经过三大运营商转换成IP地址,根据转换后的IP地址访问到百度的页面(域名转换成IP地址的过程是由DNS域名解析服务负责的)。 可以打开终端,使用ping命令ping一下: 这里可以看到百度给我返回的IP地址是:220.181.38.149。同样我们在浏览器中输入这个IP地址也可以搜索到百度页面 由于企业的服务器很多,分布在各个地区,企业使用CDN加速器,根据每一个客户端的IP地址就近的分配一台服务器(这样的就近原则跟京东快递是一样的) 第二步:服务器接收到来自客户端的请求,要进行处理,向客户端返回一个页面等信息,这个过程也被称为响应。 这样浏览器就接收到服务器的网站页面了。
环境搭建
打开vscode,安装好PlatformIO 点击小蚂蚁的图标,在Home中点击New Project创建一个新项目。 这里使用的是基于Arduino的开发框架,点击Finish。 会得到一个类似于这样的一个目录结构。
代码实现
在创建好的目录结构中新建一个data文件夹,如图所示 data文件夹中创建一个www的文件夹,这个www文件夹存放一些有关于网页的代码。 将已经编写好的html等相关文件放入到www文件夹中。 链接:data压缩包 提取码:1234 目录结构如图所示: 在src文件夹中存放ESP32的主程序,也就是main.cpp,就是在这里写ESP32的代码。 代码如下:
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#define BITS 10
#define PWM_PIN 15
#define LED_BUILTIN 5
String pwm_val;
const char *ssid = "ChinaNet-fnAr";
const char *password = "zhang411707";
AsyncWebServer server(80);
void setup()
{
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
pinMode(PWM_PIN, OUTPUT);
analogSetAttenuation(ADC_11db);
analogSetWidth(BITS);
ledcSetup(0, 5000, BITS);
ledcAttachPin(PWM_PIN, 0);
if (!SPIFFS.begin(true))
{
Serial.println("掛載SPIFFS分區出錯啦~");
return;
}
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.print("\nIP位址:");
Serial.println(WiFi.localIP());
server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("index.html");
server.serveStatic("/img", SPIFFS, "/www/img/");
server.serveStatic("/favicon.ico", SPIFFS, "/www/favicon.ico");
server.on("/sw", HTTP_GET, [](AsyncWebServerRequest *request)
{
if (request->hasParam("led")) {
AsyncWebParameter* p = request->getParam("led");
if (p->value() == "ON") {
digitalWrite(LED_BUILTIN, LOW);
} else if (p->value() == "OFF") {
digitalWrite(LED_BUILTIN, HIGH);
}
}
request->send(200, "text/plain", "OK!");
});
server.on("/pwm", HTTP_GET, [](AsyncWebServerRequest *req)
{
if (req->hasParam("val")) {
AsyncWebParameter* p = req->getParam("val");
pwm_val = p->value();
ledcWrite(0, pwm_val.toInt());
}
req->send(200, "text/plain", "OK");
});
server.begin();
Serial.println("HTTP伺服器開工了~");
}
void loop() {}
编写好代码后就可以运行了。 先点击红箭头指向的对钩,build一下,接着就开始疯狂踩坑了。
代码剖析
这里对上面的部分代码进行剖析:
AsyncWebServer server(80);
创建一个WebServer对象,将http的默认端口80传入 将鼠标指向AsyncWebServer ,同时按下Ctrl键,会跳转到ESPAsyncWebServer.h 头文件中。 可以看到跳转到AsyncWebServer 类中,可以看到这样的一个AsyncWebServer 类中有protected修饰的属性,还有被public修饰的属性和方法。 那么这行代码创建了一个server对象,在创建的时候就调用了AsyncWebServer(uint16_t port); 这行带参构造函数 查看AsyncWebServer(uint16_t port);构造函数的具体实现 接下来看AsyncWebServer类中的这一行:
~AsyncWebServer();
这是AsyncWebServer类中被public修饰的析构函数 程序运行结束后,程序在server对象销毁前自动调用析构函数,无须手动调用,而且只运行一次
AsyncWebServer类中有这样的一个函数,
void begin();
这行函数是begin()方法启动服务器进行请求监听
开始填坑
从vscode中可以看到在电脑上找不到这个ESPAsyncWebServer.h ,既然找不到这个头文件,那就手动的下载安装即可,这里给出两种解决方法:
- 第一种:
我百度了相关的资料,发现有很多类似的问题,都是缺少关键的头文件导致的。我发现ESPAsyncTCP.h 和 ESPAsyncWebServer.h 头文件存在着某种依赖关系,必须同时下载安装才可以。可以尝试从github上下载这两个库: ESPAsyncWebServer ESPAsyncTCP 直接下载zip压缩包即可。下载完成后通过Arduino IDE的Sketch > Include Library > ZIP-Library 将这两个压缩包添加进去。 可以从文档的Arduino的libraries目录中看到已经安装好的库文件。 - 第二种(理论上是可以的,但是我在第一种方法的时候就已经解决了,这个方法没有试过,此方法慎用):
vscode下面给出了有关于这个ESPAsyncWebServer.h 头文件的地址,使用CtrL + 单击 访问链接,在页面中的第一个就是。 我们需要下载这个库文件。 通过文档可以知道,安装这个库,需要切换到当前的PlotformIO项目,在platformio.ini配置文件所在的当前目录运行下面的这个程序:
pio lib install "ottowinter/ESPAsyncWebServer-esphome@^2.1.0"
运行可能会失败,这是因为当前的目录中根本找不到pio.exe,这就需要我们将pio.exe的所在目录添加到PATH环境变量中,我们可以找到pio.exe所在的目录:C:\Users\用户名\.platformio\penv\Scripts 将这个路径添加到PATH环境变量中即可,如图所示: 再次运行上面的这个安装代码,即可运行成功。
安装好上面的两个头文件之后,再次运行代码,发现还是缺少一个头文件:AsyncTCP.h ,
有了上一次的经验之后,直接点击下面给出的链接,运行代码安装:
pio lib install "esphome/AsyncTCP-esphome@^1.2.2"
再次运行,发现有一种奇怪的错误:src\main.cpp:xxx:x: error: stray '\xxx' in program ,错误的源头是程序中包含空格等非法字符,手动去掉这些空格,再次运行,程序就运行成功了。 将程序编译 下载到ESP32中后,需要将data文件夹也烧录到ESP32的文件系统,到这里ESP32就可以作为服务器了。
实验现象
打开XCOM串口助手,可以看到ESP32的IP地址是:192.168.1.83 打开浏览器,在地址栏中输入ESP32的IP地址,就可以看到一个网页了 现在使用杜邦线连接LED小灯,在网页上操作就可以看到小灯的亮灭 和 亮度强弱了。 (本文是根据本人在编译代码中遇到的问题写的,由于每个人的开发环境不同,有可能错误也不相同,仅限参考)
参考链接
https://stackoverflow.com/questions/61498846/espasyncwebserver-h-with-esp32 https://registry.platformio.org/libraries/esphome/AsyncTCP-esphome/installation https://registry.platformio.org/libraries/ottowinter/ESPAsyncWebServer-esphome/installation https://github.com/me-no-dev/ESPAsyncWebServer https://github.com/me-no-dev/ESPAsyncTCP
|