目录

ESP32 网页控制智能小车

目录

基于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实例:

在这一部分,我们定义了用于控制电机的引脚。这些引脚将用于控制四个电机的正转、反转和停止。然后,我们创建了一个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函数):

**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页面和处理电机控制请求:

在这一部分,我们定义了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){
  // ...(电机控制的代码在下一段介绍)
});

定义Web页面的HTML代码:

在这一部分,我们创建了一个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>";

控制按钮和JavaScript代码:

在这一部分,我们定义了四个按钮,分别用于控制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);