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.

Problems of getting simultaneous respiration and ECG data from ADS1292R

Other Parts Discussed in Thread: ADS1292R, ADS1292, MSP430FR5969

Hello,

I'm using ADS1292R to get simultaneous respiration and ECG data but I cannot get the correct data. I implemented the circuit according to the data sheet and I don't think there is a problem in that part. There seems a problem of data overflow if I used 500SPS because I did not see the overflow when I set the frequency to 250SPS but I want to use 500SPS, so please help me solve this problem.

Here is the code for setting up ADS1292R:

void setup_ADS1292 ()
{
send_command(SDATAC);
write_byte(CONFIG1, 0x02);// 500sps

write_byte(CONFIG2, 0xA0);

write_byte(CH1SET, 0x40); //PGA gain 4

write_byte(CH2SET, 0x00);

write_byte(RESP1, 0xF2);  // 135 phase shift according to the data sheet

write_byte(RESP2, 0x03);

send_command(RDATAC);
digitalWrite(PIN_START, HIGH);
send_command(START);
}

Here is the code for getting respiration and ECG data:

void getEKGRESP ()
{
neco=0;
neco1=0;
dalsi = 1;
int numSerialBytes = 3 + (3 * nChannels); //8-bits header plus 24-bits per ACTIVE channel
unsigned char serialBytes[numSerialBytes]; //byte buffer
int i = 0;

digitalWrite(PIN_CS, LOW);

serialBytes[i++] = SPI.transfer(0x00); // get 1st byte of header
serialBytes[i++] = SPI.transfer(0x00); //skip 2nd byte of header
serialBytes[i++] = SPI.transfer(0x00); //skip 3rd byte of header

for (int ch = 1; ch <= gMaxChan; ch++) {
a = SPI.transfer(0x00);
b = SPI.transfer(0x00);
c = SPI.transfer(0x00);

// channel 1 for Respiration signal
if(ch==1){
if (a>0x7F) {   //twos complement
a=~a;
b=~b;
c=~c;
aaa=(unsigned int)a<<8;
aaa=aaa<<8;
bbb=(unsigned int)b<<8;
ccc=(unsigned int)c;
neco=aaa|bbb|ccc;
neco=neco+1;
neco=-neco;
}
else {
aaa=(unsigned int)a<<8;
aaa=aaa<<8;
bbb=(unsigned int)b<<8;
ccc=(unsigned int)c;
neco=aaa|bbb|ccc;
}
}
// channel 2 for EKG signal
if(ch==2){
if (a>0x7F) {
a=~a;
b=~b;
c=~c;
aaa=(unsigned int)a<<8;
aaa=aaa<<8;
bbb=(unsigned int)b<<8;
ccc=(unsigned int)c;
neco1=aaa|bbb|ccc;
neco1=data_EKG+1;
neco1=-data_EKG;
}
else {
aaa=(unsigned int)a<<8;
aaa=aaa<<8;
bbb=(unsigned int)b<<8;
ccc=(unsigned int)c;
neco1=aaa|bbb|ccc;
}
}
}

digitalWrite(PIN_CS, HIGH);

data_RESP=neco/10;
data_EKG=neco1/10;
}

  • Hi Yiwen,

    Is it possible for you to send a screen shot of your SPI signals for the ADS1292? If you are getting good data at 250SPS, but not at 500SPS, I suspect you might be having trouble getting all of your data properly read between DRDY pulses. A screen shot of your CS, SCLK, DOUT and DRDY would be easier to review.
  • Hello Tom,

    Here is the code for Pin mode:
    pinMode(PIN_CS, OUTPUT);
    pinMode(PIN_START, OUTPUT);
    pinMode(IPIN_DRDY, INPUT);
    attachInterrupt(IPIN_DRDY, blink, FALLING);
    pinMode(PIN_RESET, OUTPUT);
    //ADS1292 Reset
    digitalWrite(PIN_CS, HIGH);
    digitalWrite(PIN_RESET, HIGH);
    delay(1000);
    digitalWrite(PIN_RESET, LOW);
    delay(1000);
    digitalWrite(PIN_RESET, HIGH);
    delay(100);
    digitalWrite(PIN_CS, LOW);
    delay(1000);
    digitalWrite(PIN_CS, HIGH);

    Thanks,

    Yiwen
  • Hello Tom,

    I also found the data were not very good at 250SPS and I posted another question since I cannot attach pictures here. I hope you could also address that issue.

    Thanks,

    Yiwen
  • Hi Yiwen,

    In the lower right corner, there is a 'Use rich formatting' option. Use that to insert pictures to your post.
  • Hello Tom,

    I have checked the signal from DRDY and DOUT and I found that DRDY changes more frequently when there is an overflow, but I'm not sure how to solve this problem. Basically, in order to get simultaneous respiration and ECG signal, I wrote a function to continuously ready data from Channel 1 and Channel 2 of ADS1292R but since one function cannot return two values, I defined two global variables so calling the function would store the data from 2 channels to those two variables, respectively. However, this method seems results in the overflow problem in sampling frequency of 500Hz, so could you please give me some advice?

    Thanks,

    Yiwen
  • Hi Yiwen,

    Please send along your scope shots.  How fast are you running your SPI interface?  You need to be able to read both CH1 and CH2 data between the DRDY outputs.

  • Hello Tom.

    Thanks for your prompt reply! I'm using 4MHz for SPI interface. Is it to fast? But I do not get the overflow when I chose sampling frequency of 250SPS for ADS1292R. Here are the screenshot of CS(yellow,Ch1), SCLK(blue,Ch2),DRDY(purple,Ch3) and DOUT(green,Ch4). The first two were in 250SPS and the first one was in RUN and the second is in STOP mode. The third and forth were in 500SPS. Also, the third one was in RUN mode and the forth one is STOP mode. Please let know if these information is enough for you to figure out the problem.

    Thanks,

    Yiwen

  • Hello Tom,

    Have you come with a method to solve this problem or do you need more information from me?

    Thanks,

    Yiwen
  • Hi Yiwen,

    It looks to me like you are trying to read SPI data at least 2x, but I only see /CS go low with every other SPI transfer - why is that? Also, the erratic behavior of the DRDY output tells me that you are not getting all data transferred between the DRDY signals. Try using the DRDY signal as an interrupt to your controller and let that be the start of your SPI transfer. Keep /CS low through the entire read sequence.
  • Hello Tom,

    Could you please with the code I sent you before to see if there is any problem in my code. I did using DRDY as interrupt as I set: attachInterrupt(IPIN_DRDY, blink1, FALLING);
    This overflow problem only happens at 500 SPS but not 250SPS, which really make me confused.

    Thanks,

    Yiwen
  • Hello Tom,

    I recently found that it is the real time filtering function I'm using in MSP430FR5969 which causes the overflow but it really confused me that I do not have this overflow problem before I implemented the respiration circuit and function and now It always exists even if I powered down the respiration channel and change the circuit connection to before. Thus, my basic conclusion is that the calculation performance of MCU is not fast enough at 500SPS, which cause the overflow, but I'm still quite confused why calling the real time filtering function would change the behavior of DRDY? I'm attaching the filter function here. Please let know what you think.
    long FiltECG (long ecg)
    {
    long outecg = 0;
    int n1 = 0;

    filtecg[Current1] = ecg/100;
    // Start from reg[Current], move backwards
    for (int j1=Current1; j1 >= 0; j1--){
    outecg = outecg + filtecg[n1]*B[j1];
    n1 = n1 + 1;
    }

    // Start from reg[50], move backwards till reg[Current]
    for (int j1=coef_len-1; j1 > Current1; j1--){
    outecg = outecg + filtecg[n1]*B[j1];
    n1 = n1 + 1;
    }

    Current1 = Current1 + 1;
    if (Current1 >= coef_len)
    { Current1 = 0;
    }

    return outecg/100000;
    }


    Thanks,

    Yiwen