animation
This commit is contained in:
parent
b9363f1c7d
commit
8e96e70cfd
4 changed files with 125 additions and 24 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -763,9 +763,11 @@ dependencies = [
|
|||
"embedded-io",
|
||||
"embedded-io-async",
|
||||
"embedded-storage",
|
||||
"fixed",
|
||||
"heapless",
|
||||
"mipidsi",
|
||||
"rgb",
|
||||
"smart-leds",
|
||||
"tinytga",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -48,3 +48,5 @@ embassy-futures = "0.1.2"
|
|||
heapless = "0.8.0"
|
||||
rgb = "0.8.52"
|
||||
tinytga = "0.5.0"
|
||||
smart-leds = "0.4.0"
|
||||
fixed = "1.29.0"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use embedded_graphics::{image::Image, pixelcolor::Rgb888, prelude::*};
|
||||
use embassy_time::Duration;
|
||||
use embedded_graphics::{image::Image, pixelcolor::Rgb888, prelude::*, primitives::Rectangle};
|
||||
use fixed::types::U0F8;
|
||||
use smart_leds::hsv::{Hsv, hsv2rgb};
|
||||
use tinytga::Tga;
|
||||
|
||||
pub struct Hal {
|
||||
|
|
@ -15,7 +18,6 @@ impl Hal {
|
|||
|
||||
impl Drawable for Hal {
|
||||
type Color = Rgb888;
|
||||
|
||||
type Output = ();
|
||||
|
||||
fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
|
||||
|
|
@ -40,7 +42,6 @@ impl HappyEyes {
|
|||
|
||||
impl Drawable for HappyEyes {
|
||||
type Color = Rgb888;
|
||||
|
||||
type Output = ();
|
||||
|
||||
fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
|
||||
|
|
@ -50,3 +51,86 @@ impl Drawable for HappyEyes {
|
|||
self.image_data.draw(target)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Rainbow {
|
||||
pub rate: Duration,
|
||||
pub width: u32,
|
||||
|
||||
pub elapsed: Duration,
|
||||
}
|
||||
|
||||
impl Rainbow {
|
||||
fn map(&self, x: i32) -> Rgb888 {
|
||||
let hue = ((x as f32 / self.width as f32
|
||||
+ self.elapsed.as_micros() as f32 / self.rate.as_micros() as f32)
|
||||
* 256.0) as u32 as u8;
|
||||
let color = hsv2rgb(Hsv {
|
||||
hue,
|
||||
sat: 255,
|
||||
val: 255,
|
||||
});
|
||||
Rgb888::new(color.r, color.g, color.b)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drawable for Rainbow {
|
||||
type Color = Rgb888;
|
||||
type Output = ();
|
||||
|
||||
fn draw<D>(&self, target: &mut D) -> Result<Self::Output, D::Error>
|
||||
where
|
||||
D: DrawTarget<Color = Self::Color>,
|
||||
{
|
||||
let bb = target.bounding_box();
|
||||
for dx in 0..bb.size.width {
|
||||
let color = self.map(dx as i32);
|
||||
target.fill_solid(
|
||||
&Rectangle::new(
|
||||
bb.top_left + Point::new(dx as i32, 0),
|
||||
Size::new(1, bb.size.height),
|
||||
),
|
||||
color,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RainbowFilter<'a, D> {
|
||||
pub inner_target: &'a mut D,
|
||||
pub rainbow: &'a Rainbow,
|
||||
}
|
||||
|
||||
impl<'a, D: DrawTarget<Color = Rgb888>> DrawTarget for RainbowFilter<'a, D> {
|
||||
type Color = D::Color;
|
||||
type Error = D::Error;
|
||||
|
||||
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
|
||||
where
|
||||
I: IntoIterator<Item = Pixel<Self::Color>>,
|
||||
{
|
||||
self.inner_target.draw_iter(
|
||||
pixels
|
||||
.into_iter()
|
||||
.map(|Pixel(point, color)| Pixel(point, mix(color, self.rainbow.map(point.x)))),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: Dimensions> Dimensions for RainbowFilter<'a, D> {
|
||||
fn bounding_box(&self) -> Rectangle {
|
||||
self.inner_target.bounding_box()
|
||||
}
|
||||
}
|
||||
|
||||
fn mix_u8(a: u8, b: u8) -> u8 {
|
||||
(a as u16 * b as u16 / 255) as u8
|
||||
}
|
||||
|
||||
fn mix(a: Rgb888, b: Rgb888) -> Rgb888 {
|
||||
Rgb888::new(
|
||||
mix_u8(a.r(), b.r()),
|
||||
mix_u8(a.g(), b.g()),
|
||||
mix_u8(a.b(), b.b()),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use embassy_rp::pio_programs::ws2812::{PioWs2812, PioWs2812Program};
|
|||
use embassy_rp::pwm::{self, Pwm};
|
||||
use embassy_rp::rom_data::reset_to_usb_boot;
|
||||
use embassy_rp::spi::{self, Blocking, Spi};
|
||||
use embassy_time::Delay;
|
||||
use embassy_time::{Delay, Duration, Instant, Ticker};
|
||||
use embedded_graphics::image::{Image, ImageRawLE};
|
||||
use embedded_graphics::mono_font::MonoTextStyle;
|
||||
use embedded_graphics::mono_font::ascii::FONT_10X20;
|
||||
|
|
@ -30,7 +30,7 @@ use mipidsi::interface::SpiInterface;
|
|||
use mipidsi::models::ST7789;
|
||||
use mipidsi::options::Orientation;
|
||||
|
||||
use crate::art::{Hal, HappyEyes};
|
||||
use crate::art::{Hal, HappyEyes, Rainbow, RainbowFilter};
|
||||
use crate::led_matrix::{LedMatrix, Serpentine};
|
||||
|
||||
use defmt_rtt as _;
|
||||
|
|
@ -116,8 +116,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||
|
||||
let mut led_pio = Pio::new(p.PIO0, Irqs);
|
||||
let led_program = PioWs2812Program::new(&mut led_pio.common);
|
||||
|
||||
let mut led_surface = LedMatrix::new(
|
||||
let led_surface = LedMatrix::new(
|
||||
Serpentine {
|
||||
size: Size::new(40, 8),
|
||||
},
|
||||
|
|
@ -129,23 +128,7 @@ async fn main(spawner: Spawner) -> ! {
|
|||
&led_program,
|
||||
),
|
||||
);
|
||||
led_surface.clear(Rgb888::BLACK).ok();
|
||||
/*
|
||||
Rectangle::new(Point::zero(), led_surface.size())
|
||||
.into_styled(
|
||||
PrimitiveStyleBuilder::new()
|
||||
.stroke_color(Rgb888::RED)
|
||||
.stroke_width(1)
|
||||
.fill_color(Rgb888::CSS_DARK_BLUE)
|
||||
.build(),
|
||||
)
|
||||
.draw(&mut led_surface)
|
||||
.ok();
|
||||
*/
|
||||
// let hal = Hal::new();
|
||||
let eyes = HappyEyes::new();
|
||||
eyes.draw(&mut led_surface).ok();
|
||||
led_surface.sync().await;
|
||||
spawner.spawn(led_task(led_surface)).ok();
|
||||
|
||||
let mut render = |f_keys: [bool; 4]| {
|
||||
display.clear(Rgb565::BLACK).ok();
|
||||
|
|
@ -186,6 +169,36 @@ async fn main(spawner: Spawner) -> ! {
|
|||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn led_task(mut led_surface: LedMatrix<'static>) {
|
||||
let hal = Hal::new();
|
||||
let eyes = HappyEyes::new();
|
||||
let mut rainbow = Rainbow {
|
||||
// rate: Duration::from_secs(10),
|
||||
// width: 300,
|
||||
rate: Duration::from_secs(1),
|
||||
width: 80,
|
||||
elapsed: Duration::from_secs(0),
|
||||
};
|
||||
|
||||
let mut ticker = Ticker::every(Duration::from_hz(30));
|
||||
let start = Instant::now();
|
||||
|
||||
loop {
|
||||
let elapsed = start.elapsed();
|
||||
rainbow.elapsed = elapsed;
|
||||
|
||||
led_surface.clear(Rgb888::BLACK).ok();
|
||||
eyes.draw(&mut RainbowFilter {
|
||||
inner_target: &mut led_surface,
|
||||
rainbow: &rainbow,
|
||||
})
|
||||
.ok();
|
||||
led_surface.sync().await;
|
||||
ticker.next().await;
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn dfu_button(mut btn_y: Input<'static>) {
|
||||
btn_y.wait_for_falling_edge().await;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue