Software
Reference
Architecture

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 client

Server Modules

    • __main__.py
    • hardware.py
    • ironbci.py
    • acquisition.py
    • server.py
    • dashboard.py
    • auth.py
    • filters.py
    • spike_filter.py
    • _native.py
    • recorder.py
    • monitor.py
    • osc_vrchat.py
    • lsl.py
    • webhooks.py
    • updater.py
    • doctor.py
    • mock.py
  • ModuleResponsibility
    hardware.pySPI/GPIO initialization, ADS1299 register config (PiEEG)
    ironbci.pyBLE scan, GATT notifications, ADS1299 packet parsing (IronBCI)
    acquisition.py250 Hz read loop (SPI, BLE, or mock), pub/sub queues
    server.pyWebSocket server, frame broadcast, command dispatch
    dashboard.pyHTTP server for React dashboard + REST API
    auth.py6-digit code auth, session cookies, WS token management
    filters.pyButterworth IIR bandpass (SOS), per-channel state
    spike_filter.pyHampel median-absolute-deviation spike rejection
    _native.pySoft-import of optional pieeg-core (opens in a new tab) Rust accelerator; exposes HAS_NATIVE, engine_info()
    recorder.pyCSV writer, subscribes to acquisition queue
    monitor.pyRich TUI with sparklines, standalone or embedded
    osc_vrchat.pyUDP OSC bridge for VRChat (chatbox + avatar params)
    lsl.pyLab Streaming Layer outlet
    webhooks.pyRule persistence, condition evaluation, HTTP relay
    updater.pyVersion check (PyPI or git remote), upgrade trigger
    doctor.pySystem diagnostics (Pi model, SPI, GPIO, ports, deps)
    mock.pySynthetic EEG generator (alpha, drift, noise, blinks)

    Data Flow

    1. ADS1299 chip on PiEEG shield reads analog voltages via SPI at 250 Hz
    2. hardware.py converts raw 24-bit values to µV floats
    3. acquisition.py runs a dedicated thread, pushes samples to async queues
    4. Each subscriber (server, recorder, monitor, etc.) consumes from its own queue
    5. server.py broadcasts JSON frames to all connected WebSocket clients
    6. Dashboard renders at 60 fps using Canvas 2D and refs (no React re-renders)

    Dashboard Architecture

    LayerTech
    FrameworkReact 19
    BundlerVite 6
    RenderingCanvas 2D + Three.js (WebXR)
    FFTCooley-Tukey radix-2 (Web Worker)
    StateHooks + refs only
    StylingPlain CSS

    DSP Engine

    All DSP hot paths have two interchangeable implementations:

    PathPython (default)Native (optional)
    24-bit ADC decodehardware.PiEEGHardware._decode_channelspieeg_core.decode_channels
    Butterworth bandpassfilters.MultichannelFilterpieeg_core.MultichannelFilter
    Hampel spike rejectspike_filter.HampelFilterpieeg_core.HampelFilter

    _native.py performs a single soft-import of the optional pieeg-core (opens in a new tab) wheel. When present, filters.py and spike_filter.py rebind the public class name to the Rust implementation (identical API, ~15–30× faster); when absent, the pure-Python classes remain in use. Callers never import pieeg_core directly — all detection lives in _native.py and the Python classes stay the reference implementation and fallback.

    The active engine is surfaced via:

    • startup log line and the Rich startup panel (Engine row)
    • WebSocket welcome message engine field
    • pieeg-server doctorDSP Engine section

    Install with pip install 'pieeg-server[fast]'. pieeg-core is AGPL-3.0-or-later, so the default MIT install remains license-clean.