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.

ADS1198: Can't read channel input with Arduino UNO

Part Number: ADS1198

Hello,

I'm trying capture signal with channel 1 ADS1198 and send it via SPI to Arduino UNO in my school project. Due to quarantine I don't have electrodes, so I'm trying to use potentiometer to simulate source of data. I'm unable to see any difference in captured data, while I'm moving with potentiometer.

My wiring is:

ADS1198 -> Arduino UNO

DIN -> pin 11

CS ->  pin A5

DOUT-> pin 12

DRDY-> pin 2

SCLK-> pin 13

AVDD-> 5V

DGND-> 3,3V

IN1P-> potentiometer

IN1N-> GND

My code is written in Arduino IDE:

#include <SPI.h>

#define MOSI1    11 //MOSI
#define MISO1    12 //MISO
#define CLK1     13 //SCK

#define PIN_CS     A5
#define PIN_RESET  A4
#define PIN_DRDY   2

#define RREG       0x20
#define WREG       0x40

#define ID         0x00
#define SDATAC     0x11
#define RDATAC     0x10
#define RDATA      0x12

#define WAKEUP     0x02
#define STANDBY    0x04
#define RESET      0x06
#define START      0x08
#define STOP       0x0A

#define CH1        0x05
#define CH2        0x06
#define CH3        0x07
#define CH4        0x08
#define CH5        0x09
#define CH6        0x0A
#define CH7        0x0B
#define CH8        0x0C

#define SETOFF     B10000001
#define SETPGA6    B00000000
#define SETPGA1    B00010000
#define SETPGA12   B01100000 

#define SPI_SPEED  2500000
#define NOP        0x00

uint16_t chSet;
double real_val;
const int datasize = 400; 
volatile int data[datasize];
volatile int DRDY_state = HIGH;
void waitforDRDY();
void DRDY_Interrupt();
void prepare_ADS();
void packet_init();
int16_t read_Value();
void send_command(uint8_t cmd);
uint8_t out1, out2, out3;
uint8_t debug_msg = 1U;
String sep = "---------------------------------------------------------";
String hex_to_char(int hex_in) {
  int precision = 2;
  char tmp[16];
  char format[128];
  sprintf(format, "0x%%.%dX", precision);
  sprintf(tmp, format, hex_in);
  //Serial.print(tmp);
  return(String(tmp));
}

void DRDY_Interrupt(){
  DRDY_state = LOW;  
}

void waitforDRDY(){
  while(DRDY_state){
    continue;  
  }
  noInterrupts();
  DRDY_state = HIGH;
  interrupts();
}

int16_t read_Value(){
  int16_t adc_val = 0;
  waitforDRDY();
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE1));
  digitalWrite(PIN_CS, LOW);
  delayMicroseconds(5);
  SPI.transfer(RDATA);
  delayMicroseconds(7);
  adc_val |= SPI.transfer(NOP);
  Serial.println(adc_val);
  delayMicroseconds(10);
  adc_val <<= 8;
  adc_val |= SPI.transfer(NOP);
  Serial.println(adc_val);
  delayMicroseconds(10);
  digitalWrite(PIN_CS, HIGH);
  SPI.endTransaction();

  return adc_val;
}

uint8_t read_byte(uint8_t reg_addr)
{
    int out = 0;
    
    digitalWrite(PIN_CS, LOW);

    send_command(RDATA);
    out1 = SPI.transfer(0x00);
    Serial.println(out1);
    delayMicroseconds(5);
    out2 = SPI.transfer(0x00);
    Serial.println(out2);
    delayMicroseconds(5);
    out3 = SPI.transfer(0x00);
    Serial.println(out3);
    delayMicroseconds(1);
    digitalWrite(PIN_CS, HIGH);
    out = (out1 << 8) + out2;
    /*if(debug_msg)
    {
        Serial.println(sep);
        Serial.println( "sent:\t" + hex_to_char(reg_addr) );
        Serial.println( "recieved:\t" + out);
    }
    */
    return(out);
}

void prepare_ADS(){
  digitalWrite(PIN_CS, LOW);
  delay(2);
  SPI.setDataMode(SPI_MODE1);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.begin();
}

void ADS_init_config(){
  attachInterrupt(digitalPinToInterrupt(PIN_DRDY), DRDY_Interrupt, FALLING);
  digitalWrite(PIN_CS, LOW);
  SPI.transfer(WAKEUP);
  SPI.transfer(SDATAC);
  delay(2);

  SPI.transfer(WREG | 0x01);
  SPI.transfer(0x02);

  //Config1
  SPI.transfer(B10000110);

  //Config2
  SPI.transfer(0x00);

  //Config3
  SPI.transfer(B11101001);

  SPI.transfer(WREG | 0x05);
  SPI.transfer(0x07);
  //CH1
  SPI.transfer(B00000001);
  //CH2
  SPI.transfer(B00000001);
  //CH3
  SPI.transfer(B00000001);
  //CH4
  SPI.transfer(B00000001);
  //CH5
  SPI.transfer(B00000001);
  //CH6
  SPI.transfer(B00000001);
  //CH7
  SPI.transfer(B00000001);
  //CH8
  SPI.transfer(B00000001);

  digitalWrite(PIN_CS, HIGH);
}


void send_command(uint8_t cmd)
{
    digitalWrite(PIN_CS, LOW);
    delayMicroseconds(5); // 5 = 6us at 32
    SPI.transfer(cmd);
    delayMicroseconds(10);
    digitalWrite(PIN_CS, HIGH);
}

void set_channel(uint8_t ch, uint8_t settings){
    SPI.transfer(WREG | ch);
    SPI.transfer(0x00);
    SPI.transfer(settings);  
}

void packet_init(){
  for(int i = 0; i < datasize; ++i){
    data[i] = 0;  
  }
}

void setup() 
{
    Serial.begin(9600);
    pinMode(CLK1,OUTPUT);
    pinMode(MISO1,INPUT); 
    pinMode(MOSI1,OUTPUT);
    pinMode(PIN_CS,OUTPUT);
    pinMode(PIN_RESET,OUTPUT);
    //pinMode(PIN_START,OUTPUT);
    pinMode(PIN_DRDY,INPUT);
    digitalWrite(PIN_CS,HIGH);
    //digitalWrite(PIN_START,LOW);
    
    prepare_ADS();
    ADS_init_config();
    delay(1000);
    digitalWrite(PIN_CS, LOW);
    delay(1000);
    digitalWrite(PIN_CS, HIGH);
    delay(1000);    
    send_command(SDATAC);
    delay(10);
    set_channel(CH1, SETPGA1);
}

void loop()
{
    //chSet = read_byte(RREG | ID);
    //Serial.print("-- ID" + String(chSet) + "--");
    //real_val = (double)5*(double)read_Value()/(double)65535;
    read_Value();
    Serial.println(real_val);
    delay(1000);
}

I would be pleased for any advice.

Best regards,

Michael

  • Hi Michael,

    I would recommend viewing the BIOFAQ located here: https://e2e.ti.com/support/data-converters/f/73/p/772058/2855202

    There's are a few posts on SPI communication and device verification that will help you get started. 

    The device datasheet as well as the ADS1298ECG-PDK user's guide are good resources as well.

    One thing that is not related to your problem that I noticed is that your negative input should be connected to mid-supply, 2.5V in this case. Having the negative input directly connected to GND violates the input common-mode range of the programmable gain amplifier (PGA). The amplifier needs some head-room from the power supply rails in order to function correctly. Further information can be found in the datasheet.  

  • Hello Alex,

    I reconnected IN1N to 2.5 V. Now I measure only zero. I'll try to find solution in your link, hope it will help. May I ask, if I understand it correctly, unused input pins should be connected to 5 V directly? I left them floating right now.

    Thank you very much.

    Best regards,

    Michael

  • Hi Michael,

    Connecting unused analog pins to your analog supply will reduce power dissipation. It is not necessary though, they can be left floating.  

    Happy to help! Work through the links and let me know how your debug goes. 

  • Hello Alex,

    My problem was mostly with code. I didn't let ADS1198 to start properly. I had also bad wiring, accidentaly I connected digital inputs to aruduino uno without voltage divider. Now I measure some data on channel 1.

    Thank you very much, links were very useful.

    Best regards,

    Michael.

  • Hi Michael,

    Happy to hear that the issue is resolved! Good luck and let us know if you have additional questions.