Skip to main content

Crate device_envoy

Crate device_envoy 

Source
Expand description

§device-envoy

GitHub crates.io docs.rs

Build Pico applications with LED panels, easy WiFi, and composable device abstractions.

device-envoy is a library for building embedded applications in Rust, built on the Embassy framework. It organizes hardware around device abstractions.

A device abstraction is a software encapsulation of hardware that manages timing, tasks, control flow, interrupts, channels, and state within the abstraction.

Rather than replacing HALs or drivers, device-envoy builds on them. It defines device abstractions that expose a small set of simple operations to the rest of the program.

Currently targeting Raspberry Pi Pico 1 and Pico 2 (ARM cores). RISC-V core support exists but is not actively tested.

§Start From a Template

Want a minimal starting project? Use device-envoy-blinky on GitHub as a template.

§Status

⚠️ Alpha / Experimental

The API is actively evolving. Not recommended for production use, but excellent for experimentation, learning, and exploratory projects.

§Features

  • LED Strips & Panels - NeoPixel-style (WS2812) LED arrays with 2D text rendering, animation, embedded-graphics support. Provides efficient options for power limiting and color correction.
  • WiFi (Pico W) - Connect to the Internet with automatic credentials management. On boot, opens a web form if WiFi credentials aren’t saved, then connects seamlessly to a stored network. Requires Pico W; WiFi is not supported on non-W boards.
  • Audio Player - Play audio clips over I²S hardware with runtime sequencing and volume control.
  • Button Input - Button handling with debouncing
  • Servo Control - Servo positioning and animation
  • Flash Storage - Type-safe, on-board persist storage
  • LCD Display - Text display (HD44780)
  • IR Remote - Remote control decoder (NEC protocol)
  • RFID Reader - Card detection and reading (MFRC522)
  • Clock Sync - Network time synchronization utilities
  • LED4 Display - 4-digit, 7-segment LED display control with optional animation and blinking
  • Single LED - Single LED control with animation support

§Forum

  • Using Embassy to build applications
    A place to talk about writing embedded applications with Embassy: sharing code, asking practical questions, and learning what works in practice.
    Not limited to Pico boards or to device-envoy.

§Articles

§Examples & Demos

The project includes examples (single-device tests) in examples/ and demo applications in demos/ showing integration patterns:

§Example: animated LED strip

This example cycles a 96-LED strip through red, green, and blue frames. Animated 96-LED strip example (APNG)

It shows how device-envoy generates a struct (device abstraction) for an LED strip and then animates a sequence of frames.

use device_envoy::{Result, led_strip::{Frame1d, colors}};
use device_envoy::led_strip;

led_strip! {
    LedStripAnimated {
        pin: PIN_4,
        len: 96,
    }
}

async fn example(spawner: embassy_executor::Spawner) -> Result<Infallible> {
    let p = embassy_rp::init(Default::default());
    let led_strip_animated = LedStripAnimated::new(p.PIN_4, p.PIO0, p.DMA_CH0, spawner)?;

    // Create a sequence of frames and durations and then animate them (looping, until replaced).
    let frame_duration = embassy_time::Duration::from_millis(300);
    led_strip_animated.animate([
        (Frame1d::filled(colors::RED), frame_duration),
        (Frame1d::filled(colors::GREEN), frame_duration),
        (Frame1d::filled(colors::BLUE), frame_duration),
    ])?;

    core::future::pending().await // run forever
}

For complete, runnable examples (including wiring and setup), see the examples/ and demos/ directories.

  • Basic LED Examples: Simple on/off control with blinky pattern

  • LED Strip Examples: Simple animations, color control, text rendering

  • LED Panel Examples: 12×4, 12×8, and multi-panel configurations with graphics

Animated LED panel Go Go example

  • Button Examples: Debouncing and state handling
  • Servo Examples: Position sweeps and animation playback
  • WiFi Examples: WiFi setup, time sync, DNS
  • Flash Examples: Configuration persistence and data reset

See the examples/ and demos/ directories for complete runnable code.

§Building & Running

§Prerequisites

# Add Rust targets for Pico boards
rustup target add thumbv6m-none-eabi           # Pico 1 (ARM)
rustup target add thumbv8m.main-none-eabihf    # Pico 2 (ARM)

§Quick Start

# New project template
# https://github.com/CarlKCarlK/device-envoy-blinky

# Run examples using convenient aliases
cargo blinky                # Simple LED blinky (Pico 1)
cargo blinky-2              # Simple LED blinky (Pico 2)

cargo clock-lcd-w           # LCD clock with WiFi (Pico 1 WiFi)
cargo clock-lcd-2w          # LCD clock with WiFi (Pico 2 WiFi)

cargo clock-led12x4-w       # LED panel clock (Pico 1 WiFi)
cargo clock-led12x4-2w      # LED panel clock (Pico 2 WiFi)

# Check without running (faster builds)
cargo blinky-check          # Compile only
cargo clock-lcd-w-check     # Check Pico 1 WiFi version

# Build and check everything
cargo check-all

Tools:

  • just - Optional command runner (install with cargo install just or your package manager). See justfile for commands.
  • xtask - Project’s custom automation tool (built-in, use via cargo xtask --help)

See .cargo/config.toml for all cargo aliases.

§Hardware Notes

§Standard Pinouts

Examples use conventional pin assignments for consistency:

  • PIN_0: LED strip (8-pixel simple example)
  • PIN_1: Single LED (blinky patterns) - Built-in LEDs are modeled as active-high (OnLevel::High) on all supported boards
  • PIN_3: LED panel (12×4, 48 pixels)
  • PIN_4: Extended LED panel (12×8, 96 pixels)
  • PIN_5: Long LED strip (160 pixels, broadway/marquee effects)
  • PIN_6: Large LED panel (16×16, 256 pixels)
  • PIN_8: I²S audio output data pin (DIN)
  • PIN_9: I²S audio output bit clock pin (BCLK)
  • PIN_10: I²S audio output word select pin (LRC / LRCLK)
  • PIN_13: Button (active-low)
  • PIN_11, PIN_12: Servo signals

§Testing

Host-side tests run on your development machine without hardware:

just check-all

just is the optional command runner (install with cargo install just or your package manager). See Tools above.

Tests include:

  • LED text rendering comparisons against reference images
  • 2D LED matrix mapping algebra
  • LED color space conversions

§Policy on AI-assisted development and contributions

The use of AI tools is permitted for development and contributions to this repository. AI may be used as a productivity aid for drafting, exploration, and refactoring.

All code and documentation contributed to this repository must be reviewed, edited, and validated by a human contributor. AI tools are not a substitute for design judgment, testing, or responsibility for correctness.

AGENTS.md contains the general instructions and constraints given to AI tools used during development of this repository.

§License

Licensed under either:

  • MIT license (see LICENSE-MIT file)
  • Apache License, Version 2.0

at your option.

§Glossary

Resources available on the Pico 1 and Pico 2:

Modules§

audio_playertarget_os=none
A device abstraction for playing audio clips over I²S hardware, with runtime sequencing and volume control.
buttontarget_os=none
A device abstraction for buttons with debouncing and press duration detection.
char_lcdtarget_os=none
A device abstraction for HD44780-compatible character LCDs (e.g., 16x2, 20x2, 20x4).
clock_syncwifi and target_os=none
A device abstraction that combines time sync with a local clock. See ClockSync for the full usage example.
flash_arraytarget_os=none
A device abstraction for type-safe persistent storage in flash memory.
irtarget_os=none
A device abstraction for infrared receivers using the NEC protocol.
ledtarget_os=none
A device abstraction for a single digital LED with animation support.
led4target_os=none
A device abstraction for a 4-digit, 7-segment LED display for text with optional animation and blinking.
led2d
A device abstraction for rectangular NeoPixel-style (WS2812) LED panel displays. For 1-dimensional LED strips, see the led_strip module.
led_strip
A device abstraction for 1-dimensional NeoPixel-style (WS2812) LED strips. For 2-dimensional panels, see the led2d module.
rfidtarget_os=none
A device abstraction for RFID readers using the MFRC522 chip.
servotarget_os=none
A device abstraction for hobby servos.
servo_playertarget_os=none
A device abstraction for hobby servos that can animate motion sequences.
wifi_autowifi and target_os=none
A device abstraction that connects a Pico with WiFi to the Internet and, when needed, creates a temporary WiFi network to enter credentials.

Enums§

Error
Define a unified error type for this crate.

Type Aliases§

Result
A specialized Result where the error is this crate’s Error type.