Skip to Content
FeaturesADS1299 Registers

ADS1299 Register Configuration

PiEEG-server exposes real-time ADS1299 register configuration over WebSocket. Change channel input modes, run noise diagnostics, and apply presets — all live, without restarting the stream.

This feature works on PiEEG boards (SPI). IronBCI boards use Bluetooth LE and do not expose register writes.

Capabilities

  • Switch input modes on the fly — normal electrodes, input shorted (noise floor test), test signal, temperature sensor
  • Run noise diagnostics — built-in test with per-channel RMS and automated pass/fail verdict
  • Apply named presets — one command to configure all 8 channels at once
  • Automate from any language — plain WebSocket JSON commands

Configurable registers

Channel registers CH1SETCH8SET (addresses 0x050x0C) can be written at runtime. Configuration registers (CONFIG1CONFIG3) are protected to prevent accidental sample-rate or reference changes.

Input modes

ValueModeDescription
0x00Normal electrodeStandard EEG measurement — default after startup
0x01Input shortedBoth inputs tied together internally — measures baseline noise
0x02Bias measurementRoutes bias signal to channel — verify bias drive circuit
0x04Temperature sensorOn-chip temperature sensor — useful for thermal diagnostics
0x05Test signalInternal 1× amplitude square wave from CONFIG2 — verify signal chain

WebSocket commands

Read current register state

{"cmd": "reg_read"}

Response:

{"reg_config": {"regs": {"0x05": "0x0", "0x06": "0x0", ...}, "status": "ok"}}

Write individual registers

{"cmd": "reg_write", "regs": {"0x05": "0x00", "0x06": "0x01", "0x07": "0x05"}}

This sets CH1 to normal, CH2 to input shorted, and CH3 to test signal. Other channels remain unchanged.

Apply a preset

{"cmd": "reg_preset", "preset": "internal_short"}
PresetValueUse case
normal0x00 all channelsResume standard measurement
internal_short0x01 all channelsMeasure noise floor — no electrodes needed
test_signal0x05 all channelsVerify full signal chain with known waveform
temp_sensor0x04 all channelsRead on-chip temperature

Run noise test

{"cmd": "noise_test", "duration": 3}

Switches all channels to input-shorted mode, collects samples for the specified duration, computes per-channel RMS, then restores the previous configuration.

Response:

{ "noise_test_result": { "rms": [2.5, 2.3, 3.1, 2.8, 2.6, 2.4, 2.9, 3.0], "max_rms": 3.1, "verdict": "good", "recommendation": "Electrodes OK", "duration": 3.0, "samples_collected": 750 } }
VerdictMeaning
goodAll channels below 5 µV RMS — normal
warningSome channels 5–15 µV — check electrode contact
badChannels above 15 µV — likely loose or disconnected electrodes

Dashboard register panel

The dashboard includes a visual Register panel for register configuration without writing code:

  • Per-channel input mode selector (dropdown)
  • One-click presets (Normal, Shorted, Test Signal, Temperature)
  • Noise test button with live progress and color-coded results
  • Current register state display

How it works internally

  1. Dashboard or client sends a WebSocket command
  2. Server validates — only CHnSET registers (0x050x0C) are allowed
  3. Acquisition thread pauses gracefully
  4. SPI sequence: STOPSDATAC → register writes → RDATACSTART
  5. First 25 frames (~100 ms) discarded for ADC settling
  6. Spike filter baseline resets to avoid false rejections
  7. Updated register state broadcast to all connected clients

Register writes temporarily pause data acquisition (~100 ms). This is normal and required by the ADS1299 datasheet.

Example: automated noise check in Python

import asyncio, json, websockets async def noise_check(): async with websockets.connect("ws://raspberrypi.local:1616") as ws: await ws.send(json.dumps({"cmd": "noise_test", "duration": 3})) async for msg in ws: data = json.loads(msg) if "noise_test_result" in data: result = data["noise_test_result"] print(f"Verdict: {result['verdict']}") for i, rms in enumerate(result["rms"]): print(f" CH{i+1}: {rms:.1f} µV RMS") break asyncio.run(noise_check())