Created
July 23, 2020 16:57
-
-
Save MathiasKoch/d21e9df95e76847e581bc0a11b245d1f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use embedded_hal::{digital::v2::OutputPin, PwmPin}; | |
#[derive(PartialEq)] | |
pub enum Polarity { | |
ActiveLow, | |
ActiveHigh, | |
} | |
#[allow(unused)] | |
#[derive(PartialEq)] | |
pub enum Color { | |
Red, | |
Orange, | |
Yellow, | |
Green, | |
Blue, | |
Indigo, | |
Violet, | |
Cyan, | |
Magenta, | |
White, | |
Black, | |
Pink, | |
Hex(i32), | |
Rgb(u8, u8, u8), | |
} | |
impl Color { | |
fn split(&self) -> (u8, u8, u8) { | |
match self { | |
Color::Red => (255, 0, 0), | |
Color::Orange => (83, 4, 0), | |
Color::Yellow => (255, 255, 0), | |
Color::Green => (0, 255, 0), | |
Color::Blue => (0, 0, 255), | |
Color::Indigo => (4, 0, 19), | |
Color::Violet => (23, 0, 22), | |
Color::Cyan => (0, 255, 255), | |
Color::Magenta => (255, 0, 255), | |
Color::White => (255, 255, 255), | |
Color::Black => (0, 0, 0), | |
Color::Pink => (158, 4, 79), | |
Color::Hex(h) => ( | |
((h >> 16) & 0xFF) as u8, | |
((h >> 8) & 0xFF) as u8, | |
(h & 0xFF) as u8, | |
), | |
Color::Rgb(r, g, b) => (*r, *g, *b), | |
} | |
} | |
} | |
#[allow(unused)] | |
#[derive(PartialEq, Clone, Copy)] | |
pub enum BaseColor { | |
Red, | |
Yellow, | |
Green, | |
Blue, | |
Cyan, | |
Magenta, | |
White, | |
Black, | |
Rgb(bool, bool, bool), | |
} | |
impl BaseColor { | |
fn split(self) -> (bool, bool, bool) { | |
match self { | |
BaseColor::Red => (true, false, false), | |
BaseColor::Yellow => (true, true, false), | |
BaseColor::Green => (false, true, false), | |
BaseColor::Blue => (false, false, true), | |
BaseColor::Cyan => (false, true, true), | |
BaseColor::Magenta => (true, false, true), | |
BaseColor::White => (true, true, true), | |
BaseColor::Black => (false, false, false), | |
BaseColor::Rgb(r, g, b) => (r, g, b), | |
} | |
} | |
} | |
#[allow(unused)] | |
pub struct Led<P> { | |
pin: P, | |
state: bool, | |
polarity: Polarity, | |
} | |
#[allow(unused)] | |
impl<P> Led<P> | |
where | |
P: OutputPin, | |
{ | |
pub fn new(mut pin: P, polarity: Polarity) -> Self { | |
if polarity == Polarity::ActiveHigh { | |
pin.set_high(); | |
} else { | |
pin.set_low(); | |
} | |
Self { | |
pin, | |
state: false, | |
polarity, | |
} | |
} | |
pub fn on(&mut self) { | |
if self.polarity == Polarity::ActiveHigh { | |
self.pin.set_high(); | |
} else { | |
self.pin.set_low(); | |
} | |
self.state = true; | |
} | |
pub fn off(&mut self) { | |
if self.polarity == Polarity::ActiveHigh { | |
self.pin.set_low(); | |
} else { | |
self.pin.set_high(); | |
} | |
self.state = false; | |
} | |
pub fn toggle(&mut self) { | |
if self.state { | |
self.off(); | |
} else { | |
self.on(); | |
} | |
} | |
pub fn set(&mut self, state: bool) { | |
if state { | |
self.on(); | |
} else { | |
self.off(); | |
} | |
} | |
pub fn get_state(&mut self) -> bool { | |
self.state | |
} | |
} | |
#[allow(unused)] | |
pub struct PwmLed<P> { | |
pin: P, | |
max: u32, | |
brightness: u8, | |
} | |
#[allow(unused)] | |
impl<P> PwmLed<P> | |
where | |
P: PwmPin<Duty = u32>, | |
{ | |
pub fn new(mut pin: P) -> Self { | |
pin.set_duty(0); | |
pin.enable(); | |
Self { | |
max: pin.get_max_duty(), | |
pin, | |
brightness: 0, | |
} | |
} | |
pub fn on(&mut self) { | |
self.set_brightness(100); | |
} | |
pub fn off(&mut self) { | |
self.set_brightness(0); | |
} | |
pub fn toggle(&mut self) { | |
if self.brightness > 0 { | |
self.off(); | |
} else { | |
self.on(); | |
} | |
} | |
pub fn set_brightness(&mut self, brightness: u8) { | |
if brightness > 100 { | |
self.pin.set_duty(self.max); | |
} else { | |
self.pin.set_duty(self.max * (brightness as u32) / 100); | |
} | |
} | |
pub fn get_brightness(&self) -> u8 { | |
self.brightness | |
} | |
} | |
pub struct Rgb<P1, P2, P3> { | |
red: Led<P1>, | |
green: Led<P2>, | |
blue: Led<P3>, | |
color: BaseColor, | |
} | |
impl<P1, P2, P3> Rgb<P1, P2, P3> | |
where | |
P1: OutputPin, | |
P2: OutputPin, | |
P3: OutputPin, | |
{ | |
pub fn new(mut red: Led<P1>, mut green: Led<P2>, mut blue: Led<P3>) -> Self { | |
Self { | |
color: BaseColor::Rgb(red.get_state(), green.get_state(), blue.get_state()), | |
red, | |
green, | |
blue, | |
} | |
} | |
pub fn set_color(&mut self, c: BaseColor) { | |
let (r, g, b) = c.split(); | |
self.red.set(r); | |
self.green.set(g); | |
self.blue.set(b); | |
self.color = c; | |
} | |
pub fn get_color(&self) -> BaseColor { | |
self.color | |
} | |
} | |
pub struct PwmRgb<P> { | |
red: PwmLed<P>, | |
green: PwmLed<P>, | |
blue: PwmLed<P>, | |
color: Color, | |
brightness: u8, | |
} | |
impl<P> PwmRgb<P> | |
where | |
P: PwmPin<Duty = u32>, | |
{ | |
pub fn new(red: PwmLed<P>, green: PwmLed<P>, blue: PwmLed<P>) -> Self { | |
Self { | |
color: Color::Rgb( | |
red.get_brightness(), | |
green.get_brightness(), | |
blue.get_brightness(), | |
), | |
red, | |
green, | |
blue, | |
brightness: 100, | |
} | |
} | |
pub fn set_color(&mut self, c: Color) { | |
let (r, g, b) = c.split(); | |
self.red.set_brightness(r / 255 * self.brightness); | |
self.green.set_brightness(g / 255 * self.brightness); | |
self.blue.set_brightness(b / 255 * self.brightness); | |
self.color = c; | |
} | |
pub fn set_brightness(&mut self, brightness: u8) { | |
let (r, g, b) = self.color.split(); | |
self.red.set_brightness(r / 255 * brightness); | |
self.green.set_brightness(g / 255 * brightness); | |
self.blue.set_brightness(b / 255 * brightness); | |
self.brightness = if brightness > 100 { 100 } else { brightness }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment