A lightweight servo control library for ESP32 and ESP8266
- π― Simple API β Familiar Arduino Servo-style interface
- π¦ Multi-servo support β Up to 8 servos (6 on smaller variants)
- π Servo types β 180Β°, 270Β°, 360Β° continuous, or custom angles
- β‘ High precision β 14-bit PWM (ESP32) / 10-bit PWM (ESP8266)
- π§ Configurable β Adjustable frequency (40-400Hz) and pulse width
- π§΅ Thread-safe β Safe channel allocation for RTOS (ESP32)
| Chip | Max Servos | PWM Resolution | Status |
|---|---|---|---|
| ESP32 | 8 | 14-bit | β |
| ESP32-S2 | 8 | 14-bit | β |
| ESP32-S3 | 8 | 14-bit | β |
| ESP32-C3 | 6 | 14-bit | β |
| ESP32-C6 | 6 | 14-bit | β |
| ESP32-H2 | 6 | 14-bit | β |
| ESP32-P4 | 8 | 14-bit | β |
| ESP8266 | 8 | 10-bit | β |
Arduino IDE:
Sketch β Include Library β Add .ZIP Library...
PlatformIO:
lib_deps = RoboServo#include <RoboServo.h>
RoboServo myServo;
void setup() {
myServo.attach(13); // Attach to GPIO 13
myServo.write(90); // Move to 90Β°
}
void loop() {
myServo.write(0);
delay(1000);
myServo.write(180);
delay(1000);
}uint8_t attach(int pin);
uint8_t attach(int pin, int minPulseUs, int maxPulseUs);
uint8_t attach(int pin, int minPulseUs, int maxPulseUs, RoboServoType type);
uint8_t attach(int pin, int minPulseUs, int maxPulseUs, int maxAngle);
uint8_t attach(int pin, int minPulseUs, int maxPulseUs, RoboServoType type, int frequency);
void detach();
bool attached();void write(int angle); // Set angle (0 to maxAngle)
void writeMicroseconds(int pulseUs); // Set pulse width directly
int read(); // Get current angle
int readMicroseconds(); // Get current pulse widthvoid setServoType(RoboServoType type); // SERVO_TYPE_180, _270, _360, _CUSTOM
void setMaxAngle(int angle); // Custom max angle
void setPulseLimits(int minUs, int maxUs);
void setFrequency(int frequency); // 40-400 Hz (default: 50)
RoboServoType getServoType();
int getMaxAngle();
int getMinPulse();
int getMaxPulse();
int getFrequency();
int getPin();void setSpeed(int speed); // -100 (full reverse) to +100 (full forward)
void stop(); // Stop rotation (center pulse)
void release(); // Release PWM signal (go limp)static int getAttachedCount();
static uint32_t getDefaultFrequency(); // 50 Hz
static uint8_t getServoResolution(); // 14-bitControl multiple servos as a coordinated group.
// Add/Remove
int addServo(int pin);
int addServo(int pin, int minPulseUs, int maxPulseUs, RoboServoType type);
bool removeServo(int index);
void removeAll();
// Info
int count();
RoboServo* getServo(int index);
// Group Control
void writeAll(int angle);
void writeAllMicroseconds(int pulseUs);
void writeMultiple(const int* angles, int count);
void stopAll();
void detachAll();
// Individual Control
void write(int index, int angle);
void writeMicroseconds(int index, int pulseUs);
int read(int index);// Standard 180Β° servo (default)
servo.attach(13, 500, 2500, SERVO_TYPE_180);
servo.write(90); // Center position
// Extended 270Β° servo
servo.attach(13, 500, 2500, SERVO_TYPE_270);
servo.write(135); // Center position
// Custom angle range (e.g., 120Β°)
servo.attach(13, 500, 2500, 120);
servo.write(60); // Center position
// Continuous rotation 360Β° servo
servo.attach(13, 500, 2500, SERVO_TYPE_360);
servo.setSpeed(50); // 50% forward
servo.setSpeed(-50); // 50% reverse
servo.stop(); // Stop rotation| Variant | Valid Pins |
|---|---|
| ESP32 | 2, 4, 5, 12-19, 21-23, 25-27, 32-33 |
| ESP32-S2 | 1-21, 26, 33-42 |
| ESP32-S3 | 1-21, 35-45, 47-48 |
| ESP32-C3 | 0-10, 18-21 |
| ESP32-C6 | 0-23 |
| ESP32-H2 | 0-14, 25-27 |
| ESP32-P4 | 0-54 (except 24-25) |
| ESP8266 | 0-5, 12-16 |
ESP32 Servo
βββββ βββββ
GPIO x βββββββββββββββΊ Signal (Orange/White)
5V βββββββββββββββΊ VCC (Red)
GND βββββββββββββββΊ GND (Brown/Black)
β οΈ Power Tip: Use an external 5V power supply (~1A per servo) when driving multiple servos. The ESP32's 5V pin cannot supply enough current.
RoboServo uses PWM at 50Hz by default. Conflicts may occur if analogWrite() uses different settings.
ESP32 Solutions:
| Method | Description |
|---|---|
| Order matters | Call analogWrite() before servo.attach() |
| Use LEDC directly | Replace analogWrite() with ledcAttach() + ledcWrite() |
| Match frequency | analogWriteFrequency(pin, 50) |
ESP8266 Notes:
- All PWM channels share the same frequency
- RoboServo sets the global PWM frequency on
attach() - For best results, use the same frequency for all PWM outputs
| Example | Description |
|---|---|
| BasicServo | Single servo sweep |
| MultipleServos | Independent multi-servo control |
| ServoGroup | Coordinated group movements |
| Servo360 | Continuous rotation control |
| ServoTypes | 180Β°, 270Β°, custom angles |
| CustomPulseWidth | Pulse calibration tool |
| ServoWithPWM | Coexisting with LED PWM |
| ADCServoControl | Potentiometer control |
| Problem | Solution |
|---|---|
| Servo not moving | Check 5V power supply; verify GPIO is valid for your board |
| Servo jittering | Use external power; add 100ΞΌF capacitor near servo |
| Limited rotation range | Calibrate pulse width (try 1000-2000ΞΌs range) |
Stops after analogWrite() |
Timer conflict β see solutions above |
attach() returns 255 |
No channels available or invalid pin |
MIT License β see LICENSE for details.
Made with β€οΈ for the ESP32 & ESP8266 community
v1.1.0 β’ Supports ESP32, ESP32-S2/S3, ESP32-C3/C6/H2, ESP32-P4, ESP8266