mirror of
https://github.com/esp-rs/esp-idf-hal.git
synced 2025-10-01 06:11:16 +00:00
ledc: add support for fading leds (#519)
This commit is contained in:
parent
a38789173d
commit
318bb4e4fe
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
- `Send` for `AsyncCanDriver`
|
- `Send` for `AsyncCanDriver`
|
||||||
|
- `fade_with_time`, `fade_with_step` for `LedcDriver`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix the SDMMC driver for ESP-IDF V5.5+
|
- Fix the SDMMC driver for ESP-IDF V5.5+
|
||||||
|
39
examples/ledc_fade.rs
Normal file
39
examples/ledc_fade.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use esp_idf_hal::delay::FreeRtos;
|
||||||
|
use esp_idf_hal::ledc::{config::TimerConfig, LedcDriver, LedcTimerDriver};
|
||||||
|
use esp_idf_hal::peripherals::Peripherals;
|
||||||
|
use esp_idf_hal::prelude::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
esp_idf_hal::sys::link_patches();
|
||||||
|
|
||||||
|
let peripherals = Peripherals::take()?;
|
||||||
|
|
||||||
|
let timer_driver = LedcTimerDriver::new(
|
||||||
|
peripherals.ledc.timer0,
|
||||||
|
&TimerConfig::default().frequency(25.kHz().into()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut ledc_driver = LedcDriver::new(
|
||||||
|
peripherals.ledc.channel0,
|
||||||
|
timer_driver,
|
||||||
|
peripherals.pins.gpio7,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
for _ in 0..2 {
|
||||||
|
// Fade up over 2 seconds
|
||||||
|
ledc_driver.fade_with_time(
|
||||||
|
ledc_driver.get_max_duty(),
|
||||||
|
Duration::from_secs(2).as_millis() as i32,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Fade down over 2 seconds
|
||||||
|
ledc_driver.fade_with_time(0, Duration::from_secs(2).as_millis() as i32, true)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
ledc_driver.set_duty(ledc_driver.get_max_duty() / 10)?;
|
||||||
|
FreeRtos::delay_ms(10000);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
65
src/ledc.rs
65
src/ledc.rs
@ -3,8 +3,6 @@
|
|||||||
//! Interface to the [LED Control (LEDC)
|
//! Interface to the [LED Control (LEDC)
|
||||||
//! peripheral](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/peripherals/ledc.html)
|
//! peripheral](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/peripherals/ledc.html)
|
||||||
//!
|
//!
|
||||||
//! This is an initial implementation supporting the generation of PWM signals
|
|
||||||
//! but no chrome and spoilers like fading.
|
|
||||||
//!
|
//!
|
||||||
//! # Examples
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
@ -323,6 +321,69 @@ impl<'d> LedcDriver<'d> {
|
|||||||
pub fn timer(&self) -> ledc_timer_t {
|
pub fn timer(&self) -> ledc_timer_t {
|
||||||
self.timer as _
|
self.timer as _
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fade the LED to a target duty cycle over a specified time
|
||||||
|
pub fn fade_with_time(
|
||||||
|
&mut self,
|
||||||
|
target_duty: u32,
|
||||||
|
fade_time_ms: i32,
|
||||||
|
wait: bool,
|
||||||
|
) -> Result<(), EspError> {
|
||||||
|
let max_duty = self.get_max_duty();
|
||||||
|
if target_duty > max_duty {
|
||||||
|
return Err(EspError::from_infallible::<ESP_ERR_INVALID_ARG>());
|
||||||
|
}
|
||||||
|
|
||||||
|
let fade_mode = if wait {
|
||||||
|
ledc_fade_mode_t_LEDC_FADE_WAIT_DONE
|
||||||
|
} else {
|
||||||
|
ledc_fade_mode_t_LEDC_FADE_NO_WAIT
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
esp!(ledc_set_fade_with_time(
|
||||||
|
self.speed_mode,
|
||||||
|
self.channel(),
|
||||||
|
target_duty,
|
||||||
|
fade_time_ms
|
||||||
|
))?;
|
||||||
|
esp!(ledc_fade_start(self.speed_mode, self.channel(), fade_mode))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fade the LED to a target duty cycle using steps
|
||||||
|
pub fn fade_with_step(
|
||||||
|
&mut self,
|
||||||
|
target_duty: u32,
|
||||||
|
step_size: u32,
|
||||||
|
step_time_ms: u32,
|
||||||
|
wait: bool,
|
||||||
|
) -> Result<(), EspError> {
|
||||||
|
let max_duty = self.get_max_duty();
|
||||||
|
if target_duty > max_duty {
|
||||||
|
return Err(EspError::from_infallible::<ESP_ERR_INVALID_ARG>());
|
||||||
|
}
|
||||||
|
|
||||||
|
let fade_mode = if wait {
|
||||||
|
ledc_fade_mode_t_LEDC_FADE_WAIT_DONE
|
||||||
|
} else {
|
||||||
|
ledc_fade_mode_t_LEDC_FADE_NO_WAIT
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
esp!(ledc_set_fade_with_step(
|
||||||
|
self.speed_mode,
|
||||||
|
self.channel(),
|
||||||
|
target_duty,
|
||||||
|
step_size,
|
||||||
|
step_time_ms,
|
||||||
|
))?;
|
||||||
|
|
||||||
|
esp!(ledc_fade_start(self.speed_mode, self.channel(), fade_mode))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for LedcDriver<'_> {
|
impl Drop for LedcDriver<'_> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user