finis exersise 8.3
This commit is contained in:
@@ -52,37 +52,44 @@ impl<'a, T: OutputPin> Toggle<T> for ToggleLed<'a, T> {
|
|||||||
pub struct Leds<'a,
|
pub struct Leds<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> {
|
> {
|
||||||
pub red: &'a mut RT,
|
pub red: &'a mut RT,
|
||||||
pub green: &'a mut GT,
|
pub green: &'a mut GT,
|
||||||
|
pub orange: &'a mut OT,
|
||||||
pub blue: &'a mut BT,
|
pub blue: &'a mut BT,
|
||||||
|
|
||||||
// phantom data to convince rustc the generics RP, GP and BP are used.
|
// phantom data to convince rustc the generics RP, GP and BP are used.
|
||||||
_r: PhantomData<RP>,
|
_r: PhantomData<RP>,
|
||||||
_g: PhantomData<GP>,
|
_g: PhantomData<GP>,
|
||||||
|
_o: PhantomData<OP>,
|
||||||
_b: PhantomData<BP>,
|
_b: PhantomData<BP>,
|
||||||
}
|
}
|
||||||
impl<'a,
|
impl<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> Leds<'a, RP, RT, GP, GT, BP, BT> {
|
> Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT> {
|
||||||
pub fn new(red: &'a mut RT, green: &'a mut GT, blue: &'a mut BT) -> Self {
|
pub fn new(red: &'a mut RT, green: &'a mut GT, orange: &'a mut OT, blue: &'a mut BT) -> Self {
|
||||||
Self {
|
Self {
|
||||||
red,
|
red,
|
||||||
green,
|
green,
|
||||||
|
orange,
|
||||||
blue,
|
blue,
|
||||||
|
|
||||||
_r: PhantomData,
|
_r: PhantomData,
|
||||||
_g: PhantomData,
|
_g: PhantomData,
|
||||||
|
_o: PhantomData,
|
||||||
_b: PhantomData,
|
_b: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_all(&mut self, red: PinState, green: PinState, blue: PinState) {
|
pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState, blue: PinState) {
|
||||||
let _ = self.red.set(red);
|
let _ = self.red.set(red);
|
||||||
let _ = self.blue.set(blue);
|
let _ = self.orange.set(orange);
|
||||||
let _ = self.green.set(green);
|
let _ = self.green.set(green);
|
||||||
|
let _ = self.blue.set(blue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
use embedded_hal::digital::PinState;
|
||||||
// Halt on panic
|
// Halt on panic
|
||||||
use panic_halt as _; // panic handler
|
use panic_halt as _; // panic handler
|
||||||
|
|
||||||
@@ -27,11 +28,16 @@ fn main() -> ! {
|
|||||||
//led pinnen uphalen
|
//led pinnen uphalen
|
||||||
let mut green_pin = &mut gpiod.pd12.into_push_pull_output();
|
let mut green_pin = &mut gpiod.pd12.into_push_pull_output();
|
||||||
let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
|
let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
|
||||||
|
let mut orange_pin = &mut gpiod.pd13.into_push_pull_output();
|
||||||
let mut blue_pin = &mut gpiod.pd15.into_push_pull_output();
|
let mut blue_pin = &mut gpiod.pd15.into_push_pull_output();
|
||||||
let mut green = ToggleLed::new(&mut green_pin).expect("faild to set green led");
|
let mut green = ToggleLed::new(&mut green_pin).expect("faild to set green led");
|
||||||
let mut red = ToggleLed::new(&mut red_pin).expect("faild to set red led");
|
let mut red = ToggleLed::new(&mut red_pin).expect("faild to set red led");
|
||||||
|
let mut orange = ToggleLed::new(&mut orange_pin).expect("faild to set orange led");
|
||||||
let mut blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led");
|
let mut blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led");
|
||||||
let mut leds = Leds::new(&mut red, &mut green, &mut blue);
|
let mut leds = Leds::new(&mut red, &mut green, &mut orange, &mut blue);
|
||||||
|
//user knop
|
||||||
|
let gpioa = dp.GPIOA.split();
|
||||||
|
let button = &mut gpioa.pa0.into_floating_input();
|
||||||
//leds struct en state machine maken
|
//leds struct en state machine maken
|
||||||
let mut state_machine = StateMachine::new(&mut leds);
|
let mut state_machine = StateMachine::new(&mut leds);
|
||||||
|
|
||||||
@@ -41,9 +47,20 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// Create a delay abstraction based on SysTick
|
// Create a delay abstraction based on SysTick
|
||||||
let mut delay = cp.SYST.delay(&clocks);
|
let mut delay = cp.SYST.delay(&clocks);
|
||||||
|
let mut button_high = button.is_high();
|
||||||
loop {
|
loop {
|
||||||
let _ = state_machine.second_passed();
|
let _ = state_machine.second_passed();
|
||||||
delay.delay_ms(1000_u32);
|
for _ in 0..99 {
|
||||||
|
if button_high != button.is_high() {
|
||||||
|
button_high = button.is_high();
|
||||||
|
if button_high {
|
||||||
|
state_machine.button_press();
|
||||||
|
} else {
|
||||||
|
state_machine.button_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay.delay_ms(10_u32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,44 +4,67 @@ use crate::leds::{Leds, Toggle};
|
|||||||
|
|
||||||
enum States {
|
enum States {
|
||||||
Red(StateRed),
|
Red(StateRed),
|
||||||
Blue(StateBlue),
|
Orange(StateOrange),
|
||||||
Green(StateGreen),
|
Green(StateGreen),
|
||||||
|
BridgeOpen(StateBridgeOpen)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait State<
|
trait State<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> {
|
> {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self;
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self;
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States;
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
|
||||||
|
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
|
||||||
|
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StateMachine<'a,
|
pub struct StateMachine<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> {
|
> {
|
||||||
state: States,
|
state: States,
|
||||||
leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>,
|
leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>
|
||||||
}
|
}
|
||||||
impl<'a,
|
impl<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> StateMachine<'a, RP, RT, GP, GT, BP, BT>
|
> StateMachine<'a, RP, RT, GP, GT, OP, OT, BP, BT>
|
||||||
{
|
{
|
||||||
pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>) -> Self {
|
pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: States::Red(StateRed::new(leds)),
|
state: States::Red(StateRed::new(leds)),
|
||||||
leds,
|
leds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn second_passed(&mut self) {
|
pub fn second_passed(&mut self) {
|
||||||
self.state = match &self.state {
|
self.state = match &self.state {
|
||||||
States::Red(state) => state.second_passed(self.leds),
|
States::Red(state) => state.second_passed(self.leds),
|
||||||
States::Blue(state) => state.second_passed(self.leds),
|
States::Orange(state) => state.second_passed(self.leds),
|
||||||
States::Green(state) => state.second_passed(self.leds),
|
States::Green(state) => state.second_passed(self.leds),
|
||||||
|
States::BridgeOpen(state) => state.second_passed(self.leds),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn button_press(&mut self) {
|
||||||
|
self.state = match &self.state {
|
||||||
|
States::Red(state) => state.button_press(self.leds),
|
||||||
|
States::Orange(state) => state.button_press(self.leds),
|
||||||
|
States::Green(state) => state.button_press(self.leds),
|
||||||
|
States::BridgeOpen(state) => state.button_press(self.leds),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn button_release(&mut self) {
|
||||||
|
self.state = match &self.state {
|
||||||
|
States::Red(state) => state.button_release(self.leds),
|
||||||
|
States::Orange(state) => state.button_release(self.leds),
|
||||||
|
States::Green(state) => state.button_release(self.leds),
|
||||||
|
States::BridgeOpen(state) => state.button_release(self.leds),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,15 +79,16 @@ struct StateRed {
|
|||||||
impl<
|
impl<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> State<RP, RT, GP, GT, BP, BT> for StateRed {
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateRed {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
leds.set_all(PinState::High, PinState::Low, PinState::Low);
|
leds.set_all(PinState::High, PinState::Low, PinState::Low, PinState::Low);
|
||||||
Self {
|
Self {
|
||||||
time_passed: 0
|
time_passed: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
if self.time_passed + 1 >= 4 {
|
if self.time_passed + 1 >= 4 {
|
||||||
States::Green(StateGreen::new(leds))
|
States::Green(StateGreen::new(leds))
|
||||||
} else {
|
} else {
|
||||||
@@ -73,6 +97,15 @@ impl<
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::BridgeOpen(StateBridgeOpen::new(leds))
|
||||||
|
}
|
||||||
|
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Red(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
@@ -85,40 +118,107 @@ struct StateGreen {
|
|||||||
impl<
|
impl<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> State<RP, RT, GP, GT, BP, BT> for StateGreen {
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateGreen {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
leds.set_all(PinState::Low, PinState::High, PinState::Low);
|
leds.set_all(PinState::Low, PinState::High, PinState::Low, PinState::Low);
|
||||||
Self {
|
Self {
|
||||||
time_passed: 0
|
time_passed: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
if self.time_passed + 1 >= 3 {
|
if self.time_passed + 1 >= 3 {
|
||||||
States::Blue(StateBlue::new(leds))
|
States::Orange(StateOrange::new(leds))
|
||||||
} else {
|
} else {
|
||||||
States::Green(Self {
|
States::Green(Self {
|
||||||
time_passed: self.time_passed + 1
|
time_passed: self.time_passed + 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Green(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Green(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
// ## BLUE ############################################
|
// ## ORANGE ############################################
|
||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
struct StateBlue {}
|
struct StateOrange {}
|
||||||
impl<
|
impl<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
> State<RP, RT, GP, GT, BP, BT> for StateBlue {
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateOrange {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
leds.set_all(PinState::Low, PinState::Low, PinState::High);
|
leds.set_all(PinState::Low, PinState::Low, PinState::High, PinState::Low);
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Red(StateRed::new(leds))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Orange(Self {})
|
||||||
|
}
|
||||||
|
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Orange(Self {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// ## BRIDGE_OPEN #####################################
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
struct StateBridgeOpen {
|
||||||
|
time_passed: u32
|
||||||
|
}
|
||||||
|
impl<
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateBridgeOpen {
|
||||||
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
|
leds.set_all(PinState::Low, PinState::Low, PinState::Low, PinState::High);
|
||||||
|
Self {
|
||||||
|
time_passed: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
if self.time_passed + 1 == 2 {
|
||||||
|
let _ = leds.blue.low();
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: self.time_passed + 1
|
||||||
|
})
|
||||||
|
} else if self.time_passed + 1 >= 3 {
|
||||||
|
let _ = leds.blue.high();
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: 0
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: self.time_passed + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
States::Red(StateRed::new(leds))
|
States::Red(StateRed::new(leds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,46 +14,46 @@ auther:
|
|||||||
|
|
||||||
> Maak een toestandsmachine volgens de State Pattern methode zoals beschreven in
|
> Maak een toestandsmachine volgens de State Pattern methode zoals beschreven in
|
||||||
> het boek. Er zijn drie toestanden: rood, groen en oranje. Tussen de toestanden
|
> het boek. Er zijn drie toestanden: rood, groen en oranje. Tussen de toestanden
|
||||||
> wordt geschakeld op basis van tijd: respectievelijk $4s&, &3s& en &1s&.
|
> wordt geschakeld op basis van tijd: respectievelijk $4s$, $3s$ en $1s$.
|
||||||
|
|
||||||
De State Pattern methode in rust maakt gebuik van structs en traits. Om dit
|
De State Pattern methode in rust maakt gebruik van structs en traits. Om dit
|
||||||
mognelijk te maken moet er een struct zijn die de leds kan aansturen. Hiervoor
|
mogelijk te maken moet er een struct zijn die de leds kan aansturen. Hiervoor
|
||||||
is het de Pin struct van de stm32f4xx-hal nodig in in struct. Om mijn
|
is het de Pin struct van de stm32f4xx-hal nodig in in struct. Om mijn
|
||||||
implementatie makkelijker onderhoudbaar te maken worden de Pin structs
|
implementatie makkelijker onderhoudbaar te maken worden de Pin structs
|
||||||
doorgegeven aan de state machine struct. Hiervoor is een triad nodig die
|
doorgegeven aan de state machine struct. Hiervoor is een triad nodig die
|
||||||
functions voor het aanpassen van de led status beschijft. De `toggle` functie
|
functions voor het aanpassen van de led status beschrijft. De `toggle` functie
|
||||||
die gebruikt wordt in het voorbeeld is niet geimplementeerd via een trait.
|
die gebruikt wordt in het voorbeeld is niet geïmplementeerd via een trait.
|
||||||
Deze kan dus niet gebruikt worden zonder de hal aan te passen. In de
|
Deze kan dus niet gebruikt worden zonder de hal aan te passen. In de
|
||||||
documentatie van de pin struct implementeerd die de OutputPin trait van de
|
documentatie van de pin struct implementeert die de OutputPin trait van de
|
||||||
embedded_hal crate^[https://docs.rs/stm32f4xx-hal/0.22.0/stm32f4xx_hal/gpio/struct.Pin.html#impl-OutputPin-for-Pin%3CP,+N,+Output%3CMODE%3E%3E-1]. Dus deze crate is toegevoed aan het project zodat hier
|
embedded_hal crate^[https://docs.rs/stm32f4xx-hal/0.22.0/stm32f4xx_hal/gpio/struct.Pin.html#impl-OutputPin-for-Pin%3CP,+N,+Output%3CMODE%3E%3E-1]. Dus deze crate is toegevoegd aan het project zodat hier
|
||||||
gebruik van gemaakt kan worden.
|
gebruik van gemaakt kan worden.
|
||||||
|
|
||||||
Om te testen of dit werkt is er een stuct aangemaakt met een simple toggle
|
Om te testen of dit werkt is er een struct aangemaakt met een simple toggle
|
||||||
functie en de embeded_hal geimporteerd. Dit is gedaan met de volgende code:
|
functie en de embeded_hal geïmporteerd. Dit is gedaan met de volgende code:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use embedded_hal::digital::{ErrorType as DigitalErrorType, OutputPin, PinState};
|
use embedded_hal::digital::{ErrorType as DigitalErrorType, OutputPin, PinState};
|
||||||
|
|
||||||
struct Leds<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> {
|
struct Leds<'a, Red: OutputPin, Green: OutputPin, Orange: OutputPin> {
|
||||||
red: &'a mut Red,
|
red: &'a mut Red,
|
||||||
red_state: PinState,
|
red_state: PinState,
|
||||||
green: &'a mut Green,
|
green: &'a mut Green,
|
||||||
green_state: PinState,
|
green_state: PinState,
|
||||||
blue: &'a mut Blue,
|
orange: &'a mut Orange,
|
||||||
blue_state: PinState,
|
orange_state: PinState,
|
||||||
}
|
}
|
||||||
impl<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> Leds<'a, Red, Green, Blue> {
|
impl<'a, Red: OutputPin, Green: OutputPin, Orange: OutputPin> Leds<'a, Red, Green, Orange> {
|
||||||
pub fn new(red: &'a mut Red, green: &'a mut Green, blue: &'a mut Blue) -> Self {
|
pub fn new(red: &'a mut Red, green: &'a mut Green, orange: &'a mut Orange) -> Self {
|
||||||
let _ = red.set_low();
|
let _ = red.set_low();
|
||||||
let _ = green.set_low();
|
let _ = green.set_low();
|
||||||
let _ = blue.set_low();
|
let _ = orange.set_low();
|
||||||
Self {
|
Self {
|
||||||
red,
|
red,
|
||||||
red_state: PinState::Low,
|
red_state: PinState::Low,
|
||||||
green,
|
green,
|
||||||
green_state: PinState::Low,
|
green_state: PinState::Low,
|
||||||
blue,
|
orange,
|
||||||
blue_state: PinState::Low,
|
orange_state: PinState::Low,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,9 +82,9 @@ fn main() -> ! {
|
|||||||
// create structs for pins
|
// create structs for pins
|
||||||
let mut green = gpiod.pd12.into_push_pull_output();
|
let mut green = gpiod.pd12.into_push_pull_output();
|
||||||
let mut red = gpiod.pd14.into_push_pull_output();
|
let mut red = gpiod.pd14.into_push_pull_output();
|
||||||
let mut blue = gpiod.pd15.into_push_pull_output();
|
let mut orange = gpiod.pd13.into_push_pull_output();
|
||||||
// create leds struct
|
// create leds struct
|
||||||
let mut leds = Leds::new(&mut red, &mut green, &mut blue);
|
let mut leds = Leds::new(&mut red, &mut green, &mut orange);
|
||||||
|
|
||||||
//Klok instellen
|
//Klok instellen
|
||||||
let rcc = dp.RCC.constrain();
|
let rcc = dp.RCC.constrain();
|
||||||
@@ -124,34 +124,34 @@ use crate::leds::{Leds, Toggle};
|
|||||||
|
|
||||||
enum States {
|
enum States {
|
||||||
Red(StateRed),
|
Red(StateRed),
|
||||||
Blue(StateBlue),
|
Orange(StateOrange),
|
||||||
Green(StateGreen),
|
Green(StateGreen),
|
||||||
}
|
}
|
||||||
|
|
||||||
trait State<
|
trait State<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> {
|
> {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self;
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> Self;
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States;
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> States;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StateMachine<'a,
|
pub struct StateMachine<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> {
|
> {
|
||||||
state: States,
|
state: States,
|
||||||
leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>,
|
leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT>,
|
||||||
}
|
}
|
||||||
impl<'a,
|
impl<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> StateMachine<'a, RP, RT, GP, GT, BP, BT>
|
> StateMachine<'a, RP, RT, GP, GT, OP, OT>
|
||||||
{
|
{
|
||||||
pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>) -> Self {
|
pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: States::Red(StateRed::new(leds)),
|
state: States::Red(StateRed::new(leds)),
|
||||||
leds,
|
leds,
|
||||||
@@ -160,7 +160,7 @@ impl<'a,
|
|||||||
pub fn second_passed(&mut self) {
|
pub fn second_passed(&mut self) {
|
||||||
self.state = match &self.state {
|
self.state = match &self.state {
|
||||||
States::Red(state) => state.second_passed(self.leds),
|
States::Red(state) => state.second_passed(self.leds),
|
||||||
States::Blue(state) => state.second_passed(self.leds),
|
States::Orange(state) => state.second_passed(self.leds),
|
||||||
States::Green(state) => state.second_passed(self.leds),
|
States::Green(state) => state.second_passed(self.leds),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,27 +238,27 @@ Met deze workaround toegepast de `struct Leds` is als volgt geïmplementeerd in
|
|||||||
pub struct Leds<'a,
|
pub struct Leds<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> {
|
> {
|
||||||
pub red: &'a mut RT,
|
pub red: &'a mut RT,
|
||||||
pub green: &'a mut GT,
|
pub green: &'a mut GT,
|
||||||
pub blue: &'a mut BT,
|
pub orange: &'a mut OT,
|
||||||
|
|
||||||
// phantom data to convince rustc the generics RP, GP and BP are used.
|
// phantom data to convince rustc the generics RP, GP and OP are used.
|
||||||
_r: PhantomData<RP>,
|
_r: PhantomData<RP>,
|
||||||
_g: PhantomData<GP>,
|
_g: PhantomData<GP>,
|
||||||
_b: PhantomData<BP>,
|
_b: PhantomData<OP>,
|
||||||
}
|
}
|
||||||
impl<'a,
|
impl<'a,
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> Leds<'a, RP, RT, GP, GT, BP, BT> {
|
> Leds<'a, RP, RT, GP, GT, OP, OT> {
|
||||||
pub fn new(red: &'a mut RT, green: &'a mut GT, blue: &'a mut BT) -> Self {
|
pub fn new(red: &'a mut RT, green: &'a mut GT, orange: &'a mut OT) -> Self {
|
||||||
Self {
|
Self {
|
||||||
red,
|
red,
|
||||||
green,
|
green,
|
||||||
blue,
|
orange,
|
||||||
|
|
||||||
_r: PhantomData,
|
_r: PhantomData,
|
||||||
_g: PhantomData,
|
_g: PhantomData,
|
||||||
@@ -266,9 +266,9 @@ impl<'a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_all(&mut self, red: PinState, green: PinState, blue: PinState) {
|
pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState) {
|
||||||
let _ = self.red.set(red);
|
let _ = self.red.set(red);
|
||||||
let _ = self.blue.set(blue);
|
let _ = self.orange.set(orange);
|
||||||
let _ = self.green.set(green);
|
let _ = self.green.set(green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,15 +291,15 @@ struct StateRed {
|
|||||||
impl<
|
impl<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> State<RP, RT, GP, GT, BP, BT> for StateRed {
|
> State<RP, RT, GP, GT, OP, OT> for StateRed {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> Self {
|
||||||
leds.set_all(PinState::High, PinState::Low, PinState::Low);
|
leds.set_all(PinState::High, PinState::Low, PinState::Low);
|
||||||
Self {
|
Self {
|
||||||
time_passed: 0
|
time_passed: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> States {
|
||||||
if self.time_passed + 1 >= 4 {
|
if self.time_passed + 1 >= 4 {
|
||||||
States::Green(StateGreen::new(leds))
|
States::Green(StateGreen::new(leds))
|
||||||
} else {
|
} else {
|
||||||
@@ -320,17 +320,17 @@ struct StateGreen {
|
|||||||
impl<
|
impl<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> State<RP, RT, GP, GT, BP, BT> for StateGreen {
|
> State<RP, RT, GP, GT, OP, OT> for StateGreen {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> Self {
|
||||||
leds.set_all(PinState::Low, PinState::High, PinState::Low);
|
leds.set_all(PinState::Low, PinState::High, PinState::Low);
|
||||||
Self {
|
Self {
|
||||||
time_passed: 0
|
time_passed: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> States {
|
||||||
if self.time_passed + 1 >= 3 {
|
if self.time_passed + 1 >= 3 {
|
||||||
States::Blue(StateBlue::new(leds))
|
States::Orange(StateOrange::new(leds))
|
||||||
} else {
|
} else {
|
||||||
States::Green(Self {
|
States::Green(Self {
|
||||||
time_passed: self.time_passed + 1
|
time_passed: self.time_passed + 1
|
||||||
@@ -340,20 +340,20 @@ impl<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ####################################################
|
// ####################################################
|
||||||
// ## BLUE ############################################
|
// ## ORANGE ############################################
|
||||||
// ####################################################
|
// ####################################################
|
||||||
|
|
||||||
struct StateBlue {}
|
struct StateOrange {}
|
||||||
impl<
|
impl<
|
||||||
RP: OutputPin, RT: Toggle<RP>,
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
GP: OutputPin, GT: Toggle<GP>,
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
BP: OutputPin, BT: Toggle<BP>
|
OP: OutputPin, OT: Toggle<OP>
|
||||||
> State<RP, RT, GP, GT, BP, BT> for StateBlue {
|
> State<RP, RT, GP, GT, OP, OT> for StateOrange {
|
||||||
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> Self {
|
||||||
leds.set_all(PinState::Low, PinState::Low, PinState::High);
|
leds.set_all(PinState::Low, PinState::Low, PinState::High);
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT>) -> States {
|
||||||
States::Red(StateRed::new(leds))
|
States::Red(StateRed::new(leds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,11 +392,11 @@ fn main() -> ! {
|
|||||||
//led pinnen uphalen
|
//led pinnen uphalen
|
||||||
let mut green_pin = &mut gpiod.pd12.into_push_pull_output();
|
let mut green_pin = &mut gpiod.pd12.into_push_pull_output();
|
||||||
let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
|
let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
|
||||||
let mut blue_pin = &mut gpiod.pd15.into_push_pull_output();
|
let mut orange_pin = &mut gpiod.pd15.into_push_pull_output();
|
||||||
let mut green = ToggleLed::new(&mut green_pin).expect("faild to set green led");
|
let mut green = ToggleLed::new(&mut green_pin).expect("faild to set green led");
|
||||||
let mut red = ToggleLed::new(&mut red_pin).expect("faild to set red led");
|
let mut red = ToggleLed::new(&mut red_pin).expect("faild to set red led");
|
||||||
let mut blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led");
|
let mut orange = ToggleLed::new(&mut orange_pin).expect("faild to set orange led");
|
||||||
let mut leds = Leds::new(&mut red, &mut green, &mut blue);
|
let mut leds = Leds::new(&mut red, &mut green, &mut orange);
|
||||||
//leds struct en state machine maken
|
//leds struct en state machine maken
|
||||||
let mut state_machine = StateMachine::new(&mut leds);
|
let mut state_machine = StateMachine::new(&mut leds);
|
||||||
|
|
||||||
@@ -415,3 +415,424 @@ fn main() -> ! {
|
|||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## opdracht 8.3
|
||||||
|
|
||||||
|
> Voeg nu een toestand toe waarbij de blauwe “User” knop aangeeft dat de brug open wilt gaan. Vanuit de rode toestand moet dan naar een andere toestand (brug-open?) worden gesprongen. Wanneer de knop wordt losgelaten springt brug-open naar de rode toestand. In de brug-open-toestand moet de rode led knipperen. Dit knipperen moet elke met een periodetijd van $2s$ ($2s$ aan, $1s$ uit).
|
||||||
|
|
||||||
|
Om deze aanpassing te doen motten de volgende onderdelen aangepast worden:
|
||||||
|
|
||||||
|
- blue led initialiseren en toevoegen aan `struct Leds` en alle plekken waar deze gebuikt wordt
|
||||||
|
- knop initialiseren
|
||||||
|
- functies toevoegen voor de knop `trait State` en alle implementaties ervan
|
||||||
|
- de state `BridgeOpen` toevoegen aan:
|
||||||
|
- `enum States`
|
||||||
|
- de tussen functies in `struct StateMachine`
|
||||||
|
- nieuwe `struct StateBridgeOpen`
|
||||||
|
- uitlezen van de knop een aanroepen van de nieuwe functies in `trait State`
|
||||||
|
- de `struct StateRed` aanpassen voor de nieuwe logica
|
||||||
|
- logica toevoegen aan `struct StateBridgeOpen`
|
||||||
|
|
||||||
|
### resultaat
|
||||||
|
|
||||||
|
#### leds.rs
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
use embedded_hal::digital::{OutputPin, PinState};
|
||||||
|
|
||||||
|
pub trait Toggle<T: OutputPin> {
|
||||||
|
fn toggle(&mut self) -> Result<(), T::Error>;
|
||||||
|
fn set(&mut self, state: PinState) -> Result<(), T::Error>;
|
||||||
|
fn get(&self) -> PinState;
|
||||||
|
|
||||||
|
fn high(&mut self) -> Result<(), T::Error> {
|
||||||
|
self.set(PinState::High)
|
||||||
|
}
|
||||||
|
fn low(&mut self) -> Result<(), T::Error> {
|
||||||
|
self.set(PinState::Low)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ToggleLed<'a, T: OutputPin> {
|
||||||
|
pin: &'a mut T,
|
||||||
|
state: PinState
|
||||||
|
}
|
||||||
|
impl<'a, T: OutputPin> ToggleLed<'a, T> {
|
||||||
|
pub fn new(pin: &'a mut T) -> Result<Self, T::Error> {
|
||||||
|
match pin.set_low() {
|
||||||
|
Ok(_) => Ok(Self { pin, state: PinState::Low }),
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a, T: OutputPin> Toggle<T> for ToggleLed<'a, T> {
|
||||||
|
fn toggle(&mut self) -> Result<(), T::Error> {
|
||||||
|
if self.state == PinState::High {
|
||||||
|
self.state = PinState::Low;
|
||||||
|
} else {
|
||||||
|
self.state = PinState::Low;
|
||||||
|
}
|
||||||
|
self.pin.set_state(self.state)
|
||||||
|
}
|
||||||
|
fn set(&mut self, state: PinState) -> Result<(), T::Error> {
|
||||||
|
if state != self.state {
|
||||||
|
self.state = state;
|
||||||
|
self.pin.set_state(self.state)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get(&self) -> PinState {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Leds<'a,
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> {
|
||||||
|
pub red: &'a mut RT,
|
||||||
|
pub green: &'a mut GT,
|
||||||
|
pub orange: &'a mut OT,
|
||||||
|
pub blue: &'a mut BT,
|
||||||
|
|
||||||
|
// phantom data to convince rustc the generics RP, GP and BP are used.
|
||||||
|
_r: PhantomData<RP>,
|
||||||
|
_g: PhantomData<GP>,
|
||||||
|
_o: PhantomData<OP>,
|
||||||
|
_b: PhantomData<BP>,
|
||||||
|
}
|
||||||
|
impl<'a,
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT> {
|
||||||
|
pub fn new(red: &'a mut RT, green: &'a mut GT, orange: &'a mut OT, blue: &'a mut BT) -> Self {
|
||||||
|
Self {
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
orange,
|
||||||
|
blue,
|
||||||
|
|
||||||
|
_r: PhantomData,
|
||||||
|
_g: PhantomData,
|
||||||
|
_o: PhantomData,
|
||||||
|
_b: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState, blue: PinState) {
|
||||||
|
let _ = self.red.set(red);
|
||||||
|
let _ = self.orange.set(orange);
|
||||||
|
let _ = self.green.set(green);
|
||||||
|
let _ = self.blue.set(blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### state_machine.rs
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use embedded_hal::digital::{OutputPin, PinState};
|
||||||
|
|
||||||
|
use crate::leds::{Leds, Toggle};
|
||||||
|
|
||||||
|
enum States {
|
||||||
|
Red(StateRed),
|
||||||
|
Orange(StateOrange),
|
||||||
|
Green(StateGreen),
|
||||||
|
BridgeOpen(StateBridgeOpen)
|
||||||
|
}
|
||||||
|
|
||||||
|
trait State<
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> {
|
||||||
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self;
|
||||||
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
|
||||||
|
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
|
||||||
|
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct StateMachine<'a,
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> {
|
||||||
|
state: States,
|
||||||
|
leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>
|
||||||
|
}
|
||||||
|
impl<'a,
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> StateMachine<'a, RP, RT, GP, GT, OP, OT, BP, BT>
|
||||||
|
{
|
||||||
|
pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
|
Self {
|
||||||
|
state: States::Red(StateRed::new(leds)),
|
||||||
|
leds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn second_passed(&mut self) {
|
||||||
|
self.state = match &self.state {
|
||||||
|
States::Red(state) => state.second_passed(self.leds),
|
||||||
|
States::Orange(state) => state.second_passed(self.leds),
|
||||||
|
States::Green(state) => state.second_passed(self.leds),
|
||||||
|
States::BridgeOpen(state) => state.second_passed(self.leds),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn button_press(&mut self) {
|
||||||
|
self.state = match &self.state {
|
||||||
|
States::Red(state) => state.button_press(self.leds),
|
||||||
|
States::Orange(state) => state.button_press(self.leds),
|
||||||
|
States::Green(state) => state.button_press(self.leds),
|
||||||
|
States::BridgeOpen(state) => state.button_press(self.leds),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn button_release(&mut self) {
|
||||||
|
self.state = match &self.state {
|
||||||
|
States::Red(state) => state.button_release(self.leds),
|
||||||
|
States::Orange(state) => state.button_release(self.leds),
|
||||||
|
States::Green(state) => state.button_release(self.leds),
|
||||||
|
States::BridgeOpen(state) => state.button_release(self.leds),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// ## RED #############################################
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
struct StateRed {
|
||||||
|
time_passed: u32
|
||||||
|
}
|
||||||
|
impl<
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateRed {
|
||||||
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
|
leds.set_all(PinState::High, PinState::Low, PinState::Low, PinState::Low);
|
||||||
|
Self {
|
||||||
|
time_passed: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
if self.time_passed + 1 >= 4 {
|
||||||
|
States::Green(StateGreen::new(leds))
|
||||||
|
} else {
|
||||||
|
States::Red(Self {
|
||||||
|
time_passed: self.time_passed + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::BridgeOpen(StateBridgeOpen::new(leds))
|
||||||
|
}
|
||||||
|
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Red(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// ## GREEN ###########################################
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
struct StateGreen {
|
||||||
|
time_passed: u32
|
||||||
|
}
|
||||||
|
impl<
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateGreen {
|
||||||
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
|
leds.set_all(PinState::Low, PinState::High, PinState::Low, PinState::Low);
|
||||||
|
Self {
|
||||||
|
time_passed: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
if self.time_passed + 1 >= 3 {
|
||||||
|
States::Orange(StateOrange::new(leds))
|
||||||
|
} else {
|
||||||
|
States::Green(Self {
|
||||||
|
time_passed: self.time_passed + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Green(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Green(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// ## ORANGE ############################################
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
struct StateOrange {}
|
||||||
|
impl<
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateOrange {
|
||||||
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
|
leds.set_all(PinState::Low, PinState::Low, PinState::High, PinState::Low);
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Red(StateRed::new(leds))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Orange(Self {})
|
||||||
|
}
|
||||||
|
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Orange(Self {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ####################################################
|
||||||
|
// ## BRIDGE_OPEN #####################################
|
||||||
|
// ####################################################
|
||||||
|
|
||||||
|
struct StateBridgeOpen {
|
||||||
|
time_passed: u32
|
||||||
|
}
|
||||||
|
impl<
|
||||||
|
RP: OutputPin, RT: Toggle<RP>,
|
||||||
|
GP: OutputPin, GT: Toggle<GP>,
|
||||||
|
OP: OutputPin, OT: Toggle<OP>,
|
||||||
|
BP: OutputPin, BT: Toggle<BP>
|
||||||
|
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateBridgeOpen {
|
||||||
|
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self {
|
||||||
|
leds.set_all(PinState::Low, PinState::Low, PinState::Low, PinState::High);
|
||||||
|
Self {
|
||||||
|
time_passed: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
if self.time_passed + 1 == 2 {
|
||||||
|
let _ = leds.blue.low();
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: self.time_passed + 1
|
||||||
|
})
|
||||||
|
} else if self.time_passed + 1 >= 3 {
|
||||||
|
let _ = leds.blue.high();
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: 0
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: self.time_passed + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::BridgeOpen(Self {
|
||||||
|
time_passed: self.time_passed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
|
||||||
|
States::Red(StateRed::new(leds))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### main.rs
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![deny(unsafe_code)]
|
||||||
|
#![allow(clippy::empty_loop)]
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use embedded_hal::digital::PinState;
|
||||||
|
// Halt on panic
|
||||||
|
use panic_halt as _; // panic handler
|
||||||
|
|
||||||
|
use cortex_m_rt::entry;
|
||||||
|
use stm32f4xx_hal::{self as hal};
|
||||||
|
|
||||||
|
use crate::hal::{pac, prelude::*};
|
||||||
|
|
||||||
|
mod leds;
|
||||||
|
use crate::leds::{Leds, ToggleLed};
|
||||||
|
mod state_machine;
|
||||||
|
use crate::state_machine::StateMachine;
|
||||||
|
|
||||||
|
#[entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
if let (Some(dp), Some(cp)) = (
|
||||||
|
pac::Peripherals::take(),
|
||||||
|
cortex_m::peripheral::Peripherals::take(),
|
||||||
|
) {
|
||||||
|
//GPIOD ophalen
|
||||||
|
let gpiod = dp.GPIOD.split();
|
||||||
|
//led pinnen uphalen
|
||||||
|
let mut green_pin = &mut gpiod.pd12.into_push_pull_output();
|
||||||
|
let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
|
||||||
|
let mut orange_pin = &mut gpiod.pd13.into_push_pull_output();
|
||||||
|
let mut blue_pin = &mut gpiod.pd15.into_push_pull_output();
|
||||||
|
let mut green = ToggleLed::new(&mut green_pin).expect("faild to set green led");
|
||||||
|
let mut red = ToggleLed::new(&mut red_pin).expect("faild to set red led");
|
||||||
|
let mut orange = ToggleLed::new(&mut orange_pin).expect("faild to set orange led");
|
||||||
|
let mut blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led");
|
||||||
|
let mut leds = Leds::new(&mut red, &mut green, &mut orange, &mut blue);
|
||||||
|
//user knop
|
||||||
|
let gpioa = dp.GPIOA.split();
|
||||||
|
let button = &mut gpioa.pa0.into_floating_input();
|
||||||
|
//leds struct en state machine maken
|
||||||
|
let mut state_machine = StateMachine::new(&mut leds);
|
||||||
|
|
||||||
|
//Klok instellen
|
||||||
|
let rcc = dp.RCC.constrain();
|
||||||
|
let clocks = rcc.cfgr.sysclk(48.MHz()).freeze();
|
||||||
|
|
||||||
|
// Create a delay abstraction based on SysTick
|
||||||
|
let mut delay = cp.SYST.delay(&clocks);
|
||||||
|
let mut button_high = button.is_high();
|
||||||
|
loop {
|
||||||
|
let _ = state_machine.second_passed();
|
||||||
|
for _ in 0..99 {
|
||||||
|
if button_high != button.is_high() {
|
||||||
|
button_high = button.is_high();
|
||||||
|
if button_high {
|
||||||
|
state_machine.button_press();
|
||||||
|
} else {
|
||||||
|
state_machine.button_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay.delay_ms(10_u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user