MojoScale Studio Docs
API Reference

servo

Servo motor control module.

Studio Docs Sensors & I/O

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.

API 14 available

servo.Servo(pin: int, min_us: int = None, max_us: int = None, frequency: int = None, resolution_bits: int = None) -> servo_device

Create 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.

Parameters
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.
Returns

servo_device servo_device object.

servo.Servo().write(angle) -> bool

Move this servo to an angle from 0 through 180 degrees.

Parameters
Name Type Pass as Required Description
angle float positional or keyword Yes Required value.

servo.Servo().write_us(pulse_us) -> bool

Move this servo using a raw pulse width in microseconds.

Parameters
Name Type Pass as Required Description
pulse_us int positional or keyword Yes Required value.

servo.Servo().read() -> float

Return the last requested angle in degrees.

servo.Servo().read_us() -> int

Return the last requested pulse width in microseconds.

servo.Servo().detach() -> bool

Stop the signal, reset the pin, and release this servo output.

servo.Servo().info() -> dict

Return 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

Low-level channel attach.

Prefer ``servo.Servo(pin)`` for new code. This function remains for older scripts that explicitly manage native servo channels.

Parameters
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.
Returns

bool True when the servo channel is configured and moved to its center pulse.

servo.write(channel: int, angle: float) -> bool

Low-level angle write for a channel.

Prefer ``my_servo.write(angle)`` for new code.

Parameters
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.
Returns

bool True when the pulse width is written.

servo.write_us(channel: int, pulse_us: int) -> bool

Low-level raw pulse write for a channel.

Prefer ``my_servo.write_us(pulse_us)`` for new code.

Parameters
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.
Returns

bool True when the pulse width is written.

servo.read(channel: int) -> float

Low-level angle read for a channel.

Prefer ``my_servo.read()`` for new code.

Parameters
Name Type Pass as Required Description
channel int positional or keyword Yes Servo channel created with ``attach``.
Returns

float Float angle in degrees.

servo.read_us(channel: int) -> int

Low-level pulse-width read for a channel.

Prefer ``my_servo.read_us()`` for new code.

Parameters
Name Type Pass as Required Description
channel int positional or keyword Yes Servo channel created with ``attach``.
Returns

int Integer pulse width in microseconds.

servo.detach(channel: int) -> bool

Low-level channel detach.

Prefer ``my_servo.detach()`` for new code.

Parameters
Name Type Pass as Required Description
channel int positional or keyword Yes Servo channel created with ``attach``.
Returns

bool True when an attached channel was stopped and reset; False when the channel was not attached.

servo.info(channel: int = None) -> dict

Return low-level servo channel state.

Prefer ``my_servo.info()`` for new code.

Parameters
Name Type Pass as Required Description
channel int positional or keyword No Optional servo channel. Defaults to 0.
Returns

dict Dict with ``attached``, ``pin``, ``channel``, ``frequency``, ``resolution_bits``, ``min_us``, ``max_us``, ``pulse_us``, and ``angle`` fields.