本帖最后由 伊娃老师 于 2023-9-20 00:35 编辑  
 
前情提要 
 
首先感谢DFRobot的试用机会,因为回了一趟老家,所以这么晚才准备这个帖子,我这次最终目标是实现Firebeetle 2 ESP32-S3 的实时摄像头小车制作,如果你也感兴趣,可以跟着我的探索,一起完成这个项目。 
 
因为我自己也算是初接触ESP32的Wi-Fi功能,很多东西都是一边探索一边整理出教学内容,如果有内容错误的,还请帮忙指出来,非常感谢! 
 
 
 
项目环境 
 
硬件:Firebeetle 2 ESP32-S3 
电脑:本次截屏为MAC M1,但不限WIN/MAC 
软件:Arduino IDE 2.2.2 
代码: LEDControl.ino.zip库: ESPAsyncWebServer-master.zip 
 
 
Firebeetle 2 ESP32-S3 wiki介绍 
https://wiki.dfrobot.com.cn/_SKU_DFR0975_FireBeetle_2_Board_ESP32_S3#target_8 
完整的板子介绍可以看链接,图片是目录 
  
 
 
Arduino环境配置 
 
请看wiki链接的5.1部分 
一定要慢慢、一步步看!跟着配置,不要心急! 
 
 
 
测试板载LED 
 
先让我们测试一下,你的环境有没有配置好吧! 
使用以下代码测试板载LED会不会闪烁,代码内容同wiki链接的5.2部分,只是增加了注解 
			
			
			- // 定义一个整数变量 led,用于存储 LED 灯的引脚号,这里设置为 21,因为板载LED在21
 - int led = 21;
 - 
 - // 初始化函数,Arduino 程序的入口点,在此处进行一次性的设置
 - void setup() {
 -   // 设置 led 变量指定的引脚为输出模式,以便将其用作输出控制 LED 灯
 -   pinMode(led, OUTPUT);
 - }
 - 
 - // 主循环函数,Arduino 程序的核心,将在循环中不断执行
 - void loop() {
 -   // 将 led 引脚的电压设置为高电平(即 LED 灯亮起)
 -   digitalWrite(led, HIGH);
 -   // 延迟 1000 毫秒(1 秒),保持 LED 灯亮起状态
 -   delay(1000);
 -   // 将 led 引脚的电压设置为低电平(即 LED 灯熄灭)
 -   digitalWrite(led, LOW);
 -   // 延迟 1000 毫秒(1 秒),保持 LED 灯熄灭状态
 -   delay(1000);
 - }
 
  复制代码
  
 
 
 
板载LED是type-c右边的绿色灯 
   
 
 
 
 
正式开始!  
 
 
步骤 1:准备工作 
 
 
在开始编写和理解代码之前,确保已经完成以下准备工作: 
 
 
- 连接ESP32到电脑,并确保您的Arduino IDE已经正确设置,以便能够上传代码到ESP32。
 - 确保电脑跟ESP32可以连接到同一个WiFi网络,因为这个代码将创建一个Web服务器,需要连接到WiFi网络以供其他设备访问。
 
 
  
 
 
步骤 2:安装ESPAsyncWebServer库 
 
 
在Arduino中,我们可以使用库来轻松地执行许多任务。为了连接WiFi网络和创建Web服务器,我们需要另外安装: 
ESPAsyncWebServer库 
 
 
你可以在Github找到,也可以附件直接下载: 
https://github.com/me-no-dev/ESPAsyncWebServer 
 
 
下载好之后,选择: 
项目/导入库/添加.zip库,开启下载的zip档即可 
  
 
ps. 我另外也发现ESPAsyncWebSrv也可以使用,而且可以直接搜索到,但不清楚两者区别,麻烦知道的小伙伴留言解惑,谢谢! 
  
 
 
步骤3:修改代码中的Wi-Fi帐号密码并上传 
 
10行跟11行,修改帐号密码 
 
因为我们使用网页控制LED,所以电脑、手机、平板都可以使用,但是! 
要跟电脑同一个网络,用手机、平板也是一样的, 
同一个网络!同一个网络!同一个网络! 
  
 
 
代码上传成功后, 
如果连接Wi-Fi成功:串口监视器会显示一个ip地址,每一个人的ip地址都不一样 
如果连接Wi-Fi失败:串口监视器会显示WiFi Failed!  
  
 
 
复制并修改以下代码: 
- /*
 - 这里我们使用了WiFi库和ESPAsyncWebServer库,
 - 它们用于连接WiFi网络和创建Web服务器
 - */
 - #include <WiFi.h>               //使用WiFi库
 - #include <ESPAsyncWebServer.h>  //使用ESPAsyncWebServer库
 - 
 - 
 - //修改网络名称跟Wi-Fi密码,要跟自己电脑同一个网络
 - const char *ssid = "WiFi网络名称";  // 替换成您的WiFi网络名称
 - const char *password = "WiFi密码";  // 替换成您的WiFi密码
 - 
 - AsyncWebServer server(80);  //声明对象并设置端口号,一般WebServer使用80
 - 
 - void setup() {
 -   // 启动串口通信,设置通信速率为115200波特率
 -   Serial.begin(115200);
 - 
 -   // 配置WiFi模式为Station(客户端模式)
 -   WiFi.mode(WIFI_STA);
 - 
 -   // 尝试连接到WiFi网络,使用在前面定义的网络名称(ssid)和密码(password)
 -   WiFi.begin(ssid, password);
 - 
 -   // 检查WiFi连接状态,如果连接失败,则打印错误消息并返回
 -   if (WiFi.waitForConnectResult() != WL_CONNECTED) {
 -     Serial.printf("WiFi Failed!\n");
 -     return;
 -   }
 - 
 -   // 打印ESP32的局域网IP地址,以便在串口监视器中查看
 -   Serial.print("IP Address: ");
 -   Serial.println(WiFi.localIP());
 - 
 -   // 设置LED引脚为输出模式,假设LED连接到引脚21
 -   pinMode(21, OUTPUT);
 - 
 -   // 处理根路径请求,创建一个包含控制LED的按钮的HTML页面
 -   server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
 -     String html = "<html><head><title>LED Control</title></head><body>";
 -     html += "<h1>Arduino Web Server</h1>";
 -     html += "<button id='btnOn'>Turn On LED</button>";
 -     html += "<button id='btnOff'>Turn Off LED</button>";
 -     html += "<script>";
 -     html += "document.getElementById('btnOn').addEventListener('click', function() {";
 -     html += "  var xhr = new XMLHttpRequest();";
 -     html += "  xhr.open('GET', '/led/on', true);";  // 发送请求以打开LED
 -     html += "  xhr.send();";
 -     html += "});";
 -     html += "document.getElementById('btnOff').addEventListener('click', function() {";
 -     html += "  var xhr = new XMLHttpRequest();";
 -     html += "  xhr.open('GET', '/led/off', true);";  // 发送请求以关闭LED
 -     html += "  xhr.send();";
 -     html += "});";
 -     html += "</script>";
 -     html += "</body></html>";
 - 
 -     // 发送HTML响应给客户端,状态码为200(OK),内容类型为text/html
 -     request->send(200, "text/html", html);
 -   });
 - 
 -   // 处理LED打开请求,将引脚21的电平设置为高(打开LED)
 -   server.on("/led/on", HTTP_GET, [](AsyncWebServerRequest *request) {
 -     digitalWrite(21, HIGH);  // 打开LED,假设LED连接到引脚21
 -     // 发送文本响应给客户端,表示LED已打开
 -     request->send(200, "text/plain", "LED is on");
 -   });
 - 
 -   // 处理LED关闭请求,将引脚21的电平设置为低(关闭LED)
 -   server.on("/led/off", HTTP_GET, [](AsyncWebServerRequest *request) {
 -     digitalWrite(21, LOW);  // 关闭LED,假设LED连接到引脚21
 -     // 发送文本响应给客户端,表示LED已关闭
 -     request->send(200, "text/plain", "LED is off");
 -   });
 - 
 -   // 启动Web服务器,开始监听来自客户端的请求
 -   server.begin();
 - }
 - 
 - void loop() {
 -   // 在这里可以添加其他代码,但在这个示例中,循环函数为空
 - }
 
  复制代码
  
 
步骤4:浏览器输入ip开启网页 
 
点击Turn On LED:开启LED 
点击Turn Off LED:关闭LED 
 
  
 
 
 
 
 
Arduino代码讲解 
 
 
在Arduino中,我们可以使用库来轻松地执行许多任务。 
在代码的开头,可以通过#include来引入库。 
这里我们使用了WiFi库和AsyncWebServer库,它们用于连接WiFi网络和创建Web服务器。 
- #include <WiFi.h>               //使用WiFi库
 - #include <ESPAsyncWebServer.h>  //使用ESPAsyncWebServer库
 
  复制代码
  
 
 
在 setup 函数中,我们配置了ESP32连接到WiFi网络的设置。 
这些设置包括WiFi网络的名称(ssid)和密码(password)。 
ESP32会尝试连接到这个网络。 
 
在 setup 函数中,我们还创建了一个AsyncWebServer对象(server),你后面会看到很多个"serve.函数",都是跟Web服务器有关,它将用于处理来自Web浏览器的请求。 
我们将服务器设置为监听端口80,这是Web服务器常用的端口。 
 
为了能看到ESP32的IP地址,我们使用WiFi.localIP() 
- const char *ssid = "WiFi网络名称";  // 替换成您的WiFi网络名称
 - const char *password = "WiFi密码";  // 替换成您的WiFi密码
 - 
 - AsyncWebServer server(80);  //声明对象并设置端口号,一般WebServer使用80
 - 
 - void setup() {
 -   // 启动串口通信,设置通信速率为115200波特率
 -   Serial.begin(115200);
 - 
 -   // 配置WiFi模式为Station(客户端模式)
 -   WiFi.mode(WIFI_STA);
 - 
 -   // 尝试连接到WiFi网络,使用在前面定义的网络名称(ssid)和密码(password)
 -   WiFi.begin(ssid, password);
 - 
 -   // 检查WiFi连接状态,如果连接失败,则打印错误消息并返回
 -   if (WiFi.waitForConnectResult() != WL_CONNECTED) {
 -     Serial.printf("WiFi Failed!\n");
 -     return;
 -   }
 
  复制代码
  
 
 
 
LED属于输出模式,设置板载LED的21脚为输出 
-   // 设置LED引脚为输出模式,假设LED连接到引脚21
 -   pinMode(21, OUTPUT);
 
  复制代码
  
 
 
 
server.on() 是一个函数,用于在ESPAsyncWebServer库中设置处理HTTP请求的回调函数。这个函数允许您定义当特定HTTP请求到达Web服务器时应该执行的操作。 
具体来说,server.on() 通常接受以下参数: 
 
- 路径(Path):表示服务器应该匹配的URL路径。当客户端请求与这个路径匹配的URL时,将执行回调函数。例如,在代码中的 server.on("/", ...) 中,路径是"/",表示处理根路径的请求。
 - HTTP请求方法(HTTP Method):表示服务器应该响应的HTTP请求方法,如HTTP GET、POST等。在代码中,使用 HTTP_GET 表示只处理HTTP GET请求。
 - 回调函数(Callback Function):是一个函数,它定义了当匹配的HTTP请求到达时应该执行的操作。这个函数接受一个参数,通常是一个指向AsyncWebServerRequest对象的指针,该对象包含了有关HTTP请求的信息,如请求头、参数等。
 
 
  
 
 
在 server.on("/", ...) 部分,我们定义了当有人访问根路径("/")时应该执行的操作。 
这段代码生成一个简单的HTML页面,其中包含两个按钮,用于控制LED灯的开关。 
还添加了JavaScript代码,以便通过按钮单击来向服务器发送请求,从而控制LED灯的状态。 
其实这里就是基本的HTML+JavaScript,定义了变量 html,形态为String, 
html+= 都是为了连接内容而已,也可以打一整串,就是看的很难受就是了 
 
在HTTP通信中,状态码是服务器向客户端发送的一个三位数的数字,用于表示请求的处理结果。状态码提供了一种快速的方式,让客户端了解服务器对请求的响应状态。 
当浏览器接收到状态码200时,它知道请求成功完成,服务器将发送响应内容作为HTML文档,并且该内容的类型是"text/html",因此浏览器会将其解释为HTML页面并进行渲染。 
简单来说,就是让ESP32知道这些内容是一个网页。 
- server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
 -     String html = "<html><head><title>LED Control</title></head><body>";
 -     html += "<h1>Arduino Web Server</h1>";
 -     html += "<button id='btnOn'>Turn On LED</button>";
 -     html += "<button id='btnOff'>Turn Off LED</button>";
 -     html += "<script>";
 -     html += "document.getElementById('btnOn').addEventListener('click', function() {";
 -     html += "  var xhr = new XMLHttpRequest();";
 -     html += "  xhr.open('GET', '/led/on', true);";  // 发送请求以打开LED
 -     html += "  xhr.send();";
 -     html += "});";
 -     html += "document.getElementById('btnOff').addEventListener('click', function() {";
 -     html += "  var xhr = new XMLHttpRequest();";
 -     html += "  xhr.open('GET', '/led/off', true);";  // 发送请求以关闭LED
 -     html += "  xhr.send();";
 -     html += "});";
 -     html += "</script>";
 -     html += "</body></html>";
 - 
 -     // 发送HTML响应给客户端,状态码为200(OK),内容类型为text/html
 -     request->send(200, "text/html", html);
 -   });
 
  复制代码
  
 
 
 
在 server.on("/led/on", ...) 部分,我们定义了当有人访问 "/led/on" 路径时应该执行的操作。 
这段代码将使连接到引脚21的LED灯点亮。 
 
ps.照理来说,成功点亮LED应该会在浏览器看到LED is on的文字,但我并没有看到,这里也求教大家了 
- server.on("/led/on", HTTP_GET, [](AsyncWebServerRequest *request) {
 -     digitalWrite(21, HIGH);  // 打开LED,假设LED连接到引脚21
 -     // 发送文本响应给客户端,表示LED已打开
 -     request->send(200, "text/plain", "LED is on");
 -   });
 
  复制代码
  
 
 
 
在 server.on("/led/off", ...) 部分,我们定义了当有人访问 "/led/off" 路径时应该执行的操作。 
这段代码将使连接到引脚21的LED灯熄灭。 
-   server.on("/led/off", HTTP_GET, [](AsyncWebServerRequest *request) {
 -     digitalWrite(21, LOW);  // 关闭LED,假设LED连接到引脚21
 -     // 发送文本响应给客户端,表示LED已关闭
 -     request->send(200, "text/plain", "LED is off");
 -   });
 
  复制代码
  
 
 
 
在所有配置和处理函数设置完成后,在 setup 函数的最后,我们调用 server.begin() 启动Web服务器,使其开始监听来自客户端的请求。 
复制代码
  
 
 
 
熟悉Arduino的人,可能会困惑,为什么loop中没有代码。 
因为server虽然是在 setup 函数中定义的,只会执行一次,但server会一直监听来自浏览器的HTTP请求,无论何时浏览器发送请求,这些事件处理程序都会根据请求路径来执行相应的操作。 
 
因此,虽然LED的控制逻辑在 setup 中执行,但它仍然可以通过与Web服务器事件处理程序的交互来实现对LED的控制。 
 
- void loop() {
 -   // 在这里可以添加其他代码,但在这个示例中,循环函数为空
 - }
 
  复制代码
  
 
 
后续会继续完成摄像头画面的显示以及马达的控制,最后再次感谢DFRobot! 
 
 |