ADC
micro/adc provides analog-to-digital conversion.
Basic Usage
use micro/adc
use micro/gpio
fn main() -> never {
let mut channel = adc.channel(0)
.pin(gpio.pin(26))
.init()?
loop {
let raw = channel.read() // raw ADC count
process(raw)
time.sleep_ms(100)
}
}
Initialization
let mut ch = adc.channel(0)
.pin(gpio.pin(26)) // assign GPIO pin to ADC
.init()?
On the RP2040, ADC channels 0-3 correspond to GPIO 26-29. Channel 4 is the internal temperature sensor.
Reading Values
let raw: u16 = ch.read() // raw count (0..=4095 on RP2040)
Raw values are unsigned counts. Convert to voltage or engineering units in your application.
Board Temperature Sensor
The RP2040 has an internal temperature sensor on ADC channel 4. The board package wraps it conveniently:
use board/pico
let sensor = pico.temp_sensor()
let temp_mc = sensor.read_milli_celsius() // milli-Celsius, integer
let temp_c = temp_mc / 1000
From examples/rp2040/temp_sensor:
use board/pico
use core/fmt
use std/time
fn main() -> never {
let port = pico.default_uart().init()
loop {
let temp_c: f32 = pico.temp_sensor().read_c()
fmt.write(port, "temp={}C\r\n", temp_c)
time.sleep_ms(1000)
}
}
Voltage Conversion
The board package may provide conversion helpers. For raw conversions:
// RP2040: 3.3V reference, 12-bit ADC (0..=4095)
fn raw_to_mv(raw: u16) -> u32 {
return u32.from(raw) * 3300 / 4095
}
Do and Don’t
// Do: use board.temp_sensor() for the internal temperature sensor
let sensor = pico.temp_sensor()
let temp_mc = sensor.read_milli_celsius()
// Do: use integer milli-Celsius for portable temperature math on MCUs
// (avoids floating point where possible)
// Avoid: using raw ADC counts directly in application logic
// Convert to physical units near the hardware boundary
// Avoid: reading ADC in a tight loop without delay
// ADC conversion takes time; poll at reasonable intervals