047e5799f873b701e3d5cdd2ce874a40669824b9
Board-dat/NWI/NWI1243-dat/NWI1243-dat.md
| ... | ... | @@ -21,6 +21,8 @@ |
| 21 | 21 | |
| 22 | 22 | - schematic see here: [[ESP32-S3-Board-DAT]] |
| 23 | 23 | |
| 24 | + |
|
| 25 | + |
|
| 24 | 26 | resources |
| 25 | 27 | |
| 26 | 28 | - [[WS2812-dat]] - GPIO48 |
| ... | ... | @@ -34,4 +36,7 @@ resources |
| 34 | 36 | |
| 35 | 37 | - [[ESP32-S3-dat]] - [[NWI1243]] |
| 36 | 38 | |
| 37 | -- [[kicad-sch-dat]] |
|
| ... | ... | \ No newline at end of file |
| 0 | +- [[kicad-sch-dat]] |
|
| 1 | + |
|
| 2 | + |
|
| 3 | + |
Tech-dat/acturator-dat/motor-dat/motor-brushed-dat/Motor-reduction-Gear-dat/N20-motor-dat/N20-motor-dat.md
| ... | ... | @@ -58,6 +58,10 @@ RPM |
| 58 | 58 |  |
| 59 | 59 | |
| 60 | 60 | |
| 61 | + |
|
| 62 | + |
|
| 63 | + |
|
| 64 | + |
|
| 61 | 65 | ## ref |
| 62 | 66 | |
| 63 | 67 | - [[dc-gear-motor-dat]] |
Tech-dat/acturator-dat/motor-dat/servo-dat/servo-dat.md
| ... | ... | @@ -175,6 +175,16 @@ Fine-tune by sending 1500 µs and adjusting slightly if needed. |
| 175 | 175 | - [[worm-gear-dat]] |
| 176 | 176 | |
| 177 | 177 | |
| 178 | +## servo 360 degree |
|
| 179 | + |
|
| 180 | +360度舵机:实际相当于无极变速的减速电机,可以控制速度和方向。没有0-360度角度控制的功能。控制方式和一般舵机的控制信号相同。是瓦力改装的合适动力源 |
|
| 181 | + |
|
| 182 | + |
|
| 183 | +- 高电平为1毫秒~1.5毫秒时,舵机正转(1毫秒时正转速度最快,越接近1.5毫秒越慢,1.5毫秒时舵机停转), |
|
| 184 | +- 高电平为1.5毫秒~2毫秒时舵机反转(1.5毫秒时舵机停转,越接近2毫秒反转的速度越快,2毫秒时以最快的速度反转) |
|
| 185 | + |
|
| 186 | +- [[N20-motor-dat]] |
|
| 187 | + |
|
| 178 | 188 | |
| 179 | 189 | ## demo |
| 180 | 190 | |
| ... | ... | @@ -206,6 +216,12 @@ connector to a [[crank-dat]] |
| 206 | 216 | 35KG version |
| 207 | 217 |  |
| 208 | 218 | |
| 219 | + |
|
| 220 | + |
|
| 221 | + |
|
| 222 | + |
|
| 223 | + |
|
| 224 | + |
|
| 209 | 225 | ## ref |
| 210 | 226 | |
| 211 | 227 | - [[motor-dat]] |
code-dat/motor-driver-code-dat/dual-foot-dat/dual-foot-1.ino
| ... | ... | @@ -0,0 +1,183 @@ |
| 1 | +#include <WiFi.h> |
|
| 2 | +#include <WebServer.h> |
|
| 3 | +#include <ESP32Servo.h> |
|
| 4 | + |
|
| 5 | +// ===== WiFi 配置 ===== |
|
| 6 | +const char* ssid = "motor_control"; |
|
| 7 | +const char* password = "electrodragon"; |
|
| 8 | + |
|
| 9 | +// ===== DRV8871 / GPIO 定义 (ESP32) ===== |
|
| 10 | +// DRV8871 has two inputs IN1 and IN2. Set both to control direction. |
|
| 11 | +// Forward: IN1=HIGH, IN2=LOW |
|
| 12 | +// Reverse: IN1=LOW, IN2=HIGH |
|
| 13 | +// Stop: IN1=LOW, IN2=LOW (or both HIGH for brake) |
|
| 14 | +const int IN1_PIN = 15; // IN1 -> IO15 |
|
| 15 | +const int IN2_PIN = 18; // IN2 -> IO18 |
|
| 16 | + |
|
| 17 | +// Servo pins (GPIO numbers) |
|
| 18 | +const int SERVO1_PIN = 11; |
|
| 19 | +const int SERVO2_PIN = 12; |
|
| 20 | +const int SERVO3_PIN = 13; |
|
| 21 | +const int SERVO4_PIN = 14; |
|
| 22 | + |
|
| 23 | +// ===== Web Server ===== |
|
| 24 | +WebServer server(80); |
|
| 25 | + |
|
| 26 | +// Servo objects |
|
| 27 | +Servo servo1; |
|
| 28 | +Servo servo2; |
|
| 29 | +Servo servo3; |
|
| 30 | +Servo servo4; |
|
| 31 | + |
|
| 32 | +// ===== HTML Web 控制界面 ===== |
|
| 33 | +const char html_page[] PROGMEM = R"rawliteral( |
|
| 34 | +<!DOCTYPE html><html> |
|
| 35 | +<head> |
|
| 36 | +<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
| 37 | +<title>ESP32 Motor Control (DRV8871)</title> |
|
| 38 | +<style> |
|
| 39 | +body { font-family: Arial, sans-serif; max-width: 480px; margin: 0 auto; padding: 20px; background-color: #f0f0f0; } |
|
| 40 | +h2 { text-align:center; color:#333; } |
|
| 41 | +.container { display:flex; flex-direction:column; gap:14px; } |
|
| 42 | +.control-panel { background:white; padding:20px; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.08); display:flex; gap:10px; justify-content:center; } |
|
| 43 | +.servo-panel { background:white; padding:14px; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.04); display:flex; gap:8px; justify-content:center; } |
|
| 44 | +.dir-btn { padding:16px 22px; font-size:18px; font-weight:bold; border:none; border-radius:8px; cursor:pointer; } |
|
| 45 | +.sml-btn { padding:10px 14px; font-size:14px; font-weight:bold; border:none; border-radius:6px; cursor:pointer; } |
|
| 46 | +.forward-btn { background:#2196F3; color:white; } |
|
| 47 | +.reverse-btn { background:#FF9800; color:white; } |
|
| 48 | +.stop-btn { background:#f44336; color:white; } |
|
| 49 | +.s90-btn { background:#4CAF50; color:white; } |
|
| 50 | +.s180-btn { background:#9C27B0; color:white; } |
|
| 51 | +.dir-btn:active, .sml-btn:active { transform:scale(0.97); opacity:0.9; } |
|
| 52 | +@media (max-width:420px){ .control-panel{flex-direction:column;} } |
|
| 53 | +</style> |
|
| 54 | +</head> |
|
| 55 | +<body> |
|
| 56 | +<h2>Motor Control</h2> |
|
| 57 | +<div class="container"> |
|
| 58 | + <div class="control-panel"> |
|
| 59 | + <button class="dir-btn forward-btn" onclick="sendCmd('fw')">Forward</button> |
|
| 60 | + <button class="dir-btn stop-btn" onclick="sendCmd('st')">STOP</button> |
|
| 61 | + <button class="dir-btn reverse-btn" onclick="sendCmd('rv')">Reverse</button> |
|
| 62 | + </div> |
|
| 63 | + <div class="servo-panel"> |
|
| 64 | + <div style="align-self:center;font-weight:bold">Servo14:</div> |
|
| 65 | + <button class="sml-btn s90-btn" onclick="sendCmd('s90')">90°</button> |
|
| 66 | + <button class="sml-btn s180-btn" onclick="sendCmd('s180')">180°</button> |
|
| 67 | + </div> |
|
| 68 | +</div> |
|
| 69 | +<script> |
|
| 70 | +function sendCmd(cmd){ |
|
| 71 | + fetch('/control?cmd='+cmd) |
|
| 72 | + .then(r=>{}) |
|
| 73 | + .catch(e=>console.error(e)); |
|
| 74 | +} |
|
| 75 | +</script> |
|
| 76 | +</body></html> |
|
| 77 | +)rawliteral"; |
|
| 78 | + |
|
| 79 | +// ===== 处理 Web 请求 ===== |
|
| 80 | +void handleRoot() { |
|
| 81 | + server.send(200, "text/html", html_page); |
|
| 82 | +} |
|
| 83 | + |
|
| 84 | +void handleControl() { |
|
| 85 | + // Simple command-based control: cmd=fw|rv|st|s90|s180 |
|
| 86 | + if (server.hasArg("cmd")) { |
|
| 87 | + String c = server.arg("cmd"); |
|
| 88 | + if (c == "fw") { |
|
| 89 | + // Forward: IN1=HIGH, IN2=LOW |
|
| 90 | + digitalWrite(IN1_PIN, HIGH); |
|
| 91 | + digitalWrite(IN2_PIN, LOW); |
|
| 92 | + Serial.println("Motor: Forward"); |
|
| 93 | + } else if (c == "rv") { |
|
| 94 | + // Reverse: IN1=LOW, IN2=HIGH |
|
| 95 | + digitalWrite(IN1_PIN, LOW); |
|
| 96 | + digitalWrite(IN2_PIN, HIGH); |
|
| 97 | + Serial.println("Motor: Reverse"); |
|
| 98 | + } else if (c == "st") { |
|
| 99 | + // Stop: both LOW |
|
| 100 | + digitalWrite(IN1_PIN, LOW); |
|
| 101 | + digitalWrite(IN2_PIN, LOW); |
|
| 102 | + Serial.println("Motor: Stop"); |
|
| 103 | + } else if (c == "s90") { |
|
| 104 | + // Servo4 to 90 degrees |
|
| 105 | + servo4.write(90); |
|
| 106 | + Serial.println("Servo14: 90°"); |
|
| 107 | + } else if (c == "s180") { |
|
| 108 | + // Servo4 to 180 degrees |
|
| 109 | + servo4.write(180); |
|
| 110 | + Serial.println("Servo14: 180°"); |
|
| 111 | + } |
|
| 112 | + } |
|
| 113 | + |
|
| 114 | + server.send(200, "text/plain", "OK"); |
|
| 115 | +} |
|
| 116 | + |
|
| 117 | +// ===== 初始化 ===== |
|
| 118 | +void setup() { |
|
| 119 | + Serial.begin(115200); |
|
| 120 | + delay(100); |
|
| 121 | + Serial.println("ESP32 DRV8871 AP Motor Controller starting..."); |
|
| 122 | + |
|
| 123 | + // Configure GPIO pins as outputs |
|
| 124 | + pinMode(IN1_PIN, OUTPUT); |
|
| 125 | + pinMode(IN2_PIN, OUTPUT); |
|
| 126 | + |
|
| 127 | + // 默认停止 (both LOW) |
|
| 128 | + digitalWrite(IN1_PIN, LOW); |
|
| 129 | + digitalWrite(IN2_PIN, LOW); |
|
| 130 | + |
|
| 131 | + // Attach servos and set to center (0°) |
|
| 132 | + servo1.attach(SERVO1_PIN); |
|
| 133 | + servo2.attach(SERVO2_PIN); |
|
| 134 | + servo3.attach(SERVO3_PIN); |
|
| 135 | + servo4.attach(SERVO4_PIN); |
|
| 136 | + |
|
| 137 | + servo1.write(0); |
|
| 138 | + servo2.write(0); |
|
| 139 | + servo3.write(0); |
|
| 140 | + servo4.write(0); |
|
| 141 | + |
|
| 142 | + // 启动为 WiFi AP 模式,使用固定 IP |
|
| 143 | + Serial.println("Starting WiFi AP..."); |
|
| 144 | + |
|
| 145 | + WiFi.disconnect(true); |
|
| 146 | + WiFi.mode(WIFI_AP); |
|
| 147 | + delay(100); |
|
| 148 | + |
|
| 149 | + bool apStarted = WiFi.softAP(ssid, password); |
|
| 150 | + if (!apStarted) { |
|
| 151 | + Serial.println("AP start failed! Retrying..."); |
|
| 152 | + delay(1000); |
|
| 153 | + WiFi.softAP(ssid, password); |
|
| 154 | + } |
|
| 155 | + |
|
| 156 | + delay(1000); |
|
| 157 | + IPAddress apIP(192, 168, 50, 1); |
|
| 158 | + IPAddress apGateway(192, 168, 50, 1); |
|
| 159 | + IPAddress apSubnet(255, 255, 255, 0); |
|
| 160 | + if (!WiFi.softAPConfig(apIP, apGateway, apSubnet)) { |
|
| 161 | + Serial.println("softAPConfig failed"); |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + delay(500); |
|
| 165 | + Serial.println(""); |
|
| 166 | + Serial.println("=========================="); |
|
| 167 | + Serial.print("AP SSID: "); |
|
| 168 | + Serial.println(ssid); |
|
| 169 | + Serial.print("AP Password: "); |
|
| 170 | + Serial.println(password); |
|
| 171 | + Serial.print("AP IP: "); |
|
| 172 | + Serial.println(WiFi.softAPIP()); |
|
| 173 | + Serial.println("=========================="); |
|
| 174 | + |
|
| 175 | + // Web 服务 |
|
| 176 | + server.on("/", handleRoot); |
|
| 177 | + server.on("/control", handleControl); |
|
| 178 | + server.begin(); |
|
| 179 | +} |
|
| 180 | + |
|
| 181 | +void loop() { |
|
| 182 | + server.handleClient(); |
|
| 183 | +} |
|
| ... | ... | \ No newline at end of file |
code-dat/motor-driver-code-dat/dual-foot-dat/esp32-web-pwm-motor-ap-1.ino
| ... | ... | @@ -0,0 +1,263 @@ |
| 1 | +#include <WiFi.h> |
|
| 2 | +#include <WebServer.h> |
|
| 3 | + |
|
| 4 | +// ===== WiFi 配置 ===== |
|
| 5 | +const char* ssid = "motor_control"; |
|
| 6 | +const char* password = "electrodragon"; |
|
| 7 | + |
|
| 8 | +// ===== DRV8871 / GPIO 定义 (ESP32) ===== |
|
| 9 | +// DRV8871 has two inputs IN1 and IN2. Set both to control direction. |
|
| 10 | +// Forward: IN1=HIGH, IN2=LOW |
|
| 11 | +// Reverse: IN1=LOW, IN2=HIGH |
|
| 12 | +// Stop: IN1=LOW, IN2=LOW (or both HIGH for brake) |
|
| 13 | +const int IN1_PIN = 15; // IN1 -> IO15 |
|
| 14 | +const int IN2_PIN = 18; // IN2 -> IO18 |
|
| 15 | + |
|
| 16 | +// ===== Web Server ===== |
|
| 17 | +WebServer server(80); |
|
| 18 | + |
|
| 19 | +// ===== HTML Web 控制界面 ===== |
|
| 20 | +const char html_page[] PROGMEM = R"rawliteral( |
|
| 21 | +<!DOCTYPE html><html> |
|
| 22 | +<head> |
|
| 23 | +<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
| 24 | +<title>ESP32 Motor Control (DRV8871)</title> |
|
| 25 | +<style> |
|
| 26 | +body { |
|
| 27 | + font-family: Arial, sans-serif; |
|
| 28 | + max-width: 600px; |
|
| 29 | + margin: 0 auto; |
|
| 30 | + padding: 20px; |
|
| 31 | + background-color: #f0f0f0; |
|
| 32 | +} |
|
| 33 | + |
|
| 34 | +h2 { |
|
| 35 | + text-align: center; |
|
| 36 | + color: #333; |
|
| 37 | +} |
|
| 38 | +.control-panel { |
|
| 39 | + background: white; |
|
| 40 | + padding: 20px; |
|
| 41 | + border-radius: 10px; |
|
| 42 | + box-shadow: 0 2px 10px rgba(0,0,0,0.1); |
|
| 43 | +} |
|
| 44 | +.section { |
|
| 45 | + margin-bottom: 25px; |
|
| 46 | +} |
|
| 47 | +.section-title { |
|
| 48 | + font-weight: bold; |
|
| 49 | + margin-bottom: 10px; |
|
| 50 | + font-size: 18px; |
|
| 51 | + color: #555; |
|
| 52 | +} |
|
| 53 | +.speed-buttons { |
|
| 54 | + display: grid; |
|
| 55 | + grid-template-columns: repeat(6, 1fr); |
|
| 56 | + gap: 8px; |
|
| 57 | + margin-bottom: 10px; |
|
| 58 | +} |
|
| 59 | +.speed-btn { |
|
| 60 | + padding: 15px 10px; |
|
| 61 | + font-size: 16px; |
|
| 62 | + font-weight: bold; |
|
| 63 | + border: 2px solid #4CAF50; |
|
| 64 | + background-color: white; |
|
| 65 | + color: #4CAF50; |
|
| 66 | + border-radius: 8px; |
|
| 67 | + cursor: pointer; |
|
| 68 | + transition: all 0.2s; |
|
| 69 | +} |
|
| 70 | +.speed-btn:active { |
|
| 71 | + background-color: #4CAF50; |
|
| 72 | + color: white; |
|
| 73 | + transform: scale(0.95); |
|
| 74 | +} |
|
| 75 | +.dir-buttons { |
|
| 76 | + display: grid; |
|
| 77 | + grid-template-columns: 1fr 1fr; |
|
| 78 | + gap: 10px; |
|
| 79 | +} |
|
| 80 | +.dir-btn { |
|
| 81 | + padding: 20px; |
|
| 82 | + font-size: 18px; |
|
| 83 | + font-weight: bold; |
|
| 84 | + border: none; |
|
| 85 | + border-radius: 8px; |
|
| 86 | + cursor: pointer; |
|
| 87 | + transition: all 0.2s; |
|
| 88 | +} |
|
| 89 | +.forward-btn { |
|
| 90 | + background-color: #2196F3; |
|
| 91 | + color: white; |
|
| 92 | +} |
|
| 93 | +.reverse-btn { |
|
| 94 | + background-color: #FF9800; |
|
| 95 | + color: white; |
|
| 96 | +} |
|
| 97 | +.dir-btn:active { |
|
| 98 | + transform: scale(0.95); |
|
| 99 | + opacity: 0.8; |
|
| 100 | +} |
|
| 101 | +.stop-btn { |
|
| 102 | + width: 100%; |
|
| 103 | + padding: 20px; |
|
| 104 | + font-size: 20px; |
|
| 105 | + font-weight: bold; |
|
| 106 | + background-color: #f44336; |
|
| 107 | + color: white; |
|
| 108 | + border: none; |
|
| 109 | + border-radius: 8px; |
|
| 110 | + cursor: pointer; |
|
| 111 | + margin-top: 20px; |
|
| 112 | +} |
|
| 113 | +.stop-btn:active { |
|
| 114 | + transform: scale(0.98); |
|
| 115 | + opacity: 0.8; |
|
| 116 | +} |
|
| 117 | +</style> |
|
| 118 | +</head> |
|
| 119 | +<body> |
|
| 120 | +<h2>Motor Control</h2> |
|
| 121 | +<div class="control-panel"> |
|
| 122 | + <div class="section"> |
|
| 123 | + <div class="section-title">Speed Control (0-10)</div> |
|
| 124 | + <div class="speed-buttons"> |
|
| 125 | + <button class="speed-btn" onclick="setSpeed(0)">0</button> |
|
| 126 | + <button class="speed-btn" onclick="setSpeed(1)">1</button> |
|
| 127 | + <button class="speed-btn" onclick="setSpeed(2)">2</button> |
|
| 128 | + <button class="speed-btn" onclick="setSpeed(3)">3</button> |
|
| 129 | + <button class="speed-btn" onclick="setSpeed(4)">4</button> |
|
| 130 | + <button class="speed-btn" onclick="setSpeed(5)">5</button> |
|
| 131 | + <button class="speed-btn" onclick="setSpeed(6)">6</button> |
|
| 132 | + <button class="speed-btn" onclick="setSpeed(7)">7</button> |
|
| 133 | + <button class="speed-btn" onclick="setSpeed(8)">8</button> |
|
| 134 | + <button class="speed-btn" onclick="setSpeed(9)">9</button> |
|
| 135 | + <button class="speed-btn" onclick="setSpeed(10)">10</button> |
|
| 136 | + </div> |
|
| 137 | + </div> |
|
| 138 | + <div class="section"> |
|
| 139 | + <div class="section-title">Direction Control</div> |
|
| 140 | + <div class="dir-buttons"> |
|
| 141 | + <button class="dir-btn forward-btn" onclick="setDirection('fw')">Forward</button> |
|
| 142 | + <button class="dir-btn reverse-btn" onclick="setDirection('rv')">Reverse</button> |
|
| 143 | + </div> |
|
| 144 | + </div> |
|
| 145 | + <button class="stop-btn" onclick="stopMotor()">STOP</button> |
|
| 146 | +</div> |
|
| 147 | +<script> |
|
| 148 | +let currentSpeed = 0; |
|
| 149 | +let currentDir = 'fw'; |
|
| 150 | +function setSpeed(speed) { |
|
| 151 | + currentSpeed = speed; |
|
| 152 | + sendControl(); |
|
| 153 | +} |
|
| 154 | +function setDirection(dir) { |
|
| 155 | + currentDir = dir; |
|
| 156 | + sendControl(); |
|
| 157 | +} |
|
| 158 | +function sendControl() { |
|
| 159 | + let pwmValue = Math.round((currentSpeed / 10) * 1023); |
|
| 160 | + fetch('/control?speed=' + pwmValue + '&dir=' + currentDir) |
|
| 161 | + .then(response => response.text()) |
|
| 162 | + .catch(error => console.error('Error:', error)); |
|
| 163 | +} |
|
| 164 | +function stopMotor() { |
|
| 165 | + currentSpeed = 0; |
|
| 166 | + fetch('/control?speed=0&dir=' + currentDir) |
|
| 167 | + .then(response => response.text()) |
|
| 168 | + .catch(error => console.error('Error:', error)); |
|
| 169 | +} |
|
| 170 | +</script> |
|
| 171 | +</body></html> |
|
| 172 | +)rawliteral"; |
|
| 173 | + |
|
| 174 | +// ===== 处理 Web 请求 ===== |
|
| 175 | +void handleRoot() { |
|
| 176 | + server.send(200, "text/html", html_page); |
|
| 177 | +} |
|
| 178 | + |
|
| 179 | +void handleControl() { |
|
| 180 | + // Check for direction control |
|
| 181 | + if (server.hasArg("dir")) { |
|
| 182 | + String d = server.arg("dir"); |
|
| 183 | + if (d == "fw") { |
|
| 184 | + // Forward: IN1=HIGH, IN2=LOW |
|
| 185 | + digitalWrite(IN1_PIN, HIGH); |
|
| 186 | + digitalWrite(IN2_PIN, LOW); |
|
| 187 | + Serial.println("Motor: Forward"); |
|
| 188 | + } else if (d == "rv") { |
|
| 189 | + // Reverse: IN1=LOW, IN2=HIGH |
|
| 190 | + digitalWrite(IN1_PIN, LOW); |
|
| 191 | + digitalWrite(IN2_PIN, HIGH); |
|
| 192 | + Serial.println("Motor: Reverse"); |
|
| 193 | + } |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + // Check for stop command |
|
| 197 | + if (server.hasArg("stop") || (server.hasArg("speed") && server.arg("speed").toInt() == 0)) { |
|
| 198 | + // Stop: both LOW |
|
| 199 | + digitalWrite(IN1_PIN, LOW); |
|
| 200 | + digitalWrite(IN2_PIN, LOW); |
|
| 201 | + Serial.println("Motor: Stop"); |
|
| 202 | + } |
|
| 203 | + |
|
| 204 | + server.sendHeader("Location", "/"); |
|
| 205 | + server.send(302, "text/plain", ""); |
|
| 206 | +} |
|
| 207 | + |
|
| 208 | +// ===== 初始化 ===== |
|
| 209 | +void setup() { |
|
| 210 | + Serial.begin(115200); |
|
| 211 | + delay(100); |
|
| 212 | + Serial.println("ESP32 DRV8871 AP Motor Controller starting..."); |
|
| 213 | + |
|
| 214 | + // Configure GPIO pins as outputs |
|
| 215 | + pinMode(IN1_PIN, OUTPUT); |
|
| 216 | + pinMode(IN2_PIN, OUTPUT); |
|
| 217 | + |
|
| 218 | + // 默认停止 (both LOW) |
|
| 219 | + digitalWrite(IN1_PIN, LOW); |
|
| 220 | + digitalWrite(IN2_PIN, LOW); |
|
| 221 | + |
|
| 222 | + // 启动为 WiFi AP 模式,使用固定 IP |
|
| 223 | + Serial.println("Starting WiFi AP..."); |
|
| 224 | + |
|
| 225 | + WiFi.disconnect(true); |
|
| 226 | + WiFi.mode(WIFI_AP); |
|
| 227 | + delay(100); |
|
| 228 | + |
|
| 229 | + bool apStarted = WiFi.softAP(ssid, password); |
|
| 230 | + if (!apStarted) { |
|
| 231 | + Serial.println("AP start failed! Retrying..."); |
|
| 232 | + delay(1000); |
|
| 233 | + WiFi.softAP(ssid, password); |
|
| 234 | + } |
|
| 235 | + |
|
| 236 | + delay(1000); |
|
| 237 | + IPAddress apIP(192, 168, 50, 1); |
|
| 238 | + IPAddress apGateway(192, 168, 50, 1); |
|
| 239 | + IPAddress apSubnet(255, 255, 255, 0); |
|
| 240 | + if (!WiFi.softAPConfig(apIP, apGateway, apSubnet)) { |
|
| 241 | + Serial.println("softAPConfig failed"); |
|
| 242 | + } |
|
| 243 | + |
|
| 244 | + delay(500); |
|
| 245 | + Serial.println(""); |
|
| 246 | + Serial.println("=========================="); |
|
| 247 | + Serial.print("AP SSID: "); |
|
| 248 | + Serial.println(ssid); |
|
| 249 | + Serial.print("AP Password: "); |
|
| 250 | + Serial.println(password); |
|
| 251 | + Serial.print("AP IP: "); |
|
| 252 | + Serial.println(WiFi.softAPIP()); |
|
| 253 | + Serial.println("=========================="); |
|
| 254 | + |
|
| 255 | + // Web 服务 |
|
| 256 | + server.on("/", handleRoot); |
|
| 257 | + server.on("/control", handleControl); |
|
| 258 | + server.begin(); |
|
| 259 | +} |
|
| 260 | + |
|
| 261 | +void loop() { |
|
| 262 | + server.handleClient(); |
|
| 263 | +} |
|
| ... | ... | \ No newline at end of file |
code-dat/motor-driver-code-dat/esp32-web-pwm-motor-ap-1.ino