Skip to content

dunknowcoding/RoboServo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🤖 RoboServo

A lightweight servo control library for ESP32, ESP8266, nRF52/nRF53, RP2040, STM32, AVR, UNO R4, UNO Q, and Mbed

Version ESP32 ESP32-S2/S3 ESP32-C3/C6/H2 ESP32-P4 ESP8266 nRF52 RP2040 STM32 AVR UNO R4 UNO Q Mbed License


✨ Features

  • 🎯 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
  • 🏎️ High-speed PWM — 333Hz digital servos and kHz motor/ESC outputs via RoboMotor
  • 🧵 Thread-safe — Safe channel allocation for RTOS (ESP32)

📋 Supported Boards

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
ArduinoNRF nRF52 8 10-bit
Adafruit / nRF52 DK 6 10-bit
RP2040 / RP2350 8 10-bit
STM32 6 10-bit
AVR (UNO/Nano) 6 8-bit (ISR)
AVR (Mega) 12 8-bit (ISR)
UNO R4 Minima / WiFi 8 10-bit
UNO Q 6 10-bit
Mbed (Nano 33 BLE) 8 10-bit
nRF5340 (generic core) 6 10-bit

High-Speed PWM Outputs (RoboMotor)

Chip Max Motors Default Freq PWM Resolution Mix with 50Hz Servo
ESP32 4 20 kHz 10-bit ✅ (isolated timer group)
ESP32-S2 / S3 4 20 kHz 10-bit
ESP32-C3 / C6 / H2 2 20 kHz 10-bit
ESP32-P4 4 20 kHz 10-bit
ESP8266 4 20 kHz 10-bit ❌ (global single frequency)
ArduinoNRF nRF52 4 20 kHz 10-bit ✅ (per-pin frequency groups)
Adafruit / nRF52 DK 2 20 kHz 10-bit ❌ (shared frequency)
RP2040 / RP2350 2 20 kHz 10-bit ❌ (shared frequency)
STM32 2 20 kHz 10-bit ❌ (shared frequency)
AVR ❌ (servo only)
UNO R4 / UNO Q / Mbed ❌ (servo only)

🚀 Quick Start

Installation

Arduino IDE 2.x (Library Manager):
Select an ESP32, ESP8266, nRF52, RP2040, STM32, or AVR board, then ToolsManage Libraries… → search RoboServo → Install.

Arduino IDE (ZIP):
SketchInclude LibraryAdd .ZIP Library...

PlatformIO:

lib_deps = https://github.com/dunknowcoding/RoboServo.git#v1.1.2

Basic Example

#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);
}

📖 API Reference

RoboServo Class

Attachment

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();

Position Control

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 width

Configuration

void 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();

360° Continuous Servo

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 Methods

static int getAttachedCount();
static uint32_t getDefaultFrequency();  // 50 Hz
static uint8_t getServoResolution();    // 14-bit

RoboServoGroup Class

Control 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);

High Refresh-Rate Servos (333–400 Hz)

Standard RoboServo API — attach at a higher frequency for digital servos that support it:

#include <RoboServoHighSpeed.h>

RoboServo servo;
roboServoAttachHighSpeed(servo, 13);   // 333 Hz, 500-2500 us
servo.write(90);

Or set frequency manually: servo.attach(13, 500, 2500, SERVO_TYPE_180, 333);


RoboMotor Class

High-frequency PWM for motor driver enable pins and ESC inputs (1–40 kHz, default 20 kHz).

Attachment

uint8_t attach(int pin);
uint8_t attach(int pin, int frequency);
uint8_t attach(int pin, int frequency, uint8_t resolution);

void detach();
bool attached();

Duty Cycle Control

void write(int dutyPercent);    // 0-100 %
void writeRaw(uint32_t duty);   // 0 to 2^resolution - 1
int read();                     // Current duty %
uint32_t readRaw();             // Current raw duty

Configuration

void setFrequency(int frequency);   // 1000-40000 Hz (default: 20000)
int getFrequency();
uint8_t getResolution();
int getPin();
uint8_t getChannel();

Motor Control

void stop();    // 0% duty
void brake();   // Alias for stop()

Static Methods

static int getAttachedCount();
static uint32_t getDefaultFrequency();  // 20000 Hz
static uint8_t getMotorResolution();    // 10-bit

RoboMotorGroup Class

Control multiple motors as a coordinated group.

// Add/Remove
int addMotor(int pin);
int addMotor(int pin, int frequency);
bool removeMotor(int index);
void removeAll();

// Info
int count();
RoboMotor* getMotor(int index);

// Group Control
void writeAll(int dutyPercent);
void writeMultiple(const int* duties, int count);
void stopAll();
void detachAll();

// Individual Control
void write(int index, int dutyPercent);
int read(int index);

🎛️ Servo Types

// 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

🔌 Valid GPIO Pins

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
ArduinoNRF nRF52 PWM-capable pins (see board variant)
Adafruit / nRF52 DK PWM-capable pins (see core docs)
RP2040 / RP2350 PWM-capable pins (digitalPinHasPWM)
STM32 PWM-capable pins (digitalPinHasPWM)
AVR (UNO/Nano/Mega) Any digital pin (Timer1 ISR)
UNO R4 PWM-capable pins (digitalPinHasPWM)
UNO Q Digital pins with counter_servo support
Mbed (Nano 33 BLE) Any digital pin (20 ms Ticker frame)
nRF5340 DK PWM-capable pins (core-dependent)

🔧 Wiring

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.


⚡ Timer Conflicts

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
  • RoboMotor cannot run alongside RoboServo — pick one domain per sketch

nRF52 / RP2040 / STM32 Notes:

  • ArduinoNRF boards use per-pin frequency groups via nrfPwmSetPinFrequency
  • Adafruit nRF52, RP2040, and STM32 cores share a single PWM frequency per sketch
  • RoboServo sets frequency on attach(); avoid mixing different frequencies
  • RoboMotor on shared-frequency cores is limited to 2 outputs and cannot mix 50Hz servo with 20kHz motor

AVR Notes:

  • Uses Timer1 compare interrupts (same resource as Tone and the built-in Servo library)
  • Do not mix with Tone() or the Arduino Servo library in the same sketch
  • RoboMotor is not supported on AVR — use RoboServo for 50Hz hobby servos only

UNO R4 / UNO Q / Mbed Notes:

  • UNO R4 uses FSP PWM with a 20 ms frame configured in microseconds
  • UNO Q requires the board counter_servo device (provided on the UNO Q variant)
  • Mbed boards use a 20 ms Ticker + GPIO pulse backend (not analogWrite at 500 Hz)
  • UNO Q: install Arduino_RouterBridge from Library Manager (required by the Zephyr core)
  • RoboMotor is not supported on UNO R4, UNO Q, Mbed, or AVR

nRF5340 Notes:

  • Detected via ARDUINO_ARCH_NRF53 / NRF5340_XXAA macros
  • Mbed and Zephyr nRF5340 cores use the Mbed/Zephyr backends above
  • Other nRF5340 Arduino cores fall back to shared-frequency analogWrite

RoboMotor on ESP32:

  • Motor outputs use a separate LEDC channel group (above channel 7) to avoid interfering with 50Hz servos
  • See ServoAndMotor for mixed low-speed servo + high-speed motor usage

📁 Examples

Example Description
BasicServo Single servo sweep
PlatformSmoke Minimal attach/write (no Serial, for UNO Q / CI)
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
HighSpeedServo 333Hz digital servo sweep
MotorPwm 20kHz motor duty cycle ramp
MotorGroup Coordinated multi-motor control
ServoAndMotor 50Hz servo + 20kHz motor together

🔍 Troubleshooting

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, invalid pin, or pin already in use
Motor not spinning Verify driver wiring; RoboMotor drives PWM enable, not direction pins

📄 License

MIT License — see LICENSE for details.


Made with ❤️ for the embedded robotics community

v0.5.0 • Supports ESP32, ESP8266, nRF52/nRF53, RP2040, STM32, AVR, UNO R4, UNO Q, Mbed

About

Light weighted servo and motor library for ESP32 and ESP8266 family MCUs (Updates now cover more MCUs such as STM32, NRF52), optimized for robotics and multiple servos.

Topics

Resources

License

Stars

3 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors