Sistema installativo per la tesi di Mattia Piano, Media Design, IED Cagliari, A.A. 2025-2026.
Relatori: Andrea Montaldo, Antonella Arca.
Una Mimosa pudica emette potenziali bioelettrici. Un algoritmo evolutivo interpreta quei segnali come pressione selettiva su una popolazione di organismi digitali. Un pubblico osserva e vota le forme che emergono, e il voto entra nella fitness: la selezione è insieme biologica, algoritmica e sociale.
Gli stessi biosegnali alimentano una seconda uscita: una pipeline che li raggruppa per forma e ne ricava un alfabeto di glifi, distribuito come font. Il segnale della pianta diventa scrittura.
Questa repository contiene il codice sorgente completo del sistema.
.
├── firmware/ ← ESP32-S3 (Arduino Nano ESP32): biosegnale + 7 sensori + OLED
├── web/ ← sito SvelteKit: narrazione, visualizzazione 3D viva, voto
├── bridge/ ← broker WebSocket (Bun): master ↔ client, log della serata
├── glyph_pipeline/ ← pipeline Python: dai biosegnali a un font di glifi
├── scripts/ ← demo.sh: espone il sito al pubblico via tunnel + QR
├── CLAUDE.md ← fonte di verità: stato, protocollo seriale, convenzioni
└── README.md ← questo file
Ogni sottoprogetto ha un proprio README.md o CLAUDE.md con i dettagli.
-
La pianta parla. Tre elettrodi sulla Mimosa (due sullo stelo, il riferimento nel terreno) entrano in un AD8232, front-end per biopotenziali. L'ESP32 lo campiona a 1 kHz con un timer hardware, filtra (bandpass 0.5-100 Hz + notch 50 Hz), rileva gli spike ed estrae quattro feature.
-
Il firmware emette. Una riga JSON su seriale USB ogni 100 ms, con il biosegnale e i sette sensori ambientali. Niente WiFi: solo USB-CDC.
-
Il browser ascolta. Il sito legge la seriale direttamente con la Web Serial API (Chrome/Edge), senza middleware.
-
L'algoritmo evolve. Una popolazione di 20 individui, ognuno con un genoma che governa un Game of Life. Tre feature del biosegnale perturbano l'evoluzione:
Vettore Feature Effetto A amplitudealza il tasso di mutazione B varianceoltre 0.7 innesca un'estinzione di massa C dominantFreqoltre 15 Hz fa derivare le regole dell'automa -
Il pubblico vota. Chi guarda inquadra un QR e vota dal telefono. Il bridge raccoglie i voti e li rimanda al master, dove entrano nella fitness multi-obiettivo insieme a longevità, complessità e novità. Il più adatto entra nella stirpe dei vincitori.
-
Il segnale diventa scrittura. Le registrazioni della pianta vengono segmentate, raggruppate per somiglianza di forma (clustering DTW) e vettorializzate: 32 glifi, un corpus, un font.
Una riga JSON per messaggio, ~10 Hz, 115200 baud:
{"t":12345,"bio":{"raw":1234,"filtered":0.42,"spikeRate":1.8,"amplitude":0.65,"baseline":0.50,"variance":0.32,"dominantFreq":7.5,"spikeCount":18,"leadOff":false},"env":{"temp":23.4,"humidity":58.1,"pressure":1012.3,"lux":320,"pir":false,"presence":true,"soundRMS":0.12,"soilMoisture":0.42,"imu":{"pitch":0.1,"roll":-0.2,"yaw":1.4}}}| Campo | Tipo | Descrizione |
|---|---|---|
t |
uint32 ms |
millis() dell'ESP32 dall'avvio |
bio.raw |
0..4095 |
ADC grezzo dell'AD8232 (12 bit) |
bio.filtered |
-1..+1 |
bandpass 0.5-100 Hz + notch 50 Hz, normalizzato |
bio.spikeRate |
spike/s |
spike su finestra mobile di 10 s |
bio.amplitude |
0..1 |
RMS su finestra di 1 s · vettore A |
bio.baseline |
0..1 |
media mobile lenta |
bio.variance |
0..1 |
deviazione standard su 1 s · vettore B |
bio.dominantFreq |
0..50 Hz |
frequenza dominante (FFT 256 punti) · vettore C |
bio.spikeCount |
uint16 |
picchi nell'ultima finestra di 1 s (telemetria) |
bio.leadOff |
bool |
elettrodi scollegati (LO+ o LO− dell'AD8232) |
env.temp |
°C |
temperatura aria (BME280) |
env.humidity |
%RH |
umidità relativa (BME280) |
env.pressure |
hPa |
pressione atmosferica (BME280) |
env.lux |
lux |
illuminamento (BH1750) |
env.pir |
bool |
movimento (AM312) |
env.presence |
bool |
presenza (radar LD2410C) |
env.soundRMS |
0..1 |
RMS audio (microfono I2S INMP441) |
env.soilMoisture |
0..1 |
umidità terreno, 0 secco · 1 fradicio |
env.imu.* |
rad |
pitch, roll, yaw (MPU6500, filtro Mahony) |
I campi env valgono null quando il sensore non risponde: il sito li mostra come n/d e prosegue.
Il protocollo è il motivo del monorepo: un cambio di schema si committa nello stesso momento da entrambe le parti.
- Chrome o Edge: la Web Serial API non esiste su Firefox e Safari
- Node.js 22+ e pnpm
- Bun (per il bridge)
- PlatformIO Core 6.1+ (per il firmware)
- Python 3.12+ (per la pipeline dei glifi)
- Hardware: Arduino Nano ESP32, AD8232, i sette sensori ambientali, una Mimosa pudica
cd firmware
pio run --target upload
pio device monitor # 115200 baudPinout completo e note hardware in firmware/CLAUDE.md. Un OLED opzionale sul bus I2C mostra tutti i sensori dal vivo, così il collaudo da banco non richiede il computer.
cd web
pnpm install
pnpm dev # http://localhost:5173Apri in Chrome, vai su /master, collega la scheda dal picker della Web Serial.
cd bridge && bun src/server.ts # broker sulla porta 8765
cd web && pnpm dev # il dev server proxa /ws verso il brokerIl pubblico vota da /vota. La console /master è raggiungibile solo dall'host locale dell'operatore.
./scripts/demo.sh # dalla radice del monorepoEspone il sito con un Cloudflare Tunnel e stampa un QR: il pubblico vota dal proprio telefono su rete cellulare, senza WiFi condiviso. Richiede brew install cloudflared qrencode. Dettagli e modalità in web/README.md.
cd glyph_pipeline
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
python scripts/record_session.py --duration 30 # registra dalla pianta
python -m glyph_pipeline.pipeline # genera glifi, corpus e fontSotto i 60 minuti di registrazioni reali, la pipeline usa un fallback sintetico e lo dichiara. Dettagli in glyph_pipeline/README.md.
Funzionante: acquisizione del biosegnale a 1 kHz, i sette sensori ambientali, il protocollo seriale, l'algoritmo genetico con i tre vettori di perturbazione, la visualizzazione 3D, il voto multi-utente via bridge con log della serata, l'audio generativo nel browser (Tone.js), la pipeline completa dei glifi (sei stage, dal segnale al font).
Non realizzato, per scelta esplicita:
- Catena audio hardware (DAC PCM5102A + amplificatore TDA7377): l'audio vive nel browser, non su hardware dedicato.
- Display e-paper: rinviato.
- Kit replicabile open source: resta una direzione praticabile, non un oggetto costruito.
- WiFi / MQTT: sostituiti da USB-CDC, più stabile in aula e senza dipendenze di rete.
Codice rilasciato sotto licenza MIT.
Mattia Piano · hypnos.design@gmail.com