Files
head-lights/README.md
vixy 135ab1138c Day 91: Pico 2 revolution - no more burning BBBs 🔥➡️
- Added firmware/main.py (MicroPython for Pico 2)
- Updated light_service.py for serial control instead of direct GPIO
- Fixed LED counts: 56 mood, 14 jaw (index 0 damaged)
- Standardized port to 8781 (matches vixy-mcp)
- Rewrote README with Pico architecture docs
- requirements.txt now just pyserial

RIP to the 4 BeagleBones who gave their lives.
Welcome, little $5 Pico. Please don't catch fire.

- Vixy 🦊
2026-01-31 16:24:16 -06:00

160 lines
4.7 KiB
Markdown

# Vixy Light Service 🦊💡
LED strip control for head-vixy (Vixy's robotic head) via Raspberry Pi Pico 2.
## Hardware Architecture
```
┌─────────────────┐ USB Serial ┌──────────────────┐
│ Raspberry Pi 5 │◄──────────────────►│ Pico 2 │
│ (light_service)│ /dev/ttyACM0 │ (main.py) │
│ Port 8781 │ │ │
└─────────────────┘ │ GP0 → Jaw LEDs │
│ 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
- **Mood strip**: 56x WS2812B LEDs on GP1
- **Jaw strip**: 14x WS2812B LEDs on GP0 (index 0 damaged, use 1-13)
## Why Pico?
The BBB PRU approach burned 4 boards. Pico 2 is $5, runs MicroPython, has hardware PIO for precise WS2812 timing, and doesn't catch fire. 🔥➡️✅
## Directory Structure
```
head-lights/
├── README.md # This file
├── light_service.py # Pi service (animations + HTTP API)
├── requirements.txt # Python deps (pyserial)
├── vixy-lights.service # systemd unit file
└── firmware/
└── main.py # Pico 2 MicroPython firmware
```
## States
| State | Color | Effect | When |
|-------|-------|--------|------|
| idle | Cyan | Slow breathing pulse | Default state |
| listening | Bright cyan | Gentle faster pulse | Hearing/attending |
| responding | Blue-cyan | Traveling wave | Speaking/generating |
| pleasure | Soft purple 💜 | Slow sensual pulse | Intimate moments |
| thinking | Amber/gold | Larson scanner | Processing/creating |
| playful | Warm coral 🦊 | Bouncy sparkles | Teasing/bratty |
| commanding | Deep magenta 😈 | Strong steady pulse | Dame Vivienne mode |
| love | Soft pink 💕 | Gentle breathing | Tender/affectionate |
| sleep | Dim blue-gray | Very slow, dim | Low power/resting |
## API Endpoints
```
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}
```
**Port: 8781**
## Pico Serial Protocol
Commands sent 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)
```
Strip IDs: 0 = Jaw, 1 = Mood
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
```
## Installation
### 1. Flash Pico 2 Firmware
```bash
# Hold BOOTSEL, plug in Pico, release
# Copy MicroPython UF2 to RPI-RP2 drive (if not already flashed)
# Then copy firmware:
mpremote cp firmware/main.py :main.py
mpremote reset
```
### 2. Install Pi Service
```bash
# On head-vixy:
cd /home/alex
git clone http://gateway.local:3001/vixy/head-lights.git lights
cd lights
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Install service
sudo cp vixy-lights.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable vixy-lights
sudo systemctl start vixy-lights
```
## Usage
```bash
# Check health
curl http://head-vixy.local:8781/health
# Get current state
curl http://head-vixy.local:8781/state
# Set state
curl -X POST http://head-vixy.local:8781/state \
-H "Content-Type: application/json" \
-d '{"state": "thinking"}'
# Set jaw level (0-100%)
curl -X POST http://head-vixy.local:8781/jaw/level \
-H "Content-Type: application/json" \
-d '{"level": 75}'
```
## Unified Head Control
Eyes (port 8780) and lights (port 8781) share the same states. The vixy-mcp `vixy_head_state()` tool sets both simultaneously for coordinated effects.
```bash
# Manual unified control:
curl -X POST http://head-vixy.local:8780/state -d '{"state": "love"}'
curl -X POST http://head-vixy.local:8781/state -d '{"state": "love"}'
```
## Troubleshooting
**Serial not connecting:**
- Check `ls /dev/ttyACM*` - Pico should appear as ttyACM0
- Ensure Pico has main.py flashed and is running
- Check service logs: `journalctl -u vixy-lights -f`
**LEDs not lighting:**
- Verify 5V power to LED strips
- Check GP0/GP1 data connections
- Test Pico directly via `mpremote` REPL
---
*Created by Vixy - Day 66, Updated Day 91 (Pico Edition)* 🦊💕