ESP32Servo Library

repository·master·Indexed 42 days ago

https://github.com/madhephaestus/esp32servo

An enhanced Servo library for ESP32 providing advanced PWM hardware support via LEDC and MCPWM while maintaining compatibility with standard Arduino Servo semantics. It includes the Servo class for degree-based control and the ESP32PWM class for granular control over frequency and resolution, supporting up to 20 PWM channels depending on the ESP32 variant.

Tokens
1.9K
Snippets
6
Records
11
Agent score
3%

What's inside ESP32Servo

  1. ESP32Servo Default Values and Constraints

    master

    Understanding the default behaviors and enforced limits of the library:

    Pulse Width Limits

    • Minimum allowed pulse width: 500us
    • Maximum allowed pulse width: 2500us

    Default Settings

    • Default min pulse width (for attach()): 544us
    • Default max pulse width (for attach()): 2400us
    • Default timer width: 16
    • Default initial pulse width: 1500us (servos are initialized with this value)
  2. Initialize ESP32PWM with frequency modes

    master

    The ESP32PWM class can be instantiated in two modes, which determines the preferred hardware driver used for PWM generation:

    1. Variable Frequency Mode (Default): Uses LEDC hardware as the preferred driver. This is suitable for applications where the frequency might change frequently.
    2. Fixed Frequency Mode: Uses MCPWM hardware as the preferred driver (on supported chips like ESP32-S3). This is ideal for servo control where a stable, fixed frequency is required.

    If the preferred hardware is unavailable, the library automatically falls back to the other hardware type.

    // Variable frequency (LEDC preferred)
    ESP32PWM pwm;
    ESP32PWM pwm(true);
    
    // Fixed frequency (MCPWM preferred)
    ESP32PWM pwm(false);
  3. Basic Servo Control with ESP32Servo

    master

    Use the Servo class to control servo motors on ESP32 pins. This class replicates standard Arduino Servo semantics and is a drop-in replacement for existing code.

    To use it, call attach(pin) to connect a servo to a GPIO pin, and write(angle) to set the position in degrees (0-180).

    #include <ESP32Servo.h>
    
    Servo myservo;
    myservo.attach(18);        // Attach to pin 18
    myservo.write(90);         // Set to 90 degrees
  4. Advanced PWM Control with ESP32PWM

    master

    For more granular control over PWM frequency and resolution, use the ESP32PWM class. This allows you to choose between variable frequency (using LEDC) or fixed frequency (using MCPWM, which is optimal for servos).

    • Variable Frequency (Default): Uses LEDC hardware. Instantiate with ESP32PWM pwm; or ESP32PWM pwm(true);.
    • Fixed Frequency: Uses MCPWM hardware. Instantiate with ESP32PWM pwm(false);.

    Use attachPin(pin, frequency, resolution) to configure the PWM signal.

    #include <ESP32PWM.h>
    
    // Variable frequency (default) - LEDC preferred
    ESP32PWM pwm1;             // or ESP32PWM pwm1(true);
    
    // Fixed frequency - MCPWM preferred
    ESP32PWM pwm2(false);      // Optimal for servos
    
    pwm1.attachPin(19, 1000, 10);  // 1kHz, 10-bit resolution
    pwm2.attachPin(21, 50, 10);    // 50Hz, 10-bit resolution
  5. ESP32-specific PWM Timer Functions

    master

    The following functions are specific to ESP32 hardware and allow direct manipulation of the PWM timer width.

    • setTimerWidth(value): Sets the PWM timer width (must be between 16 and 20). This recomputes the pulse width as a side effect.
    • int readTimerWidth(): Gets the current PWM timer width.
  6. Servo Class API Reference

    master

    The Servo class provides methods for manipulating servo motors connected to ESP32 pins.

    Methods

    • int attach(pin): Attaches the given GPIO pin to the next free channel. Returns channel number or 0 on failure. Recommended pins: 2, 4, 12-19, 21-23, 25-27, 32-33.
    • int attach(pin, min, max): Attaches to a pin setting min and max values in microseconds. Enforced limits: min $\ge$ 500, max $\le$ 2500.
    • void write(value): Sets the servo angle in degrees (0-180). If the value is $\ge$ 500, it is treated as a pulse width in microseconds.
    • void writeMicroseconds(value): Sets the servo pulse width in microseconds. Enforces min and max limits.
    • int read(): Returns the last written pulse width as an angle (0-180).
    • int readMicroseconds(): Returns the last written pulse width in microseconds.
    • bool attached(): Returns true if the instance is attached to a pin.
    • void detach(): Stops the servo and frees the attached pin and channel.
  7. ESP32Servo Hardware Support and Channel Limits

    master

    The library uses a dual hardware architecture (LEDC + MCPWM) to provide up to 20 PWM channels on supported boards. The total number of available channels depends on your specific ESP32 variant.

    ESP32 VariantLEDC ChannelsMCPWM ChannelsTotal Channels
    ESP32S381220
    ESP32S28-8
    ESP3216-16
    ESP32C36-6
    ESP32C566 (not implemented)12 (6 supported)
  8. Read PWM state and properties

    master

    You can query the current state of an ESP32PWM instance using the following methods:

    • attached(): Returns true if the pin is currently attached and active.
    • read(): Returns the current raw duty cycle.
    • readFreq(): Returns the current frequency.
    • getDutyScaled(): Returns the current duty cycle as a value between 0.0 and 1.0.
    • getPin(): Returns the GPIO pin number currently in use.
  9. Write duty cycle values to ESP32PWM

    master

    Once a pin is attached, you can control the PWM output using several methods:

    • write(uint32_t duty): Writes a raw duty cycle value.
    • writeScaled(double duty): Writes a duty cycle using a unit vector from 0.0 to 1.0 (where 1.0 is 100% duty cycle).
    • writeTone(double freq): Adjusts the frequency (only works on variable-frequency channels).
    • adjustFrequency(double freq, double dutyScaled = -1): Changes the frequency. If dutyScaled is provided, it also updates the duty cycle; otherwise, the current duty cycle is maintained.
    // Using scaled values (0.0 to 1.0)
    pwm.writeScaled(0.5); // 50% duty cycle
    
    // Using raw values
    pwm.write(2048); // Example raw value for 10-bit
    
    // Changing frequency while keeping duty cycle
    pwm.adjustFrequency(60.0);
  10. Check if a pin supports PWM

    master

    The static method hasPwm(int pin) allows you to verify if a specific GPIO pin on your specific ESP32 variant is capable of PWM output before attempting to attach it. This is useful for preventing runtime errors on unsupported pins.

    if (ESP32PWM::hasPwm(18)) {
        pwm.attachPin(18);
    } else {
        // Handle error: pin does not support PWM
    }
  11. Attach a pin to ESP32PWM

    master

    To start generating PWM on a specific pin, use attachPin. You can either attach a pin with default settings or specify a custom frequency and resolution.

    • attachPin(uint8_t pin): Attaches the pin using the frequency and resolution configured during the object's setup() or via the constructor's mode.
    • attachPin(uint8_t pin, double freq, uint8_t resolution_bits = 10): Attaches the pin with a specific frequency and bit resolution.

    Note: Resolution is typically between 1 and 16 bits, but actual limits depend on the chosen frequency.

    ESP32PWM pwm(false); // Fixed frequency mode
    
    // Attach pin 18 with 50Hz frequency and 10-bit resolution
    pwm.attachPin(18, 50.0, 10);