GPIO
micro/gpio provides digital I/O pin control.
use micro/gpio
use std/time
fn main() -> never {
let mut led = gpio.pin(25).into_output()
defer led.low()
loop {
led.high()
time.sleep_ms(250)
led.low()
time.sleep_ms(250)
}
}
Getting a Pin
let pin = gpio.pin(25) // get pin handle by number
Configuring Direction
let mut out = gpio.pin(25).into_output() // digital output
let inp = gpio.pin(14).into_input() // digital input (floating)
let inp = gpio.pin(14).into_input_pullup() // input with pull-up
let inp = gpio.pin(14).into_input_pulldown() // input with pull-down
Output Operations
led.high() // drive high
led.low() // drive low
led.toggle() // flip current state
These are infallible. GPIO state changes always succeed once the pin is configured.
Input Operations
let state = button.read() // true = high, false = low
if button.read() {
handle_press()
}
Common Patterns
LED toggle with defer for safe cleanup:
let mut led = gpio.pin(25).into_output()
defer led.low() // ensure LED off on any exit
loop {
led.toggle()
time.sleep_ms(500)
}
Button polling:
use micro/gpio
use std/time
fn main() -> never {
let mut led = gpio.pin(25).into_output()
let button = gpio.pin(14).into_input_pullup()
loop {
if not button.read() { // active low (pulled up)
led.high()
} else {
led.low()
}
time.sleep_ms(10)
}
}
Board package pin names:
When using a board package, you can use named pins instead of numbers:
use board/pico
use micro/gpio
fn main() -> never {
let mut led = gpio.pin(pico.pin.led).into_output()
loop {
led.toggle()
time.sleep_ms(1000)
}
}
Do and Don’t
// Do: use defer to ensure cleanup
let mut pin = gpio.pin(25).into_output()
defer pin.low()
// Do: call toggle() instead of tracking state manually
led.toggle()
// Avoid: reading pin state immediately after write without delay
// (hardware may need settling time depending on load)
// Avoid: configuring direction multiple times; configure once at startup