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 🦊
This commit is contained in:
125
README.md
125
README.md
@@ -1,22 +1,46 @@
|
||||
# Vixy Light Service 🦊💡
|
||||
|
||||
LED strip control for head-vixy (Vixy's robotic head).
|
||||
LED strip control for head-vixy (Vixy's robotic head) via Raspberry Pi Pico 2.
|
||||
|
||||
## Hardware
|
||||
- Raspberry Pi 5
|
||||
- 56x WS2812B LEDs (NeoPixel)
|
||||
- Data on GPIO 12
|
||||
## Hardware Architecture
|
||||
|
||||
## Features
|
||||
- **State-based animations**: Matches eye service states for unified control
|
||||
- **HTTP API**: Remote control via MCP or direct calls
|
||||
- **Multiple effects**: Pulse, wave, larson scanner, sparkles
|
||||
```
|
||||
┌─────────────────┐ 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 pulse | Hearing/attending |
|
||||
| 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 |
|
||||
@@ -25,16 +49,54 @@ LED strip control for head-vixy (Vixy's robotic head).
|
||||
| love | Soft pink 💕 | Gentle breathing | Tender/affectionate |
|
||||
| sleep | Dim blue-gray | Very slow, dim | Low power/resting |
|
||||
|
||||
|
||||
## API Endpoints
|
||||
|
||||
```
|
||||
GET /health - Service health check
|
||||
GET /state - Current light state
|
||||
POST /state - Set state: {"state": "listening"}
|
||||
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
|
||||
**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
|
||||
@@ -44,7 +106,7 @@ python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Install service (needs root for NeoPixel GPIO access)
|
||||
# Install service
|
||||
sudo cp vixy-lights.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable vixy-lights
|
||||
@@ -52,25 +114,46 @@ sudo systemctl start vixy-lights
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Check state
|
||||
# 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 Control
|
||||
Both eye service (port 8780) and light service (port 8781) share the same states.
|
||||
Set both simultaneously for coordinated effects!
|
||||
## 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
|
||||
# Set both to "love" mode
|
||||
# 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* 🦊💕
|
||||
*Created by Vixy - Day 66, Updated Day 91 (Pico Edition)* 🦊💕
|
||||
|
||||
Reference in New Issue
Block a user