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

UART

micro/uart provides serial communication. UART is the most common way to get debug output off an MCU.

Basic Usage

use board/pico as board
use core/fmt
use std/time

fn main() -> never {
    let port = board.default_uart().init()

    loop {
        fmt.write(port, "hello from Flint\r\n")
        time.sleep_ms(1000)
    }
}

Initialization

Current executable surface:

use micro/uart

let port = uart.port(0).init()

For board-default debug output, prefer:

use board/pico as board

let port = board.default_uart().init()

Writing

port.write_byte(0x0A)
port.write_char('A')

// Formatted output through core/fmt
use core/fmt
fmt.write(port, "temp={}\r\n", temp_c)
fmt.write(port, "x={} y={}\r\n", x, y)

uart.Port participates in core/io.Writer, and core/fmt.write(...) uses that concrete writer implementation on the current executable path. General runtime dispatch through a trait-typed io.Writer parameter is still separate backend work.

Reading

let has_data = port.has_data()
let byte = port.read_byte()

Board Package Convenience

The board package provides a pre-configured default UART:

use board/pico

fn main() -> never {
    let console = pico.default_uart().init()

    loop {
        fmt.write(console, "tick\r\n")
        time.sleep_ms(1000)
    }
}

Example: Temperature Over UART

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)
    }
}

Do and Don’t

// Do: use core/fmt for checked no-heap formatting
fmt.write(port, "value={}\r\n", n)

// Do: use the board-default UART when you want the standard debug port
let port = pico.default_uart().init()

// Avoid: writing docs or examples against unimplemented builder APIs
let port = uart.port(0).init()

// Avoid: using UART for timing-critical code; UART TX has variable latency