# device-envoy-esp
[](https://github.com/CarlKCarlK/device-envoy)
[](https://crates.io/crates/device-envoy-esp)
[](https://docs.rs/device-envoy-esp)
**Build ESP32 applications with composable device abstractions.**
`device-envoy-esp` is an embedded Rust library built on Embassy and esp-hal.
It organizes hardware around device abstractions so application code can use
small, focused APIs instead of managing low-level coordination directly.
Currently targeting ESP32-C6 and ESP32-S3 in [`device-envoy-esp`](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/), and Raspberry Pi Pico 1 and Pico 2 (ARM cores) in [`device-envoy-rp`](https://docs.rs/device-envoy-rp/latest/device_envoy_rp/).
## Start From a Template
Want a minimal starting project?
- [`device-envoy-esp-blinky` on GitHub](https://github.com/CarlKCarlK/device-envoy-esp-blinky)
## Status
⚠️ **Alpha / Experimental**
The API is actively evolving and may change without compatibility guarantees.
## Features
- **[LED Strips](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/led_strip/) & [Panels](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/led2d/)** - NeoPixel-style (WS2812) LED arrays with 2D text rendering, animation, embedded-graphics support. Provides efficient options for power limiting and color correction.
- **[WiFi](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/wifi_auto/)** - 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.
- **[Audio Player](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/audio_player/)** - Play audio clips over I²S hardware with runtime sequencing, volume control, and compression.
- **[Button Input](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/button/)** - Button handling with debouncing
- **[Servo Control](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/servo/)** - Servo positioning and animation
- **[Flash Storage](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/flash_block/)** - Type-safe, on-board persistent storage
- **[LCD Display](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/lcd_text/)** - Text display (HD44780)
- **[IR Remote](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/ir/)** - Remote control decoder (NEC protocol)
- **[RFID Reader](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/rfid/)** - Card detection and reading (MFRC522)
- **[Clock Sync](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/clock_sync/)** - Network time synchronization utilities
- **[LED4 Display](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/led4/)** - 4-digit, 7-segment LED display control with optional animation and blinking
- **[Single LED](https://docs.rs/device-envoy-esp/latest/device_envoy_esp/led/)** - Single LED control with animation support
## Forum
- **[Using Embassy to build applications](https://github.com/CarlKCarlK/device-envoy/discussions)**
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 or ESP boards, or to `device-envoy`.
## Videos and Articles
- [device-envoy: Making Embedded Fun with Rust, Embassy, and Composable Device Abstractions](https://medium.com/@carlmkadie/device-envoy-making-embedded-fun-31534917414b) -- versions: [article](https://medium.com/@carlmkadie/device-envoy-making-embedded-fun-31534917414b) or [video](https://www.youtube.com/watch?v=iUu6hvJLVOU)
- [How Rust & Embassy Shine on Embedded Devices](https://medium.com/@carlmkadie/how-rust-embassy-shine-on-embedded-devices-part-1-9f4911c92007) by Carl M. Kadie and Brad Gibson.
- [More Rust articles](https://medium.com/@carlmkadie)
## Thanks
Special thanks to [Brad Gibson](https://github.com/U007D/), organizer of the [Seattle Rust User Group](https://www.meetup.com/seattle-rust-meetup/). He introduced me to Rust programming on microcontrollers, suggested the term *device abstraction*, and encouraged thinking in terms of shared traits across controller families. Those conversations helped set the goals for device-envoy.
## Examples & Demos
The project includes **examples** (single-device tests) in `examples/` showing integration patterns:
### Example: animated LED strip
This example cycles a 96-LED strip through red, green, and blue frames.

It shows how device-envoy generates a struct (device abstraction) for an LED
strip and then animates a sequence of frames.
```rust,no_run
# #![no_std]
# #![no_main]
# use esp_backtrace as _;
# use core::convert::Infallible;
use device_envoy_esp::{Result, init_and_start, led_strip, led_strip::{LedStrip as _, Frame1d, colors}};
use embassy_time::Duration;
led_strip! {
LedStripAnimated {
pin: GPIO18,
len: 96,
}
}
async fn example(spawner: embassy_executor::Spawner) -> Result<Infallible> {
init_and_start!(p, rmt80: rmt80, mode: rmt_mode::Blocking);
let led_strip_animated = LedStripAnimated::new(p.GPIO18, rmt80.channel0, spawner)?;
// Create a sequence of frames and durations and then animate them (looping, until replaced).
let frame_duration = 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/` directory.
- **Basic LED Examples**: Simple on/off control with blinky pattern
- **LED Strip Examples**: Simple animations, color control, text rendering
- **LED Panel Examples**: 12×8, 16×16, and multi-panel configurations with graphics

- **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/` directory for complete runnable code.
## Building & Running
- If you just want to use this library, start from the template project: [`device-envoy-esp-blinky`](https://github.com/CarlKCarlK/device-envoy-esp-blinky).
- If you want to edit this project, see the [Development Guide](docs/development_guide/index.html).
## Glossary
Resources commonly used in `device-envoy-esp`:
- **RMT** ([Remote Control Transceiver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html)): ESP32-C6: 4 channels. ESP32-S3: 8 channels.
- **LEDC** ([LED PWM Controller](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html)): ESP32-C6: 4 timers, 6 channels. ESP32-S3: 4 timers, 8 channels.
- **DMA** ([Direct Memory Access](https://en.wikipedia.org/wiki/Direct_memory_access)): ESP32-C6: 3 channels (`DMA_CH0`-`DMA_CH2`). ESP32-S3: 5 channels (`DMA_CH0`-`DMA_CH4`).
- **I2S** ([Inter-IC Sound](https://en.wikipedia.org/wiki/I%C2%B2S)): ESP32-C6: 1 controller (`I2S0`). ESP32-S3: 2 controllers (`I2S0`, `I2S1`).
- **I2C** ([Inter-Integrated Circuit](https://en.wikipedia.org/wiki/I2C)): ESP32-C6: 2 controllers. ESP32-S3: 2 controllers.
- **SPI** ([Serial Peripheral Interface](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface)): ESP32-C6: 2 peripherals. ESP32-S3: 3 peripherals.
## 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](https://github.com/CarlKCarlK/device-envoy/blob/main/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 the repository root `LICENSE-MIT` file)
- Apache License, Version 2.0 (see the repository root `LICENSE-APACHE` file)
at your option.