Architecture
System Diagram
┌──────────────────────────────────────────────────────────┐
│ Raspberry Pi + PiEEG Shield (8 or 16 ch) │
│ — or — IronBCI / EAREEG board (8 ch, Bluetooth LE) │
│ │
│ hardware.py → SPI/GPIO init, ADS1299 config (PiEEG) │
│ ironbci.py → BLE scan + GATT notifications (IronBCI)│
│ ↓ │
│ acquisition.py → 250 Hz read loop (SPI or BLE) │
│ ↓ pub/sub │
│ ├── server.py → WebSocket broadcast │
│ ├── recorder.py → CSV writer │
│ ├── monitor.py → Terminal sparklines │
│ ├── osc_vrchat.py → VRChat OSC bridge │
│ └── lsl.py → Lab Streaming Layer outlet │
│ │
│ webhooks.py → event rules + HTTP relay │
│ dashboard.py → HTTP server (React UI) │
│ auth.py → session + WS token management │
│ filters.py → Butterworth bandpass (SOS) │
│ updater.py → version check + upgrade │
│ doctor.py → system diagnostics │
│ │
│ ws://0.0.0.0:1616 │ http://0.0.0.0:1617 │
└──────────┬───────────────────────────────────────────────┘
│ Local network / internet
├── Browser dashboard (React + Vite)
├── Python / Jupyter notebook
├── VRChat (OSC over UDP)
├── LSL consumers (OpenViBE, MNE…)
├── IFTTT / Zapier (webhooks)
└── Any WebSocket clientServer Modules
- __main__.py
- hardware.py
- ironbci.py
- acquisition.py
- server.py
- dashboard.py
- auth.py
- filters.py
- recorder.py
- monitor.py
- osc_vrchat.py
- lsl.py
- webhooks.py
- updater.py
- doctor.py
- mock.py
| Module | Responsibility |
|---|---|
hardware.py | SPI/GPIO initialization, ADS1299 register config (PiEEG) |
ironbci.py | BLE scan, GATT notifications, ADS1299 packet parsing (IronBCI) |
acquisition.py | 250 Hz read loop (SPI, BLE, or mock), pub/sub queues |
server.py | WebSocket server, frame broadcast, command dispatch |
dashboard.py | HTTP server for React dashboard + REST API |
auth.py | 6-digit code auth, session cookies, WS token management |
filters.py | Butterworth IIR bandpass (SOS), per-channel state |
recorder.py | CSV writer, subscribes to acquisition queue |
monitor.py | Rich TUI with sparklines, standalone or embedded |
osc_vrchat.py | UDP OSC bridge for VRChat (chatbox + avatar params) |
lsl.py | Lab Streaming Layer outlet |
webhooks.py | Rule persistence, condition evaluation, HTTP relay |
updater.py | Version check (PyPI or git remote), upgrade trigger |
doctor.py | System diagnostics (Pi model, SPI, GPIO, ports, deps) |
mock.py | Synthetic EEG generator (alpha, drift, noise, blinks) |
Data Flow
- ADS1299 chip on PiEEG shield reads analog voltages via SPI at 250 Hz
hardware.pyconverts raw 24-bit values to µV floatsacquisition.pyruns a dedicated thread, pushes samples to async queues- Each subscriber (server, recorder, monitor, etc.) consumes from its own queue
server.pybroadcasts JSON frames to all connected WebSocket clients- Dashboard renders at 60 fps using Canvas 2D and refs (no React re-renders)
Dashboard Architecture
| Layer | Tech |
|---|---|
| Framework | React 19 |
| Bundler | Vite 6 |
| Rendering | Canvas 2D + Three.js (WebXR) |
| FFT | Cooley-Tukey radix-2 (Web Worker) |
| State | Hooks + refs only |
| Styling | Plain CSS |