Hardware Peripherals Design: ZeroClaw
ZeroClaw enables microcontrollers (MCUs) and Single Board Computers (SBCs) to dynamically interpret natural language commands, generate hardware-specific code, and execute peripheral interactions in real-time.
1. Vision
Goal: ZeroClaw acts as a hardware-aware AI agent that:
- Receives natural language triggers (e.g. “Move X arm”, “Turn on LED”) via channels (WhatsApp, Telegram)
- Fetches accurate hardware documentation (datasheets, register maps)
- Synthesizes Rust code/logic using an LLM (Gemini, local open-source models)
- Executes the logic to manipulate peripherals (GPIO, I2C, SPI)
- Persists optimized code for future reuse
Mental model: ZeroClaw = brain that understands hardware. Peripherals = arms and legs it controls.
2. Two Modes of Operation
Mode 1: Edge-Native (Standalone)
Target: Wi-Fi-enabled boards (ESP32, Raspberry Pi).
ZeroClaw runs directly on the device. The board spins up a gRPC/nanoRPC server and communicates with peripherals locally.
ZeroClaw on ESP32 / Raspberry Pi (Edge-Native)
Channels (WhatsApp, Telegram)
│
▼
Agent Loop (LLM calls) ──► RAG: datasheets, register maps ──► LLM context
│
▼
Code synthesis ──► Wasm / dynamic exec ──► GPIO / I2C / SPI ──► persist
│
▼
gRPC/nanoRPC server ◄──► Peripherals (GPIO, I2C, SPI, sensors, actuators)
Workflow:
- User sends WhatsApp: “Turn on LED on pin 13”
- ZeroClaw fetches board-specific docs (e.g. ESP32 GPIO mapping)
- LLM synthesizes Rust code
- Code runs in a sandbox (Wasm or dynamic linking)
- GPIO is toggled; result returned to user
- Optimized code is persisted for future “Turn on LED” requests
All happens on-device. No host required.
Mode 2: Host-Mediated (Development / Debugging)
Target: Hardware connected via USB / J-Link / Aardvark to a host (macOS, Linux).
ZeroClaw runs on the host and maintains a hardware-aware link to the target. Used for development, introspection, and flashing.
ZeroClaw on Mac (host) STM32 Nucleo-F401RE (or other MCU)
───────────────────── ──────────────────────────────────
- Channels - Memory map
- LLM - Peripherals (GPIO, ADC, I2C)
- Hardware probe ◄────────► - Flash / RAM
- Flash / debug
USB / J-Link / Aardvark
VID/PID discovery
Workflow:
- User sends Telegram: “What are the readable memory addresses on this USB device?”
- ZeroClaw identifies connected hardware (VID/PID, architecture)
- Performs memory mapping; suggests available address spaces
- Returns result to user
Or:
- User: “Flash this firmware to the Nucleo”
- ZeroClaw writes/flashes via OpenOCD or probe-rs
- Confirms success
Or:
- ZeroClaw auto-discovers: “STM32 Nucleo on /dev/ttyACM0, ARM Cortex-M4”
- Suggests: “I can read/write GPIO, ADC, flash. What would you like to do?”
Mode Comparison
| Aspect | Edge-Native | Host-Mediated |
|---|---|---|
| ZeroClaw runs on | Device (ESP32, RPi) | Host (Mac, Linux) |
| Hardware link | Local (GPIO, I2C, SPI) | USB, J-Link, Aardvark |
| LLM | On-device or cloud (Gemini) | Host (cloud or local) |
| Use case | Production, standalone | Dev, debug, introspection |
| Channels | WhatsApp, etc. (via WiFi) | Telegram, CLI, etc. |
3. Legacy / Simpler Modes (Pre-LLM-on-Edge)
For boards without WiFi or before full Edge-Native is ready:
Mode A: Host + Remote Peripheral (STM32 via serial)
Host runs ZeroClaw; peripheral runs minimal firmware. Simple JSON over serial.
Mode B: RPi as Host (Native GPIO)
ZeroClaw on Pi; GPIO via rppal or sysfs. No separate firmware.
4. Technical Requirements
| Requirement | Description |
|---|---|
| Language | Pure Rust. no_std where applicable for embedded targets (STM32, ESP32). |
| Communication | Lightweight gRPC or nanoRPC stack for low-latency command processing. |
| Dynamic execution | Safely run LLM-generated logic on-the-fly: Wasm runtime for isolation, or dynamic linking where supported. |
| Documentation retrieval | RAG (Retrieval-Augmented Generation) pipeline to feed datasheet snippets, register maps, and pinouts into LLM context. |
| Hardware discovery | VID/PID-based identification for USB devices; architecture detection (ARM Cortex-M, RISC-V, etc.). |
RAG Pipeline (Datasheet Retrieval)
- Index: Datasheets, reference manuals, register maps (PDF → chunks, embeddings).
- Retrieve: On user query (“turn on LED”), fetch relevant snippets (e.g. GPIO section for target board).
- Inject: Add to LLM system prompt or context.
- Result: LLM generates accurate, board-specific code.
Dynamic Execution Options
| Option | Pros | Cons |
|---|---|---|
| Wasm | Sandboxed, portable, no FFI | Overhead; limited HW access from Wasm |
| Dynamic linking | Native speed, full HW access | Platform-specific; security concerns |
| Interpreted DSL | Safe, auditable | Slower; limited expressiveness |
| Pre-compiled templates | Fast, secure | Less flexible; requires template library |
Recommendation: Start with pre-compiled templates + parameterization; evolve to Wasm for user-defined logic once stable.
5. CLI and Config
See the CLI reference for zeroclaw hardware / zeroclaw peripheral subcommands and the Config reference for the [peripherals] and [[peripherals.boards]] fields.
6. Architecture: Peripheral as Extension Point
New Trait: Peripheral
#![allow(unused)]
fn main() {
/// A hardware peripheral that exposes capabilities as tools.
#[async_trait]
pub trait Peripheral: Send + Sync {
fn name(&self) -> &str;
fn board_type(&self) -> &str; // e.g. "nucleo-f401re", "rpi-gpio"
async fn connect(&mut self) -> anyhow::Result<()>;
async fn disconnect(&mut self) -> anyhow::Result<()>;
async fn health_check(&self) -> bool;
/// Tools this peripheral provides (gpio_read, gpio_write, sensor_read, etc.)
fn tools(&self) -> Vec<Box<dyn Tool>>;
}
}
Flow
- Startup: ZeroClaw loads config, sees
peripherals.boards. - Connect: For each board, create a
Peripheralimpl, callconnect(). - Tools: Collect tools from all connected peripherals; merge with default tools.
- Agent loop: Agent can call
gpio_write,sensor_read, etc., these delegate to the peripheral. - Shutdown: Call
disconnect()on each peripheral.
Board Support
Boards are identified by USB VID/PID in the canonical registry:
| Board | Architecture | USB VID:PID |
|---|---|---|
nucleo-f401re | ARM Cortex-M4 | 0x0483:0x374b |
nucleo-f411re | ARM Cortex-M4 | 0x0483:0x3748 |
arduino-uno | AVR ATmega328P | 0x2341:0x0043 |
arduino-uno | Arduino Uno Q / ATmega328P | 0x2341:0x0078 |
arduino-mega | AVR ATmega2560 | 0x2341:0x0042 |
cp2102 | USB-UART bridge | 0x10c4:0xea60 |
cp2102n | USB-UART bridge | 0x10c4:0xea70 |
esp32 | ESP32 (CH340) | 0x1a86:0x7523 |
esp32 | ESP32 (CH340) | 0x1a86:0x55d4 |
Each connected board is driven over one of the subsystem transports:
| Transport | Description |
|---|---|
serial | Newline-delimited JSON over USB CDC serial |
swd | SWD debug probe (probe-rs) |
uf2 | UF2 mass-storage firmware flashing |
native | Direct Linux GPIO/I2C/SPI (rppal, sysfs) |
aardvark | Total Phase Aardvark USB adapter (I2C/SPI/GPIO) |
The base tools every board exposes, plus the Aardvark-conditional set, are listed in Hardware subsystem → Runtime tools.
7. Communication Protocols
gRPC / nanoRPC (Edge-Native, Host-Mediated)
For low-latency, typed RPC between ZeroClaw and peripherals:
- nanoRPC or tonic (gRPC): Protobuf-defined services.
- Methods:
GpioWrite,GpioRead,I2cTransfer,SpiTransfer,MemoryRead,FlashWrite, etc. - Enables streaming, bidirectional calls, and code generation from
.protofiles.
Serial Transport (Host-Mediated, legacy)
Simple JSON over serial for boards without gRPC support:
Request (host → peripheral):
{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}
Response (peripheral → host):
{"id":"1","ok":true,"result":"done"}
8. Firmware (Separate Repo or Crate)
- zeroclaw-firmware or zeroclaw-peripheral: a separate crate/workspace.
- Targets:
thumbv7em-none-eabihf(STM32),armv7-unknown-linux-gnueabihf(RPi), etc. - Uses
embassyor Zephyr for STM32. - Implements the protocol above.
- User flashes this to the board; ZeroClaw connects and discovers capabilities.
9. Capability Layers
The subsystem is built in layers; each is independently usable. Rather than tracking phase status here (which drifts as work lands), the layers are:
-
Skeleton. The
Peripheraltrait, config schema, andzeroclaw peripheralCLI. The--peripheralflag wires a board into the agent. -
Host-mediated discovery.
zeroclaw hardware discoverenumerates USB devices by VID/PID; the board registry maps them to architecture and name;zeroclaw hardware introspect <path>reports the memory map and peripheral list. -
Serial / probe transport.
SerialPeripheralcarries the JSON protocol over USB CDC; theprobefeature adds probe-rs SWD for flash, memory map, and memory read (see thehardware_*tools). -
RAG pipeline. Datasheets are indexed and injected into LLM context on hardware queries.
Usage:
zeroclaw config set peripherals.datasheet-dir docs/datasheets. Place.mdor.txtfiles named by board (e.g.nucleo-f401re.md,rpi-gpio.md). Files in_generic/or namedgeneric.mdapply to all boards. Chunks are retrieved by keyword match and injected into the user message context. -
Edge-native (Raspberry Pi). ZeroClaw runs on the Pi with native GPIO via rppal (the
peripheral-rpifeature). -
ESP32. Host-mediated over the serial transport, same JSON protocol as STM32. ESP32 dev boards are in the registry by their CH340 USB VID/PID.
Usage: Flash
firmware/esp32to the ESP32, addboard = "esp32",transport = "serial",path = "/dev/ttyUSB0"to config. -
Dynamic execution. LLM-generated logic runs through parameterized templates, with a sandboxed Wasm runtime as the longer-term direction for user-defined logic.
10. Security Considerations
- Serial path: Validate
pathis in allowlist (e.g./dev/ttyACM*,/dev/ttyUSB*); never arbitrary paths. - GPIO: Restrict which pins are exposed; avoid power/reset pins.
- No secrets on peripheral: Firmware should not store API keys; host handles auth.
11. Non-Goals (For Now)
- Running full ZeroClaw on bare STM32 (no WiFi, limited RAM), use Host-Mediated instead
- Real-time guarantees: peripherals are best-effort
- Arbitrary native code execution from LLM: prefer Wasm or templates
12. Related Documents
- adding-boards-and-tools.md: How to add boards and datasheets
- network-deployment.md: RPi and network deployment
13. References
- Zephyr RTOS Rust support
- Embassy: async embedded framework
- rppal: Raspberry Pi GPIO in Rust
- STM32 Nucleo-F401RE
- tonic: gRPC for Rust
- probe-rs: ARM debug probe, flash, memory access
- nusb: USB device enumeration (VID/PID)
14. Raw Prompt Summary
“Boards like ESP, Raspberry Pi, or boards with WiFi can connect to an LLM (Gemini or open-source). ZeroClaw runs on the device, creates its own gRPC, spins it up, and communicates with peripherals. User asks via WhatsApp: ‘move X arm’ or ‘turn on LED’. ZeroClaw gets accurate documentation, writes code, executes it, stores it optimally, runs it, and turns on the LED, all on the development board.
For STM Nucleo connected via USB/J-Link/Aardvark to my Mac: ZeroClaw from my Mac accesses the hardware, installs or writes what it wants on the device, and returns the result. Example: ‘Hey ZeroClaw, what are the available/readable addresses on this USB device?’ It can figure out what’s connected where and suggest.“