基于ESP32的网页控制智能小车。硬件部分包括一个四驱车,由一个电机驱动模块控制,8根杜邦线连接到ESP32板子上,电源由锂电池模块供应,通过一根MicroUSB到USB-A线连接。软件部分使用Arduino编程,使用了ESPAsyncWebServer第三方库,可以从库管理器中下载或者从GitHub下载。
在这一部分,我们首先导入了必要的库,包括用于Wi-Fi和Web服务器的库。然后,我们定义了全局变量,包括静态IP地址、网关、子网掩码,以及Wi-Fi网络名称和密码。这些是配置Wi-Fi连接所需的参数。
1
2
3
4
5
6
7
8
9
10
|
#include <WiFi.h>
#include <WiFiClient.h>
#include <ESPAsyncWebServer.h>
IPAddress staticIP(192, 168, 10, 22);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 255, 0);
const char* ssid = "***"; // Wi-Fi网络名称
const char* password = "***"; // Wi-Fi密码
|
在这一部分,我们定义了用于控制电机的引脚。这些引脚将用于控制四个电机的正转、反转和停止。然后,我们创建了一个AsyncWebServer实例,监听端口80,用于处理Web页面和电机控制请求。
1
2
3
4
5
6
7
8
9
10
|
#define MOTOA_P 14
#define MOTOA_N 27
#define MOTOB_P 32
#define MOTOB_N 33
#define MOTOC_P 25
#define MOTOC_N 26
#define MOTOD_P 22
#define MOTOD_N 23
AsyncWebServer server(80);
|
在**setup**
函数中,首先初始化串口通信,然后配置ESP32的静态IP地址和连接到Wi-Fi网络。接下来,将电机引脚设置为输出,以便能够控制电机的旋转方向。最后,定义了Web页面和启动了Web服务器。在这里,Web页面的定义被省略了,稍后会详细介绍。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
void setup() {
Serial.begin(115200); // 初始化串口通信
WiFi.config(staticIP, gateway, subnet); // 配置静态IP地址
WiFi.begin(ssid, password); // 连接到Wi-Fi网络
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("连接到Wi-Fi...");
}
Serial.print("已连接到Wi-Fi,IP地址为: ");
Serial.println(WiFi.localIP());
// 设置电机引脚为输出
pinMode(MOTOA_P, OUTPUT);
pinMode(MOTOA_N, OUTPUT);
pinMode(MOTOB_P, OUTPUT);
pinMode(MOTOB_N, OUTPUT);
pinMode(MOTOC_P, OUTPUT);
pinMode(MOTOC_N, OUTPUT);
pinMode(MOTOD_P, OUTPUT);
pinMode(MOTOD_N, OUTPUT);
// 定义Web页面
// ...(后续代码在下一段介绍)
// 启动Web服务器
server.begin();
}
|
在这一部分,我们定义了Web页面的处理方式和电机控制请求的处理方式。这是通过使用AsyncWebServer库的**on**
方法来完成的。Web页面的HTML代码将在下一段介绍,而电机控制请求的处理代码将在最后一段介绍。
1
2
3
4
5
6
7
8
9
|
// 定义Web页面
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
// ...(Web页面的HTML代码在下一段介绍)
});
// 处理电机控制请求
server.on("/motor", HTTP_GET, [](AsyncWebServerRequest *request){
// ...(电机控制的代码在下一段介绍)
});
|
在这一部分,我们创建了一个HTML页面的字符串。这个页面包括了一些基本的HTML标记,如字符集、视口设置等。CSS样式的定义被省略,稍后将详细介绍。此外,还创建了电机控制的按钮和相关的JavaScript代码,用于在Web页面上触发电机控制请求。
1
2
3
4
5
6
7
8
9
|
String html = "<html><head><meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<style>";
// ...(CSS样式在下一段介绍)
html += "</style>";
html += "</head><body>";
html += "<h1>ESP32电机控制</h1>";
// ...(控制按钮和JavaScript代码在下一段介绍)
html += "</body></html>";
|
在这一部分,我们定义了四个按钮,分别用于控制A和B电机组的正转、反转,以及C和D电机组的正转、反转。然后,通过JavaScript代码为这些按钮添加了**touchstart**
事件监听器,以便在按下按钮时发送电机控制请求。
1
2
3
4
5
6
7
8
9
10
|
html += "<button type='button' id='btnABForward'>A和B正转</button>";
html += "<button type='button' id='btnABReverse'>A和B反转</button>";
html += "<button type='button' id='btnCDForward'>C和D正转</button>";
html += "<button type='button' id='btnCDReverse'>C和D反转</button>";
html += "<script>";
html += "document.getElementById('btnABForward').addEventListener('touchstart', function() {";
html += " fetch('/motor?group=AB&action=forward');";
html += "});";
// ...(其他按钮的事件监听和请求代码在下一段介绍)
html += "</script>";
|
在这一部分,我们处理了电机控制请求。首先,通过**request->arg()**
获取传递的参数,包括电机组名称(group)和动作(action)。然后,根据这些参数来控制电机的正转、反转或停止动作。如果接收到无效的参数,将返回HTTP 400错误响应。最后,发送HTTP 200响应,表示电机已被控制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
String group = request->arg("group");
if (group == "AB") {
// A和B电机组的控制
if (request->arg("action") == "forward") {
// 正转
digitalWrite(MOTOA_P, HIGH);
digitalWrite(MOTOA_N, LOW);
digitalWrite(MOTOB_P, HIGH);
digitalWrite(MOTOB_N, LOW);
} else if (request->arg("action") == "reverse") {
// 反转
digitalWrite(MOTOA_P, LOW);
digitalWrite(MOTOA_N, HIGH);
digitalWrite(MOTOB_P, LOW);
digitalWrite(MOTOB_N, HIGH);
}
} else if (group == "CD") {
// C和D电机组的控制
if (request->arg("action") == "forward") {
// 正转
digitalWrite(MOTOC_P, HIGH);
digitalWrite(MOTOC_N, LOW);
digitalWrite(MOTOD_P, HIGH);
digitalWrite(MOTOD_N, LOW);
} else if (request->arg("action") == "reverse") {
// 反转
digitalWrite(MOTOC_P, LOW);
digitalWrite(MOTOC_N, HIGH);
digitalWrite(MOTOD_P, LOW);
digitalWrite(MOTOD_N, HIGH);
}
} else if (group == "ABCD" && request->arg("action") == "stop") {
// 停止所有电机
digitalWrite(MOTOA_P, LOW);
digitalWrite(MOTOA_N, LOW);
digitalWrite(MOTOB_P, LOW);
digitalWrite(MOTOB_N, LOW);
digitalWrite(MOTOC_P, LOW);
digitalWrite(MOTOC_N, LOW);
digitalWrite(MOTOD_P, LOW);
digitalWrite(MOTOD_N, LOW);
} else {
Serial.println("无效的电机组选择");
request->send(400, "text/plain", "无效的电机组选择");
return;
}
request->send(200, "text/plain", "电机已控制: " + group);
|