Other Parts Discussed in Thread: ADS1292
Hello,
I am currently using an ADS1299 to develop an EEG device for a University project. I have designed the acquisition circuit that I attach following the schematic of the ADS1299 kit and the advices given by the datasheet. I am communicating with a computer by means of an Arduino Nano (I also attach the code).
/********************************************************* TESIS DE GRADO EEG v1.0 Instituto de Ingenieria Biomedica Facultad de Ingenieria, Universidad de Buenos Aires Brian Daniel Santillan, Florencia Grosso. Tutors: Sergio Lew. Ariel Burman. Code description: This code controls the IC ADS1299 through an Arduino NANO *********************************************************/ // Libraries #include <SPI.h> // Clock #define tCLK 0.0005 //clock de 2MHz, 500ns // Commands // System commands #define WAKEUP 0x02 #define STANDBY 0x04 #define RESET 0x06 #define START 0x08 #define STOP 0x0A // Data Read Commands #define RRDATAC 0x10 #define SSDATAC 0x11 #define RRDATA 0x12 // Register Read Commands #define RREG 0x20 #define WREG 0x40 // Registers #define ID 0x00 #define CONFIG1 0x01 #define CONFIG2 0x02 #define CONFIG3 0x03 //#define LOFF 0x04 #define CH1SET 0x05 #define CH2SET 0x06 #define CH3SET 0x07 #define CH4SET 0x08 #define CH5SET 0x09 #define CH6SET 0x0A #define CH7SET 0x0B #define CH8SET 0x0C //#define BIAS_SENSP 0x0D //#define BIAS_SENSN 0x0E //#define LOFF_SENSP 0x0F //#define LOFF_SENSN 0x10 //#define LOFF_FLIP 0x11 //#define LOFF_STATP 0x12 //#define LOFF_STATN 0x13 //#define GPIO 0x14 //#define MISC1 0x15 //#define MISC2 0x16 #define CONFIG4 0x17 // Pins for the arduino board const int PIN_DRDY = 2; const int PIN_START = 5; const int PIN_SS = 10; const int PIN_MOSI = 11; // DIN const int PIN_MISO = 12; // DOUT const int PIN_SCK = 13; const int PIN_RESET = 4; // Prototypes of used functions void wake_up(); void send_command(uint8_t command); void send_command_and_wait(uint8_t command, float time_to_wait); byte fRREG(byte address); void fWREG(byte address, byte data); void getDeviceID(); void reset_communication(void); // Global variables boolean power_up = true; boolean verbose = true; byte deviceID = 0; void setup() { /* Initialization routine for SPI bus */ // Initalize communication with computer. // Open serial port (USB), max rate 115bps Serial.begin(115200); // Wait until data transmission through serial port is completed (in case there's a transmission going on) Serial.flush(); Serial.println("Conexi�n con PC establecida"); delay(2000); // Set SPI communication. 2 MHz clock, MSB first, Mode 0. // MODE 0 = Output Edge: Falling - Data Capture: Rising (pag. 38) // MODE 1 = Output Edge: Rising - Data Capture: Falling (pag. 38) SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE1)); // Initialize SPI. SPI.begin(); // Set Pin modes pinMode(PIN_START, OUTPUT); pinMode(PIN_DRDY, INPUT); pinMode(PIN_SS, OUTPUT); pinMode(PIN_MOSI, OUTPUT); pinMode(PIN_MISO, INPUT); pinMode(PIN_SCK, OUTPUT); reset_communication; // Set pin initial value digitalWrite(PIN_START, LOW); digitalWrite(PIN_SS, HIGH); /* Follow initial flow at power-up (page 62) */ // Delay>tPOR in ms (make sure thatVCAP1 1.1v = ok) delay(300); // Reset the device send_command_and_wait(RESET, 18*tCLK); // (Datasheet, p.35) // Cancel RDATAC mode after reset send_command_and_wait(SSDATAC, 4*tCLK); // (Datasheet, p.42) /* TEST 1 */ // Read ADS1299 ID to check that it receives data and there's communication while(deviceID == 0) { getDeviceID(); } // Switch internal reference on (p.48) fWREG(CONFIG3,0xE0); // 0x60 -> enable internal ref, 0xE0 -> power down internal ref // Define the Data rate (p.46) // [it is set at minimum always, then changed by the desired value] fWREG(CONFIG1,0x96); // 16kSPS -> 0x90, 8kSPS -> 0x91, ..., 250SPS -> 0x96 // Define test signals (p.47) fWREG(CONFIG2,0xD4); // external test signal -> 0xC0, internal test signal -> 0xD0 // 0 always ; 0 1*-(VREFP-VREFN)/2400) 1 2*-(VREFP-VREFN)/2400) - 00 fclk/2^21 01 fclk/2^20 11 at dc /* TEST 2 */ // Read the written registers and print data if (verbose) { Serial.println("Check config regs:"); Serial.print("CONFIG1: "); Serial.println(fRREG(CONFIG1), HEX); Serial.print("CONFIG2: "); Serial.println(fRREG(CONFIG2), HEX); Serial.print("CONFIG3: "); Serial.println(fRREG(CONFIG3), HEX); } // Set all channels (p.50) //0x01 normal operation, unity gain & input shorted //0x81 power-down, unity gain & input shorted //0x05 normal operation, unity gain & test signal fWREG(CH1SET,0x05); fWREG(CH2SET,0x81); fWREG(CH3SET,0x81); fWREG(CH4SET,0x81); fWREG(CH5SET,0x81); fWREG(CH6SET,0x81); fWREG(CH7SET,0x81); fWREG(CH8SET,0x81); /* TEST 3 */ // Read written registers // read the written registers and print data if (verbose) { Serial.println("Check channels:"); Serial.print("CH1SET: "); Serial.println(fRREG(CH1SET), HEX); Serial.print("CH4SET: "); Serial.println(fRREG(CH4SET), HEX);// we may have trouble here since it has to print a binary, if not use print(xxx, BIN) } } // Operation loop for the Arduino. void loop() { // Activate conversion send_command_and_wait(START, 20); //(Settling time, p.34) // Continuous conversion of data (p. 40) send_command(RRDATAC); digitalWrite(SS, LOW); // Read data // Serial.print("Data Ready printer"); if (digitalRead(PIN_DRDY) == LOW) { Serial.print("There is Data Ready "); byte read_out = SPI.transfer(0x00); Serial.println(read_out, HEX); } } /* SYSTEM COMMANDS */ // TODO: This should be sent as a command too. Though we must figure out how to handle // the intermediate delay. // Wake-up from standby mode void wake_up() { // Set SS low to communicate with device. digitalWrite(SS, LOW); SPI.transfer(WAKEUP); // Must wait at least 4 tCLK cycles (Datasheet, pg. 40) delay(4*tCLK); // SS high to end communication digitalWrite(SS, HIGH); } // Send a command to the ADS 1299. Requires no delay. void send_command(uint8_t command) { digitalWrite(SS, LOW); SPI.transfer(command); digitalWrite(SS, HIGH); } // Send a command to the ADS 1299. Issues a delay afterwards void send_command_and_wait(uint8_t command, float time_to_wait) { digitalWrite(SS, LOW); SPI.transfer(command); digitalWrite(SS, HIGH); delay(time_to_wait); } /* REGISTER READ/WRITE COMMANDS */ // Read from register. Shouldn't it be returning the byte read? // @param address: the starting register address. // @param numberRegMinusOne: number of register to read - 1. (reads only 1 for now) byte fRREG(byte address) { // RREG expects 001rrrrr where rrrrr = _address byte op_code = RREG + address; digitalWrite(SS, LOW); // send_command_and_wait(SSDATAC, 4*tCLK); SPI.transfer(op_code); SPI.transfer(0x00); byte data = SPI.transfer(0x00); // Close SPI digitalWrite(SS, HIGH); delay(1); return data; } // Write to register. // @param address: the starting register address. // @param data: value to write. // @param numberRegMinusOne: number of register to write - 1. (we fix it to 0x00 for now) void fWREG(byte address, byte data) { // WREG expects 001rrrrr where rrrrr = _address // Open SPI. byte op_code = WREG + address; digitalWrite(SS, LOW); // send_command_and_wait(SSDATAC, 4*tCLK); SPI.transfer(op_code); // Write only one register SPI.transfer(0x00); SPI.transfer(data); // Close SPI digitalWrite(SS, HIGH); if (verbose) { Serial.print("Register 0x"); Serial.print(address, HEX); Serial.println(" modified."); } delay(1); } // Method to retrieve device ID void getDeviceID() { // Halt SPI data transfer and start reading delay(500); send_command_and_wait(SSDATAC, 4*tCLK); delay(10); byte data = fRREG(ID); // If retrieved ID is valid, then no power up is needed deviceID = data; if(verbose) { Serial.println("Device ID: "); Serial.println(deviceID, BIN); } } void reset_communication(void){ //Resetea la comunicaci�n (datasheet p.30) digitalWrite(PIN_SS, HIGH); digitalWrite(PIN_RESET, HIGH); delay(1000); digitalWrite(PIN_RESET, LOW); delay(1000); digitalWrite(PIN_RESET, HIGH); delay(100); digitalWrite(PIN_SS, LOW); delay(1000); digitalWrite(PIN_SS, HIGH); }
I am being able to read the registers after writing them, checking that the correct data has been written, but the problem is when I try to use the test signal. I have no triggering of the DRDY output and thus I have no output at all. Occasionally I was able to make it trigger but got all 0's. I have double checked the code comparing it to other works for thesis using the same or similar parts (ADS1292), I have double checked the code and the circuit with the datasheet, but I have no results.
If you could please help me to see what I'm missing or doing wrong, I would really appreciate it, since I am running out of ideas.
Thank you.
Best,
Florencia