Polling
Now that we've learned how to read GPIO inputs, let's consider how we might use these reads practically. Suppose we want our program to turn on an LED when Button A is pressed and turn it off when Button B is pressed. We can do this by polling the state of both buttons in a loop, and responding accordingly when a button is read to be pressed. Here's how we might write this program:
#![no_main] #![no_std] use cortex_m_rt::entry; use embedded_hal::delay::DelayNs; use embedded_hal::digital::{InputPin, OutputPin}; use microbit::hal::timer::Timer; use microbit::{hal::gpio, Board}; use panic_rtt_target as _; use rtt_target::rtt_init_print; #[entry] fn main() -> ! { rtt_init_print!(); let board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0); // Configure buttons let mut button_a = board.buttons.button_a; let mut button_b = board.buttons.button_b; // Configure LED (top-left LED at row1, col1) let mut row1 = board .display_pins .row1 .into_push_pull_output(gpio::Level::Low); let _col1 = board .display_pins .col1 .into_push_pull_output(gpio::Level::Low); loop { let on_pressed = button_a.is_low().unwrap(); let off_pressed = button_b.is_low().unwrap(); match (on_pressed, off_pressed) { // Stay in current state until something is pressed. (false, false) => (), // Change to on state. (true, false) => row1.set_high().unwrap(), // Change to off state. (false, true) => row1.set_low().unwrap(), // Stay in current state until something is released. (true, true) => (), } timer.delay_ms(10_u32); } }
This method of repeatedly checking inputs in a loop is called polling. When we check the state of some input, we say we are polling that input. In this case, we are polling both Button A and Button B.
Polling is simple but allows us to do interesting things based on the external world. For all of our device's inputs, we can "poll" them in a loop, and respond to the results in some way, one by one. This kind of method is very conceptually simple and is a good starting point for many projects. We'll soon find out why polling might not be the best method for all (or even most) cases, but let's try it out first.
Note "Polling" is often used on two levels of granularity. At one level, "polling" is used to refer to asking (once) what the state of an input is. At a higher level, "polling", or perhaps "polling in a loop", is used to refer to asking (repeatedly) what the state of an input is in a simple control flow like the one we used above. This kind of use of the word to refer to a control flow is used only in the simplest of programs, and seldom used in production (it's not practical as we'll soon see), so generally when embedded engineers talk about polling, they mean the former, i.e. to ask (once) what the state of an input is.