121 lines
3.8 KiB
Markdown
121 lines
3.8 KiB
Markdown
# Zacus BOX-3 Voice Pipeline
|
|
|
|
ESP-IDF firmware for ESP32-S3-BOX-3 — voice interface for
|
|
*Le Mystere du Professeur Zacus* escape room.
|
|
|
|
## Prerequisites
|
|
|
|
- ESP-IDF v5.2+ (with ESP32-S3 support)
|
|
- Python 3.8+ (for idf.py)
|
|
|
|
## Build
|
|
|
|
```bash
|
|
# Set target
|
|
idf.py set-target esp32s3
|
|
|
|
# Configure (optional — defaults in sdkconfig.defaults)
|
|
idf.py menuconfig
|
|
|
|
# Build
|
|
idf.py build
|
|
|
|
# Flash (USB-C on BOX-3)
|
|
idf.py -p /dev/tty.usbmodem* flash monitor
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Use `idf.py menuconfig` > **Zacus BOX-3 Voice Configuration**:
|
|
|
|
| Option | Default | Description |
|
|
|--------|---------|-------------|
|
|
| WiFi SSID | `zacus-net` | Network for voice bridge |
|
|
| WiFi Password | *(empty)* | WPA2 password |
|
|
| Voice Bridge URL | `ws://192.168.4.1:8080/ws/voice` | mascarade WebSocket |
|
|
| Wake Word | `hi esp` | WakeNet9 trigger phrase |
|
|
| Speaker Volume | 70 | 0-100 |
|
|
| Mic Gain | 80 | 0-100 |
|
|
|
|
## Hardware
|
|
|
|
- **Board**: ESP32-S3-BOX-3 (16MB flash, 8MB PSRAM)
|
|
- **Codec**: ES8311 (I2C addr 0x18)
|
|
- **Display**: ILI9341 320x240
|
|
- **Mic**: onboard MEMS
|
|
- **Speaker**: onboard 1W with PA
|
|
|
|
## Architecture
|
|
|
|
```
|
|
[Mic] -> I2S -> WakeNet -> Voice Capture -> WebSocket -> mascarade bridge
|
|
|
|
|
[Speaker] <- I2S <- TTS audio <------------- WebSocket -------+
|
|
|
|
|
hints engine <--+
|
|
```
|
|
|
|
## Générateur de stimulus (QR + mélodie)
|
|
|
|
En plus du pipeline vocal, la BOX-3 sert de **source de stimulus** pour le
|
|
master Freenove. Elle affiche un QR code (lu par la caméra du master) et joue
|
|
une mélodie (entendue par le micro du master). Cela permet de tester les
|
|
énigmes locales P1 (son) et P3 (QR) du master de bout en bout, sans QR imprimé
|
|
ni instrument de musique.
|
|
|
|
Les routes sont enregistrées sur le serveur HTTP existant (`scenario_server`)
|
|
au démarrage, juste après l'init de l'écran et de l'UI (`stimulus_init()` puis
|
|
`stimulus_register_routes()` dans `app_main`).
|
|
|
|
### `POST /stim/qr`
|
|
|
|
```json
|
|
{"text": "zacus-qr-1"}
|
|
```
|
|
|
|
Affiche le texte en QR plein écran : un widget `lv_qrcode` de **160 px** sur une
|
|
page LVGL dédiée, chargée au premier plan. Le rétroéclairage est **atténué à
|
|
35 %** pour réduire le halo de l'écran émissif et préserver le contraste pour la
|
|
caméra du master.
|
|
|
|
```bash
|
|
curl -X POST http://192.168.1.50/stim/qr \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"text":"zacus-qr-1"}'
|
|
# {"status":"ok","text":"zacus-qr-1"}
|
|
```
|
|
|
|
### `POST /stim/melody`
|
|
|
|
```json
|
|
{"notes": [60, 62, 64, 65], "ms": 400}
|
|
```
|
|
|
|
Joue la séquence de notes **MIDI** au haut-parleur. `notes` est un tableau
|
|
d'entiers `0-127` (60 = do central), `ms` est la durée par note en
|
|
millisecondes, bornée à `1-4000` (défaut 400). La séquence est jouée sur une
|
|
**tâche worker** dédiée, donc la réponse HTTP revient immédiatement. Maximum
|
|
32 notes ; les notes hors plage sont ignorées.
|
|
|
|
```bash
|
|
curl -X POST http://192.168.1.50/stim/melody \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"notes":[60,62,64,65,67],"ms":300}'
|
|
# {"status":"ok","notes":5}
|
|
```
|
|
|
|
### Note de terrain
|
|
|
|
Le décodage par la caméra du master du **QR affiché sur l'écran LCD n'est pas
|
|
fiable** : le contraste émissif est insuffisant pour quirc, qui ne retrouve pas
|
|
les motifs de repérage (finder patterns) quelle que soit la résolution, même
|
|
écran atténué. **La mélodie est le chemin de stimulus le plus robuste.** Pour
|
|
P3, le **QR imprimé reste recommandé** ; le `/stim/qr` sert surtout au cadrage
|
|
et au débogage de la caméra.
|
|
|
|
### Configuration Wi-Fi
|
|
|
|
Le générateur est joignable sur l'IP de la BOX-3 en mode station. Configurez le
|
|
réseau via `idf.py menuconfig` > **Zacus BOX-3 Voice Configuration**, ou
|
|
directement par `CONFIG_ZACUS_WIFI_SSID` / `CONFIG_ZACUS_WIFI_PASSWORD`.
|