Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. Use AtomicBool

    We have already seen how to use a Mutex, so for this exercise, let's try something new.

  2. Toggle the LED in the main loop

    In general, we want to avoid doing any work in the interrupt handler, so use the AtomicBool to signal to the main loop that the LED should be toggled. Remove any other code from the loop for now.

  3. Use FallingEdge interrupt type

  4. 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);
    }
}
}