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.

ADS1256: Proper sequencing of channel switching

Part Number: ADS1256

Hi, using the Waveshare ADS1256 HAT for a Raspberry based DAQ. I have it reading in at a good rate (4 channels, 1 kHz), and want to clarify a couple things about the spec and my code. 

So first, my WaitDRDY() function is just a while loop, intend to implement that off an interrupt eventually. It works now, but could be more efficient.

The big one is the filter settling time per Table 13 in the spec and how I'm implementing it. My understanding is that when the multiplexer switches from one channel to the next, it takes a certain length of time to sample that new value and filter it out, presumably to prevent the previous channel from ghosting onto the new one. At my 30 ksps rate, I should allow 210 us for that to happen, and that's T18 on the attached sequence. So in my code, I timestamp between sync and wakeup, send the wakeup and data read commands, then have a while loop that waits 210 us before the next set of events. I've tried moving that buffer array to before the while loop, but then I get garbage data. Wondering if I have the timing sequence understood correctly, and if there's a slicker way to implement that 210 us delay, like driving off the interrupt of some other pin? 

Thanks much!

Dave Ruxton

 

UDOUBLE ADS1256_FastRead(UBYTE Channel){

UDOUBLE Value = 0;
UBYTE buf[3] = {0,0,0};
struct timeval stop, start;
int diffTime;


ADS1256_WaitDRDY();                                        //Wait till Data Ready pin goes low
ADS1256_SetChannel(Channel);                         //Write next channel to MUX register (if on chan 0, send chan 1)
ADS1256_WriteCmd(CMD_SYNC);                     //Send Sync command
gettimeofday(&start, NULL);                                 //Start timestamp for filter settling time (t18 in spec)
ADS1256_WriteCmd(CMD_WAKEUP);               //Send Wakeup command
DEV_Digital_Write(DEV_CS_PIN, 0);                  //Pull down Chip Select Pin (not shown in spec, but apparently necessary?
DEV_SPI_WriteByte(CMD_RDATA);                    //Send Read Data command
while(1){                                                                //Wait for filter settle time, continuously check timer till time has elapsed
gettimeofday(&stop, NULL);
diffTime = (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec;
if(diffTime >= 210){ //210 us for 30 ksps sample rate per ads1236 spec
break;
}
}
buf[0] = DEV_SPI_ReadByte();                           //Read data bytes into array
buf[1] = DEV_SPI_ReadByte();
buf[2] = DEV_SPI_ReadByte();
DEV_Digital_Write(DEV_CS_PIN, 1);
Value = ((UDOUBLE)buf[0] << 16) & 0x00FF0000;              //Read and shift bytes into Value
Value |= ((UDOUBLE)buf[1] << 8);
Value |= buf[2];
if (Value & 0x800000)                                          //Don't know what this does, was in the original lib


Value &= 0xFF000000;
DEV_Digital_Write(DEV_CS_PIN, 1);                //Toggle CS pin high, not sure if necessary, left it in
return Value;
}

  • Hi David,

    Typically you want DRDY to be interrupt-driven, not based on a timer. Using a timer is possible, but it then also becomes possible to lose track of where you are in the loop and get corrupted data.

    Alternatively you could continuously read back the STATUS byte (register 0), where bit 0 copies the state of DRDY. Then, when that bit drops low, this indicates that new data are ready.

    The output from the ADS1256 is in binary two's complement format. The instruction "if (value & 0x800000)" is checking if the ADC output code MSB is 1, which indicates that it is a negative number.

    Also, one additional point: the waveshare board is not a TI product, and we do not provide support for it directly. I can help with the general operation of the ADS1256, but for board- or firmware-specific questions, you will have to reach out to waveshare. You can also search through some of the other posts on this forum that have used the waveshare board, and it seems like other people had trouble retrieving data at the highest data rates. I am still not sure why.

    -Bryan

  • Thanks, I'm actually getting pretty close to spec 30 ksps when I rewrite the sequencing per above, but I'm artificially limiting the timing between the wakeup call and starting the next channel switch by 210 us per that filter settling time. Is that a correct interpretation of your spec? 

  • Hi David,

    The interpretation is correct, but there is no guarantee that the times given in Table 13 will be accurate 100% of the time. Whatever clock you are providing to the ADC will have some tolerance that will change slightly with temperature and time. If the clock slows down, even a little bit (1-2%), you might start reading data before new data is available since you are assuming that t18 is always exactly 210 us, whereas this time is dependent on fCLK. This is why it makes more sense to use DRDY as an interrupt, or at least poll the STATUS byte to see if new data are ready.

    Again, what you are doing will work, it is just not guaranteed to work. I leave it to you to decide how to proceed.

    -Bryan

  • Gotcha, I'll give it a shot. Thanks for your help!