Hardware
Devices
PiEEG-16
Specification

Specification

Everything you need to know about the hardware, plus the low-level details for writing your own driver.

PiEEG-16 shield on a Raspberry Pi

Hardware

Channels16 single-ended biosignal inputs (2 groups of 8)
Extra inputsReference (SRB1, common to all channels) and bias drive
Analog front end2 × Texas Instruments ADS1299, 8 channels each
Chip arrangementTwo independent chips on one SPI bus, each with its own chip select and DRDY line (not daisy-chained)
Resolution24-bit, delta-sigma
Sample rate250 SPS as set by PiEEG software (the ADS1299 supports 250 SPS to 16 kSPS)
Gain1 as set by PiEEG software (ADS1299 supports 1, 2, 4, 6, 8, 12, 24)
Reference voltage4.5 V internal
SignalsEEG, EMG, ECG
ElectrodesDry or wet Ag/AgCl
Electrode connectors2.54 mm pin headers (channels 1–8, channels 9–16, reference, bias)
HostRaspberry Pi 4, Raspberry Pi 5
Host connector40-pin GPIO header
InterfaceSPI0, plus 2 DRDY lines and a software chip select
Power5 V via the Raspberry Pi, from a battery (power bank) only
IsolationNone. Battery operation is required.

Software support

SoftwareDevice setting
PiEEG Server--device pieeg16 (default)
Python SDK (opens in a new tab)GUI/pieeg16_drdy_only.py, Save_data/Save_data_OS.py
BrainFlowNot supported (BrainFlow's PIEEG_BOARD is the 8-channel board)

GPIO pins

Header pinGPIOSignalChip
19GPIO 10SPI0 MOSIBoth
21GPIO 9SPI0 MISOBoth
23GPIO 11SPI0 SCLKBoth
24GPIO 8SPI0 CE0#1 (ch 1–8)
35GPIO 19Chip select, driven by software#2 (ch 9–16)
37GPIO 26DRDY 1, active low#1
33GPIO 13DRDY 2, active low#2

PiEEG-16 pins on the Raspberry Pi header

PiGPIO chip
Raspberry Pi 4/dev/gpiochip0
Raspberry Pi 5The chip labelled pinctrl-rp1 in gpiodetect (/dev/gpiochip4 on older OS releases, /dev/gpiochip0 on newer ones)

SPI settings

SettingValue
Devices/dev/spidev0.0 for chip 1, /dev/spidev0.1 for chip 2 (with GPIO 19 as its chip select)
Mode1 (CPOL 0, CPHA 1)
Bit orderMSB first
Word size8 bits
Clock4 MHz in the current SDK script. PiEEG Server uses 4 MHz on Pi 4 and 2 MHz on Pi 5. Lower it (1 MHz) if you see glitches.

Data frame

Each chip delivers a 27-byte frame per sample:

BytesContent
1–3ADS1299 status word (normally 0xC0 0x00 0x08)
4–6Channel 1 of this chip
……
25–27Channel 8 of this chip

Chip 1 gives channels 1–8, chip 2 gives channels 9–16. Each channel is a 24-bit, big-endian, two's-complement value. The SDK only accepts a sample when chip 2's status word is 0xC0 0x00 0x08, which filters out bad frames.

Converting to microvolts

This is the conversion used by the PiEEG SDK scripts and PiEEG Server:

raw = (b[0] << 16) | (b[1] << 8) | b[2]   # 3 bytes of one channel
if raw & 0x800000:                       # negative value
    raw -= 16777214
uV = raw * 4.5 / 16777215 * 1_000_000    # about 0.268 µV per count

Reading a sample

import spidev, gpiod                      # gpiod==1.5.4
 
chip = gpiod.chip("0")                    # see the GPIO chip table above
cs2 = chip.get_line(19)                   # chip select for ADS1299 #2
# ... request cs2 as output (high), DRDY 26 and 13 as inputs,
#     open spi1 = spidev 0.0 and spi2 = spidev 0.1 (mode 1),
#     configure both chips (see below), then for every sample:
 
wait_for_drdy(drdy1)                      # wait for GPIO 26 high → low
frame1 = spi1.readbytes(27)               # channels 1–8
 
wait_for_drdy(drdy2)                      # wait for GPIO 13 high → low
cs2.set_value(0)
frame2 = spi2.readbytes(27)               # channels 9–16
cs2.set_value(1)

Full working version: pieeg16_drdy_only.py (opens in a new tab).

ADS1299 commands

CommandCode
WAKEUP0x02
RESET0x06
START0x08
STOP0x0A
RDATAC (read data continuously)0x10
SDATAC (stop continuous read)0x11

Write a register with three bytes: [0x40 | address, 0x00, value]. Read one with [0x20 | address, 0x00, 0x00]. For chip 2, pull GPIO 19 low around each transfer.

Default register settings

Both chips get the same settings. Start-up sequence used by PiEEG software, chip 1 first, then chip 2: WAKEUP, STOP, RESET, SDATAC, write the registers below, then RDATAC and START.

AddressRegisterValueMeaning
0x01CONFIG10x96250 SPS
0x02CONFIG20xD4Internal test-signal settings (not used in normal mode)
0x03CONFIG30xFFInternal reference buffer on, internal bias reference, bias buffer on
0x04LOFF0x00Lead-off detection off
0x05–0x0CCH1SET–CH8SET0x00Normal electrode input, gain 1
0x0DBIAS_SENSP0x00
0x0EBIAS_SENSN0x00
0x0FLOFF_SENSP0x00
0x10LOFF_SENSN0x00
0x11LOFF_FLIP0x00
0x14GPIO0x80
0x15MISC10x20SRB1 on: the reference electrode is shared by all channels
0x17CONFIG40x00Continuous conversion

Noise self-test: set every CHnSET on both chips to 0x01 (input shorted). The signal should stay within a few µV. If it does, the board is fine and any noise comes from the cables, electrodes or surroundings. See Noise elimination.

⚠️

Changing CONFIG1–3 changes the sample rate or reference. PiEEG Server expects 250 SPS on both chips.