//! This example shows the ease of debouncing a button with async rust. //! Hook up a button or switch between pin 9 and ground. #![no_std] #![no_main] use defmt::info; use embassy_executor::Spawner; use embassy_rp::block::ImageDef; use embassy_rp::gpio::{Input, Level, Pull}; use embassy_time::{with_deadline, Duration, Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; #[link_section = ".start_block"] #[used] pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe(); // Program metadata for `picotool info` #[link_section = ".bi_entries"] #[used] pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [ embassy_rp::binary_info_rp_cargo_bin_name!(), embassy_rp::binary_info_rp_cargo_version!(), embassy_rp::binary_info_rp_program_description!(c"Blinky"), embassy_rp::binary_info_rp_program_build_attribute!(), ]; pub struct Debouncer<'a> { input: Input<'a>, debounce: Duration, } impl<'a> Debouncer<'a> { pub fn new(input: Input<'a>, debounce: Duration) -> Self { Self { input, debounce } } pub async fn debounce(&mut self) -> Level { loop { let l1 = self.input.get_level(); self.input.wait_for_any_edge().await; Timer::after(self.debounce).await; let l2 = self.input.get_level(); if l1 != l2 { break l2; } } } } #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); let mut btn = Debouncer::new(Input::new(p.PIN_9, Pull::Up), Duration::from_millis(20)); info!("Debounce Demo"); loop { // button pressed btn.debounce().await; let start = Instant::now(); info!("Button Press"); match with_deadline(start + Duration::from_secs(1), btn.debounce()).await { // Button Released < 1s Ok(_) => { info!("Button pressed for: {}ms", start.elapsed().as_millis()); continue; } // button held for > 1s Err(_) => { info!("Button Held"); } } match with_deadline(start + Duration::from_secs(5), btn.debounce()).await { // Button released <5s Ok(_) => { info!("Button pressed for: {}ms", start.elapsed().as_millis()); continue; } // button held for > >5s Err(_) => { info!("Button Long Held"); } } // wait for button release before handling another press btn.debounce().await; info!("Button pressed for: {}ms", start.elapsed().as_millis()); } }