This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1299EEGFE-PDK: No data output from the ADS1299. Please help.

Part Number: ADS1299EEGFE-PDK

Tool/software:

I'm trying to set up a continous stream of EEG data without using the TI GUI but it seems like the ADS is not responding. I'm using a RP Pico as my MCU. I have looked at the SPI connections with a scope and it seems like stuff is going in for sure but nothing is outputing. Any help would be greatly appreciated. My code looks as follows - 

#include <Calculus.h>
#include <Filters.h>
#include <Definitions.h>
#include <PicoADS1299.h>

// Pin definitions
const int DRDY_PIN = 8; // Data‑Ready (active‑low)
const int RESET_PIN = 9; // Reset / Start conversion
const int CS_PIN = 5; // Chip‑Select
// (SPI pins for Pi‑Pico are hardware‑defined: SCK=2, MOSI=3, MISO=4)

PicoADS1299 ADS; // ADS1299 instance

void setup() {
Serial.begin(115200);
delay(2000); // let Serial come up

// Initialize ADS: (DRDY pin, RST pin, CS pin, SCK freq in MHz, isDaisy)
ADS.initialize(DRDY_PIN, RESET_PIN, CS_PIN, 3, false);
ADS.verbose = true; // optional register‑dump feedback

ADS.RESET(); // reset all registers
ADS.SDATAC(); // stop any continuous‑read mode
// configure your registers...
ADS.WREG(CONFIG1, 0b11010110);
ADS.WREG(CONFIG2, 0b11010101);
ADS.WREG(CONFIG3, 0b11001010);
ADS.WREG(CH1SET, 0b10100000);
ADS.WREG(CH2SET, 0b00100000);
ADS.WREG(CH3SET, 0b00100000);
ADS.WREG(CH4SET, 0b00100000);
ADS.WREG(CH5SET, 0b00100000);
ADS.WREG(CH6SET, 0b00100000);
ADS.WREG(CH7SET, 0b00100000);
ADS.WREG(CH8SET, 0b00100000);
ADS.WREG(BIAS_SENSP, 0xFF);
ADS.WREG(BIAS_SENSN, 0xFF);
ADS.WREG(LOFF_SENSP, 0x00);
ADS.WREG(LOFF_SENSN, 0x00);
ADS.WREG(CONFIG4, 0x02);

ADS.RREGS(0x00, 0x17); // read back all regs (ID→CONFIG4)

ADS.RDATAC(); // enter continuous‑read mode
ADS.START(); // kick off conversions
}

void loop() {
// wait here while DRDY is HIGH; as soon as it goes LOW, data is ready
while (digitalRead(DRDY_PIN)) { /* nothing */ }

ADS.updateChannelData(); // fill ADS.channelData[0..7]

// print all 8 channels, tab‑delimited
for (uint8_t ch = 0; ch < 8; ch++) {
Serial.print(ADS.channelData[ch]);
if (ch < 7) Serial.print('\t');
}
Serial.println();
}

The code is based directly off of https://github.com/indrayudd/PicoADS1299/tree/main but it doesn't seem to work. I also tried to do in micropython but it still gave me register values as 0 and no data - 


from machine import Pin, SPI
import utime

# ADS1299 SPI command‑codes (from Definitions.h)
_WAKEUP = 0x02
_STANDBY = 0x04
_RESET = 0x06
_START = 0x08
_STOP = 0x0A
_RDATA = 0x12
_RDATAC = 0x10
_SDATAC = 0x11
_RREG = 0x20
_WREG = 0x40

CONFIG3 = 0x03


def hardware_reset():
RESET.value(0)
utime.sleep_ms(50) # ≥ 32 ms Tpor
RESET.value(1)
utime.sleep_ms(20) # ≥ 18 tCLK (~8 µs)


def send_software_reset():
CS.value(0)
spi.write(bytes([_RESET]))
CS.value(1)
utime.sleep_us(12) # ≥ 18 tCLK at 2 MHz SPI (~9 µs)

def send_cmd(cmd):
CS.value(0)
spi.write(bytes([cmd]))
CS.value(1)
utime.sleep_us(4)

def rregs(start_addr, num_regs):
"""
Read `num_regs` registers starting from `start_addr` (0–31).
Returns a list of `num_regs` byte values.
"""
# Build the command header:
# - first byte: 0x20 | (start_addr & 0x1F)
# - second byte: num_regs - 1
header = bytearray(2)
header[0] = _RREG | (start_addr & 0x1F)
header[1] = (num_regs - 1) & 0xFF

# Create a buffer for header + dummy bytes
buf = bytearray(2 + num_regs)
buf[0:2] = header

# Assert CS, perform full-duplex transfer, de-assert CS
CS.value(0)
spi.write_readinto(buf, buf)
CS.value(1)

# buf[2:] now holds the register values
return list(buf[2:])

def wreg(addr, value):
CS.value(0)
spi.write(bytes([_WREG | (addr & 0x1F), 0x00, value]))
CS.value(1)

def rreg(addr):
"""
Read exactly one register at `addr` and return its value.
Mirrors ADS1299::RREG(addr) in C++.
"""
buf = bytearray(3)
buf[0] = _RREG | (addr & 0x1F) # 0x20 + addr
buf[1] = 0x00 # count = 0 → read 1 reg
buf[2] = 0x00 # placeholder for returned data

CS.value(0)
spi.write_readinto(buf, buf) # send header + dummy, read back 3 bytes
CS.value(1)

return buf[2] # the single register’s value


# Initialization
SCLK = 2
MOSI = 3
MISO = 4
CS = Pin(5, Pin.OUT, value=1) # active‑low
DRDY = Pin(8, Pin.IN, Pin.PULL_UP) # Idle - high, hmm
RESET = Pin(9, Pin.OUT, value=1)

'''SPI Setup - SCK, MOSI become outputs, MISO becomes input.
Idle state of SCK is set low because polarity = 0, replicating -> digitalWrite(SCK, LOW)'''
spi = SPI(
0,
baudrate=4_000_000,
polarity=0, # SCK idle low (CPOL=0)
phase=1, # sample on trailing edge (CPHA=1)
sck=Pin(SCLK), # GP2
mosi=Pin(MOSI), # GP3
miso=Pin(MISO), # GP4
)

hardware_reset()
print("Hello from the Pico!") # goes over USB serial at 115200 bps
utime.sleep_ms(2000)

send_software_reset()

send_cmd(_SDATAC)

rregs(0x00, 0x18)
wreg(CONFIG3, 0xE0)
val = rreg(CONFIG3)
print("CONFIG3 =", hex(val))

send_cmd(_RDATAC)
send_cmd(_START)


# ── Read Loop: only channel 1 ──
while True:
if not DRDY.value(): # DRDY goes low when data’s ready
buf = bytearray(3 + 3) # 3 status bytes + 3 bytes for CH1
CS.value(0)
spi.readinto(buf) # clocks in 6 bytes
CS.value(1)

# Skip status: buf[0:3]
b0, b1, b2 = buf[3], buf[4], buf[5]
val = (b0 << 16) | (b1 << 8) | b2
# Sign‑extend 24→32 bits
if val & 0x800000:
val |= 0xFF000000

print(val) # only channel 1 value