feat: using duty cycles to make leds flow

This commit is contained in:
Jet Pham 2025-10-02 20:04:32 -07:00
parent c8b6ff7ffe
commit d3874cc7ad
No known key found for this signature in database
3 changed files with 79 additions and 19 deletions

7
Cargo.lock generated
View file

@ -749,6 +749,7 @@ dependencies = [
"esp-bootloader-esp-idf",
"esp-hal",
"esp-wifi",
"libm",
"panic-rtt-target",
"rtt-target",
"smoltcp",
@ -925,6 +926,12 @@ dependencies = [
"syn",
]
[[package]]
name = "libm"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "linked_list_allocator"
version = "0.10.5"

View file

@ -10,6 +10,7 @@ path = "./src/bin/main.rs"
[dependencies]
defmt = "1.0.1"
libm = "0.2"
esp-bootloader-esp-idf = { version = "0.2.0", features = ["esp32c6"] }
esp-hal = { version = "=1.0.0-rc.0", features = [
"defmt",

View file

@ -9,20 +9,29 @@
use defmt::info;
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::gpio::{Level, Output, OutputConfig};
use esp_hal::ledc::{
channel::{self, config::PinConfig, ChannelIFace},
timer::{self, config::Duty, LSClockSource, TimerIFace},
LSGlobalClkSource, Ledc, LowSpeed,
};
use esp_hal::main;
use esp_hal::time::Rate;
use esp_hal::timer::timg::TimerGroup;
use panic_rtt_target as _;
extern crate alloc;
// This creates a default app-descriptor required by the esp-idf bootloader.
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
use core::f32::consts::PI;
esp_bootloader_esp_idf::esp_app_desc!();
fn calculate_sine_brightness(angle: f32) -> f32 {
let sine_value = libm::sinf(angle);
(sine_value + 1.0) / 2.0
}
#[main]
fn main() -> ! {
// generator version: 0.5.0
rtt_target::rtt_init_defmt!();
@ -34,24 +43,67 @@ fn main() -> ! {
let timg0 = TimerGroup::new(peripherals.TIMG0);
let _init = esp_wifi::init(timg0.timer0, esp_hal::rng::Rng::new(peripherals.RNG)).unwrap();
let mut led = Output::new(peripherals.GPIO15, Level::Low, OutputConfig::default());
let mut ledc = Ledc::new(peripherals.LEDC);
ledc.set_global_slow_clock(LSGlobalClkSource::APBClk);
let mut lstimer0 = ledc.timer::<LowSpeed>(timer::Number::Timer0);
lstimer0
.configure(timer::config::Config {
duty: Duty::Duty8Bit,
clock_source: LSClockSource::APBClk,
frequency: Rate::from_hz(1000),
})
.unwrap();
let mut channels = [
ledc.channel(channel::Number::Channel0, peripherals.GPIO1),
ledc.channel(channel::Number::Channel1, peripherals.GPIO18),
ledc.channel(channel::Number::Channel2, peripherals.GPIO9),
ledc.channel(channel::Number::Channel3, peripherals.GPIO19),
ledc.channel(channel::Number::Channel4, peripherals.GPIO20),
ledc.channel(channel::Number::Channel5, peripherals.GPIO21),
];
for channel in channels.iter_mut() {
channel
.configure(channel::config::Config {
timer: &lstimer0,
duty_pct: 0,
pin_config: PinConfig::PushPull,
})
.unwrap();
}
// Initialize delay
let delay = Delay::new();
info!("Starting LED blink program on GPIO15...");
let mut angle: f32 = 0.0;
let cycle_duration_ms = 1000;
let steps_per_cycle = (cycle_duration_ms / 20) as u32;
let angle_step = (2.0 * PI) / steps_per_cycle as f32;
info!("Starting smooth sine wave LED brightness control (1 second cycle)...");
loop {
// Turn LED on
led.set_high();
info!("LED ON");
delay.delay_millis(1000);
for (i, channel) in channels.iter_mut().enumerate() {
let phase_offset = (i as f32) * (2.0 * PI) / 6.0;
let led_angle = angle + phase_offset;
// Turn LED off
led.set_low();
info!("LED OFF");
delay.delay_millis(1000);
let brightness = calculate_sine_brightness(led_angle);
let duty_pct = (brightness * 100.0) as u8;
channel.set_duty(duty_pct).unwrap();
if i == 0 {
info!("Base angle: {}, LED 0 brightness: {}%", angle, duty_pct);
}
}
delay.delay_millis(20);
angle += angle_step;
if angle >= 2.0 * PI {
angle = 0.0;
}
}
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-rc.0/examples/src/bin
}