5ba1dc2c0bfeb88d28b31f88912f24b6f961852e
Board-dat/Board-DAT.md
| ... | ... | @@ -436,6 +436,7 @@ MT7688 |
| 436 | 436 | |
| 437 | 437 | [[LAN8720-dat]] - [[NWI1199-DAT]] |
| 438 | 438 | |
| 439 | +[[ESP32-S3-dat]] - [[NWI1243-dat]] |
|
| 439 | 440 | |
| 440 | 441 | ### NRF |
| 441 | 442 |
Tech-dat/acturator-dat/motor-dat/servo-dat/servo-360-dat/servo-360-dat.md
| ... | ... | @@ -0,0 +1,44 @@ |
| 1 | + |
|
| 2 | +# servo-360-dat |
|
| 3 | + |
|
| 4 | + |
|
| 5 | +## servo 360 degree |
|
| 6 | + |
|
| 7 | +360° (continuous-rotation) servo |
|
| 8 | +A 360° servo is effectively a geared DC motor with continuous-variable speed and direction control — it does not provide absolute angle positioning. It uses the same PWM control signal as a regular hobby servo, but the pulse width controls motor speed and direction instead of shaft angle. (Commonly used as a power source for modified robots and drivetrains.) |
|
| 9 | + |
|
| 10 | +Control notes |
|
| 11 | + |
|
| 12 | +- Typical PWM time base: ~20 ms period (50 Hz). Pulse width (high time) is usually in the ~0.5–2.5 ms range; 1.5 ms is the neutral/stop point for many servos. |
|
| 13 | +- Behavior for continuous-rotation servos: |
|
| 14 | + - Pulse < center (e.g., 0.5 ms → 1.5 ms): forward rotation. The smaller the pulse, the faster the forward speed (0.5 ms → fastest forward). |
|
| 15 | + - ~1.5 ms: stop / neutral. |
|
| 16 | + - Pulse > center (e.g., 1.5 ms → 2.5 ms): reverse rotation. The larger the pulse, the faster the reverse speed (2.5 ms → fastest reverse). |
|
| 17 | +- Some servos use narrower ranges (e.g., 1.0–2.0 ms). Always check with a servo-tester or measure the actual response for the specific model. |
|
| 18 | + |
|
| 19 | +Example mapping (typical) |
|
| 20 | + |
|
| 21 | +- 0.5 ms — fastest forward |
|
| 22 | +- 1.0 ms — moderate forward |
|
| 23 | +- 1.5 ms — stop |
|
| 24 | +- 2.0 ms — moderate reverse |
|
| 25 | +- 2.5 ms — fastest reverse |
|
| 26 | + |
|
| 27 | +Arduino tip: use Servo.writeMicroseconds(x) to send precise pulse widths (e.g., 1000–2000 µs) and calibrate the stop point for your servo. |
|
| 28 | + |
|
| 29 | + |
|
| 30 | +- [[N20-motor-dat]] |
|
| 31 | + |
|
| 32 | +| Pulse (ms) | Pulse (µs) | Angle (°) | degree | |
|
| 33 | +| ---------: | ---------: | ---------: | ---------------- | |
|
| 34 | +| 0.5 ms | 500 µs | 0 | fastest forward | |
|
| 35 | +| 1.0 ms | 1000 µs | 45 | moderate forward | |
|
| 36 | +| 1.5 ms | 1500 µs | 90 | stop | |
|
| 37 | +| 2.0 ms | 2000 µs | 135 | moderate reverse | |
|
| 38 | +| 2.5 ms | 2500 µs | 180 or -90 | fastest reverse | |
|
| 39 | + |
|
| 40 | + |
|
| 41 | + |
|
| 42 | +## ref |
|
| 43 | + |
|
| 44 | +- [[servo-dat]] |
|
| ... | ... | \ No newline at end of file |
Tech-dat/acturator-dat/motor-dat/servo-dat/servo-dat.md
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | |
| 12 | 12 | - [[servo-HDK-dat]] - [[servo-SDK-dat]] |
| 13 | 13 | |
| 14 | - |
|
| 14 | +- [[servo-360-dat]] |
|
| 15 | 15 | |
| 16 | 16 | ## products |
| 17 | 17 | |
| ... | ... | @@ -67,11 +67,13 @@ The control of the steering gear generally requires a time base pulse of about 2 |
| 67 | 67 | |
| 68 | 68 | Taking the 180-degree angle servo as an example, the corresponding control relationship is as follows: |
| 69 | 69 | |
| 70 | -- 0.5ms------------ 0 degrees; |
|
| 71 | -- 1.0ms------------ 45 degrees; |
|
| 72 | -- 1.5ms------------ 90 degrees; |
|
| 73 | -- 2.0ms------------ 135 degrees; |
|
| 74 | -- 2.5ms------------ 180 degrees; |
|
| 70 | +| Pulse (ms) | Pulse (µs) | Angle (°) | |
|
| 71 | +| ---------: | ---------: | ---------: | |
|
| 72 | +| 0.5 ms | 500 µs | 0 | |
|
| 73 | +| 1.0 ms | 1000 µs | 45 | |
|
| 74 | +| 1.5 ms | 1500 µs | 90 | |
|
| 75 | +| 2.0 ms | 2000 µs | 135 | |
|
| 76 | +| 2.5 ms | 2500 µs | 180 or -90 | |
|
| 75 | 77 | |
| 76 | 78 | |
| 77 | 79 |  |
| ... | ... | @@ -155,34 +157,6 @@ Fine-tune by sending 1500 µs and adjusting slightly if needed. |
| 155 | 157 | - [[worm-gear-dat]] |
| 156 | 158 | |
| 157 | 159 | |
| 158 | -## servo 360 degree |
|
| 159 | - |
|
| 160 | -360° (continuous-rotation) servo |
|
| 161 | -A 360° servo is effectively a geared DC motor with continuous-variable speed and direction control — it does not provide absolute angle positioning. It uses the same PWM control signal as a regular hobby servo, but the pulse width controls motor speed and direction instead of shaft angle. (Commonly used as a power source for modified robots and drivetrains.) |
|
| 162 | - |
|
| 163 | -Control notes |
|
| 164 | - |
|
| 165 | -- Typical PWM time base: ~20 ms period (50 Hz). Pulse width (high time) is usually in the ~0.5–2.5 ms range; 1.5 ms is the neutral/stop point for many servos. |
|
| 166 | -- Behavior for continuous-rotation servos: |
|
| 167 | - - Pulse < center (e.g., 0.5 ms → 1.5 ms): forward rotation. The smaller the pulse, the faster the forward speed (0.5 ms → fastest forward). |
|
| 168 | - - ~1.5 ms: stop / neutral. |
|
| 169 | - - Pulse > center (e.g., 1.5 ms → 2.5 ms): reverse rotation. The larger the pulse, the faster the reverse speed (2.5 ms → fastest reverse). |
|
| 170 | -- Some servos use narrower ranges (e.g., 1.0–2.0 ms). Always check with a servo-tester or measure the actual response for the specific model. |
|
| 171 | - |
|
| 172 | -Example mapping (typical) |
|
| 173 | - |
|
| 174 | -- 0.5 ms — fastest forward |
|
| 175 | -- 1.0 ms — moderate forward |
|
| 176 | -- 1.5 ms — stop |
|
| 177 | -- 2.0 ms — moderate reverse |
|
| 178 | -- 2.5 ms — fastest reverse |
|
| 179 | - |
|
| 180 | -Arduino tip: use Servo.writeMicroseconds(x) to send precise pulse widths (e.g., 1000–2000 µs) and calibrate the stop point for your servo. |
|
| 181 | - |
|
| 182 | - |
|
| 183 | -- [[N20-motor-dat]] |
|
| 184 | - |
|
| 185 | - |
|
| 186 | 160 | ## demo |
| 187 | 161 | |
| 188 | 162 | https://t.me/electrodragon3/401 |
code-dat/motor-driver-code-dat/dual-foot-dat/dual-foot-2.ino
| ... | ... | @@ -74,7 +74,8 @@ h2 { text-align:center; color:#333; } |
| 74 | 74 | <div class="servo-panel"> |
| 75 | 75 | <div style="align-self:center;font-weight:bold">Servo14:</div> |
| 76 | 76 | <button class="sml-btn s90-btn" onclick="sendCmd('s90')">90°</button> |
| 77 | - <button class="sml-btn s180-btn" onclick="sendCmd('s-90')">-90°</button> |
|
| 77 | + <button class="sml-btn s180-btn" onclick="sendCmd('s180')">180°</button> |
|
| 78 | + <button class="sml-btn stop-btn" onclick="sendCmd('s0')">0°</button> |
|
| 78 | 79 | </div> |
| 79 | 80 | <div class="relay-panel"> |
| 80 | 81 | <div class="relay-item"><div style="font-weight:bold">Relay1:</div><button class="relay-btn on-btn" onclick="sendCmd('r1_on')">ON</button><button class="relay-btn off-btn" onclick="sendCmd('r1_off')">OFF</button></div> |
| ... | ... | @@ -99,7 +100,7 @@ void handleRoot() { |
| 99 | 100 | } |
| 100 | 101 | |
| 101 | 102 | void handleControl() { |
| 102 | - // Simple command-based control: cmd=fw|rv|st|s90|s-90|rX_on|rX_off |
|
| 103 | + // Simple command-based control: cmd=fw|rv|st|s90|s180|s0|rX_on|rX_off |
|
| 103 | 104 | if (server.hasArg("cmd")) { |
| 104 | 105 | String c = server.arg("cmd"); |
| 105 | 106 | if (c == "fw") { |
| ... | ... | @@ -121,10 +122,14 @@ void handleControl() { |
| 121 | 122 | // Servo4 to 90 degrees |
| 122 | 123 | servo4.write(90); |
| 123 | 124 | Serial.println("Servo14: 90°"); |
| 124 | - } else if (c == "s-90") { |
|
| 125 | - // Servo4 to -90 degrees |
|
| 126 | - servo4.write(-90); |
|
| 127 | - Serial.println("Servo14: -90°"); |
|
| 125 | + } else if (c == "s180") { |
|
| 126 | + // Servo4 to 180 degrees |
|
| 127 | + servo4.write(180); |
|
| 128 | + Serial.println("Servo14: 180°"); |
|
| 129 | + } else if (c == "s0") { |
|
| 130 | + // Servo4 to 0 degrees (center/stop) |
|
| 131 | + servo4.write(0); |
|
| 132 | + Serial.println("Servo14: 0°"); |
|
| 128 | 133 | } else if (c == "r1_on") { |
| 129 | 134 | digitalWrite(RELAY1_PIN, HIGH); |
| 130 | 135 | Serial.println("Relay1: ON"); |
| ... | ... | @@ -191,11 +196,6 @@ void setup() { |
| 191 | 196 | servo4.write(0); |
| 192 | 197 | |
| 193 | 198 | // 启动为 WiFi AP 模式,使用固定 IP |
| 194 | - Serial.println("Starting WiFi AP..."); |
|
| 195 | - |
|
| 196 | - WiFi.disconnect(true); |
|
| 197 | - WiFi.mode(WIFI_AP); |
|
| 198 | - delay(100); |
|
| 199 | 199 | |
| 200 | 200 | bool apStarted = WiFi.softAP(ssid, password); |
| 201 | 201 | if (!apStarted) { |
code-dat/motor-driver-code-dat/dual-foot-dat/dual-foot-3.ino
| ... | ... | @@ -0,0 +1,271 @@ |
| 1 | +// add IO35 == LED, IO48 == WS2812 to code, and apply functions: LED for motors, IO48 for servos |
|
| 2 | + |
|
| 3 | +#include <WiFi.h> |
|
| 4 | +#include <WebServer.h> |
|
| 5 | +#include <ESP32Servo.h> |
|
| 6 | +#include <Adafruit_NeoPixel.h> |
|
| 7 | + |
|
| 8 | +// ===== WiFi 配置 ===== |
|
| 9 | +const char* ssid = "motor_control"; |
|
| 10 | +const char* password = "electrodragon"; |
|
| 11 | + |
|
| 12 | +// ===== DRV8871 / GPIO 定义 (ESP32) ===== |
|
| 13 | +// DRV8871 has two inputs IN1 and IN2. Set both to control direction. |
|
| 14 | +// Forward: IN1=HIGH, IN2=LOW |
|
| 15 | +// Reverse: IN1=LOW, IN2=HIGH |
|
| 16 | +// Stop: IN1=LOW, IN2=LOW (or both HIGH for brake) |
|
| 17 | +const int IN1_PIN = 15; // IN1 -> IO15 |
|
| 18 | +const int IN2_PIN = 18; // IN2 -> IO18 |
|
| 19 | + |
|
| 20 | +// Servo pins (GPIO numbers) |
|
| 21 | +const int SERVO1_PIN = 11; |
|
| 22 | +const int SERVO2_PIN = 12; |
|
| 23 | +const int SERVO3_PIN = 13; |
|
| 24 | +const int SERVO4_PIN = 14; |
|
| 25 | + |
|
| 26 | +// Relay pins (GPIO numbers) for ON/OFF control |
|
| 27 | +const int RELAY1_PIN = 5; |
|
| 28 | +const int RELAY2_PIN = 6; |
|
| 29 | +const int RELAY3_PIN = 19; |
|
| 30 | +const int RELAY4_PIN = 20; |
|
| 31 | + |
|
| 32 | +// New: motor status input (IO35 is input-only on many ESP32 boards) |
|
| 33 | +const int MOTOR_STATUS_PIN = 35; // read-only, used to observe motor/driver state |
|
| 34 | + |
|
| 35 | +// New: WS2812 (NeoPixel) for servo status |
|
| 36 | +const int WS2812_PIN = 48; // user requested IO48 |
|
| 37 | +const int NUM_PIXELS = 1; |
|
| 38 | +Adafruit_NeoPixel pixels(NUM_PIXELS, WS2812_PIN, NEO_GRB + NEO_KHZ800); |
|
| 39 | + |
|
| 40 | +// ===== Web Server ===== |
|
| 41 | +WebServer server(80); |
|
| 42 | + |
|
| 43 | +// Servo objects |
|
| 44 | +Servo servo1; |
|
| 45 | +Servo servo2; |
|
| 46 | +Servo servo3; |
|
| 47 | +Servo servo4; |
|
| 48 | + |
|
| 49 | +// ===== HTML Web 控制界面 ===== |
|
| 50 | +const char html_page[] PROGMEM = R"rawliteral( |
|
| 51 | +<!DOCTYPE html><html> |
|
| 52 | +<head> |
|
| 53 | +<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
| 54 | +<title>ESP32 Motor & Relay Control</title> |
|
| 55 | +<style> |
|
| 56 | +body { font-family: Arial, sans-serif; max-width: 640px; margin: 0 auto; padding: 20px; background-color: #f0f0f0; } |
|
| 57 | +h2 { text-align:center; color:#333; } |
|
| 58 | +.container { display:flex; flex-direction:column; gap:14px; } |
|
| 59 | +.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; } |
|
| 60 | +.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; } |
|
| 61 | +.relay-panel { background:white; padding:14px; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.04); display:flex; gap:8px; flex-wrap:wrap; justify-content:center; } |
|
| 62 | +.dir-btn { padding:16px 22px; font-size:18px; font-weight:bold; border:none; border-radius:8px; cursor:pointer; } |
|
| 63 | +.sml-btn { padding:10px 14px; font-size:14px; font-weight:bold; border:none; border-radius:6px; cursor:pointer; } |
|
| 64 | +.relay-btn { padding:10px 12px; font-size:14px; font-weight:bold; border:none; border-radius:6px; cursor:pointer; } |
|
| 65 | +.forward-btn { background:#2196F3; color:white; } |
|
| 66 | +.reverse-btn { background:#FF9800; color:white; } |
|
| 67 | +.stop-btn { background:#f44336; color:white; } |
|
| 68 | +.s90-btn { background:#4CAF50; color:white; } |
|
| 69 | +.s180-btn { background:#9C27B0; color:white; } |
|
| 70 | +.on-btn { background:#4CAF50; color:white; } |
|
| 71 | +.off-btn { background:#f44336; color:white; } |
|
| 72 | +.dir-btn:active, .sml-btn:active, .relay-btn:active { transform:scale(0.97); opacity:0.9; } |
|
| 73 | +.relay-item { display:flex; gap:6px; align-items:center; } |
|
| 74 | +@media (max-width:420px){ .control-panel{flex-direction:column;} } |
|
| 75 | +</style> |
|
| 76 | +</head> |
|
| 77 | +<body> |
|
| 78 | +<h2>Motor & Relay Control</h2> |
|
| 79 | +<div class="container"> |
|
| 80 | + <div class="control-panel"> |
|
| 81 | + <button class="dir-btn forward-btn" onclick="sendCmd('fw')">Forward</button> |
|
| 82 | + <button class="dir-btn stop-btn" onclick="sendCmd('st')">STOP</button> |
|
| 83 | + <button class="dir-btn reverse-btn" onclick="sendCmd('rv')">Reverse</button> |
|
| 84 | + </div> |
|
| 85 | + <div class="servo-panel"> |
|
| 86 | + <div style="align-self:center;font-weight:bold">Servo14:</div> |
|
| 87 | + <button class="sml-btn s90-btn" onclick="sendCmd('s90')">90°</button> |
|
| 88 | + <button class="sml-btn s180-btn" onclick="sendCmd('s180')">180°</button> |
|
| 89 | + <button class="sml-btn stop-btn" onclick="sendCmd('s0')">0°</button> |
|
| 90 | + </div> |
|
| 91 | + <div class="relay-panel"> |
|
| 92 | + <div class="relay-item"><div style="font-weight:bold">Relay1:</div><button class="relay-btn on-btn" onclick="sendCmd('r1_on')">ON</button><button class="relay-btn off-btn" onclick="sendCmd('r1_off')">OFF</button></div> |
|
| 93 | + <div class="relay-item"><div style="font-weight:bold">Relay2:</div><button class="relay-btn on-btn" onclick="sendCmd('r2_on')">ON</button><button class="relay-btn off-btn" onclick="sendCmd('r2_off')">OFF</button></div> |
|
| 94 | + <div class="relay-item"><div style="font-weight:bold">Relay3:</div><button class="relay-btn on-btn" onclick="sendCmd('r3_on')">ON</button><button class="relay-btn off-btn" onclick="sendCmd('r3_off')">OFF</button></div> |
|
| 95 | + <div class="relay-item"><div style="font-weight:bold">Relay4:</div><button class="relay-btn on-btn" onclick="sendCmd('r4_on')">ON</button><button class="relay-btn off-btn" onclick="sendCmd('r4_off')">OFF</button></div> |
|
| 96 | + </div> |
|
| 97 | +</div> |
|
| 98 | +<script> |
|
| 99 | +function sendCmd(cmd){ |
|
| 100 | + fetch('/control?cmd='+cmd) |
|
| 101 | + .then(r=>{}) |
|
| 102 | + .catch(e=>console.error(e)); |
|
| 103 | +} |
|
| 104 | +</script> |
|
| 105 | +</body></html> |
|
| 106 | +)rawliteral"; |
|
| 107 | + |
|
| 108 | +// ===== 处理 Web 请求 ===== |
|
| 109 | +void handleRoot() { |
|
| 110 | + server.send(200, "text/html", html_page); |
|
| 111 | +} |
|
| 112 | + |
|
| 113 | +void handleControl() { |
|
| 114 | + // Simple command-based control: cmd=fw|rv|st|s90|s180|s0|rX_on|rX_off |
|
| 115 | + if (server.hasArg("cmd")) { |
|
| 116 | + String c = server.arg("cmd"); |
|
| 117 | + if (c == "fw") { |
|
| 118 | + // Forward: IN1=HIGH, IN2=LOW |
|
| 119 | + digitalWrite(IN1_PIN, HIGH); |
|
| 120 | + digitalWrite(IN2_PIN, LOW); |
|
| 121 | + Serial.println("Motor: Forward"); |
|
| 122 | + // read motor status input and log |
|
| 123 | + int mstat = digitalRead(MOTOR_STATUS_PIN); |
|
| 124 | + Serial.print("MOTOR_STATUS (IO35): "); Serial.println(mstat==HIGH?"HIGH":"LOW"); |
|
| 125 | + } else if (c == "rv") { |
|
| 126 | + // Reverse: IN1=LOW, IN2=HIGH |
|
| 127 | + digitalWrite(IN1_PIN, LOW); |
|
| 128 | + digitalWrite(IN2_PIN, HIGH); |
|
| 129 | + Serial.println("Motor: Reverse"); |
|
| 130 | + int mstat = digitalRead(MOTOR_STATUS_PIN); |
|
| 131 | + Serial.print("MOTOR_STATUS (IO35): "); Serial.println(mstat==HIGH?"HIGH":"LOW"); |
|
| 132 | + } else if (c == "st") { |
|
| 133 | + // Stop: both LOW |
|
| 134 | + digitalWrite(IN1_PIN, LOW); |
|
| 135 | + digitalWrite(IN2_PIN, LOW); |
|
| 136 | + Serial.println("Motor: Stop"); |
|
| 137 | + int mstat = digitalRead(MOTOR_STATUS_PIN); |
|
| 138 | + Serial.print("MOTOR_STATUS (IO35): "); Serial.println(mstat==HIGH?"HIGH":"LOW"); |
|
| 139 | + } else if (c == "s90") { |
|
| 140 | + // Servo4 to 90 degrees |
|
| 141 | + servo4.write(90); |
|
| 142 | + Serial.println("Servo14: 90°"); |
|
| 143 | + // indicate servo action on WS2812 (green) |
|
| 144 | + setServoPixel(0, 200, 0); |
|
| 145 | + } else if (c == "s180") { |
|
| 146 | + // Servo4 to 180 degrees |
|
| 147 | + servo4.write(180); |
|
| 148 | + Serial.println("Servo14: 180°"); |
|
| 149 | + // indicate servo action on WS2812 (purple) |
|
| 150 | + setServoPixel(150, 0, 150); |
|
| 151 | + } else if (c == "s0") { |
|
| 152 | + // Servo4 to 0 degrees (center/stop) |
|
| 153 | + servo4.write(0); |
|
| 154 | + Serial.println("Servo14: 0°"); |
|
| 155 | + // turn pixel off |
|
| 156 | + setServoPixel(0, 0, 0); |
|
| 157 | + } else if (c == "r1_on") { |
|
| 158 | + digitalWrite(RELAY1_PIN, HIGH); |
|
| 159 | + Serial.println("Relay1: ON"); |
|
| 160 | + } else if (c == "r1_off") { |
|
| 161 | + digitalWrite(RELAY1_PIN, LOW); |
|
| 162 | + Serial.println("Relay1: OFF"); |
|
| 163 | + } else if (c == "r2_on") { |
|
| 164 | + digitalWrite(RELAY2_PIN, HIGH); |
|
| 165 | + Serial.println("Relay2: ON"); |
|
| 166 | + } else if (c == "r2_off") { |
|
| 167 | + digitalWrite(RELAY2_PIN, LOW); |
|
| 168 | + Serial.println("Relay2: OFF"); |
|
| 169 | + } else if (c == "r3_on") { |
|
| 170 | + digitalWrite(RELAY3_PIN, HIGH); |
|
| 171 | + Serial.println("Relay3: ON"); |
|
| 172 | + } else if (c == "r3_off") { |
|
| 173 | + digitalWrite(RELAY3_PIN, LOW); |
|
| 174 | + Serial.println("Relay3: OFF"); |
|
| 175 | + } else if (c == "r4_on") { |
|
| 176 | + digitalWrite(RELAY4_PIN, HIGH); |
|
| 177 | + Serial.println("Relay4: ON"); |
|
| 178 | + } else if (c == "r4_off") { |
|
| 179 | + digitalWrite(RELAY4_PIN, LOW); |
|
| 180 | + Serial.println("Relay4: OFF"); |
|
| 181 | + } |
|
| 182 | + } |
|
| 183 | + |
|
| 184 | + server.send(200, "text/plain", "OK"); |
|
| 185 | +} |
|
| 186 | + |
|
| 187 | +// helper: set single pixel color |
|
| 188 | +void setServoPixel(uint8_t r, uint8_t g, uint8_t b) { |
|
| 189 | + pixels.setPixelColor(0, pixels.Color(r, g, b)); |
|
| 190 | + pixels.show(); |
|
| 191 | +} |
|
| 192 | + |
|
| 193 | +// ===== 初始化 ===== |
|
| 194 | +void setup() { |
|
| 195 | + Serial.begin(115200); |
|
| 196 | + delay(100); |
|
| 197 | + Serial.println("ESP32 DRV8871 AP Motor Controller starting..."); |
|
| 198 | + |
|
| 199 | + // Configure GPIO pins as outputs |
|
| 200 | + pinMode(IN1_PIN, OUTPUT); |
|
| 201 | + pinMode(IN2_PIN, OUTPUT); |
|
| 202 | + |
|
| 203 | + // Relay pins |
|
| 204 | + pinMode(RELAY1_PIN, OUTPUT); |
|
| 205 | + pinMode(RELAY2_PIN, OUTPUT); |
|
| 206 | + pinMode(RELAY3_PIN, OUTPUT); |
|
| 207 | + pinMode(RELAY4_PIN, OUTPUT); |
|
| 208 | + |
|
| 209 | + // New: motor status pin as input |
|
| 210 | + pinMode(MOTOR_STATUS_PIN, INPUT); |
|
| 211 | + |
|
| 212 | + // New: init NeoPixel for servo status |
|
| 213 | + pixels.begin(); |
|
| 214 | + pixels.show(); // clear |
|
| 215 | + |
|
| 216 | + // Default: stop motor and relays OFF (LOW) |
|
| 217 | + digitalWrite(IN1_PIN, LOW); |
|
| 218 | + digitalWrite(IN2_PIN, LOW); |
|
| 219 | + digitalWrite(RELAY1_PIN, LOW); |
|
| 220 | + digitalWrite(RELAY2_PIN, LOW); |
|
| 221 | + digitalWrite(RELAY3_PIN, LOW); |
|
| 222 | + digitalWrite(RELAY4_PIN, LOW); |
|
| 223 | + |
|
| 224 | + // Attach servos and set to center (0°) |
|
| 225 | + servo1.attach(SERVO1_PIN); |
|
| 226 | + servo2.attach(SERVO2_PIN); |
|
| 227 | + servo3.attach(SERVO3_PIN); |
|
| 228 | + servo4.attach(SERVO4_PIN); |
|
| 229 | + |
|
| 230 | + servo1.write(0); |
|
| 231 | + servo2.write(0); |
|
| 232 | + servo3.write(0); |
|
| 233 | + servo4.write(0); |
|
| 234 | + |
|
| 235 | + // 启动为 WiFi AP 模式,使用固定 IP |
|
| 236 | + |
|
| 237 | + bool apStarted = WiFi.softAP(ssid, password); |
|
| 238 | + if (!apStarted) { |
|
| 239 | + Serial.println("AP start failed! Retrying..."); |
|
| 240 | + delay(1000); |
|
| 241 | + WiFi.softAP(ssid, password); |
|
| 242 | + } |
|
| 243 | + |
|
| 244 | + delay(1000); |
|
| 245 | + IPAddress apIP(192, 168, 50, 1); |
|
| 246 | + IPAddress apGateway(192, 168, 50, 1); |
|
| 247 | + IPAddress apSubnet(255, 255, 255, 0); |
|
| 248 | + if (!WiFi.softAPConfig(apIP, apGateway, apSubnet)) { |
|
| 249 | + Serial.println("softAPConfig failed"); |
|
| 250 | + } |
|
| 251 | + |
|
| 252 | + delay(500); |
|
| 253 | + Serial.println(""); |
|
| 254 | + Serial.println("=========================="); |
|
| 255 | + Serial.print("AP SSID: "); |
|
| 256 | + Serial.println(ssid); |
|
| 257 | + Serial.print("AP Password: "); |
|
| 258 | + Serial.println(password); |
|
| 259 | + Serial.print("AP IP: "); |
|
| 260 | + Serial.println(WiFi.softAPIP()); |
|
| 261 | + Serial.println("=========================="); |
|
| 262 | + |
|
| 263 | + // Web 服务 |
|
| 264 | + server.on("/", handleRoot); |
|
| 265 | + server.on("/control", handleControl); |
|
| 266 | + server.begin(); |
|
| 267 | +} |
|
| 268 | + |
|
| 269 | +void loop() { |
|
| 270 | + server.handleClient(); |
|
| 271 | +} |
|
| ... | ... | \ No newline at end of file |