import servo
The servo module drives hobby-style PWM servos from ESP32 GPIO pins using the native LEDC peripheral. Create one servo object for each output pin; the firmware allocates the native PWM channel automatically.
Quick example
import servo
import system
pan = servo.Servo(18)
tilt = servo.Servo(pin=19, min_us=1000, max_us=2000)
pan.write(30)
tilt.write(150)
def center():
pan.write(90)
tilt.write_us(1500)
system.schedule("center", 1000, 1000, -1, center)
importservo
Servo motor control module.
The servo module drives hobby-style PWM servos from ESP32 GPIO pins using the native LEDC peripheral. Create one servo object for each output pin; the firmware allocates the native PWM channel automatically.
servo.Servo(pin: int, min_us: int = None, max_us: int = None, frequency: int = None, resolution_bits: int = None) -> servo_device
servo.Servo(pin: int, min_us: int = None, max_us: int = None, frequency: int = None, resolution_bits: int = None) -> servo_deviceCreate a servo output object.
The firmware selects a free native PWM channel and binds it to the returned servo object. Keep that object and call methods on it; users do not manage ESP32 LEDC channel numbers.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
pin |
int |
positional or keyword | Yes | GPIO output pin connected to the servo signal wire. |
min_us |
int |
positional or keyword | No | Optional pulse width for 0 degrees. Defaults to 500. |
max_us |
int |
positional or keyword | No | Optional pulse width for 180 degrees. Defaults to 2500. |
frequency |
int |
positional or keyword | No | Optional PWM frequency in hertz. Defaults to 50. |
resolution_bits |
int |
positional or keyword | No | Optional LEDC duty resolution from 1 through 14. Defaults to 14. |
servo_device servo_device object.
servo.Servo().write(angle) -> bool
servo.Servo().write(angle) -> boolMove this servo to an angle from 0 through 180 degrees.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
angle |
float |
positional or keyword | Yes | Required value. |
servo.Servo().write_us(pulse_us) -> bool
servo.Servo().write_us(pulse_us) -> boolMove this servo using a raw pulse width in microseconds.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
pulse_us |
int |
positional or keyword | Yes | Required value. |
servo.Servo().read() -> float
servo.Servo().read() -> floatReturn the last requested angle in degrees.
servo.Servo().read_us() -> int
servo.Servo().read_us() -> intReturn the last requested pulse width in microseconds.
servo.Servo().detach() -> bool
servo.Servo().detach() -> boolStop the signal, reset the pin, and release this servo output.
servo.Servo().info() -> dict
servo.Servo().info() -> dictReturn this servo's pin, channel, pulse, angle, and configuration. Duplicate pins, invalid pins, exhausted servo channels, and unsupported timing settings raise firmware errors.
servo.attach(pin: int, channel: int = None, min_us: int = None, max_us: int = None, frequency: int = None, resolution_bits: int = None) -> bool
servo.attach(pin: int, channel: int = None, min_us: int = None, max_us: int = None, frequency: int = None, resolution_bits: int = None) -> boolLow-level channel attach.
Prefer ``servo.Servo(pin)`` for new code. This function remains for older scripts that explicitly manage native servo channels.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
pin |
int |
positional or keyword | Yes | GPIO output pin connected to the servo signal wire. |
channel |
int |
positional or keyword | No | Optional servo channel. Defaults to 0. Supported channels are 0 through 7. |
min_us |
int |
positional or keyword | No | Optional pulse width for 0 degrees. Defaults to 500. |
max_us |
int |
positional or keyword | No | Optional pulse width for 180 degrees. Defaults to 2500. |
frequency |
int |
positional or keyword | No | Optional PWM frequency in hertz. Defaults to 50. |
resolution_bits |
int |
positional or keyword | No | Optional LEDC duty resolution from 1 through 14. Defaults to 14. |
bool True when the servo channel is configured and moved to its center pulse.
servo.write(channel: int, angle: float) -> bool
servo.write(channel: int, angle: float) -> boolLow-level angle write for a channel.
Prefer ``my_servo.write(angle)`` for new code.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
channel |
int |
positional or keyword | Yes | Servo channel created with ``attach``. |
angle |
float |
positional or keyword | Yes | Target angle from 0 through 180 degrees. |
bool True when the pulse width is written.
servo.write_us(channel: int, pulse_us: int) -> bool
servo.write_us(channel: int, pulse_us: int) -> boolLow-level raw pulse write for a channel.
Prefer ``my_servo.write_us(pulse_us)`` for new code.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
channel |
int |
positional or keyword | Yes | Servo channel created with ``attach``. |
pulse_us |
int |
positional or keyword | Yes | Target pulse width in microseconds. It must be inside the configured ``min_us`` and ``max_us`` range for the channel. |
bool True when the pulse width is written.
servo.read(channel: int) -> float
servo.read(channel: int) -> floatLow-level angle read for a channel.
Prefer ``my_servo.read()`` for new code.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
channel |
int |
positional or keyword | Yes | Servo channel created with ``attach``. |
float Float angle in degrees.
servo.read_us(channel: int) -> int
servo.read_us(channel: int) -> intLow-level pulse-width read for a channel.
Prefer ``my_servo.read_us()`` for new code.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
channel |
int |
positional or keyword | Yes | Servo channel created with ``attach``. |
int Integer pulse width in microseconds.
servo.detach(channel: int) -> bool
servo.detach(channel: int) -> boolLow-level channel detach.
Prefer ``my_servo.detach()`` for new code.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
channel |
int |
positional or keyword | Yes | Servo channel created with ``attach``. |
bool True when an attached channel was stopped and reset; False when the channel was not attached.
servo.info(channel: int = None) -> dict
servo.info(channel: int = None) -> dictReturn low-level servo channel state.
Prefer ``my_servo.info()`` for new code.
| Name | Type | Pass as | Required | Description |
|---|---|---|---|---|
channel |
int |
positional or keyword | No | Optional servo channel. Defaults to 0. |
dict Dict with ``attached``, ``pin``, ``channel``, ``frequency``, ``resolution_bits``, ``min_us``, ``max_us``, ``pulse_us``, and ``angle`` fields.