feat: add animations!
This commit is contained in:
parent
d3874cc7ad
commit
f3bcebc44c
8 changed files with 124 additions and 32 deletions
13
src/animations/binary.rs
Normal file
13
src/animations/binary.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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;
|
||||
|
||||
let mut leds = [0u8; 6];
|
||||
(0..6).for_each(|i| {
|
||||
if count & (1 << i) != 0 {
|
||||
leds[5-i] = 100;
|
||||
}
|
||||
});
|
||||
|
||||
leds
|
||||
}
|
||||
13
src/animations/mod.rs
Normal file
13
src/animations/mod.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
pub type AnimationFunction = fn(u32) -> [u8; 6];
|
||||
|
||||
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;
|
||||
19
src/animations/ping.rs
Normal file
19
src/animations/ping.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
pub fn ping_animation(time_ms: u32) -> [u8; 6] {
|
||||
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 led_index = if cycle_position < 6.0 / 10.0 {
|
||||
(cycle_position * 10.0) as usize
|
||||
} else {
|
||||
(10.0 - (cycle_position * 10.0)) as usize
|
||||
};
|
||||
|
||||
// Ensure we don't go out of bounds
|
||||
if led_index < 6 {
|
||||
leds[led_index] = 100;
|
||||
}
|
||||
|
||||
leds
|
||||
}
|
||||
10
src/animations/surge.rs
Normal file
10
src/animations/surge.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
use core::f32::consts::PI;
|
||||
|
||||
pub fn surge_animation(time_ms: u32) -> [u8; 6] {
|
||||
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]
|
||||
}
|
||||
20
src/animations/tyler.rs
Normal file
20
src/animations/tyler.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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
|
||||
}
|
||||
17
src/animations/wave.rs
Normal file
17
src/animations/wave.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use core::f32::consts::PI;
|
||||
|
||||
pub fn wave_animation(time_ms: u32) -> [u8; 6] {
|
||||
let cycle_duration_ms = 1000;
|
||||
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 phase_offset = (i as f32) * (2.0 * PI) / 6.0;
|
||||
let led_angle = angle + phase_offset;
|
||||
let sine_value = libm::sinf(led_angle);
|
||||
let brightness = (sine_value + 1.0) / 2.0;
|
||||
*led = (brightness * 100.0) as u8;
|
||||
});
|
||||
|
||||
leds
|
||||
}
|
||||
|
|
@ -21,14 +21,16 @@ use panic_rtt_target as _;
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
use core::f32::consts::PI;
|
||||
use firebeetle_2_board_esp32_c6::animations::{
|
||||
wave::wave_animation,
|
||||
surge::surge_animation,
|
||||
ping::ping_animation,
|
||||
binary::binary_animation,
|
||||
tyler::tyler_animation
|
||||
};
|
||||
|
||||
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() -> ! {
|
||||
|
|
@ -64,7 +66,7 @@ fn main() -> ! {
|
|||
ledc.channel(channel::Number::Channel5, peripherals.GPIO21),
|
||||
];
|
||||
|
||||
for channel in channels.iter_mut() {
|
||||
channels.iter_mut().for_each(|channel| {
|
||||
channel
|
||||
.configure(channel::config::Config {
|
||||
timer: &lstimer0,
|
||||
|
|
@ -72,37 +74,33 @@ fn main() -> ! {
|
|||
pin_config: PinConfig::PushPull,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
let delay = Delay::new();
|
||||
|
||||
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)...");
|
||||
let animations = [wave_animation, surge_animation, binary_animation, ping_animation, tyler_animation];
|
||||
let mut current_animation_index = 0;
|
||||
let mut animation_start_time = 0u32;
|
||||
let animation_switch_interval_ms = 3000;
|
||||
let frame_delay_ms = 10;
|
||||
|
||||
loop {
|
||||
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;
|
||||
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 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;
|
||||
delay.delay_millis(frame_delay_ms);
|
||||
animation_start_time += frame_delay_ms;
|
||||
|
||||
if animation_start_time >= animation_switch_interval_ms {
|
||||
animation_start_time = 0;
|
||||
current_animation_index = (current_animation_index + 1) % animations.len();
|
||||
info!("Switching to animation {}", current_animation_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
#![no_std]
|
||||
|
||||
pub mod animations;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue