HomeSpan/docs/NOW.md

5.2 KiB

Pulse Width Modulation (PWM)

The ESP32 has up to 16 PWM channels that can be used to drive a variety of devices. HomeSpan includes an integrated PWM library with dedicated classes designed for controlling Dimmable LEDs as well as Servo Motors. Both classes are provided in a standalone header file that is accessed by placing the following near the top of your sketch:

#include "extras/PwmPin.h"

LedPin(uint8_t pin [,float level [,uint16_t frequency]])

Creating an instance of this class configures the specified pin to output a PWM signal suitable for a controlling dimmable LED. Arguments, along with their defaults if left unspecified, are as follows:

  • pin - the pin on which the PWM control signal will be output
  • level - sets the initial %duty-cycle of the PWM from from 0 (LED completely off) to 100 (LED fully on). Default=0 (LED initially off)
  • frequency - sets the PWM frequency, in Hz, from 1-65535 (ESP32 only) or 5-65535 (ESP32-S2 and ESP32-C3). Defaults to 5000 Hz if unspecified, or if set to 0

The following methods are supported:

  • void set(float level)

    • sets the PWM %duty-cycle to level, where level ranges from 0 (LED completely off) to 100 (LED fully on)
  • int getPin()

    • returns the pin number (or -1 if LedPin was not successfully initialized)

LedPin also includes a static class function that converts Hue/Saturation/Brightness values (typically used by HomeKit) to Red/Green/Blue values (typically used to control multi-color LEDS).

  • static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b)

    • h - input Hue value, range 0-360
    • s - input Saturation value, range 0-1
    • v - input Brightness value, range 0-1
    • r - output Red value, range 0-1
    • g - output Green value, range 0-1
    • b - output Blue value, range 0-1

See tutorial sketch #10 (RGB_LED) for an example of using LedPin to control an RGB LED.

ServoPin(uint8_t pin [,double initDegrees [,uint16_t minMicros, uint16_t maxMicros, double minDegrees, double maxDegrees]])

Creating an instance of this class configures the specified pin to output a 50 Hz PWM signal, which is suitable for controlling most Servo Motors. There are three forms of the constructor: one with just a single argument; one with two arguments; and one with all six arguments. Arguments, along with their defaults if left unspecified, are as follows:

  • pin - the pin on which the PWM control signal will be output. The control wire of a Servo Motor should be connected this pin
  • initDegrees - the initial position (in degrees) to which the Servo Motor should be set (default=0°)
  • minMicros - the pulse width (in microseconds) that moves the Servo Motor to its "minimium" position of minDegrees (default=1000𝛍s)
  • maxMicros - the pulse width (in microseconds) that moves the Servo Motor to its "maximum" position of maxDegrees (default=2000𝛍s)
  • minDegrees - the position (in degrees) to which the Servo Motor moves when receiving a pulse width of minMicros (default=-90°)
  • maxDegrees - the position (in degrees) to which the Servo Motor moves when receiving a pulse width of maxMicros (default=90°)

The minMicros parameter must be less than the maxMicros parameter, but setting minDegrees to a value greater than maxDegrees is allowed and can be used to reverse the minimum and maximum positions of the Servo Motor. The following methods are supported:

  • void set(double position)

    • sets the position of the Servo Motor to position (in degrees). In order to protect the Servo Motor, values of position less than minDegrees are automatically reset to minDegrees, and values greater than maxDegrees are automatically reset to maxDegrees.
  • int getPin()

    • returns the pin number (or -1 if ServoPin was not successfully initialized)

A worked example showing how ServoPin can be used to control the Horizontal Tilt of a motorized Window Shade can be found in the Arduino IDE under File → Examples → HomeSpan → Other Examples → ServoControl.

PWM Resource Allocation and Limitations

The following PWM resources are available:

  • ESP32: 16 Channels / 8 Timers (arranged in two distinct sets of 8 Channels and 4 Timers)
  • ESP32-S2: 8 Channels / 4 Timers
  • ESP32-C3: 6 Channels / 4 Timers
  • ESP32-S3: 8 Channels / 4 Timers

HomeSpan automatically allocates Channels and Timers to LedPin and ServoPin objects as they are instantiated. Every pin assigned consumes a single Channel; every unique frequency specified among all channels (within the same set, for the ESP32) consumes a single Timer. HomeSpan will conserve resources by re-using the same Timer for all Channels operating at the same frequency. HomeSpan also automatically configures each Timer to support the maximum duty-resolution possible for the frequency specified.

HomeSpan will report a non-fatal error message to the Arduino Serial Monitor when insufficient Channel or Timer resources prevent the creation of a new LedPin or ServoPin object. Calls to the set() method for objects that failed to be properly created are silently ignored.


↩️ Back to the Welcome page