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! 🛠️