Exercise: toggle LED with interrupt
Now that we have set up the GPIO interrupt, try using it to toggle the LED. There are many ways to achieve this, so let's set some specific requirements:
-
Use
AtomicBoolWe have already seen how to use a Mutex, so for this exercise, let's try something new.
-
Toggle the LED in the main loop
In general, we want to avoid doing any work in the interrupt handler, so use the
AtomicBoolto signal to the main loop that the LED should be toggled. Remove any other code from the loop for now. -
Use
FallingEdgeinterrupt type -
Take care of debouncing
You will encounter switch bounce - several interrupt events occurring from a single button press. Try to come up with a solution for this problem so that the LED is only toggled once per button press. There are a multitude of ways to implement this so any solution that works is fine.
Solution
First, we'll need to import atomic and then declare our static object object.
#![allow(unused)] fn main() { use core::sync::atomic; static BUTTON_EVENT: atomic::AtomicBool = atomic::AtomicBool::new(false); }
Next, set the BUTTON_EVENT in the button_handler():
#![allow(unused)] fn main() { BUTTON_EVENT.store(true, atomic::Ordering::Relaxed); }
Finally, in the main loop, let's check the BUTTON_EVENT and if it's true, toggle the LED.
#![allow(unused)] fn main() { loop { if BUTTON_EVENT.load(atomic::Ordering::Relaxed) { led.toggle(); // Delay before resetting the BUTTON_EVENT acts as debouncing logic. delay.delay_millis(150); BUTTON_EVENT.store(false, atomic::Ordering::Relaxed); } } }