feat: expand into 8 leds
This commit is contained in:
parent
f3bcebc44c
commit
dab048d301
7 changed files with 95 additions and 106 deletions
|
|
@ -1,11 +1,11 @@
|
|||
pub fn binary_animation(time_ms: u32) -> [u8; 6] {
|
||||
let increment_interval_ms = 1000.0 / 64.0;
|
||||
let count = (time_ms as f32 / increment_interval_ms) as u32 % 64;
|
||||
pub fn binary_animation(time_ms: u32) -> [u8; 8] {
|
||||
let increment_interval_ms = 3000 / 256;
|
||||
let count = (time_ms / increment_interval_ms) % 256;
|
||||
|
||||
let mut leds = [0u8; 6];
|
||||
(0..6).for_each(|i| {
|
||||
let mut leds = [0u8; 8];
|
||||
(0..8).for_each(|i| {
|
||||
if count & (1 << i) != 0 {
|
||||
leds[5-i] = 100;
|
||||
leds[7-i] = 100;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
pub type AnimationFunction = fn(u32) -> [u8; 6];
|
||||
pub type AnimationFunction = fn(u32) -> [u8; 8];
|
||||
|
||||
pub mod wave;
|
||||
pub mod surge;
|
||||
pub mod ping;
|
||||
pub mod binary;
|
||||
pub mod tyler;
|
||||
|
||||
pub use wave::wave_animation;
|
||||
pub use surge::surge_animation;
|
||||
pub use ping::ping_animation;
|
||||
pub use binary::binary_animation;
|
||||
pub use tyler::tyler_animation;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
pub fn ping_animation(time_ms: u32) -> [u8; 6] {
|
||||
pub fn ping_animation(time_ms: u32) -> [u8; 8] {
|
||||
let cycle_duration_ms = 1000;
|
||||
let cycle_position = (time_ms % cycle_duration_ms) as f32 / cycle_duration_ms as f32;
|
||||
|
||||
let mut leds = [0u8; 6];
|
||||
let mut leds = [0u8; 8];
|
||||
|
||||
let led_index = if cycle_position < 6.0 / 10.0 {
|
||||
(cycle_position * 10.0) as usize
|
||||
let led_index = if cycle_position < 8.0 / 14.0 {
|
||||
(cycle_position * 14.0) as usize
|
||||
} else {
|
||||
(10.0 - (cycle_position * 10.0)) as usize
|
||||
(14.0 - (cycle_position * 14.0)) as usize
|
||||
};
|
||||
|
||||
// Ensure we don't go out of bounds
|
||||
if led_index < 6 {
|
||||
if led_index < 8 {
|
||||
leds[led_index] = 100;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use core::f32::consts::PI;
|
||||
|
||||
pub fn surge_animation(time_ms: u32) -> [u8; 6] {
|
||||
pub fn surge_animation(time_ms: u32) -> [u8; 8] {
|
||||
let cycle_duration_ms = 2000;
|
||||
let angle = (time_ms as f32 / cycle_duration_ms as f32) * 2.0 * PI;
|
||||
let sine_value = libm::sinf(angle);
|
||||
let brightness = (sine_value + 1.0) / 2.0;
|
||||
let duty = (brightness * 100.0) as u8;
|
||||
[duty; 6]
|
||||
[duty; 8]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
use core::f32::consts::PI;
|
||||
use defmt::info;
|
||||
|
||||
pub fn tyler_animation(time_ms: u32) -> [u8; 6] {
|
||||
let cycle_duration_ms = 3000;
|
||||
let angle = (time_ms as f32 / cycle_duration_ms as f32) * 2.0 * PI;
|
||||
|
||||
let mut leds = [0u8; 6];
|
||||
leds.iter_mut().enumerate().for_each(|(i, led)| {
|
||||
let sine_value = (1..i+2).fold(1.0, |acc, i| {
|
||||
let b = i as f32;
|
||||
acc * libm::sinf(b * angle + (b * 0.5)) - 0.1
|
||||
});
|
||||
info!("{:?}", sine_value);
|
||||
let brightness = sine_value.max(0.0);
|
||||
*led = (brightness * 100.0) as u8;
|
||||
});
|
||||
|
||||
leds
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
use core::f32::consts::PI;
|
||||
|
||||
pub fn wave_animation(time_ms: u32) -> [u8; 6] {
|
||||
pub fn wave_animation(time_ms: u32) -> [u8; 8] {
|
||||
let cycle_duration_ms = 1000;
|
||||
let angle = (time_ms as f32 / cycle_duration_ms as f32) * 2.0 * PI;
|
||||
|
||||
let mut leds = [0u8; 6];
|
||||
let mut leds = [0u8; 8];
|
||||
leds.iter_mut().enumerate().for_each(|(i, led)| {
|
||||
let phase_offset = (i as f32) * (2.0 * PI) / 6.0;
|
||||
let phase_offset = (i as f32) * (2.0 * PI) / 8.0;
|
||||
let led_angle = angle + phase_offset;
|
||||
let sine_value = libm::sinf(led_angle);
|
||||
let brightness = (sine_value + 1.0) / 2.0;
|
||||
|
|
|
|||
136
src/bin/main.rs
136
src/bin/main.rs
|
|
@ -6,35 +6,54 @@
|
|||
holding buffers for the duration of a data transfer."
|
||||
)]
|
||||
|
||||
use defmt::info;
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::delay::Delay;
|
||||
use esp_hal::ledc::{
|
||||
channel::{self, config::PinConfig, ChannelIFace},
|
||||
timer::{self, config::Duty, LSClockSource, TimerIFace},
|
||||
LSGlobalClkSource, Ledc, LowSpeed,
|
||||
use esp_hal::{
|
||||
clock::CpuClock,
|
||||
gpio::{Level, Output, OutputConfig},
|
||||
main,
|
||||
time::{Duration, Instant},
|
||||
timer::timg::TimerGroup,
|
||||
};
|
||||
use esp_hal::main;
|
||||
use esp_hal::time::Rate;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use panic_rtt_target as _;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use firebeetle_2_board_esp32_c6::animations::{
|
||||
wave::wave_animation,
|
||||
surge::surge_animation,
|
||||
ping::ping_animation,
|
||||
binary::binary_animation,
|
||||
tyler::tyler_animation
|
||||
binary::binary_animation, ping::ping_animation, surge::surge_animation, wave::wave_animation,
|
||||
};
|
||||
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
struct SoftwarePWM {
|
||||
duty_cycles: [u16; 8],
|
||||
pwm_period: u16,
|
||||
current_step: u16,
|
||||
}
|
||||
|
||||
impl SoftwarePWM {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
duty_cycles: [0; 8],
|
||||
pwm_period: 2000,
|
||||
current_step: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duty_cycles(&mut self, duty_cycles: [u8; 8]) {
|
||||
for (i, &duty) in duty_cycles.iter().enumerate() {
|
||||
self.duty_cycles[i] = (duty as u16 * 20).min(2000);
|
||||
}
|
||||
}
|
||||
|
||||
fn should_be_high(&self, led_index: usize) -> bool {
|
||||
self.current_step < self.duty_cycles[led_index]
|
||||
}
|
||||
|
||||
fn update_step(&mut self) {
|
||||
self.current_step = (self.current_step + 1) % self.pwm_period;
|
||||
}
|
||||
}
|
||||
|
||||
#[main]
|
||||
fn main() -> ! {
|
||||
|
||||
rtt_target::rtt_init_defmt!();
|
||||
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
|
|
@ -45,63 +64,56 @@ 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 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),
|
||||
let mut leds = [
|
||||
Output::new(peripherals.GPIO1, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO18, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO9, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO19, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO20, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO21, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO22, Level::Low, OutputConfig::default()),
|
||||
Output::new(peripherals.GPIO23, Level::Low, OutputConfig::default()),
|
||||
];
|
||||
|
||||
channels.iter_mut().for_each(|channel| {
|
||||
channel
|
||||
.configure(channel::config::Config {
|
||||
timer: &lstimer0,
|
||||
duty_pct: 0,
|
||||
pin_config: PinConfig::PushPull,
|
||||
})
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
let delay = Delay::new();
|
||||
let animations = [wave_animation, surge_animation, binary_animation, ping_animation, tyler_animation];
|
||||
let mut pwm = SoftwarePWM::new();
|
||||
let animations = [
|
||||
wave_animation,
|
||||
surge_animation,
|
||||
binary_animation,
|
||||
ping_animation,
|
||||
];
|
||||
let mut current_animation_index = 0;
|
||||
let mut animation_start_time = 0u32;
|
||||
let animation_switch_interval_ms = 3000;
|
||||
let frame_delay_ms = 10;
|
||||
|
||||
let mut animation_start = Instant::now();
|
||||
|
||||
loop {
|
||||
let current_animation = animations[current_animation_index];
|
||||
let led_values = current_animation(animation_start_time);
|
||||
info!("LED values: {:?}", led_values);
|
||||
|
||||
channels.iter_mut()
|
||||
.zip(led_values.iter())
|
||||
.for_each(|(channel, &duty_pct)| {
|
||||
channel.set_duty(duty_pct).unwrap();
|
||||
});
|
||||
let animation_elapsed_ms = animation_start.elapsed().as_millis() as u32;
|
||||
let led_values = current_animation(animation_elapsed_ms);
|
||||
|
||||
delay.delay_millis(frame_delay_ms);
|
||||
animation_start_time += frame_delay_ms;
|
||||
pwm.set_duty_cycles(led_values);
|
||||
|
||||
if animation_start_time >= animation_switch_interval_ms {
|
||||
animation_start_time = 0;
|
||||
let pwm_cycles = 100;
|
||||
for _ in 0..pwm_cycles {
|
||||
for i in 0..8 {
|
||||
if pwm.should_be_high(i) {
|
||||
leds[i].set_high();
|
||||
} else {
|
||||
leds[i].set_low();
|
||||
}
|
||||
}
|
||||
|
||||
pwm.update_step();
|
||||
|
||||
let delay_start = Instant::now();
|
||||
while delay_start.elapsed() < Duration::from_micros(5) {}
|
||||
}
|
||||
|
||||
if animation_elapsed_ms >= animation_switch_interval_ms {
|
||||
animation_start = Instant::now();
|
||||
current_animation_index = (current_animation_index + 1) % animations.len();
|
||||
info!("Switching to animation {}", current_animation_index);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue