基于 Arduino IDE 搭建一个轻量的 ESP32 Web 服务器

打印 上一主题 下一主题

主题 887|帖子 887|积分 2661


ESP32 是乐鑫公司继 ESP8266 后新发布的 MCU,集成了 WiFi 模块和低功耗蓝牙模块,经常应用于物联网相关的项目。本教程将基于 Arduino IDE2.0 以上版本的软件中,搭建一个轻量的 ESP32 Web 服务器。
   [!NOTE]
  Web 服务器到底是什么,它是怎样工作的?
  Web 服务器是用于存储和处置处罚网页,并将其提供给 Web 客户端的装备。Web 客户端就是我们在盘算机和手机上使用的 Web 浏览器。Web 客户端和 Web 服务器使用称为超文本传输协议 (HTTP) 的特殊协议进行通讯。
  

  在此协议中,客户端通过发送针对特定网页的 HTTP 哀求来启动对话。然后,服务器会发回该网页的内容,假如找不到,则会发回错误消息(如著名的 404 错误)。
  ESP32 的 WiFi 工作模式

ESP32 不仅能够毗连到现有的 WiFi 网络并充当 Web 服务器,还可以创建自己的网络,允许其他装备直接毗连到它并访问网页。
ESP32 的 WiFi 模块可以在三种模式下运行:Station(STA)模式软接入点(AP)模式STA + AP 模式
Station(STA)模式

在 Station(STA)模式下,ESP32 毗连到现有的 WiFi 网络(由无线路由器创建的网络)。

在 STA 模式下,ESP32 从其毗连的无线路由器获取 IP 地点。使用此 IP 地点,它可以设置 Web 服务器并向现有 WiFi 网络上的全部毗连装备提供网页。
软接入点(AP)模式

在接入点(AP)模式下,ESP32 会创建自己的 WiFi 网络并充当集线器,就像 WiFi 路由器一样。但是,与 WiFi 路由器差别的是,它没有有线网络的接口。因此,这种操纵模式称为软接入点(soft-AP)。别的,不能凌驾 5 个工作站同时毗连到它。

在 AP 模式下,ESP32 会创建一个新的 WiFi 网络,并为其分配一个 SSID(网络名称)和一个 IP 地点。使用此 IP 地点,它可以向全部毗连的装备提供网页。
用 ESP32 Web 服务器点灯

将 LED 毗连到 ESP32

了解了 Web 服务器工作原理的基础知识,以及 ESP32 可以创建服务器的模式,再学习两个例子学习一下,怎样通过 WiFi 进行点灯操纵。
我这里使用的是 ESP32-WROOM 单片机,再用两个 220Ω 限流电阻器分别将两个 LED 毗连到数字 D4 和 D5,接纳的接法是共阴极接法(LED 的负极和 GND 毗连,靠 GPIO 输出高电平点亮 LED)。

   [!NOTE]
  ESP32 只是一个芯片,这个教程适用于任何基于 ESP32 计划的开发板,乃至可以用在 ESP8266 的开发板上。
  示例 1 – 在 AP 模式下搭建 ESP32 Web 服务器

本示例代码是基于 Arduino 框架编写的 ESP32 步伐,步伐中创建了一个无线接入点(Access Point, AP),并在该 AP 模式下运行一个简朴的 Web 服务器。用户可以通过毗连到 ESP32 创建的 WiFi 网络,并在浏览器中输入 IP 地点来访问 Web 页面,以控制两个 GPIO 引脚上的 LED 状态。
完备的代码已经推送至我的代码堆栈,链接在文章末端,必要的小伙伴可以自取(不会 git 命令的小伙伴,也可以在找我的小助理要代码)。以下是对代码的分段分析:
包含库和定义常量

  1. #include <WiFi.h>
  2. #include <WebServer.h>
  3. const char* ssid     = "ESP32";
  4. const char* password = "12345678";
  5. IPAddress local_ip(192,168,1,1);
  6. IPAddress gateway(192,168,1,1);
  7. IPAddress subnet(255,255,255,0);
  8. WebServer server(80);
  9. uint8_t led_1_pin = 4;
  10. bool led_1_status = LOW;
  11. uint8_t led_2_pin = 5;
  12. bool led_2_status = LOW;
复制代码


  • 引入了 WiFi 和 WebServer 库,用于处置处罚 Wi-Fi 毗连和 HTTP 哀求。
  • 定义了 SSID、暗码以及静态 IP 设置信息,用来设置 ESP32 作为无线接入点时的网络参数。
  • 创建了一个 WebServer 对象,监听端口 80,这是 HTTP 协议默认使用的端口。
  • 定义了两个 LED 所毗连的 GPIO 引脚编号以及它们的初始状态。
setup() 函数

  1. void setup()
  2. {
  3.     Serial.begin(115200);
  4.     pinMode(led_1_pin, OUTPUT);
  5.     pinMode(led_2_pin, OUTPUT);
  6.     WiFi.softAP(ssid, password);
  7.     WiFi.softAPConfig(local_ip, gateway, subnet);
  8.     delay(100);
  9.     server.on("/", handle_on_connect);
  10.     server.on("/LED1On", handle_led_1_turn_on);
  11.     server.on("/LED1Off", handle_led_1_turn_off);
  12.     server.on("/LED2On", handle_led_2_turn_on);
  13.     server.on("/LED2Off", handle_led_2_turn_off);
  14.     server.onNotFound(handle_not_found);
  15.     server.begin();
  16.     Serial.println("HTTP server started");
  17. }
复制代码


  • 初始化串行通讯,设置 LED 引脚为输出模式。
  • 设置 ESP32 进入软 AP 模式,并设置了静态 IP 设置。
  • 设置了 Web 服务器的路由及其对应的处置处罚函数。
  • 启动 Web 服务器,并打印一条消息表明服务器已启动。
loop() 函数

  1. void loop()
  2. {
  3.     server.handleClient();
  4.     if (led_1_status)
  5.         digitalWrite(led_1_pin, HIGH);
  6.     else
  7.             digitalWrite(led_1_pin, LOW);
  8.     if (led_2_status)
  9.         digitalWrite(led_2_pin, HIGH);
  10.     else
  11.             digitalWrite(led_2_pin, LOW);
  12. }
复制代码


  • 连续调用 handleClient 方法处置处罚客户端哀求。
  • 根据 led_1_status 和 led_2_status 变量的状态更新 LED 的实际物理状态。
HTTP 哀求处置处罚器

  1. void handle_on_connect()
  2. {
  3.     led_1_status = LOW;
  4.     led_2_status = LOW;
  5.     Serial.println("GPIO4 Status: OFF | GPIO5 Status: OFF");
  6.     server.send(200, "text/html", send_html(led_1_status, led_2_status));
  7. }
  8. void handle_led_1_turn_on()
  9. {
  10.     led_1_status = HIGH;
  11.     Serial.println("GPIO4 Status: ON");
  12.     server.send(200, "text/html", send_html(true, led_2_status));
  13. }
  14. void handle_led_1_turn_off()
  15. {
  16.     led_1_status = LOW;
  17.     Serial.println("GPIO4 Status: OFF");
  18.     server.send(200, "text/html", send_html(false, led_2_status));
  19. }
  20. void handle_led_2_turn_on()
  21. {
  22.     led_2_status = HIGH;
  23.     Serial.println("D5 Status: ON");
  24.     server.send(200, "text/html", send_html(led_1_status, true));
  25. }
  26. void handle_led_2_turn_off()
  27. {
  28.     led_2_status = LOW;
  29.     Serial.println("GPIO5 Status: OFF");
  30.     server.send(200, "text/html", send_html(led_1_status, false));
  31. }
  32. void handle_not_found()
  33. {
  34.     server.send(404, "text/plain", "Not found");
  35. }
复制代码


  • 这些函数定义了当吸收到特定 HTTP 哀求时应执行的操纵,比方打开或关闭 LED,并发送相应的 HTML 响应给客户端。
HTML 生成函数 send_html

  1. String send_html(uint8_t led_1_stat, uint8_t led_2_stat)
  2. {
  3.     String ptr = "<!DOCTYPE html> <html>\n";
  4.     ptr += "<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">\n";
  5.     ptr += "<title>LED Control</title>\n";
  6.     ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  7.     ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  8.     ptr += ".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  9.     ptr += ".button-on {background-color: #3498db;}\n";
  10.     ptr += ".button-on:active {background-color: #2980b9;}\n";
  11.     ptr += ".button-off {background-color: #34495e;}\n";
  12.     ptr += ".button-off:active {background-color: #2c3e50;}\n";
  13.     ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  14.     ptr += "</style>\n";
  15.     ptr += "</head>\n";
  16.     ptr += "<body>\n";
  17.     ptr += "<h1>ESP32 Web Server</h1>\n";
  18.     ptr += "<h3>Using Access Point(AP) Mode</h3>\n";
  19.     if (led_1_stat)
  20.         ptr += "<p>LED1 Status: ON</p><a class="button button-off" href="/LED1Off">OFF</a>\n";
  21.     else
  22.         ptr += "<p>LED1 Status: OFF</p><a class="button button-on" href="/LED1On">ON</a>\n";
  23.     if (led_2_stat)
  24.         ptr += "<p>LED2 Status: ON</p><a class="button button-off" href="/LED2Off">OFF</a>\n";
  25.     else
  26.         ptr += "<p>LED2 Status: OFF</p><a class="button button-on" href="/LED2On">ON</a>\n";
  27.     ptr += "<style>\n";
  28.     ptr += "body {margin-top: 15%;}\n";
  29.     ptr += ".footer-text { font-size: 30px; }";
  30.     ptr += ".bold-text { font-weight: bold; }";
  31.     ptr += "</style>\n";
  32.     ptr += "<div class='footer'>";
  33.     ptr += "<p class='footer-text'>This software was written by <span class='bold-text'>Grayson Zheng</span>.</p>";
  34.     ptr += "</div>\n";
  35.     ptr += "</body>\n";
  36.     ptr += "</html>\n";
  37.     return ptr;
  38. }
复制代码


  • 该函数构建并返回一个包含当前 LED 状态的 HTML 页面,用户可以通过这个页面与 ESP32 进行交互,控制 LED 的开关。
毗连 ESP32 Web 服务器并访问

把步伐下载至 ESP32 后,Web 服务器就启动了,这时可以用一部可以毗连到 WiFi 的手机、平板电脑或电脑等装备,搜索一个 WiFi 名为 “ESP32” 的网络。如下图所示,我使用的是小米 11:
输入预设的暗码 :12345678
毗连成功后,如下图。这里提示一下,由于 ESP32 确实没有接入互联网,没办法访问外界的网络,不外这不影响我们加下来的操纵。小米手机在检测到当前的 WiFi 无法访问互联网的时候,会弹出提示窗口,选择 “保持毗连” 即可。其他手机不知是否有类似的提示,选择类似的操纵即可。
怎样打开浏览器,在地点栏输入预设的 “192.168.1.1”,然后进入即可实现点灯的操纵。假如能看到如下图一样的界面,就证明实验成功了。

整个操纵过程,会在串口有对应的输出,可以通过串口进行对应的调试:

具体操纵,如视频所示:

     ESP32 Web 服务器
  
示例 2 – 在 WiFi STA 模式下搭建 ESP32 Web 服务器

本示例代码同样也是基于 Arduino 框架编写的 ESP32 步伐,用于创建一个 Web 服务器,该服务器毗连到现有的 WiFi 网络(Station 模式),并提供了一个简朴的 Web 界面来控制两个 GPIO 引脚上的 LED。
完备的代码与上一个示例放在同一个堆栈,已经推送至我的代码堆栈(链接在文章末端),必要的小伙伴可以自取(不会 git 命令的小伙伴,也可以在找我的小助理要代码)。
由于大部分代码与示例 1 相同,所以接下来的代码分析只说明代码修改的部分,以下是对代码的分段分析:
包含库和定义常量

  1. #include <WiFi.h>
  2. #include <WebServer.h>
  3. const char* ssid =     "Grayson";
  4. const char* password = "Zhengxinyu13@";
  5. // IPAddress local_ip(192,168,1,1);
  6. // IPAddress gateway(192,168,1,1);
  7. // IPAddress subnet(255,255,255,0);
  8. WebServer server(80);
  9. uint8_t led_1_pin = 4;
  10. bool led_1_status = LOW;
  11. uint8_t led_2_pin = 5;
  12. bool led_2_status = LOW;
复制代码
引入了 WiFi 库和 WebServer 库,另有两个 LED 所毗连的 GPIO 引脚编号以及它们的初始状态这些代码稳定。修改的地方:


  • 定义了要毗连的 WiFi 网络的 SSID 和暗码,这部分不要照抄,写自己家里的 WiFi 或者热点网络。
  • 由于是 STA 模式,静态 IP 设置信息是不必要设置的,所以这里把 AP 模式的设置静态 IP 的代码注释(删除也行)。
setup() 函数

  1. void setup()
  2. {
  3.     Serial.begin(115200);
  4.     pinMode(led_1_pin, OUTPUT);
  5.     pinMode(led_2_pin, OUTPUT);
  6.     delay(100);
  7.     Serial.print("Connecting to ");
  8.     Serial.println(ssid);
  9.     //connect to your local wi-fi network
  10.     WiFi.begin(ssid, password);
  11.     while (WiFi.status() != WL_CONNECTED) {
  12.         delay(500);
  13.         Serial.print(".");
  14.     }
  15.     Serial.println("");
  16.     Serial.println("WiFi connected..!");
  17.     Serial.print("Got IP: ");  Serial.println(WiFi.localIP());
  18.     server.on("/", handle_on_connect);
  19.     server.on("/LED1On", handle_led_1_turn_on);
  20.     server.on("/LED1Off", handle_led_1_turn_off);
  21.     server.on("/LED2On", handle_led_2_turn_on);
  22.     server.on("/LED2Off", handle_led_2_turn_off);
  23.     server.onNotFound(handle_not_found);
  24.     server.begin();
  25.     Serial.println("HTTP server started");
  26. }
复制代码
初始化串行通讯、设置 LED 引脚为输出模式、设置 Web 服务器的路由及其对应的处置处罚函数等稳定,去掉之前 AP 模式用到的 IP 设置。改为:


  • 每 500 毫秒尝试一次毗连到指定的 WiFi 网络
  • 成功毗连后,打印出分配给 ESP32 的本地 IP 地点。
HTML 生成函数 send_html

  1. String send_html(uint8_t led_1_stat, uint8_t led_2_stat)
  2. {
  3.     ...
  4.     ptr += "</head>\n";
  5.     ptr += "<body>\n";
  6.     ptr += "<h1>ESP32 Web Server</h1>\n";
  7.     ptr += "<h3>Using Station(STA) Mode</h3>\n"; // 修改此行
  8.     if (led_1_stat)
  9.         ptr += "<p>LED1 Status: ON</p><a class="button button-off" href="/LED1Off">OFF</a>\n";
  10.     ...
  11. }
复制代码
send_html 函数只修改了一行,把 ptr += "<h3>Using Access Point(AP) Mode</h3>\n"; 修改为 ptr += "<h3>Using Station(STA) Mode</h3>\n";。
毗连 ESP32 Web 服务器并访问

把步伐下载至 ESP32 后,Web 服务器就启动了。我们先打开 Arduino IDE 自带的串口监视器,设置波特率为 115200bps,再按一下开发板上的复位按钮(Reset),稍等一会就可以在串口监视器中看到打印信息:

打开毗连到同一个 WiFi 的手机、平板电脑或电脑的浏览器,输入分配给 ESP32 Web 服务器的 IP 地点,就可以进行点灯操纵了。操纵过程同样会有串口的调试信息打印出来,具体过程如下:

     ESP32
  

代码链接

GitHub:zhengxinyu13/Simple_ESP32_Web_Server
Gitee:Grayson_Zheng/Simple_ESP32_Web_Server
GitCode:Simple_ESP32_Web_Server - GitCode
   [!NOTE]
  不会使用 git 命令克隆代码的小伙伴,可以在我主页找到我助理的地球号,或者直接看下面,找我的助理领取。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表