-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcar_final_code.ino
More file actions
174 lines (148 loc) · 4.7 KB
/
Copy pathcar_final_code.ino
File metadata and controls
174 lines (148 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <WiFi.h>
#include <WebServer.h>
// ----- CONFIGURE THESE PINS -----
const int IN1 = 27; // Steering motor IN1
const int IN2 = 26; // Steering motor IN2
const int IN3 = 25; // Drive motor IN3
const int IN4 = 33; // Drive motor IN4
// --------------------------------
// PWM settings
const int PWM_FREQ = 1000; // 1 kHz safe for MX1508
const int PWM_BITS = 8; // 8-bit resolution: 0-255
// PWM channels
const int CH_IN1 = 0;
const int CH_IN2 = 1;
const int CH_IN3 = 2;
const int CH_IN4 = 3;
WebServer server(80);
// Default speeds (0-255)
int driveSpeed = 128; // Forward/Reverse default 50%
int steerSpeed = 255; // Left/Right default ~100%
// Mobile web UI
const char* htmlPage = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align:center; margin-top:20px; }
button { width:160px; height:60px; font-size:20px; margin:8px; }
input[type=range] { width:80%; }
</style>
</head>
<body>
<h2>ESP32 Car Control</h2>
<p>Drive Speed: <span id="driveTxt">50</span>%</p>
<input id="driveSpeed" type="range" min="0" max="100" value="50"
oninput="updateSpeed('drive', this.value)">
<p>Steering Speed: <span id="steerTxt">90</span>%</p>
<input id="steerSpeed" type="range" min="0" max="100" value="100"
oninput="updateSpeed('steer', this.value)">
<p>
<button id="fwd" ontouchstart="hold('forward')" ontouchend="release()"
onmousedown="hold('forward')" onmouseup="release()">Forward</button><br>
<button id="left" ontouchstart="hold('left')" ontouchend="release()"
onmousedown="hold('left')" onmouseup="release()">Left</button>
<button id="right" ontouchstart="hold('right')" ontouchend="release()"
onmousedown="hold('right')" onmouseup="release()">Right</button><br>
<button id="rev" ontouchstart="hold('reverse')" ontouchend="release()"
onmousedown="hold('reverse')" onmouseup="release()">Reverse</button>
</p>
<script>
function hold(cmd) {
fetch('/move?dir=' + cmd);
}
function release() {
fetch('/stop');
}
function updateSpeed(type, val) {
if(type === 'drive') {
document.getElementById('driveTxt').innerText = val;
} else {
document.getElementById('steerTxt').innerText = val;
}
fetch('/speed?type=' + type + '&val=' + val);
}
</script>
</body>
</html>
)rawliteral";
// ---------- Motor control ----------
void stopAll() {
ledcWrite(CH_IN1, 0);
ledcWrite(CH_IN2, 0);
ledcWrite(CH_IN3, 0);
ledcWrite(CH_IN4, 0);
}
// Swapped left/right directions
void steerLeft() {
ledcWrite(CH_IN1, 0);
ledcWrite(CH_IN2, steerSpeed);
}
void steerRight() {
ledcWrite(CH_IN1, steerSpeed);
ledcWrite(CH_IN2, 0);
}
void driveForward() {
ledcWrite(CH_IN3, driveSpeed);
ledcWrite(CH_IN4, 0);
}
void driveReverse() {
ledcWrite(CH_IN3, 0);
ledcWrite(CH_IN4, driveSpeed);
}
// ---------- HTTP handlers ----------
void handleRoot() {
server.send(200, "text/html", htmlPage);
}
void handleMove() {
String dir = server.hasArg("dir") ? server.arg("dir") : "";
if (dir == "forward") driveForward();
else if (dir == "reverse") driveReverse();
else if (dir == "left") steerLeft();
else if (dir == "right") steerRight();
server.send(200, "text/plain", "OK");
}
void handleStop() {
stopAll();
server.send(200, "text/plain", "Stopped");
}
void handleSpeed() {
if (server.hasArg("type") && server.hasArg("val")) {
int pct = constrain(server.arg("val").toInt(), 0, 100);
if (server.arg("type") == "drive") {
driveSpeed = map(pct, 0, 100, 0, 255);
Serial.printf("Drive speed: %d%% -> %d\n", pct, driveSpeed);
} else if (server.arg("type") == "steer") {
steerSpeed = map(pct, 0, 100, 0, 255);
Serial.printf("Steer speed: %d%% -> %d\n", pct, steerSpeed);
}
}
server.send(200, "text/plain", "Speed updated");
}
// ---------- Setup ----------
void setup() {
Serial.begin(115200);
// Configure PWM channels
ledcSetup(CH_IN1, PWM_FREQ, PWM_BITS); ledcAttachPin(IN1, CH_IN1);
ledcSetup(CH_IN2, PWM_FREQ, PWM_BITS); ledcAttachPin(IN2, CH_IN2);
ledcSetup(CH_IN3, PWM_FREQ, PWM_BITS); ledcAttachPin(IN3, CH_IN3);
ledcSetup(CH_IN4, PWM_FREQ, PWM_BITS); ledcAttachPin(IN4, CH_IN4);
stopAll(); // Car stopped at boot
// Start Access Point
const char* apName = "ESP32-Car";
const char* apPass = "12345678";
WiFi.softAP(apName, apPass);
Serial.println("AP started. Connect to SSID: ESP32-Car, pass: 12345678");
Serial.println(WiFi.softAPIP());
// Routes
server.on("/", handleRoot);
server.on("/move", handleMove);
server.on("/stop", handleStop);
server.on("/speed", handleSpeed);
server.begin();
}
// ---------- Loop ----------
void loop() {
server.handleClient();
}