Adjust colors and the blinker patterns
This commit is contained in:
parent
d7a70119c8
commit
80d8dedbaf
|
@ -33,6 +33,31 @@ const LIGHT_SCALE: I16F16 = I16F16::lit("256.0");
|
||||||
const DASHBOARD_BRIGHTESS: u8 = 1;
|
const DASHBOARD_BRIGHTESS: u8 = 1;
|
||||||
const BODY_BRIGHTNESS: u8 = 8;
|
const BODY_BRIGHTNESS: u8 = 8;
|
||||||
|
|
||||||
|
struct DebouncedButton<P: PinId> {
|
||||||
|
debounce: Instant,
|
||||||
|
pin: Pin<P, FunctionSio<SioInput>, PullUp>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: PinId> DebouncedButton<P> {
|
||||||
|
fn new(pin: Pin<P, FunctionSio<SioInput>, PullUp>) -> Self {
|
||||||
|
Self {
|
||||||
|
debounce: Instant((0 as u32).into()),
|
||||||
|
pin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_low(&self, time: Instant) -> bool {
|
||||||
|
if time <= self.debounce {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.pin.is_low().unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_debounce(&mut self, time: Instant) {
|
||||||
|
self.debounce = time + Instant((100 as u32).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct BikeUI<
|
struct BikeUI<
|
||||||
D: SpiDevice,
|
D: SpiDevice,
|
||||||
P: ValidSpiPinout<D>,
|
P: ValidSpiPinout<D>,
|
||||||
|
@ -42,10 +67,10 @@ struct BikeUI<
|
||||||
NextId: PinId,
|
NextId: PinId,
|
||||||
> {
|
> {
|
||||||
spi: RefCell<Spi<Enabled, D, P, 8>>,
|
spi: RefCell<Spi<Enabled, D, P, 8>>,
|
||||||
left_blinker_button: Pin<LeftId, FunctionSio<SioInput>, PullUp>,
|
left_blinker_button: DebouncedButton<LeftId>,
|
||||||
right_blinker_button: Pin<RightId, FunctionSio<SioInput>, PullUp>,
|
right_blinker_button: DebouncedButton<RightId>,
|
||||||
previous_animation_button: Pin<PreviousId, FunctionSio<SioInput>, PullUp>,
|
previous_animation_button: DebouncedButton<PreviousId>,
|
||||||
next_animation_button: Pin<NextId, FunctionSio<SioInput>, PullUp>,
|
next_animation_button: DebouncedButton<NextId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
|
@ -66,10 +91,10 @@ impl<
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
spi: RefCell::new(spi),
|
spi: RefCell::new(spi),
|
||||||
left_blinker_button,
|
left_blinker_button: DebouncedButton::new(left_blinker_button),
|
||||||
right_blinker_button,
|
right_blinker_button: DebouncedButton::new(right_blinker_button),
|
||||||
previous_animation_button,
|
previous_animation_button: DebouncedButton::new(previous_animation_button),
|
||||||
next_animation_button,
|
next_animation_button: DebouncedButton::new(next_animation_button),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,14 +108,18 @@ impl<
|
||||||
NextId: PinId,
|
NextId: PinId,
|
||||||
> UI for BikeUI<D, P, LeftId, RightId, PreviousId, NextId>
|
> UI for BikeUI<D, P, LeftId, RightId, PreviousId, NextId>
|
||||||
{
|
{
|
||||||
fn check_event(&self) -> Option<Event> {
|
fn check_event(&mut self, current_time: Instant) -> Option<Event> {
|
||||||
if self.left_blinker_button.is_low().unwrap_or(false) {
|
if self.left_blinker_button.is_low(current_time) {
|
||||||
|
self.left_blinker_button.set_debounce(current_time);
|
||||||
Some(Event::LeftBlinker)
|
Some(Event::LeftBlinker)
|
||||||
} else if self.right_blinker_button.is_low().unwrap_or(false) {
|
} else if self.right_blinker_button.is_low(current_time) {
|
||||||
|
self.right_blinker_button.set_debounce(current_time);
|
||||||
Some(Event::RightBlinker)
|
Some(Event::RightBlinker)
|
||||||
} else if self.previous_animation_button.is_low().unwrap_or(false) {
|
} else if self.previous_animation_button.is_low(current_time) {
|
||||||
|
self.previous_animation_button.set_debounce(current_time);
|
||||||
Some(Event::PreviousPattern)
|
Some(Event::PreviousPattern)
|
||||||
} else if self.next_animation_button.is_low().unwrap_or(false) {
|
} else if self.next_animation_button.is_low(current_time) {
|
||||||
|
self.next_animation_button.set_debounce(current_time);
|
||||||
Some(Event::NextPattern)
|
Some(Event::NextPattern)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -111,9 +140,9 @@ impl<
|
||||||
}
|
}
|
||||||
for (idx, rgb) in body_lights.iter().enumerate() {
|
for (idx, rgb) in body_lights.iter().enumerate() {
|
||||||
lights[(idx + 4) * 4 + 0] = 0xe0 + BODY_BRIGHTNESS;
|
lights[(idx + 4) * 4 + 0] = 0xe0 + BODY_BRIGHTNESS;
|
||||||
lights[(idx + 4) * 4 + 1] = (I16F16::from(rgb.r) * LIGHT_SCALE).saturating_as();
|
lights[(idx + 4) * 4 + 1] = (I16F16::from(rgb.b) * LIGHT_SCALE).saturating_as();
|
||||||
lights[(idx + 4) * 4 + 2] = (I16F16::from(rgb.b) * LIGHT_SCALE).saturating_as();
|
lights[(idx + 4) * 4 + 2] = (I16F16::from(rgb.g) * LIGHT_SCALE).saturating_as();
|
||||||
lights[(idx + 4) * 4 + 3] = (I16F16::from(rgb.g) * LIGHT_SCALE).saturating_as();
|
lights[(idx + 4) * 4 + 3] = (I16F16::from(rgb.r) * LIGHT_SCALE).saturating_as();
|
||||||
}
|
}
|
||||||
let mut spi = self.spi.borrow_mut();
|
let mut spi = self.spi.borrow_mut();
|
||||||
spi.write(lights.as_slice());
|
spi.write(lights.as_slice());
|
||||||
|
|
|
@ -33,7 +33,7 @@ fn linear_ease(value: I8F8, frames: U16F0, slope: I8F8) -> I8F8 {
|
||||||
value_i16f16.saturating_as()
|
value_i16f16.saturating_as()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
pub struct Instant(pub U128F0);
|
pub struct Instant(pub U128F0);
|
||||||
|
|
||||||
impl Default for Instant {
|
impl Default for Instant {
|
||||||
|
@ -61,7 +61,7 @@ impl Sub for Instant {
|
||||||
pub const FPS: u8 = 30;
|
pub const FPS: u8 = 30;
|
||||||
|
|
||||||
pub trait UI {
|
pub trait UI {
|
||||||
fn check_event(&self) -> Option<Event>;
|
fn check_event(&mut self, current_time: Instant) -> Option<Event>;
|
||||||
fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern);
|
fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +193,10 @@ impl Blinker {
|
||||||
fn new(
|
fn new(
|
||||||
starting_dashboard: DashboardPattern,
|
starting_dashboard: DashboardPattern,
|
||||||
starting_body: BodyPattern,
|
starting_body: BodyPattern,
|
||||||
home_dashboard: DashboardPattern,
|
|
||||||
home_body: BodyPattern,
|
|
||||||
direction: BlinkerDirection,
|
direction: BlinkerDirection,
|
||||||
time: Instant,
|
time: Instant,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut ending_dashboard = home_dashboard.clone();
|
let mut ending_dashboard = OFF_DASHBOARD.clone();
|
||||||
|
|
||||||
match direction {
|
match direction {
|
||||||
BlinkerDirection::Left => {
|
BlinkerDirection::Left => {
|
||||||
|
@ -213,7 +211,7 @@ impl Blinker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ending_body = home_body.clone();
|
let mut ending_body = OFF_BODY.clone();
|
||||||
match direction {
|
match direction {
|
||||||
BlinkerDirection::Left => {
|
BlinkerDirection::Left => {
|
||||||
for i in 0..30 {
|
for i in 0..30 {
|
||||||
|
@ -241,8 +239,8 @@ impl Blinker {
|
||||||
time,
|
time,
|
||||||
),
|
),
|
||||||
fade_in: Fade::new(
|
fade_in: Fade::new(
|
||||||
home_dashboard.clone(),
|
OFF_DASHBOARD.clone(),
|
||||||
home_body.clone(),
|
OFF_BODY.clone(),
|
||||||
ending_dashboard.clone(),
|
ending_dashboard.clone(),
|
||||||
ending_body.clone(),
|
ending_body.clone(),
|
||||||
BLINKER_FRAMES,
|
BLINKER_FRAMES,
|
||||||
|
@ -251,8 +249,8 @@ impl Blinker {
|
||||||
fade_out: Fade::new(
|
fade_out: Fade::new(
|
||||||
ending_dashboard.clone(),
|
ending_dashboard.clone(),
|
||||||
ending_body.clone(),
|
ending_body.clone(),
|
||||||
home_dashboard.clone(),
|
OFF_DASHBOARD.clone(),
|
||||||
home_body.clone(),
|
OFF_BODY.clone(),
|
||||||
BLINKER_FRAMES,
|
BLINKER_FRAMES,
|
||||||
time,
|
time,
|
||||||
),
|
),
|
||||||
|
@ -395,8 +393,6 @@ impl App {
|
||||||
self.current_animation = Box::new(Blinker::new(
|
self.current_animation = Box::new(Blinker::new(
|
||||||
self.dashboard_lights.clone(),
|
self.dashboard_lights.clone(),
|
||||||
self.lights.clone(),
|
self.lights.clone(),
|
||||||
self.home_pattern.dashboard(),
|
|
||||||
self.home_pattern.body(),
|
|
||||||
BlinkerDirection::Left,
|
BlinkerDirection::Left,
|
||||||
time,
|
time,
|
||||||
));
|
));
|
||||||
|
@ -405,8 +401,6 @@ impl App {
|
||||||
self.current_animation = Box::new(Blinker::new(
|
self.current_animation = Box::new(Blinker::new(
|
||||||
self.dashboard_lights.clone(),
|
self.dashboard_lights.clone(),
|
||||||
self.lights.clone(),
|
self.lights.clone(),
|
||||||
self.home_pattern.dashboard(),
|
|
||||||
self.home_pattern.body(),
|
|
||||||
BlinkerDirection::Right,
|
BlinkerDirection::Right,
|
||||||
time,
|
time,
|
||||||
));
|
));
|
||||||
|
@ -456,7 +450,7 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, time: Instant) {
|
pub fn tick(&mut self, time: Instant) {
|
||||||
match self.ui.check_event() {
|
match self.ui.check_event(time) {
|
||||||
Some(event) => {
|
Some(event) => {
|
||||||
self.update_state(event);
|
self.update_state(event);
|
||||||
self.update_animation(time);
|
self.update_animation(time);
|
||||||
|
|
|
@ -26,26 +26,26 @@ pub const BLINKER_AMBER: RGB<I8F8> = RGB {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PRIDE_RED: RGB<I8F8> = RGB {
|
pub const PRIDE_RED: RGB<I8F8> = RGB {
|
||||||
r: I8F8::lit("0.89"),
|
r: I8F8::lit("0.95"),
|
||||||
g: I8F8::lit("0.01"),
|
g: I8F8::lit("0.00"),
|
||||||
b: I8F8::lit("0.01"),
|
b: I8F8::lit("0.00"),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PRIDE_ORANGE: RGB<I8F8> = RGB {
|
pub const PRIDE_ORANGE: RGB<I8F8> = RGB {
|
||||||
r: I8F8::lit("1.0"),
|
r: I8F8::lit("1.0"),
|
||||||
g: I8F8::lit("0.54"),
|
g: I8F8::lit("0.25"),
|
||||||
b: I8F8::lit("0"),
|
b: I8F8::lit("0"),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PRIDE_YELLOW: RGB<I8F8> = RGB {
|
pub const PRIDE_YELLOW: RGB<I8F8> = RGB {
|
||||||
r: I8F8::lit("1.0"),
|
r: I8F8::lit("1.0"),
|
||||||
g: I8F8::lit("0.92"),
|
g: I8F8::lit("0.85"),
|
||||||
b: I8F8::lit("0"),
|
b: I8F8::lit("0"),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PRIDE_GREEN: RGB<I8F8> = RGB {
|
pub const PRIDE_GREEN: RGB<I8F8> = RGB {
|
||||||
r: I8F8::lit("0"),
|
r: I8F8::lit("0"),
|
||||||
g: I8F8::lit("0.5"),
|
g: I8F8::lit("0.95"),
|
||||||
b: I8F8::lit("0.05"),
|
b: I8F8::lit("0.05"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ pub const PRIDE_INDIGO: RGB<I8F8> = RGB {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PRIDE_VIOLET: RGB<I8F8> = RGB {
|
pub const PRIDE_VIOLET: RGB<I8F8> = RGB {
|
||||||
r: I8F8::lit("0.45"),
|
r: I8F8::lit("0.75"),
|
||||||
g: I8F8::lit("0.16"),
|
g: I8F8::lit("0.0"),
|
||||||
b: I8F8::lit("0.50"),
|
b: I8F8::lit("0.80"),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TRANS_BLUE: RGB<I8F8> = RGB {
|
pub const TRANS_BLUE: RGB<I8F8> = RGB {
|
||||||
|
@ -178,7 +178,7 @@ pub const BRAKES_DASHBOARD: DashboardPattern = [BRAKES_RED; 3];
|
||||||
|
|
||||||
pub const BRAKES_BODY: BodyPattern = [BRAKES_RED; 60];
|
pub const BRAKES_BODY: BodyPattern = [BRAKES_RED; 60];
|
||||||
|
|
||||||
pub const BLINKER_FRAMES: U16F0 = U16F0::lit("15");
|
pub const BLINKER_FRAMES: U16F0 = U16F0::lit("10");
|
||||||
|
|
||||||
pub const LEFT_BLINKER_DASHBOARD: DashboardPattern = [BLINKER_AMBER, RGB_OFF, RGB_OFF];
|
pub const LEFT_BLINKER_DASHBOARD: DashboardPattern = [BLINKER_AMBER, RGB_OFF, RGB_OFF];
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ struct GTKUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UI for GTKUI {
|
impl UI for GTKUI {
|
||||||
fn check_event(&self) -> Option<Event> {
|
fn check_event(&mut self, _: Instant) -> Option<Event> {
|
||||||
match self.rx.try_recv() {
|
match self.rx.try_recv() {
|
||||||
Ok(event) => Some(event),
|
Ok(event) => Some(event),
|
||||||
Err(TryRecvError::Empty) => None,
|
Err(TryRecvError::Empty) => None,
|
||||||
|
|
Loading…
Reference in New Issue