Servo

[中文]

This component uses the LEDC peripheral to generate PWM signals for independent control of multiple servos through servo handles. The maximum number of servos is limited by the number of LEDC channels on the chip (ESP32 chips support 16 channels and ESP32-S2 chips support 8 channels) at a selectable frequency of 50 ~ 400 Hz. When using this layer of APIs, users only need to create a servo handle and specify the target angle to control a servo.

Generally, there is a reference signal inside the servo generating a fixed period and pulse width, which is used to compare with the input PWM signal to output a voltage difference so as to control the rotation direction and angle of a motor. A common 180 angular rotation servo usually takes 20 ms (50 Hz) as a clock period and 0.5 ~ 2.5 ms as its high level pulse, making it rotates between 0 ~ 180 degrees.

This component can be used in scenarios with lower control accuracy requirements, such as toy cars, remote control robots, home automation, etc.

Instructions

  1. Initialization: Use iot_servo_new() to create a servo handle. Please note that ESP32 contains two sets of channels as LEDC_LOW_SPEED_MODE and LEDC_HIGH_SPEED_MODE, while some chips may only support one group. The configuration items in this step mainly include maximum angle, signal frequency, and minimum and maximum input pulse width to calculate the correspondence between angle and duty cycle; as well as GPIO, LEDC timer, and LEDC channel to specify PWM output resources;

  2. Set a target angle: use iot_servo_write_angle() to specify the servo handle and target angle so as to realize angle control of the servo;

  3. Read the current angle: you can use iot_servo_read_angle() to read the current angle of the servo. Please note that this is a theoretical number calculated based on the input signal;

  4. De-initialization: you can use iot_servo_del() to delete a servo handle when the servo is no longer used.

Each servo handle owns one LEDC channel, and a channel cannot be used by more than one servo handle at the same time. Multiple servo handles can share the same LEDC timer only when they use the same speed mode, frequency, and duty resolution. Use different LEDC timers for servos that require different PWM frequencies.

Application Example

servo_handle_t servos[2] = { NULL };
servo_config_t servo_cfg = SERVO_CONFIG_DEFAULT(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, LEDC_CHANNEL_0, SERVO_CH0_PIN);
iot_servo_new(&servo_cfg, &servos[0]);

servo_cfg.channel = LEDC_CHANNEL_1;
servo_cfg.gpio_num = SERVO_CH1_PIN;
iot_servo_new(&servo_cfg, &servos[1]);

float angle = 100.0f;

// Set angle to 100 degree
iot_servo_write_angle(servos[0], angle);

// Get current angle of servo
iot_servo_read_angle(servos[0], &angle);

//deinit servo
iot_servo_del(servos[0]);
iot_servo_del(servos[1]);

API Reference

Header File

Functions

esp_err_t iot_servo_new(const servo_config_t *config, servo_handle_t *ret_servo)

Create a servo motor instance.

Parameters
  • config – Pointer of servo configure struct

  • ret_servo – Pointer to the created servo handle

Returns

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_ERR_NO_MEM No memory for servo instance

  • ESP_ERR_INVALID_STATE LEDC timer/channel resource conflict

  • ESP_FAIL Configure ledc failed

esp_err_t iot_servo_del(servo_handle_t servo)

Delete a servo motor instance.

Parameters

servo – Servo handle created by iot_servo_new

Returns

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

  • ESP_FAIL Stop ledc channel failed

esp_err_t iot_servo_write_angle(servo_handle_t servo, float angle)

Set the servo motor to a certain angle.

Note

This API is not thread-safe

Parameters
  • servo – Servo handle created by iot_servo_new

  • angle – The angle to go

Returns

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

esp_err_t iot_servo_read_angle(servo_handle_t servo, float *angle)

Read current angle of the servo.

Parameters
  • servo – Servo handle created by iot_servo_new

  • angle – Current angle of the channel

Returns

  • ESP_OK Success

  • ESP_ERR_INVALID_ARG Parameter error

Structures

struct servo_config_t

Configuration of servo motor.

Public Members

uint16_t max_angle

Servo max angle

uint16_t min_width_us

Pulse width corresponding to minimum angle, which is usually 500us

uint16_t max_width_us

Pulse width corresponding to maximum angle, which is usually 2500us

uint32_t freq

PWM frequency

ledc_mode_t speed_mode

LEDC channel group with specified speed mode

ledc_timer_t timer_number

Timer number of ledc

ledc_channel_t channel

LEDC channel to use

gpio_num_t gpio_num

GPIO number of PWM output

Macros

SERVO_CONFIG_DEFAULT(_speed_mode, _timer_number, _channel, _gpio_num)

Default configuration for a common 180-degree servo.

The default PWM settings are 50 Hz with 500 us ~ 2500 us pulse width.

Type Definitions

typedef struct servo_t *servo_handle_t