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