use atmega_hal::port::{Pin, mode}; #[derive(PartialEq, Eq)] pub enum ButtonState { Inactive, // button is not pressed and the state is same from last time Active, // button is pressed and the state is same from last time Pressed, // The button was just pressed Released // The button was just released } const DEBOUNCECYCLES: u8 = 50; pub struct Button { input: Pin, active_high: bool, last_active: bool, active: bool, integrator: u8 } impl Button { pub fn create(input: Pin, active_high: bool) -> Button { Button { input, active_high, last_active: false, active: false, integrator: 0, } } pub fn step(&mut self) { let mut btn_active = self.input.is_low(); if self.active_high { btn_active = !btn_active; } if !btn_active { if self.integrator > 0 { self.integrator -= 1; } } else if self.integrator < DEBOUNCECYCLES { self.integrator += 1; } self.active = self.pressed(); } fn pressed(&mut self) -> bool{ if self.integrator == 0 { self.last_active = self.active; self.active = false; } else if self.integrator >= DEBOUNCECYCLES { self.integrator = DEBOUNCECYCLES; self.last_active = self.active; self.active = true; } self.active } pub fn state(&self) -> ButtonState { if self.active { if self.last_active { return ButtonState::Active; } return ButtonState::Pressed; } if !self.last_active { return ButtonState::Inactive; } return ButtonState::Released; } }