{"id":43639862,"url":"https://github.com/dunknowcoding/roboservo","last_synced_at":"2026-05-27T21:00:46.848Z","repository":{"id":336480958,"uuid":"1149345341","full_name":"dunknowcoding/RoboServo","owner":"dunknowcoding","description":"Light weighted servo library for ESP32 and ESP8266 family MCUs, optimized for robotics and multiple servos.","archived":false,"fork":false,"pushed_at":"2026-02-04T20:31:44.000Z","size":21,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-05T03:28:06.130Z","etag":null,"topics":["arduinio","arduino-library","esp32","esp32-c3","esp32-c6","esp32-h2","esp32-s2","esp32-s3","esp32p4","esp8266","platfomio","robotics","servo"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dunknowcoding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-04T02:20:36.000Z","updated_at":"2026-02-04T20:43:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dunknowcoding/RoboServo","commit_stats":null,"previous_names":["dunknowcoding/roboservo"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dunknowcoding/RoboServo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FRoboServo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FRoboServo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FRoboServo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FRoboServo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dunknowcoding","download_url":"https://codeload.github.com/dunknowcoding/RoboServo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunknowcoding%2FRoboServo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33583399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduinio","arduino-library","esp32","esp32-c3","esp32-c6","esp32-h2","esp32-s2","esp32-s3","esp32p4","esp8266","platfomio","robotics","servo"],"created_at":"2026-02-04T18:00:20.569Z","updated_at":"2026-05-27T21:00:46.839Z","avatar_url":"https://github.com/dunknowcoding.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003e🤖 RoboServo\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cstrong\u003eA lightweight servo control library for ESP32 and ESP8266\u003c/strong\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/version-0.2.0-blue?style=flat-square\" alt=\"Version\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/ESP32-supported-blue?style=flat-square\" alt=\"ESP32\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/ESP32--S2/S3-supported-blue?style=flat-square\" alt=\"ESP32-S2/S3\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/ESP32--C3/C6/H2-supported-blue?style=flat-square\" alt=\"ESP32-C3/C6/H2\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/ESP32--P4-supported-blue?style=flat-square\" alt=\"ESP32-P4\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/ESP8266-supported-orange?style=flat-square\" alt=\"ESP8266\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-MIT-green?style=flat-square\" alt=\"License\"\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n---\n\n## ✨ Features\n\n- 🎯 **Simple API** — Familiar Arduino Servo-style interface\n- 📦 **Multi-servo support** — Up to 8 servos (6 on smaller variants)\n- 🔄 **Servo types** — 180°, 270°, 360° continuous, or custom angles\n- ⚡ **High precision** — 14-bit PWM (ESP32) / 10-bit PWM (ESP8266)\n- 🔧 **Configurable** — Adjustable frequency (40-400Hz) and pulse width\n- 🏎️ **High-speed PWM** — 333Hz digital servos and kHz motor/ESC outputs via `RoboMotor`\n- 🧵 **Thread-safe** — Safe channel allocation for RTOS (ESP32)\n\n---\n\n## 📋 Supported Boards\n\n| Chip | Max Servos | PWM Resolution | Status |\n|:-----|:----------:|:--------------:|:------:|\n| ESP32 | 8 | 14-bit | ✅ |\n| ESP32-S2 | 8 | 14-bit | ✅ |\n| ESP32-S3 | 8 | 14-bit | ✅ |\n| ESP32-C3 | 6 | 14-bit | ✅ |\n| ESP32-C6 | 6 | 14-bit | ✅ |\n| ESP32-H2 | 6 | 14-bit | ✅ |\n| ESP32-P4 | 8 | 14-bit | ✅ |\n| ESP8266 | 8 | 10-bit | ✅ |\n\n### High-Speed PWM Outputs (RoboMotor)\n\n| Chip | Max Motors | Default Freq | PWM Resolution | Mix with 50Hz Servo |\n|:-----|:----------:|:------------:|:--------------:|:-------------------:|\n| ESP32 | 4 | 20 kHz | 10-bit | ✅ (isolated timer group) |\n| ESP32-S2 / S3 | 4 | 20 kHz | 10-bit | ✅ |\n| ESP32-C3 / C6 / H2 | 2 | 20 kHz | 10-bit | ✅ |\n| ESP32-P4 | 4 | 20 kHz | 10-bit | ✅ |\n| ESP8266 | 4 | 20 kHz | 10-bit | ❌ (global single frequency) |\n\n---\n\n## 🚀 Quick Start\n\n### Installation\n\n**Arduino IDE 2.x (Library Manager):**  \nSelect an **ESP32** or **ESP8266** board, then `Tools` → `Manage Libraries…` → search **RoboServo** → Install.\n\n**Arduino IDE (ZIP):**  \n`Sketch` → `Include Library` → `Add .ZIP Library...`\n\n**PlatformIO:**\n```ini\nlib_deps = https://github.com/dunknowcoding/RoboServo.git#v1.1.2\n```\n\n### Basic Example\n\n```cpp\n#include \u003cRoboServo.h\u003e\n\nRoboServo myServo;\n\nvoid setup() {\n    myServo.attach(13);   // Attach to GPIO 13\n    myServo.write(90);    // Move to 90°\n}\n\nvoid loop() {\n    myServo.write(0);\n    delay(1000);\n    myServo.write(180);\n    delay(1000);\n}\n```\n\n---\n\n## 📖 API Reference\n\n### RoboServo Class\n\n#### Attachment\n\n```cpp\nuint8_t attach(int pin);\nuint8_t attach(int pin, int minPulseUs, int maxPulseUs);\nuint8_t attach(int pin, int minPulseUs, int maxPulseUs, RoboServoType type);\nuint8_t attach(int pin, int minPulseUs, int maxPulseUs, int maxAngle);\nuint8_t attach(int pin, int minPulseUs, int maxPulseUs, RoboServoType type, int frequency);\n\nvoid detach();\nbool attached();\n```\n\n#### Position Control\n\n```cpp\nvoid write(int angle);               // Set angle (0 to maxAngle)\nvoid writeMicroseconds(int pulseUs); // Set pulse width directly\nint read();                          // Get current angle\nint readMicroseconds();              // Get current pulse width\n```\n\n#### Configuration\n\n```cpp\nvoid setServoType(RoboServoType type);   // SERVO_TYPE_180, _270, _360, _CUSTOM\nvoid setMaxAngle(int angle);              // Custom max angle\nvoid setPulseLimits(int minUs, int maxUs);\nvoid setFrequency(int frequency);         // 40-400 Hz (default: 50)\n\nRoboServoType getServoType();\nint getMaxAngle();\nint getMinPulse();\nint getMaxPulse();\nint getFrequency();\nint getPin();\n```\n\n#### 360° Continuous Servo\n\n```cpp\nvoid setSpeed(int speed);  // -100 (full reverse) to +100 (full forward)\nvoid stop();               // Stop rotation (center pulse)\nvoid release();            // Release PWM signal (go limp)\n```\n\n#### Static Methods\n\n```cpp\nstatic int getAttachedCount();\nstatic uint32_t getDefaultFrequency();  // 50 Hz\nstatic uint8_t getServoResolution();    // 14-bit\n```\n\n---\n\n### RoboServoGroup Class\n\nControl multiple servos as a coordinated group.\n\n```cpp\n// Add/Remove\nint addServo(int pin);\nint addServo(int pin, int minPulseUs, int maxPulseUs, RoboServoType type);\nbool removeServo(int index);\nvoid removeAll();\n\n// Info\nint count();\nRoboServo* getServo(int index);\n\n// Group Control\nvoid writeAll(int angle);\nvoid writeAllMicroseconds(int pulseUs);\nvoid writeMultiple(const int* angles, int count);\nvoid stopAll();\nvoid detachAll();\n\n// Individual Control\nvoid write(int index, int angle);\nvoid writeMicroseconds(int index, int pulseUs);\nint read(int index);\n```\n\n---\n\n### High Refresh-Rate Servos (333–400 Hz)\n\nStandard `RoboServo` API — attach at a higher frequency for digital servos that support it:\n\n```cpp\n#include \u003cRoboServoHighSpeed.h\u003e\n\nRoboServo servo;\nroboServoAttachHighSpeed(servo, 13);   // 333 Hz, 500-2500 us\nservo.write(90);\n```\n\nOr set frequency manually: `servo.attach(13, 500, 2500, SERVO_TYPE_180, 333);`\n\n---\n\n### RoboMotor Class\n\nHigh-frequency PWM for motor driver enable pins and ESC inputs (1–40 kHz, default 20 kHz).\n\n#### Attachment\n\n```cpp\nuint8_t attach(int pin);\nuint8_t attach(int pin, int frequency);\nuint8_t attach(int pin, int frequency, uint8_t resolution);\n\nvoid detach();\nbool attached();\n```\n\n#### Duty Cycle Control\n\n```cpp\nvoid write(int dutyPercent);    // 0-100 %\nvoid writeRaw(uint32_t duty);   // 0 to 2^resolution - 1\nint read();                     // Current duty %\nuint32_t readRaw();             // Current raw duty\n```\n\n#### Configuration\n\n```cpp\nvoid setFrequency(int frequency);   // 1000-40000 Hz (default: 20000)\nint getFrequency();\nuint8_t getResolution();\nint getPin();\nuint8_t getChannel();\n```\n\n#### Motor Control\n\n```cpp\nvoid stop();    // 0% duty\nvoid brake();   // Alias for stop()\n```\n\n#### Static Methods\n\n```cpp\nstatic int getAttachedCount();\nstatic uint32_t getDefaultFrequency();  // 20000 Hz\nstatic uint8_t getMotorResolution();    // 10-bit\n```\n\n---\n\n### RoboMotorGroup Class\n\nControl multiple motors as a coordinated group.\n\n```cpp\n// Add/Remove\nint addMotor(int pin);\nint addMotor(int pin, int frequency);\nbool removeMotor(int index);\nvoid removeAll();\n\n// Info\nint count();\nRoboMotor* getMotor(int index);\n\n// Group Control\nvoid writeAll(int dutyPercent);\nvoid writeMultiple(const int* duties, int count);\nvoid stopAll();\nvoid detachAll();\n\n// Individual Control\nvoid write(int index, int dutyPercent);\nint read(int index);\n```\n\n---\n\n## 🎛️ Servo Types\n\n```cpp\n// Standard 180° servo (default)\nservo.attach(13, 500, 2500, SERVO_TYPE_180);\nservo.write(90);  // Center position\n\n// Extended 270° servo  \nservo.attach(13, 500, 2500, SERVO_TYPE_270);\nservo.write(135); // Center position\n\n// Custom angle range (e.g., 120°)\nservo.attach(13, 500, 2500, 120);\nservo.write(60);  // Center position\n\n// Continuous rotation 360° servo\nservo.attach(13, 500, 2500, SERVO_TYPE_360);\nservo.setSpeed(50);   // 50% forward\nservo.setSpeed(-50);  // 50% reverse\nservo.stop();         // Stop rotation\n```\n\n---\n\n## 🔌 Valid GPIO Pins\n\n| Variant | Valid Pins |\n|:--------|:-----------|\n| ESP32 | 2, 4, 5, 12-19, 21-23, 25-27, 32-33 |\n| ESP32-S2 | 1-21, 26, 33-42 |\n| ESP32-S3 | 1-21, 35-45, 47-48 |\n| ESP32-C3 | 0-10, 18-21 |\n| ESP32-C6 | 0-23 |\n| ESP32-H2 | 0-14, 25-27 |\n| ESP32-P4 | 0-54 (except 24-25) |\n| ESP8266 | 0-5, 12-16 |\n\n---\n\n## 🔧 Wiring\n\n```\nESP32                    Servo\n─────                    ─────\nGPIO x  ──────────────►  Signal (Orange/White)\n5V      ──────────────►  VCC (Red)\nGND     ──────────────►  GND (Brown/Black)\n```\n\n\u003e ⚠️ **Power Tip:** Use an external 5V power supply (~1A per servo) when driving multiple servos. The ESP32's 5V pin cannot supply enough current.\n\n---\n\n## ⚡ Timer Conflicts\n\nRoboServo uses PWM at 50Hz by default. Conflicts may occur if `analogWrite()` uses different settings.\n\n**ESP32 Solutions:**\n\n| Method | Description |\n|:-------|:------------|\n| **Order matters** | Call `analogWrite()` before `servo.attach()` |\n| **Use LEDC directly** | Replace `analogWrite()` with `ledcAttach()` + `ledcWrite()` |\n| **Match frequency** | `analogWriteFrequency(pin, 50)` |\n\n**ESP8266 Notes:**\n- All PWM channels share the same frequency\n- RoboServo sets the global PWM frequency on `attach()`\n- For best results, use the same frequency for all PWM outputs\n- **RoboMotor cannot run alongside RoboServo** — pick one domain per sketch\n\n**RoboMotor on ESP32:**\n- Motor outputs use a separate LEDC channel group (above channel 7) to avoid interfering with 50Hz servos\n- See [ServoAndMotor](examples/ServoAndMotor) for mixed low-speed servo + high-speed motor usage\n\n---\n\n## 📁 Examples\n\n| Example | Description |\n|:--------|:------------|\n| [BasicServo](examples/BasicServo) | Single servo sweep |\n| [MultipleServos](examples/MultipleServos) | Independent multi-servo control |\n| [ServoGroup](examples/ServoGroup) | Coordinated group movements |\n| [Servo360](examples/Servo360) | Continuous rotation control |\n| [ServoTypes](examples/ServoTypes) | 180°, 270°, custom angles |\n| [CustomPulseWidth](examples/CustomPulseWidth) | Pulse calibration tool |\n| [ServoWithPWM](examples/ServoWithPWM) | Coexisting with LED PWM |\n| [ADCServoControl](examples/ADCServoControl) | Potentiometer control |\n| [HighSpeedServo](examples/HighSpeedServo) | 333Hz digital servo sweep |\n| [MotorPwm](examples/MotorPwm) | 20kHz motor duty cycle ramp |\n| [MotorGroup](examples/MotorGroup) | Coordinated multi-motor control |\n| [ServoAndMotor](examples/ServoAndMotor) | 50Hz servo + 20kHz motor together |\n\n---\n\n## 🔍 Troubleshooting\n\n| Problem | Solution |\n|:--------|:---------|\n| Servo not moving | Check 5V power supply; verify GPIO is valid for your board |\n| Servo jittering | Use external power; add 100μF capacitor near servo |\n| Limited rotation range | Calibrate pulse width (try 1000-2000μs range) |\n| Stops after `analogWrite()` | Timer conflict — see solutions above |\n| `attach()` returns 255 | No channels available, invalid pin, or pin already in use |\n| Motor not spinning | Verify driver wiring; RoboMotor drives PWM enable, not direction pins |\n\n---\n\n## 📄 License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n---\n\n\u003cp align=\"center\"\u003e\n  Made with ❤️ for the ESP32 \u0026 ESP8266 community\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003csub\u003ev0.2.0 • Supports ESP32, ESP32-S2/S3, ESP32-C3/C6/H2, ESP32-P4, ESP8266\u003c/sub\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunknowcoding%2Froboservo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdunknowcoding%2Froboservo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunknowcoding%2Froboservo/lists"}