ESP-Based Phone-Controlled Cybertruck
Remote-controlled innovation powered by ESP32
About the Project
Built a remotely controlled Cybertruck using an ESP microcontroller with a mobile/web interface. This project demonstrates the power of IoT and embedded systems in modern robotics, showcasing how microcontrollers can efficiently handle motor control and sensor feedback.
Key Achievements
- Real-time communication and control
- Optimized latency for precise movement
- Dual connectivity with Wi-Fi/Bluetooth
- Efficient motor control and sensor integration
Technical Insights
Real-time Control
Achieved instant response to user inputs with optimized latency for precise control
Dual Connectivity
Enhanced maneuverability through Wi-Fi/Bluetooth integration
Future Potential
Ready for AI-driven self-driving and gesture-controlled robotics
Skills & Tools
💻 Programming & Development
C++
Advanced
JavaScript
Intermediate
Node.js
Intermediate
TypeScript
Intermediate
🌐 Web Technologies
Next.js
Intermediate
React
Intermediate
Tailwind CSS
Intermediate
HTML/CSS
Advanced
🔧 Hardware & Electronics
ESP32
Advanced
Arduino
Advanced
Motor Control
Intermediate
Circuit Design
Intermediate
🛠️ Development Tools
Arduino IDE
Advanced
VS Code
Advanced
Git
Intermediate
Figma
Basic
Project Demo
Click to play demo video
Watch the ESP-Based Phone-Controlled Cybertruck in action
Features Demonstrated
Real-time Control
Smooth Movement
Responsive Interface
Project Impact
This project showcases the potential of ESP-based automation and IoT integration in modern robotics. The successful implementation of real-time control and sensor feedback opens doors for future developments in AI-driven self-driving systems and gesture-controlled robotics.
Code Showcase
Main Setup and Configuration
Initial setup including WiFi AP mode, motor pins, and server configuration
#include <WiFi.h>
#include <WebServer.h>
// Access Point credentials
const char* ssid = "ESP32_Car";
const char* password = "12345678";
// Motor pins
const int rightMotorForward = 27;
const int rightMotorBackward = 26;
const int leftMotorForward = 12;
const int leftMotorBackward = 14;
WebServer server(80);
void setup() {
// Initialize motor pins as output
pinMode(rightMotorForward, OUTPUT);
pinMode(rightMotorBackward, OUTPUT);
pinMode(leftMotorForward, OUTPUT);
pinMode(leftMotorBackward, OUTPUT);
// Stop all motors at the start
stopMotors();
// Start Wi-Fi in Access Point mode
WiFi.softAP(ssid, password);
Serial.begin(115200);
Serial.println("Access Point started");
Serial.print("IP Address: ");
Serial.println(WiFi.softAPIP());
// Define web server routes
server.on("/", handleRoot);
server.on("/forward", []() { handleMotor(true, false, true, false); });
server.on("/backward", []() { handleMotor(false, true, false, true); });
server.on("/left", []() { handleMotor(false, true, true, false); });
server.on("/right", []() { handleMotor(true, false, false, true); });
server.on("/stop", []() { stopMotors(); });
server.begin();
Serial.println("Server started");
}
void loop() {
server.handleClient();
}Motor Control Functions
Functions for controlling the motors and handling movement commands
void handleMotor(bool rf, bool rb, bool lf, bool lb) {
digitalWrite(rightMotorForward, rf ? HIGH : LOW);
digitalWrite(rightMotorBackward, rb ? HIGH : LOW);
digitalWrite(leftMotorForward, lf ? HIGH : LOW);
digitalWrite(leftMotorBackward, lb ? HIGH : LOW);
server.send(200, "text/plain", "Motor command executed");
}
void stopMotors() {
digitalWrite(rightMotorForward, LOW);
digitalWrite(rightMotorBackward, LOW);
digitalWrite(leftMotorForward, LOW);
digitalWrite(leftMotorBackward, LOW);
server.send(200, "text/plain", "Motors stopped");
}Web Interface
HTML and JavaScript code for the web control interface
void handleRoot() {
server.send(200, "text/html", R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Car Control</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }
button { padding: 20px; margin: 10px; font-size: 20px; cursor: pointer; }
</style>
<script>
let activeKey = null;
document.addEventListener("keydown", function(event) {
if (event.key !== activeKey) {
activeKey = event.key;
sendCommand(event.key);
}
});
document.addEventListener("keyup", function(event) {
activeKey = null;
sendCommand("stop");
});
function sendCommand(key) {
let url = "";
switch (key.toLowerCase()) {
case "w": url = "/forward"; break;
case "a": url = "/left"; break;
case "s": url = "/backward"; break;
case "d": url = "/right"; break;
case " ": url = "/stop"; break;
default: return;
}
fetch(url).catch(err => console.log(err));
}
</script>
</head>
<body>
<h1>WiFi Car Control</h1>
<p>Use the buttons below or the keyboard (W/A/S/D/Space) to control the car.</p>
<button onmousedown="sendCommand('w')" onmouseup="sendCommand('stop')">W</button><br>
<button onmousedown="sendCommand('a')" onmouseup="sendCommand('stop')">A</button>
<button onmousedown="sendCommand(' ')" onmouseup="sendCommand('stop')">Stop</button>
<button onmousedown="sendCommand('d')" onmouseup="sendCommand('stop')">D</button><br>
<button onmousedown="sendCommand('s')" onmouseup="sendCommand('stop')">S</button>
</body>
</html>
)rawliteral");
}