Move all animations to Pico firmware, Pi becomes HTTP-serial bridge
Pico runs all 9 mood animations and jaw modes locally instead of receiving per-LED serial commands from the Pi. New protocol: bare integers for fire-and-forget jaw amplitude, "mood X" / "jaw X" for mode switches. Cuts light_service.py from 409 to 193 lines. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
50
README.md
50
README.md
@@ -8,14 +8,15 @@ LED strip control for head-vixy (Vixy's robotic head) via Raspberry Pi Pico 2.
|
||||
┌─────────────────┐ USB Serial ┌──────────────────┐
|
||||
│ Raspberry Pi 5 │◄──────────────────►│ Pico 2 │
|
||||
│ (light_service)│ /dev/ttyACM0 │ (main.py) │
|
||||
│ Port 8781 │ │ │
|
||||
└─────────────────┘ │ GP0 → Jaw LEDs │
|
||||
│ GP1 → Mood LEDs │
|
||||
│ Port 8781 │ │ Animation Engine │
|
||||
└─────────────────┘ │ │
|
||||
HTTP-to-serial │ GP0 → Jaw LEDs │
|
||||
bridge │ GP1 → Mood LEDs │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
- **Raspberry Pi 5** - Runs Python service, HTTP API, animation logic
|
||||
- **Raspberry Pi Pico 2** - Controls LED strips via PIO, receives serial commands
|
||||
- **Raspberry Pi 5** - Thin HTTP-to-serial bridge, forwards mode commands
|
||||
- **Raspberry Pi Pico 2** - Runs all LED animations locally via PIO
|
||||
- **Mood strip**: 56x WS2812B LEDs on GP1
|
||||
- **Jaw strip**: 14x WS2812B LEDs on GP0 (index 0 damaged, use 1-13)
|
||||
|
||||
@@ -28,11 +29,12 @@ The BBB PRU approach burned 4 boards. Pico 2 is $5, runs MicroPython, has hardwa
|
||||
```
|
||||
head-lights/
|
||||
├── README.md # This file
|
||||
├── light_service.py # Pi service (animations + HTTP API)
|
||||
├── light_service.py # Pi service (HTTP-to-serial bridge)
|
||||
├── requirements.txt # Python deps (pyserial)
|
||||
├── vixy-lights.service # systemd unit file
|
||||
├── docs/plans/ # Design documents
|
||||
└── firmware/
|
||||
└── main.py # Pico 2 MicroPython firmware
|
||||
└── main.py # Pico 2 MicroPython firmware (animation engine)
|
||||
```
|
||||
|
||||
## States
|
||||
@@ -49,7 +51,6 @@ head-lights/
|
||||
| love | Soft pink 💕 | Gentle breathing | Tender/affectionate |
|
||||
| sleep | Dim blue-gray | Very slow, dim | Low power/resting |
|
||||
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```
|
||||
@@ -57,30 +58,26 @@ GET /health - Service health (includes serial connection status)
|
||||
GET /state - Current light state + jaw level
|
||||
POST /state - Set state: {"state": "listening"}
|
||||
POST /jaw/level - Set jaw level: {"level": 0-100}
|
||||
POST /jaw/mode - Set jaw mode: {"mode": "talking"}
|
||||
```
|
||||
|
||||
**Port: 8781**
|
||||
|
||||
## Pico Serial Protocol
|
||||
|
||||
Commands sent over USB serial at 115200 baud:
|
||||
All animations run on the Pico. The Pi sends mode commands over USB serial at 115200 baud:
|
||||
|
||||
```
|
||||
<strip> <index> <r> <g> <b> - Set single LED
|
||||
<strip> -1 - Trigger strip update (show)
|
||||
<strip> clear - Clear strip
|
||||
<strip> fill <r> <g> <b> - Fill entire strip (mood only)
|
||||
```
|
||||
| Command | Example | Response | Description |
|
||||
|---------|---------|----------|-------------|
|
||||
| `<integer>` | `72` | *(none)* | Jaw amplitude 0-100, fire-and-forget |
|
||||
| `mood <mode>` | `mood thinking` | `OK` | Switch mood animation |
|
||||
| `jaw <mode>` | `jaw talking` | `OK` | Switch jaw animation mode |
|
||||
|
||||
Strip IDs: 0 = Jaw, 1 = Mood
|
||||
**Mood modes:** idle, listening, responding, pleasure, thinking, playful, commanding, love, sleep, off
|
||||
|
||||
Examples:
|
||||
```
|
||||
1 0 255 0 0 # Set mood LED 0 to red
|
||||
1 -1 # Show mood strip
|
||||
0 clear # Clear jaw strip
|
||||
1 fill 0 255 255 # Fill mood with cyan
|
||||
```
|
||||
**Jaw modes:** idle, talking, off
|
||||
|
||||
Bare integers are the fast path for jaw amplitude during speech — minimal bytes, no response wait.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -122,7 +119,7 @@ curl http://head-vixy.local:8781/health
|
||||
# Get current state
|
||||
curl http://head-vixy.local:8781/state
|
||||
|
||||
# Set state
|
||||
# Set mood state
|
||||
curl -X POST http://head-vixy.local:8781/state \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"state": "thinking"}'
|
||||
@@ -131,6 +128,11 @@ curl -X POST http://head-vixy.local:8781/state \
|
||||
curl -X POST http://head-vixy.local:8781/jaw/level \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"level": 75}'
|
||||
|
||||
# Set jaw mode
|
||||
curl -X POST http://head-vixy.local:8781/jaw/mode \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"mode": "talking"}'
|
||||
```
|
||||
|
||||
## Unified Head Control
|
||||
|
||||
Reference in New Issue
Block a user