#include <WiFi.h>
#include <WebServer.h>
// 替换为你的WiFi名称和密码
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
// 电机控制引脚定义
#define AIN1 18
#define AIN2 19
#define PWMA 5
#define BIN1 25
#define BIN2 26
#define PWMB 27
#define STBY 21
// PWM通道设置
#define PWM_CHANNEL_A 0
#define PWM_CHANNEL_B 1
#define PWM_FREQ 1000
#define PWM_RESOLUTION 8
WebServer server(80); // 创建Web服务器,监听80端口
// 当前电机速度,0-255
uint8_t speedA = 0;
uint8_t speedB = 0;
// 方向记录(示例用,可扩展为更复杂的逻辑)
String dirA = "停止";
String dirB = "停止";
// 设置电机方向和速度函数
void motorA_forward(uint8_t speed) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
ledcWrite(PWM_CHANNEL_A, speed);
speedA = speed;
dirA = "正转";
}
void motorA_backward(uint8_t speed) {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
ledcWrite(PWM_CHANNEL_A, speed);
speedA = speed;
dirA = "反转";
}
void motorA_stop() {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
ledcWrite(PWM_CHANNEL_A, 0);
speedA = 0;
dirA = "停止";
}
void motorB_forward(uint8_t speed) {
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
ledcWrite(PWM_CHANNEL_B, speed);
speedB = speed;
dirB = "正转";
}
void motorB_backward(uint8_t speed) {
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
ledcWrite(PWM_CHANNEL_B, speed);
speedB = speed;
dirB = "反转";
}
void motorB_stop() {
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
ledcWrite(PWM_CHANNEL_B, 0);
speedB = 0;
dirB = "停止";
}
// 停止所有电机
void motorStop() {
motorA_stop();
motorB_stop();
}
// 处理网页请求:主页
void handleRoot() {
String html = R"rawliteral(
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>ESP32 电机控制</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f2f5;
text-align: center;
padding: 20px;
}
h2 {
color: #333;
}
.motor-control {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
padding: 20px;
margin: 20px auto;
max-width: 400px;
}
select, input[type="number"] {
padding: 10px;
width: 80%;
margin: 10px 0;
font-size: 16px;
}
button {
padding: 10px 20px;
font-size: 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
.status {
margin-top: 20px;
font-weight: bold;
}
</style>
</head>
<body>
<h2>ESP32 Motor Control Panel</h2>
<div class="motor-control">
<h3>电机A 控制</h3>
方向:
<select id="dirA">
<option value="stop">停止</option>
<option value="forward">正转</option>
<option value="backward">反转</option>
</select><br>
速度(0-255): <input type="number" id="speedA" min="0" max="255" value="0"><br>
<button onclick="sendCommand('A')">发送指令</button>
</div>
<div class="motor-control">
<h3>电机B 控制</h3>
方向:
<select id="dirB">
<option value="stop">停止</option>
<option value="forward">正转</option>
<option value="backward">反转</option>
</select><br>
速度(0-255): <input type="number" id="speedB" min="0" max="255" value="0"><br>
<button onclick="sendCommand('B')">发送指令</button>
</div>
<div class="status" id="status">
当前状态:<br>
电机A:速度=<span id="curSpeedA">0</span>, 状态=<span id="curDirA">停止</span><br>
电机B:速度=<span id="curSpeedB">0</span>, 状态=<span id="curDirB">停止</span>
</div>
<script>
function sendCommand(motor) {
let dir = motor === 'A' ? document.getElementById("dirA").value : document.getElementById("dirB").value;
let speed = motor === 'A' ? parseInt(document.getElementById("speedA").value) : parseInt(document.getElementById("speedB").value);
fetch('/control?motor=' + motor + '&dir=' + dir + '&speed=' + speed)
.then(response => {
if (response.status === 200) {
updateStatus();
}
});
}
function updateStatus() {
fetch('/status')
.then(res => res.json())
.then(data => {
document.getElementById("curSpeedA").innerText = data.speedA;
document.getElementById("curDirA").innerText = data.dirA;
document.getElementById("curSpeedB").innerText = data.speedB;
document.getElementById("curDirB").innerText = data.dirB;
});
}
setInterval(updateStatus, 1000); // 每秒更新一次状态
window.onload = updateStatus;
</script>
</body>
</html>
)rawliteral";
server.send(200, "text/html", html);
}
// 处理控制命令 /control?motor=A&dir=forward&speed=128
void handleControl() {
if (server.hasArg("motor") && server.hasArg("dir") && server.hasArg("speed")) {
char motor = server.arg("motor")[0];
String dir = server.arg("dir");
int speed = server.arg("speed").toInt();
speed = constrain(speed, 0, 255);
if (motor == 'A') {
if (dir == "forward") motorA_forward(speed);
else if (dir == "backward") motorA_backward(speed);
else motorA_stop();
} else if (motor == 'B') {
if (dir == "forward") motorB_forward(speed);
else if (dir == "backward") motorB_backward(speed);
else motorB_stop();
}
}
server.send(200, "text/plain", "OK");
}
// 返回当前状态 /status
void handleStatus() {
String json = "{"
"\"speedA\":" + String(speedA) + ","
"\"speedB\":" + String(speedB) + ","
"\"dirA\":\"" + dirA + "\","
"\"dirB\":\"" + dirB + "\""
"}";
server.send(200, "application/json", json);
}
void setup() {
Serial.begin(115200);
Serial.println("\n启动中...");
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(STBY, OUTPUT);
// 初始化PWM
ledcSetup(PWM_CHANNEL_A, PWM_FREQ, PWM_RESOLUTION);
ledcSetup(PWM_CHANNEL_B, PWM_FREQ, PWM_RESOLUTION);
ledcAttachPin(PWMA, PWM_CHANNEL_A);
ledcAttachPin(PWMB, PWM_CHANNEL_B);
digitalWrite(STBY, HIGH); // 启用TB6612FNG
// 连接WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// 设置路由
server.on("/", handleRoot);
server.on("/control", handleControl);
server.on("/status", handleStatus);
server.begin();
Serial.println("HTTP Server Started");
}
void loop() {
server.handleClient();
}
引脚连接图
最新发布