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
![](47-08-17-21-06-2023.png)
... ...
@@ -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