LED Dimming Driver
The LED lights used in our project have five color options: red, green, blue, warm (WW), and cold (CW), so we need five PWM channels to control them. The target functions include turning on/off LED lights, and controlling their color, color temperature, brightness, breathing, and fading. However, since we are using the ESP32-C3-DevKitM-1 in practice, which only has R, G, and B channels, we can only change LEDs' colors but not their color temperature during development.
According to the requirements of the smart light project, the LED dimming driver is encapsulated and provided in the form of a light_driver
component, which can be found at book-esp32c3-iot-projects/device_firmware/components/light_driver
.
Besides, to save the status of LED lights, the project also introduces an app_storage
component. Its underlayer adopts NVS, which stores key-value pairs in the main flash partition by calling APIs in esp_partition.h
. The component can be found at book-esp32c3-iot-projects/device_firmware/components/app_storage
.
1. light_driver
component
According to the requirements of this project, the light_driver
component implements functions such as initializing/deinitializing the LED dimming driver, turning on/off lights, controlling their color, brightness, color temperature, etc. Table 6.1 lists the APIs provided for the main application by the LED dimming driver in the light_driver
component.
Table 6.1. APIs provided by the LED dimming driver in light_driver
API | Function |
---|---|
light_driver_init() | Initialize light_driver |
light_driver_deinit() | Deinitialize light_driver |
light_driver_config() | Configure fade time and blink cycle of light_driver |
light_driver_set_switch() | Turn on/off LED lights |
light_driver_get_switch() | Get the on/off status of LED lights |
light_driver_set_hue() | Set the Hue |
light_driver_get_hue() | Get the Hue |
light_driver_set_saturation() | Set the Saturation |
light_driver_get_saturation() | Get the Saturation |
light_driver_set_value() | Set the Value (as in HSV) |
light_driver_get_value() | Get the Value (as in HSV) |
light_driver_set_hsv() | Set the three HSV components in one call |
light_driver_get_hsv() | Get the three HSV components in one call |
light_driver_set_lightness() | Set the Lightness (as in HSL) |
light_driver_get_lightness() | Get the Lightness (as in HSL) |
light_driver_set_hsl() | Set the three HSL components in one call |
light_driver_get_hsl() | Get the three HSL components in one call |
light_driver_set_color_temperature() | Set the color temperature |
light_driver_get_color_temperature() | Get the color temperature |
light_driver_set_brightness() | Set the brightness |
light_driver_get_brightness() | Get the brightness |
light_driver_set_ctb() | Set color temperature and brightness in one call |
light_driver_get_ctb() | Get color temperature and brightness in one call |
light_driver_set_rgb() | Set the three RGB components in one call |
light_driver_breath_start() | Set the color of LED breathing and start breathing |
light_driver_breath_stop() | Stop breathing |
light_driver_blink_start() | Set the colour of LED blinking and start blinking |
light_driver_blink_stop() | Stop blinking |
2. app_storage
component
The app_storage
component uses non-volatile storage (NVS) at its underlying layer. Table 6.2 shows the APIs provided for the main application by the app_storage
component.
Table 6.2. APIs provided by the app_storage
component
API | Function |
---|---|
app_storage_init() | Initialize app_storage |
app_storage_set() | Store data in key-value pair format |
app_storage_get() | Get key-value pairs |
app_storage_erase() | Erase a specific key-value pair |
3. Saving LED status
When the LED lights are powered up, we may expect them to be set to the color and brightness of last use. To achieve this function, we need to save the status of the lights after each control and load the latest status when the driver is initialized. This status saving function is implemented in the light_driver
component. Every time an API in the light_driver
component is called to modify the LEDs' status, the new status will be saved, which will be loaded when the initialization API is called.
//Save LED status
if (app_storage_get(LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_ status_t)) ! = ESP_OK) {
//Code Omitted
}
//Load LED status
if (app_storage_set(LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_ status_t)) ! = ESP_OK) {
//Code Omitted
}
4. Initializing the driver
When adding the LED dimming driver to the smart light project, you need to write the code to initialize the driver in the app_main()
function. To use such code, a light_driver_config_t
parameter should be provided, which specifies the ESP32-C3 GPIOs used by the five PWM channels, the fade time, the breathing cycles, the PWM frequency, the clock source of the LEDC, the PWM duty resolution, etc. The driver initialization code in app_main()
is defined as function app_driver_init()
, and called as follows:
void app_driver_init()
{
//Code Omitted
//Initialize LED dimming driver
light_driver_config_t driver_config = {
.gpio_red= LIGHT_GPIO_RED,
.gpio_green = LIGHT_GPIO_GREEN,
.gpio_blue = LIGHT_GPIO_BLUE,
.gpio_cold = LIGHT_GPIO_COLD,
.gpio_warm = LIGHT_GPIO_WARM,
.fade_period_ms = LIGHT_FADE_PERIOD_MS,
.blink_period_ms = LIGHT_BLINK_PERIOD_MS,
.freq_hz = LIGHT_FREQ_HZ,
.clk_cfg = LEDC_USE_APB_CLK,
.duty_resolution = LEDC_TIMER_11_BIT,
};
ESP_ERROR_CHECK(light_driver_init(&driver_config));
//Code Omitted
}
5. Controlling LED status
After initializing the LED dimming driver, we can use the APIs provided by the light_driver
component to control the LED lights. Combined with the button driver, the LED lights can be turned on/off through a button. Here, we will focus on controlling the on/off status, the color, and the color temperature.
(1) On/off status
The following API can be used to control the on/off status of the LED lights.
//Turn on the light
light_driver_set_switch(true);
//Turn off the light
light_driver_set_switch(false);
(2) Color
After initializing the LED dimming driver and turning on the lights, the color of the LEDs can be controlled based on RGB, HSL, or HSV color spaces. When using LED dimming APIs, pay attention to the parameter value range of these APIs:
- HSV: Hue ≤ 360, Saturation ≤ 100, Value ≤ 100.
- HSL: Hue ≤ 360, Saturation ≤ 100, Lightness ≤ 100.
- RGB: Red ≤ 255, Green ≤ 255, Blue ≤ 255.
The following APIs are used for adjusting all three components of RGB, HSL, or HSV color space in one call. You can also adjust only one component using APIs listed in Table 6.1.
//RGB color control
light_driver_set_rgb(uint8_t red, uint8_t green, uint8_t blue);
//HSL color control
light_driver_set_hsl(uint16_t hue, uint8_t saturation, uint8_t lightness);
//HSV color control
light_driver_set_hsv(uint16_t hue, uint8_t saturation, uint8_t value);
(3) Color temperature
In addition to controlling the on/off status and color, light_driver
APIs can also be used to control the color temperature (but not available for simulated lights). The following API can be used to change the color temperature and brightness:
light_driver_set_ctb(uint8_t color_temperature, uint8_t brightness);
📝 Source code
Please refer to
book-esp32c3-iot-projects/device_firmware/2_light_drivers
for the complete code to add the LED dimming driver and the button driver to the smart light project. You can also check the running results after compiling the code and flashing it onto the development board.