LED APIs
LED
The LED provides a convenient and thread-safe wrapper around the ESP-IDF LEDC perhipheral.
It allows for both instant and hardware-based timed changing (fading) of duty cycle (in floating point percent [0,100]).
API Reference
Header File
Classes
-
class Led : public espp::BaseComponent
Provides a wrapper around the LEDC peripheral in ESP-IDF which allows for thread-safe control over one or more channels of LEDs using a simpler API.
Linear LED Example
fmt::print("Starting linear led example!\n"); float num_seconds_to_run = 10.0f; int led_fade_time_ms = 1000; std::vector<espp::Led::ChannelConfig> led_channels{{ .gpio = 2, .channel = LEDC_CHANNEL_5, .timer = LEDC_TIMER_2, }}; espp::Led led(espp::Led::Config{ .timer = LEDC_TIMER_2, .frequency_hz = 5000, .channels = led_channels, .duty_resolution = LEDC_TIMER_10_BIT, }); auto led_channel = led_channels[0].channel; auto start = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now(); float elapsed = std::chrono::duration<float>(now - start).count(); while (elapsed < num_seconds_to_run) { // if we can change the led, the previous fade is done if (led.can_change(led_channel)) { auto maybe_duty = led.get_duty(led_channel); if (maybe_duty.has_value()) { auto current_duty = maybe_duty.value(); float new_duty = (current_duty < 50.0f) ? 100.0f : 0.0f; // start a new fade to the opposite duty cycle led.set_fade_with_time(led_channel, new_duty, led_fade_time_ms); } } // sleep for a little bit std::this_thread::sleep_for(100ms); // update our elapsed time now = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration<float>(now - start).count(); }
Breathing LED Example
fmt::print("Starting gaussian led example!\n"); float breathing_period = 3.5f; // seconds float num_periods_to_run = 2.0f; std::vector<espp::Led::ChannelConfig> led_channels{{ .gpio = 2, .channel = LEDC_CHANNEL_5, .timer = LEDC_TIMER_2, }}; espp::Led led(espp::Led::Config{ .timer = LEDC_TIMER_2, .frequency_hz = 5000, .channels = led_channels, .duty_resolution = LEDC_TIMER_10_BIT, .clock_config = LEDC_USE_RC_FAST_CLK, }); espp::Gaussian gaussian({.gamma = 0.1f, .alpha = 1.0f, .beta = 0.5f}); auto breathe = [&gaussian, &breathing_period]() -> float { static auto breathing_start = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration<float>(now - breathing_start).count(); float t = std::fmod(elapsed, breathing_period) / breathing_period; return gaussian(t); }; auto led_callback = [&breathe, &led, &led_channels](auto &m, auto &cv) -> bool { led.set_duty(led_channels[0].channel, 100.0f * breathe()); std::unique_lock<std::mutex> lk(m); cv.wait_for(lk, 10ms); return false; }; auto led_task = espp::Task::make_unique({.callback = led_callback, .task_config = {.name = "breathe"}}); led_task->start(); float wait_time = num_periods_to_run * breathing_period; fmt::print("Sleeping for {:.1f}s...\n", wait_time); std::this_thread::sleep_for(wait_time * 1.0s);
Public Functions
-
inline explicit Led(const Config &config) noexcept
Initialize the LEDC subsystem according to the configuration.
- Parameters
config – The configuration structure for the LEDC subsystem.
-
inline ~Led()
Stop the LEDC subsystem and free memory.
-
inline bool can_change(ledc_channel_t channel)
Can the LED settings can be changed for the channel? If this function returns true, then (threaded race conditions aside), the set_duty() and set_fade_with_time() functions should not block.
- Parameters
channel – The channel to check
- Returns
True if the channel settings can be changed, false otherwise
-
inline std::optional<float> get_duty(ledc_channel_t channel) const
Get the current duty cycle this channel has.
- Parameters
channel – The channel in question
- Returns
The duty percentage [0.0f, 100.0f] if the channel is managed, std::nullopt otherwise
-
inline void set_duty(ledc_channel_t channel, float duty_percent)
Set the duty cycle for this channel.
Note
This function will block until until a current fade process completes (if there is one).
- Parameters
channel – The channel to set the duty cycle for.
duty_percent – The new duty percentage, [0.0, 100.0].
-
inline void set_fade_with_time(ledc_channel_t channel, float duty_percent, uint32_t fade_time_ms)
Set the duty cycle for this channel, fading from the current duty cycle to the new duty cycle over
fade_time_ms
milliseconds.Note
This function will block until until a current fade process completes (if there is one).
- Parameters
channel – The channel to fade.
duty_percent – The new duty percentage to fade to, [0.0, 100.0].
fade_time_ms – The number of milliseconds for which to fade.
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
-
struct ChannelConfig
Represents one LED channel.
Public Members
-
size_t gpio
The GPIO pin the LED is connected to.
-
ledc_channel_t channel
The LEDC channel that you want associated with this LED.
-
ledc_timer_t timer
The LEDC timer that you want associated with this LED channel.
-
float duty{0}
The starting duty cycle (%) [0, 100] that you want the LED channel to have.
-
ledc_mode_t speed_mode{LEDC_LOW_SPEED_MODE}
The LEDC speed mode you want for this LED channel.
-
bool output_invert = {false}
Whether to invert the GPIO output for this LED channel.
-
size_t gpio
-
struct Config
Configuration Struct for the LEDC subsystem including the different LED channels that should be associated.
Public Members
-
int isr_core_id = -1
The core to install the LEDC fade function (interrupt) on. If -1, then the LEDC interrupt is installed on the core that this constructor is called on. If 0 or 1, then the LEDC interrupt is installed on the specified core.
-
ledc_timer_t timer
The LEDC timer that you want associated with the LEDs.
-
size_t frequency_hz
The frequency that you want to run the PWM hardawre for the LEDs at.
Note
this is inversely related to the duty resolution configuration.
-
std::vector<ChannelConfig> channels
The LED channels that you want to control.
-
ledc_timer_bit_t duty_resolution{LEDC_TIMER_13_BIT}
The resolution of the duty cycle for these LEDs.
Note
this is inversely related to the frequency configuration.
-
ledc_clk_cfg_t clock_config{LEDC_AUTO_CLK}
The LEDC clock configuration you want for these LED channels.
-
ledc_mode_t speed_mode{LEDC_LOW_SPEED_MODE}
The LEDC speed mode you want for these LED channels.
-
int isr_core_id = -1
-
inline explicit Led(const Config &config) noexcept