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
![](2023-12-04-18-30-29.png)
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
![](2025-12-06-14-56-46.png)
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