Skip to content

Commit

Permalink
Update to work with newest protocol (#25)
Browse files Browse the repository at this point in the history
* Add dial turn flash behavior and pulse interval setting

* Swap dial turn led indication to default on state

* Update to latest panel-protocol

* This is for Edward

* Add fade

* Fix fading

* Remove extra comments

* Update to latest 0.4

Co-authored-by: Brian Schwind <[email protected]>
  • Loading branch information
efyang and bschwind authored Jul 14, 2021
1 parent 4b29ba3 commit 96c9faa
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 50 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![no_main]
#![no_std]

use crate::rgb_led::LED_COUNT;
use panel_protocol::PulseMode;
use panic_reset as _; // panic handler

use stm32f4xx_hal as hal;
Expand Down Expand Up @@ -80,7 +82,7 @@ fn main() -> ! {
let mut led_strip = LedStrip::new(spi);

let timer = MonoTimer::new(cp.DWT, cp.DCB, clocks);
// human relaxed breath time: around 4s in/out and 4s wait
// Human relaxed breath time: around 4s in/out and 4s wait
let mut pulser = Pulser::new(4000, &timer);

// PWM Setup
Expand Down Expand Up @@ -121,7 +123,7 @@ fn main() -> ! {
let mut encoder_button = Button::new(debounced_encoder_pin);

let mut led_color = (0u8, 30u8, 255u8);
let mut led_pulse = false;
let mut led_pulse = PulseMode::Solid;

// Set up USB communication.
// First we set the D+ pin low for 100ms to simulate a USB
Expand Down Expand Up @@ -163,6 +165,9 @@ fn main() -> ! {
// Turn the LED on to indicate we've powered up successfully.
led.set_low().unwrap();

let mut current_led = 0usize;
let mut led_intensities = [0.0; LED_COUNT];

loop {
match encoder_button.poll() {
Some(ButtonEvent::Press) => {
Expand All @@ -179,6 +184,8 @@ fn main() -> ! {
if let Some(diff) = counter.poll() {
if !encoder_button.is_pressed() {
protocol.report(Report::DialValue { diff }).unwrap();

current_led = current_led.wrapping_add(diff as usize) % 4;
}
}

Expand All @@ -195,9 +202,9 @@ fn main() -> ! {
1 => back_light.set_color_temperature(value),
_ => {},
},
Command::Led { r, g, b, pulse } => {
Command::Led { r, g, b, pulse_mode } => {
led_color = (r, g, b);
led_pulse = pulse;
led_pulse = pulse_mode;
},
Command::Bootload => {
led.set_high().unwrap();
Expand All @@ -207,11 +214,44 @@ fn main() -> ! {
}
}

let intensity = if led_pulse { pulser.intensity() } else { 1.0 };
led_strip.set_all(Rgb::new(
(led_color.0 as f32 * intensity) as u8,
(led_color.1 as f32 * intensity) as u8,
(led_color.2 as f32 * intensity) as u8,
));
match led_pulse {
PulseMode::Breathing { interval_ms } => {
pulser.set_interval_ms(u16::from(interval_ms) as u32, &timer);
let intensity = pulser.intensity();

led_strip.set_all(Rgb::new(
(led_color.0 as f32 * intensity) as u8,
(led_color.1 as f32 * intensity) as u8,
(led_color.2 as f32 * intensity) as u8,
));
},
PulseMode::DialTurn => {
let mut new_led_intensities = [0.0; LED_COUNT];
new_led_intensities[current_led] = 1.0;
let mut leds = [Rgb::new(led_color.0, led_color.1, led_color.2); LED_COUNT];
for (led_intensity, new_led_intensity) in
led_intensities.iter_mut().zip(new_led_intensities.iter())
{
*led_intensity = 0.995 * *led_intensity + 0.005 * new_led_intensity;
}

for (mut led, intensity) in leds.iter_mut().zip(led_intensities.iter()) {
led.r = ((led.r as f32) * intensity) as u8;
led.g = ((led.g as f32) * intensity) as u8;
led.b = ((led.b as f32) * intensity) as u8;
}

led_strip.set_colors(&leds);
},
PulseMode::Solid => {
let intensity = 1.0;

led_strip.set_all(Rgb::new(
(led_color.0 as f32 * intensity) as u8,
(led_color.1 as f32 * intensity) as u8,
(led_color.2 as f32 * intensity) as u8,
));
},
};
}
}
13 changes: 9 additions & 4 deletions src/rgb_led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ use nb::block;
// Reference implementation:
// https://github.com/smart-leds-rs/ws2812-spi-rs/blob/fac281eb57b5f72c48e368682645e3b0bd5b4b83/src/lib.rs

const LED_COUNT: usize = 4;
pub const LED_COUNT: usize = 4;
const PI: f32 = 3.141_592_7e0;

pub struct LedStrip<F: FullDuplex<u8>> {
spi_bus: F,
}

#[derive(Copy, Clone)]
pub struct Rgb {
r: u8,
g: u8,
b: u8,
pub r: u8,
pub g: u8,
pub b: u8,
}

impl Rgb {
Expand Down Expand Up @@ -128,6 +129,10 @@ impl Pulser {
Self { instant, interval_ticks }
}

pub fn set_interval_ms(&mut self, interval_ms: u32, timer: &MonoTimer) {
self.interval_ticks = timer.frequency().0 as f32 * (interval_ms as f32 / 1000.0);
}

pub fn intensity(&mut self) -> f32 {
let intervals = self.instant.elapsed() as f32 / self.interval_ticks;
let pulse = (-1.0 * libm::cosf(2.0 * PI * intervals) + 1.0) * 0.5;
Expand Down

0 comments on commit 96c9faa

Please sign in to comment.