Skip to content
My Account

Software

RTOS Servo Library for ESP8266

A small library to turn a hobby servo to an angle on an ESP8266, with a 50 Hz PWM output and a default pin of GPIO13.

  • ESP8266
  • 2 min read
No ratings yet, be the first.

A small library that lets an ESP8266 control a hobby servo with two calls: one to set up the PWM output, and one to turn to an angle. It works for many types of servo and uses the PWM timers of the chip.

The author tested it with an SG90, and the repository also targets the ESP32.

The functions

FunctionWhat it does
servo_init()Sets up one PWM output on the servo pin, at 50 Hz
servo_rotate_to_angle(angle)Turns the servo to the angle, 0 to 180 degrees

servo_rotate_to_angle starts a task, so your code does not wait. If a move is still running, the next one waits for it to finish. A move sets the PWM duty, starts the PWM for half a second, and then stops it, so the pulses stop once the servo has had time to arrive.

The PWM pin

The default PWM pin is GPIO13. You change it with the PWM_GPIO define at the top of servo.c.

The ESP8266 has software PWM on all I/O pins, GPIO0 to GPIO16, with a resolution of 10 bits. The ESP32 LED PWM controller has 16 independent channels, and every pin that can be an output can be a PWM pin, except GPIO34 to GPIO39, which cannot generate PWM.

From angle to pulse

A hobby servo expects a pulse every 20 ms, and the length of the pulse sets the angle. The library turns an angle into a duty cycle with a fixed formula, which maps 0 to 180 degrees onto pulses of 0.5 ms to 2.65 ms. The comment in the code explains why: the SG90 that was used works on 500 µs to 2650 µs, while its specification says 500 µs to 2400 µs. If your servo behaves differently, change the numbers in calc_duty_from_angle.

See the SG90 servo guide for the servo itself.

Example

The repository has an example, scr/main.c, that starts a task which asks the servo to turn to 180 degrees:

void servo_task(void *arg) {
    while (true) {
        servo_rotate_to_angle(180);
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
}

void user_init(void) {
    uart_set_baud(0, 115200);
    xTaskCreate(servo_task, "Servo Task", 4096, NULL, tskIDLE_PRIORITY, NULL);
}

The code that follows the loop, which turns the servo back to 0 degrees, is never reached, so change the example to fit what you want to do.

Good to know

  • The source uses the pwm.h of ESP-Open-RTOS, which is the ESP8266 SDK used for the ESP8266 HomeKit projects on this site.
  • Release 1.0.0 was made on 11 December 2021, and the repository is under the MIT licence.

Everything is in the RTOS-Servo-library repository on GitHub.

Advertisement
All projects

More projects

Keep building.

Electronics, 3D printing and CNC builds, documented from the first idea to the last screw.

All projects