77 lines
5.2 KiB
Markdown
77 lines
5.2 KiB
Markdown
# 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)](../examples/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*](../Other%20Examples/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.
|
|
|
|
---
|
|
|
|
[↩️](README.md) Back to the Welcome page
|