> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/nullclaw/nullclaw/llms.txt
> Use this file to discover all available pages before exploring further.

# Hardware Integration

> Connect Arduino, Raspberry Pi GPIO, STM32/Nucleo boards, and other hardware peripherals to NullClaw

NullClaw provides native hardware peripheral support for embedded boards, enabling AI-powered control of GPIO pins, sensors, actuators, and microcontroller flashing.

## Overview

NullClaw's hardware architecture:

<CardGroup cols={3}>
  <Card title="Arduino" icon="microchip">
    Serial JSON protocol over USB
  </Card>

  <Card title="Raspberry Pi" icon="raspberry-pi">
    Direct GPIO access via sysfs
  </Card>

  <Card title="STM32/Nucleo" icon="circuit-board">
    Flash & debug via probe-rs
  </Card>
</CardGroup>

## Supported Hardware

### Arduino Boards

<Tabs>
  <Tab title="Uno/Nano">
    * Serial: `/dev/ttyACM0` or `/dev/ttyUSB0`
    * Baud: 9600
    * Protocol: JSON over serial
  </Tab>

  <Tab title="Mega">
    * Serial: `/dev/ttyACM0`
    * Baud: 9600
    * More GPIO pins, same protocol
  </Tab>

  <Tab title="ESP32">
    * Serial: `/dev/ttyUSB0`
    * Baud: 115200
    * WiFi-capable (future support)
  </Tab>
</Tabs>

### Raspberry Pi

* All models with GPIO header (Zero, 3, 4, 5)
* Direct GPIO via `/sys/class/gpio`
* I2C, SPI support planned
* Native Linux, no external tools

### STM32/Nucleo Boards

* STM32F4, STM32L4, STM32H7 series
* Nucleo-F401RE, Nucleo-F411RE
* Flash via `probe-rs` CLI
* Debug via SWD/JTAG

## Hardware Tools

NullClaw exposes hardware capabilities as tools:

| Tool              | Description              | Boards         |
| ----------------- | ------------------------ | -------------- |
| `hardware_info`   | List connected devices   | All            |
| `hardware_memory` | Read/write device memory | STM32, Arduino |
| `i2c`             | I2C bus communication    | RPi, Arduino   |
| `spi`             | SPI bus communication    | RPi, Arduino   |
| `gpio_read`       | Read GPIO pin state      | RPi, Arduino   |
| `gpio_write`      | Set GPIO pin state       | RPi, Arduino   |
| `flash_firmware`  | Flash firmware to MCU    | STM32, Arduino |

## Arduino Setup

### Flash Arduino Sketch

Upload the serial JSON protocol sketch:

```cpp arduino_bridge.ino theme={null}
void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    
    // Parse JSON: {"cmd":"gpio_write","pin":13,"value":1}
    if (cmd.indexOf("gpio_write") > 0) {
      int pin = cmd.substring(cmd.indexOf("pin":) + 5, cmd.indexOf(",")).toInt();
      int value = cmd.substring(cmd.indexOf("value":) + 7, cmd.indexOf("}")).toInt();
      
      digitalWrite(pin, value);
      Serial.println("{\"status\":\"ok\"}");
    }
  }
}
```

<Note>
  Full protocol implementation available in `~/.nullclaw/workspace/examples/arduino_bridge.ino`
</Note>

### Configure NullClaw

```json config.json theme={null}
{
  "peripherals": {
    "arduino": {
      "enabled": true,
      "port": "/dev/ttyACM0",
      "baud": 9600,
      "timeout_ms": 1000
    }
  },
  "tools": {
    "hardware_info": { "enabled": true },
    "i2c": { "enabled": true },
    "gpio_read": { "enabled": true },
    "gpio_write": { "enabled": true }
  }
}
```

### Find Serial Port

```bash theme={null}
# Linux
ls /dev/ttyACM* /dev/ttyUSB*

# macOS
ls /dev/tty.usbmodem* /dev/cu.usbmodem*

# With dmesg (Linux)
dmesg | grep tty
```

### Test Connection

```bash theme={null}
# Check hardware
nullclaw hardware scan

# Get device info
nullclaw hardware info

# Test GPIO
nullclaw agent -m "Set Arduino pin 13 to HIGH"
```

## Raspberry Pi Setup

### Enable GPIO Access

```bash theme={null}
# Add user to gpio group
sudo usermod -aG gpio $USER

# Reload groups
newgrp gpio

# Verify permissions
ls -l /sys/class/gpio/export
```

### Configure NullClaw

```json config.json theme={null}
{
  "peripherals": {
    "raspberry_pi": {
      "enabled": true,
      "gpio_base": "/sys/class/gpio"
    }
  },
  "tools": {
    "gpio_read": { "enabled": true },
    "gpio_write": { "enabled": true }
  }
}
```

### GPIO Pin Mapping

Raspberry Pi GPIO pins (BCM numbering):

| Physical | BCM     | Name       |
| -------- | ------- | ---------- |
| 3        | GPIO 2  | SDA        |
| 5        | GPIO 3  | SCL        |
| 7        | GPIO 4  | GPCLK0     |
| 11       | GPIO 17 | GPIO\_GEN0 |
| 13       | GPIO 27 | GPIO\_GEN2 |
| 15       | GPIO 22 | GPIO\_GEN3 |

Use BCM numbers in commands:

```bash theme={null}
nullclaw agent -m "Set GPIO 17 to HIGH"
```

### Example Usage

<CodeGroup>
  ```bash Read Pin theme={null}
  nullclaw agent -m "Read the state of GPIO pin 17"
  ```

  ```bash Write Pin theme={null}
  nullclaw agent -m "Turn on LED connected to GPIO 22"
  ```

  ```bash Blink LED theme={null}
  nullclaw agent -m "Blink LED on GPIO 27 five times with 500ms delay"
  ```
</CodeGroup>

## STM32/Nucleo Setup

### Install probe-rs

```bash theme={null}
# Install probe-rs CLI
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-installer.sh | sh

# Verify installation
probe-rs --version
```

### Configure NullClaw

```json config.json theme={null}
{
  "peripherals": {
    "stm32": {
      "enabled": true,
      "probe": "auto",
      "chip": "STM32F401RETx"
    }
  },
  "tools": {
    "hardware_memory": { "enabled": true },
    "flash_firmware": { "enabled": true }
  }
}
```

### Flash Firmware

```bash theme={null}
# Build firmware
zig build firmware

# Flash to board
nullclaw hardware flash --board nucleo-f401re --file zig-out/bin/firmware.bin

# Or via agent
nullclaw agent -m "Flash firmware.bin to the STM32 board"
```

### Read/Write Memory

```bash theme={null}
# Read memory address
nullclaw agent -m "Read memory at address 0x08000000"

# Write byte
nullclaw agent -m "Write value 0xFF to address 0x20000000"
```

<Warning>
  Direct memory access can brick devices. Only use on development boards with recovery options.
</Warning>

## Hardware Commands

### Scan Devices

```bash theme={null}
# List all connected hardware
nullclaw hardware scan

# Output:
# Found 3 devices:
# - Arduino Uno (/dev/ttyACM0)
# - STM32F401RE (probe: 0483:374b)
# - Raspberry Pi GPIO (native)
```

### Device Info

```bash theme={null}
# Get capabilities
nullclaw hardware info arduino

# Output:
# Board: Arduino Uno
# Type: arduino_uno
# GPIO Pins: D2-D13, A0-A5
# Flash: 32 KB
# Serial: Yes
# I2C: Yes
# SPI: Yes
```

### Flash Firmware

```bash theme={null}
# Arduino
nullclaw hardware flash --board arduino --port /dev/ttyACM0 --file sketch.hex

# STM32
nullclaw hardware flash --board stm32 --chip STM32F401RETx --file firmware.bin
```

### Monitor Serial

```bash theme={null}
# Watch serial output
nullclaw hardware monitor /dev/ttyACM0

# With baud rate
nullclaw hardware monitor /dev/ttyACM0 --baud 115200
```

## I2C Communication

Read sensors via I2C bus:

### Configure I2C

```json config.json theme={null}
{
  "tools": {
    "i2c": {
      "enabled": true,
      "bus": "/dev/i2c-1",
      "allowed_addresses": ["0x48", "0x68", "0x76"]
    }
  }
}
```

### Read I2C Device

```bash theme={null}
# Scan I2C bus
nullclaw agent -m "Scan I2C bus 1 for devices"

# Read from device
nullclaw agent -m "Read temperature from I2C device at 0x48"

# Write to device
nullclaw agent -m "Write 0x01 to I2C device 0x68 register 0x6B"
```

### Common I2C Sensors

| Device  | Address | Type                 |
| ------- | ------- | -------------------- |
| BMP280  | 0x76    | Temperature/Pressure |
| MPU6050 | 0x68    | Accelerometer/Gyro   |
| ADS1115 | 0x48    | ADC                  |
| SSD1306 | 0x3C    | OLED Display         |

## SPI Communication

Communicate with SPI devices:

### Configure SPI

```json config.json theme={null}
{
  "tools": {
    "spi": {
      "enabled": true,
      "bus": "/dev/spidev0.0",
      "max_speed_hz": 1000000,
      "mode": 0
    }
  }
}
```

### SPI Transfer

```bash theme={null}
# Transfer data
nullclaw agent -m "Send [0x9F, 0x00, 0x00] via SPI and read response"
```

## Security

Hardware access is restricted:

### Serial Port Allowlist

Only specific paths allowed:

```zig theme={null}
const allowed_serial_prefixes = [_][]const u8{
    "/dev/ttyACM",
    "/dev/ttyUSB",
    "/dev/tty.usbmodem",
    "/dev/cu.usbmodem",
    "/dev/tty.usbserial",
    "/dev/cu.usbserial",
};
```

Prevents access to system serial devices.

### I2C Address Restrictions

```json config.json theme={null}
{
  "tools": {
    "i2c": {
      "allowed_addresses": ["0x48", "0x68"]  // Specific devices only
    }
  }
}
```

Empty list denies all I2C access.

### GPIO Pin Limits

```json config.json theme={null}
{
  "peripherals": {
    "raspberry_pi": {
      "allowed_pins": [17, 22, 27]  // Specific pins only
    }
  }
}
```

### Memory Access Guards

STM32 memory access:

* Read-only by default
* Write requires explicit approval
* Flash regions protected
* System memory blocked

## Troubleshooting

### Device Not Found

```bash theme={null}
# Check USB connections
lsusb

# Check serial ports
ls -l /dev/ttyACM* /dev/ttyUSB*

# Check permissions
groups  # Should include 'dialout' or 'uucp'

# Add user to group
sudo usermod -aG dialout $USER
```

### Permission Denied

```bash theme={null}
# GPIO access
sudo chmod 666 /sys/class/gpio/export
sudo usermod -aG gpio $USER

# Serial access
sudo usermod -aG dialout $USER

# I2C access
sudo usermod -aG i2c $USER
```

### Arduino Not Responding

Check serial protocol:

```bash theme={null}
# Test with screen
screen /dev/ttyACM0 9600

# Send test command
{"cmd":"ping"}
# Should receive: {"status":"ok"}
```

### STM32 Flash Failed

```bash theme={null}
# Check probe connection
probe-rs list

# Verify chip
probe-rs info --chip STM32F401RETx

# Try recovery mode
probe-rs erase --chip STM32F401RETx
```

### GPIO Pin Not Working

```bash theme={null}
# Check if exported
ls /sys/class/gpio/gpio17

# Export manually
echo 17 > /sys/class/gpio/export

# Set direction
echo out > /sys/class/gpio/gpio17/direction

# Test
echo 1 > /sys/class/gpio/gpio17/value
```

## Advanced Usage

### Custom Peripheral

Implement custom hardware interface:

```zig custom_board.zig theme={null}
const Peripheral = @import("peripherals.zig").Peripheral;

pub const CustomBoard = struct {
    name_str: []const u8 = "custom_board",
    
    pub fn peripheral(self: *CustomBoard) Peripheral {
        return .{
            .ptr = @ptrCast(self),
            .vtable = &vtable,
        };
    }
    
    const vtable = Peripheral.VTable{
        .name = name,
        .board_type = boardType,
        .health_check = healthCheck,
        .init_peripheral = initPeripheral,
        .read = read,
        .write = write,
        .flash = flash,
        .capabilities = capabilities,
    };
    
    fn name(ptr: *anyopaque) []const u8 {
        const self: *CustomBoard = @ptrCast(@alignCast(ptr));
        return self.name_str;
    }
    
    // Implement other methods...
};
```

### Multi-Board Setup

```json config.json theme={null}
{
  "peripherals": {
    "arduino_1": {
      "enabled": true,
      "port": "/dev/ttyACM0",
      "alias": "sensor_board"
    },
    "arduino_2": {
      "enabled": true,
      "port": "/dev/ttyACM1",
      "alias": "actuator_board"
    },
    "stm32": {
      "enabled": true,
      "chip": "STM32F401RETx",
      "alias": "control_board"
    }
  }
}
```

Reference by alias:

```bash theme={null}
nullclaw agent -m "Read sensor from sensor_board"
nullclaw agent -m "Activate relay on actuator_board"
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Sandboxing" href="/guides/sandboxing" icon="shield">
    Secure hardware access with sandboxing
  </Card>

  <Card title="AI Providers" href="/guides/providers" icon="brain">
    Configure AI models for hardware control
  </Card>
</CardGroup>
