本帖最后由 伊娃老师 于 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!
|