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;
|
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!();
|
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]
|
#[main]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
|
@ -64,7 +66,7 @@ fn main() -> ! {
|
||||||
ledc.channel(channel::Number::Channel5, peripherals.GPIO21),
|
ledc.channel(channel::Number::Channel5, peripherals.GPIO21),
|
||||||
];
|
];
|
||||||
|
|
||||||
for channel in channels.iter_mut() {
|
channels.iter_mut().for_each(|channel| {
|
||||||
channel
|
channel
|
||||||
.configure(channel::config::Config {
|
.configure(channel::config::Config {
|
||||||
timer: &lstimer0,
|
timer: &lstimer0,
|
||||||
|
|
@ -72,37 +74,33 @@ fn main() -> ! {
|
||||||
pin_config: PinConfig::PushPull,
|
pin_config: PinConfig::PushPull,
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
});
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
let animations = [wave_animation, surge_animation, binary_animation, ping_animation, tyler_animation];
|
||||||
let mut angle: f32 = 0.0;
|
let mut current_animation_index = 0;
|
||||||
let cycle_duration_ms = 1000;
|
let mut animation_start_time = 0u32;
|
||||||
let steps_per_cycle = (cycle_duration_ms / 20) as u32;
|
let animation_switch_interval_ms = 3000;
|
||||||
let angle_step = (2.0 * PI) / steps_per_cycle as f32;
|
let frame_delay_ms = 10;
|
||||||
|
|
||||||
info!("Starting smooth sine wave LED brightness control (1 second cycle)...");
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for (i, channel) in channels.iter_mut().enumerate() {
|
let current_animation = animations[current_animation_index];
|
||||||
let phase_offset = (i as f32) * (2.0 * PI) / 6.0;
|
let led_values = current_animation(animation_start_time);
|
||||||
let led_angle = angle + phase_offset;
|
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);
|
delay.delay_millis(frame_delay_ms);
|
||||||
let duty_pct = (brightness * 100.0) as u8;
|
animation_start_time += frame_delay_ms;
|
||||||
|
|
||||||
channel.set_duty(duty_pct).unwrap();
|
if animation_start_time >= animation_switch_interval_ms {
|
||||||
|
animation_start_time = 0;
|
||||||
if i == 0 {
|
current_animation_index = (current_animation_index + 1) % animations.len();
|
||||||
info!("Base angle: {}, LED 0 brightness: {}%", angle, duty_pct);
|
info!("Switching to animation {}", current_animation_index);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delay.delay_millis(20);
|
|
||||||
|
|
||||||
angle += angle_step;
|
|
||||||
if angle >= 2.0 * PI {
|
|
||||||
angle = 0.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
pub mod animations;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue