回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【花雕学编程】Arduino动手做(246)---ESP8266 Web 服务器:从手机控制组件 简单

头像 驴友花雕 2025.01.15 11 0

14.jpg
23.jpg

10-.jpg
19.jpg

  【花雕学编程】239种传感器执行器系列实验(资料代码+仿真编程+图形编程)
  实验二百四十六:ESP8266串口wifi模块 NodeMCU Lua V3物联网开发板 CH340
  实验项目之十四:ESP8266 Web 服务器:从手机控制组件

 

54.jpg
58 (2).jpg

来自百科,“Web 服务器是服务器软件或专门用于运行此软件的硬件,可以满足万维网上的客户端请求”。本例子中,使用ESP8266(NodeMCU V3)的功能来充当我们的 Web 服务器并托管我们的网站。在浏览器中键入 Web 服务器的地址发出“请求”,并收到了 html 标记形式的“响应”。NodeMCU ESP8266 Web 服务器接收此请求并使用 HTML 响应进行回复。它还处理我们组件的接口,因此它会检查来自 Web 浏览器的请求并采取相应的行动。ESP8266 芯片及其最新的 ESP32 芯片都是关于 wifi 和连接的。这使其非常适合我们的物联网 (IOT) 项目。

 

58-1.jpg

实验开源代码

代码
/*
  【花雕学编程】239种传感器执行器系列实验(资料代码+仿真编程+图形编程)
   实验二百四十六:ESP8266串口wifi模块 NodeMCU Lua V3物联网开发板 CH340
   实验项目之十四:ESP8266 Web 服务器:从手机控制组件
*/

#include <ESP8266WiFi.h> // 包含ESP8266WiFi库,用于WiFi连接
#include <ESP8266WebServer.h> // 包含ESP8266WebServer库,用于创建Web服务器

/********** 请修改以下内容 *************************/
const char* ssid = "zhz3"; // 设置Wi-Fi名称
const char* password = "z156721";  // 设置Wi-Fi密码

ESP8266WebServer server(80);  // 创建一个Web服务器对象,监听80端口

uint8_t LEDPin = D3;  // 定义LED连接的引脚
bool LEDStatus = LOW;  // 定义LED的初始状态(低电平)

uint8_t buzzerPin = D4;  // 定义蜂鸣器连接的引脚
bool buzzerStatus = LOW;  // 定义蜂鸣器的初始状态(低电平)

void setup() {
  Serial.begin(115200);  // 初始化串口通信,波特率为115200
  Serial.println(" ");
  Serial.println("正在连接Wi-Fi网络...");
  pinMode(LEDPin, OUTPUT);  // 设置LED引脚为输出模式
  pinMode(buzzerPin, OUTPUT);  // 设置蜂鸣器引脚为输出模式

  Serial.println("正在连接Wi-Fi网络...");
  Serial.println(ssid);

  // 连接到本地Wi-Fi网络
  WiFi.begin(ssid, password);

  // 检查Wi-Fi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Wi-Fi连接成功!");
  Serial.print("获取到的IP地址: ");  
  Serial.println(WiFi.localIP());  // 打印ESP8266的IP地址

  // 设置Web服务器的路由和处理函数
  server.on("/", handleRoot);  // 根路径的处理函数
  server.on("/toggleLED", updateLED);  // 切换LED状态的处理函数
  server.on("/toggleBuzzer", updateBuzzerSound);  // 切换蜂鸣器状态的处理函数
  server.onNotFound(handleNotFound);  // 未找到路径的处理函数

  server.begin();  // 启动Web服务器
  Serial.println("HTTP服务器已启动");
}

void loop() {
  server.handleClient();  // 处理客户端请求
}

// 处理根路径请求
void handleRoot() {
  server.send(200, "text/html", prepareHTML());  // 返回HTML页面
}

// 切换LED状态
void updateLED() {
  Serial.println("正在更新LED状态...");
  LEDStatus = !LEDStatus;  // 切换LED状态
  digitalWrite(LEDPin, LEDStatus);  // 更新LED引脚电平
  server.send(200, "text/html", prepareHTML());  // 返回更新后的HTML页面
}

// 切换蜂鸣器状态
void updateBuzzerSound() {
  Serial.println("正在更新蜂鸣器状态...");
  buzzerStatus = !buzzerStatus;  // 切换蜂鸣器状态
  if (buzzerStatus)
    tone(buzzerPin, 1200);  // 打开蜂鸣器,频率为1200Hz
  else
    noTone(buzzerPin);  // 关闭蜂鸣器

  server.send(200, "text/html", prepareHTML());  // 返回更新后的HTML页面
}

// 处理未找到的路径
void handleNotFound() {
  server.send(404, "text/plain", "路径未找到");  // 返回404错误
}

// 生成HTML页面
String prepareHTML() {
  String html  = "<!DOCTYPE html>"
                 "<html>"
                 "<head>"
                 "<meta charset=\"UTF-8\">"
                 "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
                 "<title>NodeMCU ESP8266 Web Server</title>"
                 "<style>"
                 "/* 样式代码省略 */"
                 "</style>"
                 "</head>"
                 "<body>"
                 "<nav class=\"nav\" tabindex=\"-1\" onclick=\"this.focus()\">"
                 "<div class=\"container\">"
                 "<a class=\"pagename current\" href=\"#\">wwww.ESP8266.com</a>"
                 "</div>"
                 "</nav>"
                 ""
                 "<div class=\"container\">"
                 "<div class=\"hero\">"
                 "<h1>NodeMCU ESP8266 Web Server</h1>"
                 "<div class=\"flex-container\">"
                 "  <div class=\"flex-child magenta\">"
                 "<span class=\"component-label\">LED</span>"
                 "  </div>"
                 "  <div class=\"flex-child green\">"
                 "<div class=\"grid-child green\">"
                 "<div style=\"display: inline\">"
                 "<div class=\"onoffswitch\">";
  if (LEDStatus)
    html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"ledSwitch\" tabindex=\"0\" checked onclick=\"window.location.href='toggleLED'\">";
  else
    html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"ledSwitch\" tabindex=\"0\" onclick=\"window.location.href='toggleLED'\">";

  html = html +
         "<label class=\"onoffswitch-label\" for=\"ledSwitch\">"
         "<span class=\"onoffswitch-inner\"></span>"
         "<span class=\"onoffswitch-switch\"></span>"
         "</label>"
         "</div>"
         "</div>"
         "</div>"
         "  </div>"
         "</div>"
         "<div class=\"flex-container\">"
         "  <div class=\"flex-child magenta\">"
         "<span class=\"component-label\">蜂鸣器</span>"
         "  </div>"
         "  <div class=\"flex-child green\">"
         "<div class=\"grid-child green\">"
         "<div style=\"display: inline\">"
         "<div class=\"onoffswitch\">";
  if (buzzerStatus)
    html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"buzzerSwitch\" tabindex=\"0\" checked onclick=\"window.location.href='toggleBuzzer'\">";
  else
    html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"buzzerSwitch\" tabindex=\"0\" onclick=\"window.location.href='toggleBuzzer'\">";

  html = html +
         "<label class=\"onoffswitch-label\" for=\"buzzerSwitch\">"
         "<span class=\"onoffswitch-inner\"></span>"
         "<span class=\"onoffswitch-switch\"></span>"
         "</label>"
         "</div>"
         "</div>"
         "</div>"
         "  </div>"
         "</div>"
         "</div>"
         "</div>"
         "</body>"
         "</html>";

  return html;  // 返回生成的HTML页面
}

以下是代码的详细注释,逐行解释每一部分的功能和作用:

1. 引入库

#include <ESP8266WiFi.h>  // 引入ESP8266 Wi-Fi库,用于连接和管理Wi-Fi网络
#include <ESP8266WebServer.h>  // 引入ESP8266 Web服务器库,用于创建HTTP服务器

2. 定义Wi-Fi配置

/********** 请修改以下内容 *************************/
const char* ssid     = "<请输入您的Wi-Fi SSID>";  // 定义Wi-Fi名称(SSID)
const char* password = "<请输入您的Wi-Fi密码>";  // 定义Wi-Fi密码

3. 创建Web服务器对象

ESP8266WebServer server(80);  // 创建一个Web服务器对象,监听80端口(HTTP默认端口)

4. 定义引脚和状态变量

uint8_t LEDPin = D7;  // 定义LED连接的引脚(D7)
bool LEDStatus = LOW;  // 定义LED的初始状态(低电平,表示关闭)

uint8_t buzzerPin = D1;  // 定义蜂鸣器连接的引脚(D1)
bool buzzerStatus = LOW;  // 定义蜂鸣器的初始状态(低电平,表示关闭)

5. setup() 函数
setup() 函数在设备启动时运行一次,用于初始化硬件和配置。

void setup() {
 Serial.begin(115200);  // 初始化串口通信,波特率为115200,用于调试信息输出
 pinMode(LEDPin, OUTPUT);  // 设置LED引脚为输出模式
 pinMode(buzzerPin, OUTPUT);  // 设置蜂鸣器引脚为输出模式

 Serial.println("正在连接Wi-Fi网络...");
 Serial.println(ssid);

 // 连接到本地Wi-Fi网络
 WiFi.begin(ssid, password);

 // 检查Wi-Fi是否连接成功
 while (WiFi.status() != WL_CONNECTED) {
   delay(1000);  // 每隔1秒检查一次
   Serial.print(".");  // 打印连接状态(...)
 }
 Serial.println("");
 Serial.println("Wi-Fi连接成功!");
 Serial.print("获取到的IP地址: ");  
 Serial.println(WiFi.localIP());  // 打印ESP8266的IP地址,用于访问Web服务器

 // 设置Web服务器的路由和处理函数
 server.on("/", handleRoot);  // 根路径("/")的处理函数
 server.on("/toggleLED", updateLED);  // 切换LED状态的路由("/toggleLED")的处理函数
 server.on("/toggleBuzzer", updateBuzzerSound);  // 切换蜂鸣器状态的路由("/toggleBuzzer")的处理函数
 server.onNotFound(handleNotFound);  // 未找到路径的处理函数

 server.begin();  // 启动Web服务器
 Serial.println("HTTP服务器已启动");
}

6. loop() 函数
loop() 函数在设备运行期间不断循环,用于处理客户端请求。

void loop() {
 server.handleClient();  // 处理客户端请求
}

7. 处理根路径请求
当用户访问根路径(/)时,返回一个HTML页面。

void handleRoot() {
 server.send(200, "text/html", prepareHTML());  // 返回HTTP状态码200和HTML页面
}

8. 切换LED状态
当用户访问 /toggleLED 路径时,切换LED的状态。

void updateLED() {
 Serial.println("正在更新LED状态...");
 LEDStatus = !LEDStatus;  // 切换LED状态(开/关)
 digitalWrite(LEDPin, LEDStatus);  // 更新LED引脚电平
 server.send(200, "text/html", prepareHTML());  // 返回更新后的HTML页面
}

9. 切换蜂鸣器状态
当用户访问 /toggleBuzzer 路径时,切换蜂鸣器的状态。

void updateBuzzerSound() {
 Serial.println("正在更新蜂鸣器状态...");
 buzzerStatus = !buzzerStatus;  // 切换蜂鸣器状态(开/关)
 if (buzzerStatus)
   tone(buzzerPin, 1200);  // 打开蜂鸣器,频率为1200Hz
 else
   noTone(buzzerPin);  // 关闭蜂鸣器

 server.send(200, "text/html", prepareHTML());  // 返回更新后的HTML页面
}

10. 处理未找到的路径
当用户访问未定义的路径时,返回404错误。

void handleNotFound() {
 server.send(404, "text/plain", "路径未找到");  // 返回HTTP状态码404和错误信息
}

11. 生成HTML页面
动态生成包含LED和蜂鸣器控制开关的HTML页面。

String prepareHTML() {
 String html  = "<!DOCTYPE html>"
                "<html>"
                "<head>"
                "<meta charset=\"UTF-8\">"
                "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
                "<title>NodeMCU ESP8266 Web Server</title>"
                "<style>"
                "/* 样式代码省略 */"
                "</style>"
                "</head>"
                "<body>"
                "<nav class=\"nav\" tabindex=\"-1\" onclick=\"this.focus()\">"
                "<div class=\"container\">"
                "<a class=\"pagename current\" href=\"#\">wwww.donskytech.com</a>"
                "</div>"
                "</nav>"
                ""
                "<div class=\"container\">"
                "<div class=\"hero\">"
                "<h1>NodeMCU ESP8266 Web Server</h1>"
                "<div class=\"flex-container\">"
                "  <div class=\"flex-child magenta\">"
                "<span class=\"component-label\">LED</span>"
                "  </div>"
                "  <div class=\"flex-child green\">"
                "<div class=\"grid-child green\">"
                "<div style=\"display: inline\">"
                "<div class=\"onoffswitch\">";
 if (LEDStatus)
   html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"ledSwitch\" tabindex=\"0\" checked onclick=\"window.location.href='toggleLED'\">";
 else
   html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"ledSwitch\" tabindex=\"0\" onclick=\"window.location.href='toggleLED'\">";

 html = html +
        "<label class=\"onoffswitch-label\" for=\"ledSwitch\">"
        "<span class=\"onoffswitch-inner\"></span>"
        "<span class=\"onoffswitch-switch\"></span>"
        "</label>"
        "</div>"
        "</div>"
        "</div>"
        "  </div>"
        "</div>"
        "<div class=\"flex-container\">"
        "  <div class=\"flex-child magenta\">"
        "<span class=\"component-label\">蜂鸣器</span>"
        "  </div>"
        "  <div class=\"flex-child green\">"
        "<div class=\"grid-child green\">"
        "<div style=\"display: inline\">"
        "<div class=\"onoffswitch\">";
 if (buzzerStatus)
   html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"buzzerSwitch\" tabindex=\"0\" checked onclick=\"window.location.href='toggleBuzzer'\">";
 else
   html = html + "<input type=\"checkbox\" name=\"onoffswitch\" class=\"onoffswitch-checkbox\" id=\"buzzerSwitch\" tabindex=\"0\" onclick=\"window.location.href='toggleBuzzer'\">";

 html = html +
        "<label class=\"onoffswitch-label\" for=\"buzzerSwitch\">"
        "<span class=\"onoffswitch-inner\"></span>"
        "<span class=\"onoffswitch-switch\"></span>"
        "</label>"
        "</div>"
        "</div>"
        "</div>"
        "  </div>"
        "</div>"
        "</div>"
        "</div>"
        "</body>"
        "</html>";

 return html;  // 返回生成的HTML页面
}

代码功能总结
Wi-Fi连接:ESP8266连接到指定的Wi-Fi网络。
Web服务器:创建一个Web服务器,监听HTTP请求。
LED控制:通过Web页面控制LED的开关状态。
蜂鸣器控制:通过Web页面控制蜂鸣器的开关状态。
HTML页面生成:动态生成包含LED和蜂鸣器控制开关的HTML页面。
路由处理:处理根路径、LED切换、蜂鸣器切换以及未找到路径的请求。

通过这段代码,用户可以通过浏览器访问ESP8266的IP地址,控制连接的LED和蜂鸣器。

实验串口返回情况

 

58.jpg

在手机端打开浏览器,输入IP地址:192.168.28.40

 

58 (3).jpg

控制LED和蜂鸣器后的实验串口返回情况

 

58-.jpg

实验场景图

 

58 (1).jpg
58 (4).jpg

实验记录视频(32秒)

 

【【花雕学编程】Arduino动手做(246)---ESP8266 Web 服务器:从手机控制组件】 

 

https://www.bilibili.com/video/BV1CjcBezEKJ/?share_source=copy_web&vd_source=371a292a55e5ca9be994cbb4a86cc987


评论

user-avatar
icon 他的勋章
    展开更多