Project 7 : Servo Control Wirelessly
Share
ESP32 Servo Control with slider
📋 What You'll Build
In this tutorial, you'll create a wireless servo motor controller using an ESP32. You'll be able to control a servo motor through a web interface on your phone or computer - no external WiFi network needed!
🛠️ Required Components
Hardware:
- ESP32 Development Board (ESP32 )
- Servo Motor (SG90 micro servo or similar)
- Breadboard (half-size is fine)
- Jumper Wires (male-to-male, at least 3 wires)
- Micro USB Cable (for programming ESP32)
🔌 Step 2: Circuit Wiring
Servo Motor Pin Identification:
- Brown/Black Wire: Ground (GND)
- Red Wire: Power (VCC)
- Orange/Yellow Wire: Signal (Control)
Wiring Connections:
ESP32 Servo Motor
----- -----------
GND → Brown/Black wire
3.3V → Red wire
GPIO 18 → Orange/Yellow wire
Step-by-Step Wiring:
- Place ESP32 on breadboard
- Connect Ground: ESP32 GND → Servo Brown/Black wire
- Connect Power: ESP32 3.3V → Servo Red wire
- Connect Signal: ESP32 GPIO 18 → Servo Orange/Yellow wire
Visual Wiring Guide:

💻 Step 3: Upload the Code
Code :
---------------------------------------------------------------------------------------
#include <WiFi.h>
#include <WebServer.h>
#include <ESP32Servo.h>
// Access Point credentials
const char* ap_ssid = "ESP32_ServoControl";
const char* ap_password = "12345678"; // Must be at least 8 characters
// Servo setup
Servo myServo;
const int servoPin = 18; // GPIO pin for servo
int servoPosition = 90; // Initial position (0-180 degrees)
// Web server on port 80
WebServer server(80);
void setup() {
Serial.begin(115200);
delay(1000);
// Initialize servo
myServo.attach(servoPin);
myServo.write(servoPosition);
Serial.println("Servo initialized at position 90");
// Create Access Point
WiFi.mode(WIFI_AP);
bool result = WiFi.softAP(ap_ssid, ap_password);
if(result == true) {
Serial.println("Access Point created successfully!");
} else {
Serial.println("Failed to create Access Point!");
return;
}
IPAddress IP = WiFi.softAPIP();
Serial.println("========================================");
Serial.print("WiFi Network: ");
Serial.println(ap_ssid);
Serial.print("Password: ");
Serial.println(ap_password);
Serial.print("IP Address: http://");
Serial.println(IP);
Serial.println("========================================");
// Define web server routes
server.on("/", HTTP_GET, handleRoot);
server.on("/servo", HTTP_GET, handleServo);
server.on("/getpos", HTTP_GET, handleGetPosition);
// Start server
server.begin();
Serial.println("Web server started!");
Serial.println("Connect to WiFi and go to the IP address above");
}
void loop() {
server.handleClient();
delay(10); // Small delay to prevent watchdog issues
}
// Serve the main HTML page
void handleRoot() {
String html = R"(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 Servo Control</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
background-color: #f0f0f0;
}
.container {
max-width: 400px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
margin-bottom: 30px;
}
.slider-container {
margin: 20px 0;
}
.slider {
width: 100%;
height: 25px;
border-radius: 15px;
outline: none;
background: #ddd;
-webkit-appearance: none;
}
.slider::-webkit-slider-thumb {
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
border: none;
}
.value-display {
font-size: 24px;
font-weight: bold;
color: #4CAF50;
margin: 20px 0;
}
.labels {
display: flex;
justify-content: space-between;
margin-top: 5px;
font-size: 14px;
color: #666;
}
.status {
margin-top: 20px;
padding: 10px;
background: #e8f5e8;
border-radius: 5px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<h1>🎛️ Servo Motor Control</h1>
<div class="slider-container">
<input type="range" min="0" max="180" value="90" class="slider" id="servoSlider">
<div class="labels">
<span>0°</span>
<span>90°</span>
<span>180°</span>
</div>
</div>
<div class="value-display">
Position: <span id="servoValue">90</span>°
</div>
<div class="status" id="status">
Ready to control servo
</div>
</div>
<script>
var slider = document.getElementById("servoSlider");
var output = document.getElementById("servoValue");
var status = document.getElementById("status");
// Update display when slider moves
slider.oninput = function() {
output.innerHTML = this.value;
status.innerHTML = "Moving to " + this.value + "°...";
// Send position to ESP32
var xhr = new XMLHttpRequest();
xhr.open("GET", "/servo?pos=" + this.value, true);
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
status.innerHTML = "Servo moved to " + slider.value + "°";
} else {
status.innerHTML = "Error: Could not move servo";
}
}
};
xhr.send();
}
// Get current position on page load
window.onload = function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var pos = parseInt(this.responseText);
slider.value = pos;
output.innerHTML = pos;
status.innerHTML = "Connected! Current position: " + pos + "°";
}
};
xhr.open("GET", "/getpos", true);
xhr.send();
}
</script>
</body>
</html>
)";
server.send(200, "text/html", html);
Serial.println("Served main page");
}
// Handle servo position changes
void handleServo() {
Serial.println("Received servo request");
if (server.hasArg("pos")) {
int pos = server.arg("pos").toInt();
// Constrain position to valid range
pos = constrain(pos, 0, 180);
// Move servo to new position
myServo.write(pos);
servoPosition = pos;
Serial.print("Servo moved to: ");
Serial.println(pos);
server.send(200, "text/plain", "OK");
} else {
Serial.println("Missing position parameter");
server.send(400, "text/plain", "Missing position parameter");
}
}
// Get current servo position
void handleGetPosition() {
Serial.println("Received position request");
server.send(200, "text/plain", String(servoPosition));
}
--------------------------------------------------------------------------------------
Copy the Code:
Copy the complete code from the previous artifact
Paste it into a new Arduino IDE sketch
Configure Arduino IDE:
Board: Tools → Board → ESP32 Arduino → ESP32 Dev Module
Port: Tools → Port → Select your ESP32 port (usually COM3, COM4 on Windows)
Upload Speed: 115200
Upload Process:
Click Upload button (arrow icon)
Wait for "Connecting..." message
Press and hold BOOT button on ESP32 until upload starts
Wait for "Hard resetting via RTS pin..." message
Upload complete!
🌐 Step 4: Connect and Test
A. Check Serial Monitor:
- Open Tools → Serial Monitor
- Set baud rate to 115200
- You should see:
Access Point created successfully!WiFi Network: ESP32_ServoControlPassword: 12345678IP Address: http://192.168.4.1Web server started!
B. Connect to ESP32 WiFi:
-
On your phone/computer:
- Open WiFi settings
- Look for network: ESP32_ServoControl
- Connect using password: 12345678
C. Access Web Interface:
- Open web browser
- Go to: 192.168.4.1
- You should see the servo control interface!
🎮 Step 5: Using the Interface
Web Interface Features:
- Slider: Drag to control servo position (0° to 180°)
- Position Display: Shows current angle
- Status Messages: Confirms servo movements
- Responsive Design: Works on phones and computers
Testing:
- Move the slider left and right
- Watch the servo motor rotate
- Check Serial Monitor for debug messages
- Position range: 0° (fully left) to 180° (fully right)
🔧 Troubleshooting Common Issues
Problem: Can't find ESP32 WiFi network
Solutions:
- Check if ESP32 is powered (LED should be on)
- Verify code uploaded successfully
- Press RESET button on ESP32
- Check Serial Monitor for error messages
Problem: Connected to WiFi but can't access webpage
Solutions:
- Make sure you're going to 192.168.4.1 (not .0)
- Try adding http:// before the IP:
http://192.168.4.1 - Clear browser cache
- Try different browser
Problem: Servo doesn't move
Solutions:
- Check all wire connections
- Verify servo is connected to GPIO 18
- Make sure servo gets power (3.3V connection)
- Try different servo motor
Problem: Upload fails
Solutions:
- Check correct board selected (ESP32 Dev Module)
- Verify correct COM port
- Press and hold BOOT button during upload
- Try different USB cable
🎯 Understanding the Code
Main Components:
- WiFi Access Point: Creates "ESP32_ServoControl" network
- Web Server: Serves HTML page and handles requests
- Servo Control: Moves servo based on slider input
- HTML Interface: User-friendly web page with slider
Key Functions:
-
WiFi.softAP(): Creates WiFi hotspot -
server.on(): Defines web routes -
myServo.write(): Moves servo to position -
server.send(): Sends web responses
🚀 Expanding the Project
Easy Modifications:
-
Change WiFi Name/Password:
const char* ap_ssid = "MyServoControl";
const char* ap_password = "mypassword123"; -
Change Servo Pin:
const int servoPin = 19; // Use GPIO 19 instead -
Add Multiple Servos:
Connect second servo to different GPIO pin
Add another slider in HTML
Create additional servo object
Advanced Features to Add:
- Preset Positions: Buttons for common angles
- Speed Control: Adjust servo movement speed
- Multiple Servos: Control several servos simultaneously
- Sensor Integration: Add sensors for automatic control
- Data Logging: Save servo positions to file
📚 Learning Resources
Next Steps:
- Learn HTML/CSS: Customize the web interface
- Explore ESP32 Features: WiFi, Bluetooth, sensors
- Arduino Programming: Understand C++ basics
- Electronics Basics: Voltage, current, components
Helpful Websites:
- Arduino Reference: arduino.cc/reference
- ESP32 Documentation: docs.espressif.com
- Electronics Tutorials: learn.sparkfun.com
✅ Project Checklist
- [ ] All components purchased
- [ ] Arduino IDE installed with ESP32 support
- [ ] ESP32Servo library installed
- [ ] Circuit wired correctly
- [ ] Code uploaded successfully
- [ ] Serial Monitor shows correct messages
- [ ] Can connect to ESP32 WiFi
- [ ] Web interface loads at 192.168.4.1
- [ ] Servo moves when slider is moved
- [ ] Project working smoothly
🎉 Congratulations!
You've successfully built a wireless servo controller! You now have:
- A working ESP32 project
- Understanding of WiFi Access Points
- Web server programming experience
- Motor control knowledge
- Foundation for more advanced projects
What's Next? Try the advanced modifications or build similar projects with different sensors and actuators!
Happy Making! 🛠️