Project 7 : Servo Control Wirelessly

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:

  1. Place ESP32 on breadboard
  2. Connect Ground: ESP32 GND → Servo Brown/Black wire
  3. Connect Power: ESP32 3.3V → Servo Red wire
  4. 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:

  1. Open ToolsSerial Monitor
  2. Set baud rate to 115200
  3. 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:

  1. On your phone/computer:
    • Open WiFi settings
    • Look for network: ESP32_ServoControl
    • Connect using password: 12345678

C. Access Web Interface:

  1. Open web browser
  2. Go to: 192.168.4.1
  3. 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:

  1. Move the slider left and right
  2. Watch the servo motor rotate
  3. Check Serial Monitor for debug messages
  4. 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:

  1. WiFi Access Point: Creates "ESP32_ServoControl" network
  2. Web Server: Serves HTML page and handles requests
  3. Servo Control: Moves servo based on slider input
  4. 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:

  1. Change WiFi Name/Password:
    const char* ap_ssid = "MyServoControl";
    const char* ap_password = "mypassword123";
  2. Change Servo Pin:
    const int servoPin = 19; // Use GPIO 19 instead
  3. 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:

  1. Learn HTML/CSS: Customize the web interface
  2. Explore ESP32 Features: WiFi, Bluetooth, sensors
  3. Arduino Programming: Understand C++ basics
  4. 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! 🛠️

Back to blog

Leave a comment