Improve visuals and animation
This commit is contained in:
parent
654bd8bdf6
commit
700bc71bf6
3 changed files with 124 additions and 65 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -900,6 +900,7 @@ dependencies = [
|
|||
"esp-println",
|
||||
"esp-wifi",
|
||||
"heapless",
|
||||
"libm",
|
||||
"log",
|
||||
"smart-leds",
|
||||
"smoltcp",
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ smart-leds = "0.4.0"
|
|||
ws2812-spi = "0.5.0"
|
||||
embassy-futures = "0.1.1"
|
||||
embassy-sync = "0.7.0"
|
||||
libm = "0.2.15"
|
||||
|
||||
[profile.dev]
|
||||
# Rust debug is too slow.
|
||||
|
|
|
|||
183
src/bin/main.rs
183
src/bin/main.rs
|
|
@ -1,20 +1,28 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use core::ops::BitXor;
|
||||
use core::ops::Rem;
|
||||
use core::pin::Pin;
|
||||
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::select::{Either, select};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
|
||||
use embassy_sync::channel::{Channel, Sender};
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_sync::watch::{self, Watch};
|
||||
use embassy_time::{Duration, Instant, Timer, WithTimeout};
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::gpio::{Input, InputConfig, Pull};
|
||||
use esp_hal::gpio::{DriveMode, Input, InputConfig, Pull};
|
||||
use esp_hal::peripherals::GPIO;
|
||||
use esp_hal::rng;
|
||||
use esp_hal::spi::master::{Config, Spi};
|
||||
use esp_hal::time::Rate;
|
||||
use esp_hal::timer::systimer::SystemTimer;
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use esp_hal::{Async, Blocking, DriverMode};
|
||||
use libm::sin;
|
||||
use log::info;
|
||||
use smart_leds::RGB8;
|
||||
use smart_leds::SmartLedsWrite;
|
||||
|
|
@ -28,11 +36,30 @@ fn panic(_: &core::panic::PanicInfo) -> ! {
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
struct TargetState {
|
||||
enabled: [bool; 12],
|
||||
}
|
||||
|
||||
impl Default for TargetState {
|
||||
fn default() -> Self {
|
||||
TargetState {
|
||||
enabled: [false; 12],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CHANNEL: StaticCell<Channel<NoopRawMutex, i32, 2>> = StaticCell::new();
|
||||
static STATE: Mutex<CriticalSectionRawMutex, TargetState> = Mutex::new(TargetState {
|
||||
enabled: [false; 12],
|
||||
});
|
||||
|
||||
const ORDER: [usize; 12] = [5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11];
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
let channel = CHANNEL.init(Channel::new());
|
||||
//let state_watch = STATE.init(Arc::new(Mutex::new(TargetState::default())));
|
||||
// generator version: 0.3.1
|
||||
|
||||
esp_println::logger::init_logger_from_env();
|
||||
|
|
@ -55,23 +82,7 @@ async fn main(spawner: Spawner) {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
spawner
|
||||
.spawn(listen_rotary_encoder(
|
||||
RotaryEncoderConfig {
|
||||
clk: Input::new(
|
||||
peripherals.GPIO8,
|
||||
InputConfig::default().with_pull(Pull::Up),
|
||||
),
|
||||
ot: Input::new(
|
||||
peripherals.GPIO10,
|
||||
InputConfig::default().with_pull(Pull::Up),
|
||||
),
|
||||
},
|
||||
channel.sender(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let mut led_strip = {
|
||||
let led_strip = {
|
||||
let spi = Spi::new(
|
||||
peripherals.SPI2,
|
||||
Config::default().with_frequency(Rate::from_mhz(3)),
|
||||
|
|
@ -81,56 +92,35 @@ async fn main(spawner: Spawner) {
|
|||
Ws2812::new(spi)
|
||||
};
|
||||
|
||||
let colors = [
|
||||
RGB8 { r: 0, g: 255, b: 0 },
|
||||
RGB8 { r: 255, g: 0, b: 0 },
|
||||
RGB8 { r: 255, g: 0, b: 0 },
|
||||
RGB8 {
|
||||
r: 0,
|
||||
g: 255,
|
||||
b: 255,
|
||||
},
|
||||
RGB8 {
|
||||
r: 255,
|
||||
g: 0,
|
||||
b: 255,
|
||||
},
|
||||
RGB8 {
|
||||
r: 255,
|
||||
g: 255,
|
||||
b: 0,
|
||||
},
|
||||
];
|
||||
let mut color_idx = 0;
|
||||
let encoder = RotaryEncoderConfig {
|
||||
clk: Input::new(
|
||||
peripherals.GPIO8,
|
||||
InputConfig::default().with_pull(Pull::Up),
|
||||
),
|
||||
ot: Input::new(
|
||||
peripherals.GPIO10,
|
||||
InputConfig::default().with_pull(Pull::Up),
|
||||
),
|
||||
};
|
||||
spawner
|
||||
.spawn(listen_rotary_encoder(encoder, channel.sender()))
|
||||
.unwrap();
|
||||
spawner.spawn(render_gems(led_strip)).unwrap();
|
||||
|
||||
let mut state = TargetState::default();
|
||||
let mut cnt = 0;
|
||||
loop {
|
||||
let delta = channel.receive().await;
|
||||
color_idx += delta;
|
||||
// led_strip
|
||||
// .write([
|
||||
// colors[color_idx % colors.len()],
|
||||
// colors[(color_idx + 1) % colors.len()],
|
||||
// colors[(color_idx + 2) % colors.len()],
|
||||
// colors[(color_idx + 3) % colors.len()],
|
||||
// ])
|
||||
// .unwrap();
|
||||
//
|
||||
cnt = (cnt + delta).clamp(0, 12);
|
||||
|
||||
let cnt = 12;
|
||||
|
||||
led_strip
|
||||
.write((0..cnt).map(|it| {
|
||||
if it <= (color_idx % cnt) {
|
||||
RGB8 {
|
||||
r: 255,
|
||||
g: 50,
|
||||
b: 00,
|
||||
state.enabled = [false; 12];
|
||||
for i in (0..12) {
|
||||
state.enabled[ORDER[i]] = (cnt > i as i32);
|
||||
}
|
||||
} else {
|
||||
RGB8 { r: 0, g: 0, b: 0 }
|
||||
{
|
||||
let mut state_lock = STATE.lock().await;
|
||||
*state_lock = state.clone();
|
||||
}
|
||||
}))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-beta.0/examples/src/bin
|
||||
|
|
@ -153,6 +143,73 @@ enum RotaryDirection {
|
|||
Ccw,
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn render_gems(
|
||||
mut strip: Ws2812<Spi<'static, Blocking>>,
|
||||
//target: Mutex<NoopRawMutex, TargetState>,
|
||||
) {
|
||||
let mut temp = [0.0f32; 12];
|
||||
let mut last_state = TargetState::default();
|
||||
let mut frame = 0usize;
|
||||
|
||||
loop {
|
||||
frame = frame.wrapping_add(1);
|
||||
|
||||
{
|
||||
let target = STATE.lock().await;
|
||||
|
||||
for i in (0..12) {
|
||||
if target.enabled[i] && !last_state.enabled[i] {
|
||||
temp[i] = 3.0;
|
||||
} else {
|
||||
let trg = if target.enabled[i] { 1.0 } else { 0.0 };
|
||||
let speed = ((temp[i] - trg).abs() * 0.2).clamp(0.1, 0.5);
|
||||
|
||||
if temp[i] < trg {
|
||||
temp[i] = (temp[i] + speed).min(trg);
|
||||
} else {
|
||||
temp[i] = (temp[i] - speed).max(trg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_state = target.clone();
|
||||
}
|
||||
|
||||
strip
|
||||
.write(temp.iter().enumerate().map(|(index, it)| {
|
||||
let temp = *it;
|
||||
// let temp = *it
|
||||
// + (((sin(
|
||||
// //(index.wrapping_mul(182945).bitxor(48194291).rem(100) as f64) +
|
||||
// (frame as f64 * 0.05),
|
||||
// ) as f32)
|
||||
// / 2.0
|
||||
// + 0.5)
|
||||
// * 0.1);
|
||||
|
||||
let green_tint = 20.0;
|
||||
|
||||
if temp > 1.0 {
|
||||
RGB8 {
|
||||
r: 255u8,
|
||||
g: (50.0 + (255.0 - 50.0) * (temp - 1.0)) as u8,
|
||||
b: (255.0 * (temp - 1.0)) as u8,
|
||||
}
|
||||
} else {
|
||||
RGB8 {
|
||||
r: (255.0 * temp) as u8,
|
||||
g: (green_tint * temp) as u8,
|
||||
b: (20.0 * (1.0 - temp)) as u8,
|
||||
}
|
||||
}
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
Timer::after_millis(1000 / 24).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn listen_rotary_encoder(
|
||||
mut config: RotaryEncoderConfig<'static, 'static>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue