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.

ADS124S08: Trouble sampling CH1

Part Number: ADS124S08

I am working with the ADS124S08.  I am able to write and read back register settings, I have accessed the internal temperature sensor and am able to display the data.

Problem is with trying to access CH1 conversion data.  

I get FF FF Ex for the three bites read if I short the CH1+ and CH1- lines together.  I am using REF0 at 5V.

My setup registers are as follows

output_low(CS_ADC);
delay_us(ADC_DELAY);

SPI_XFER_124S08(ADS124S08_WAKE_UP); // WAKEUP command
SPI_XFER_124S08(ADS124S08_RESET); // RESET command
delay_us(ADC_DELAY);
SPI_XFER_124S08(ADS124S08_WREG | ADS124S08_STATUS); // WREG register starting with STATUS register 0x43H
// write only status reg
SPI_XFER_124S08(0x00); // 1-1 = 0


SPI_XFER_124S08(0x00); // clear POL bit on Status reg
delay_us(ADC_DELAY);
SPI_XFER_124S08(0x42); //WREN REG starting with MUX reg at 0x02
SPI_XFER_124S08(0x03); //write to four regs MUX PGA RATE and REF

SPI_XFER_124S08(0x01); // MUX Register
// CH 1 selected

SPI_XFER_124S08(0x08); // PGA Register
// Gain = 1

SPI_XFER_124S08(0x09); // Sample Rate Register

SPI_XFER_124S08(0x30); // REF register

then I loop the following code for the data:

delay_ms(100);

output_high(START_ADC); // Start Line high
// Conversion starts here

output_high(CS_ADC);
delay_us(ADC_DELAY); // Just a small delay here

//DRDY_ticks = 0; // initialize safety counter prior to polling


DRDY_flg = 0; // clear flag for conversion

while(!DRDY_flg) {
// hang here waiting for ADS124S08 conversion to occur

delay_ms(100);
output_toggle(G0_SELECT);  // used by scope to check where code is running.

} // end conversion wait loop

output_low(CS_ADC);
delay_ms(ADC_DELAY);

if(DRDY_flg) { // conversion occurred

SPI_XFER_124S08(0x12); // RDATA Register


DATA_1 = SPI_XFER_124S08(0);
DATA_2 = SPI_XFER_124S08(0);
DATA_3 = SPI_XFER_124S08(0);


output_low(START_ADC);
//output_high(CS_ADC); // disable ADC communication

DRDY_flg = 0;

ADC_DELAY is 100

I believe I am set up correctly, and it does run, just not reading the right values I feel.  if I open the CH+ and CH1- lines so they are floating, I lower data like 00 0A 23 and it sort of floats around.

I can post more information if you need it.  

  • Hi Greg,

    The ADS124S08 outputs the conversion result in binary 2's complement.  The negative full-scale is 0x800000 and 0xFFFFFF is actually -1 decimal.  So the value being returned is slightly negative and this could be due to having a negative ADC offset.

    The ADC input is a differential measurement, which means that the output code is based on the AINP and AINN input values.  If the AINP voltage is greater than AINN then the output code will be positive and if AINP is less than AINN the output code will be negative.  The mux configuration you are using is AIN0 is AINP and AIN1 is AINN.  If you let the input float, they could be floating to any value.  If you leave AIN0 open (or floating) and only connect AIN1, the input is in an undetermined state.  AIN0 and AIN1 should be connected to a valid input voltage within the input range of the ADC.

    The PGA register setting you are using is gain of 1 with the PGA enabled.  You cannot make a ground referenced measurement with the PGA enabled as it will be outside of the input range for the PGA.  As the reference is 5V, I would assume that you are attempting to make a measurement relative to AGND.  If so, the AINN input should connect to AGND and the voltage to be measured should connect to AIN0 (AINP input).  You need to also set the PGA to disabled and bypassed.

    For the Data Rate register setting you are using the Sinc3 filter and 400sps data output rate.  The first conversion after the START pin goes high will take 3 complete conversions before the digital filter will completely settle.  At the point where the START pin goes high, the DRDY pin will go high and conversion data will not be available until DRDY goes low.  It appears that you are doing the opposite in your while loop, but perhaps this is ok depending on how you are determining the state of DRDY as that portion of the code is not shown.

    Best regards,

    Bob B

  • Thanks Bob, yes twos complement is confusing.  Shorting the positive and negative terminals of CH1 should read near zero, and looking at the data sheet FF FF FF is near zero in the twos complement world.  I have changed my code to use signed INT32 variables as I was using unsigned INT32.  Tomorrow I will connect a bridge to the CH1 input and see how it does.  as for the DRDY, I am setting it to '1' in my interrupt when DRDY goes low.  so a bit backwards but my flag is set to be a '1' when the event (DRDY low) occurs.  More tomorrow, 6PM here and a 12 hr day at the office.

  • Hi Greg,

    One further thought.  When using INT32  you have to properly sign extend the 24-bit values to 32-bit format.  There are many ways to do this.  One method is assemble the data then left shift by 8, followed by a right shift by eight.  What this does is forces a value to the sign bit (msb) which will follow back through when right shifting back to the correct value.  You could also monitor the most significant bit of the 24-bit value and if it is high, you can simply 'or' 0xFF000000 to set the appropriate bits to set the sign.

    Best regards,

    Bob B

  • Thank you Bob, here is where I am now.  I set my SPS to be 1000 and using the low latency filter so my rate register is 0x1B.

    I get this sort of output when I short the CH1+ and CH1- lines together:

    $CA 19 19#
    $CA 17 17#
    $CA 17 17#
    $CA 7 7#
    $CA 16777180 16777180#
    $CA 16777198 16777198#
    $CA 16777196 16777196#
    $CA 9 9#
    $CA 54 54#
    $CA 31 31#
    $CA 16777206 16777206#
    $CA 16777212 16777212#
    $CA 16777187 16777187#
    $CA 16777209 16777209#
    $CA 16777200 16777200#
    $CA 16777183 16777183#
    $CA 16777169 16777169#
    $CA 16777193 16777193#
    $CA 70 70#

    The second number in the string can be ignored as it is what my filter algorithm output is and it is bypassed right now,  I would expect the lower (near zero numbers) but not the large 16777206 numbers.

    here is my conversion in C:

    signed int32 convert_2s_complement(signed int32 number) {
    // converts the number to decimal from 2's complement
    // 24th bit tested for set.

    int32 bit_test = 0x00800000; // 24th bit set to 1
    int32 value = 0;

    value = number & bit_test;

    if (value > 0) { //24th bit set number is negative

    number = ~number + 1;
    number = number * (-1);

    }


    return number;


    } // end convert_2s_complement()

    I welcome your thoughts.  

  • one other thing, here is my fprintf statement, perhaps I just have it formatted wrong for signed INT32

    fprintf(OOK_SERIAL, "$CA\t%ld\t%ld#\n\r",DATA_1_32,ADC_NUM);       // using CE command for testing ADC

  • Hi Greg,

    You made an error in the actual number conversion as the value you are inverting is not properly sign-extended to 32-bits initially.  So try the following changes:

    if (value > 0) { //24th bit set number is negative

    number |= 0xFF000000;  // This extends the 24-bit sign to 32 bits

    }

    You do not need to make the number negative by multiplication as the value will be adjusted by value of the sign bit for the integer. For example, the 24-bit value of 0xFFFFFF when placed into the 32-bit integer will be represented by 0x00FFFFFF.  By 'or'ing to the value 0xFF000000 the value will now be sign-extended to 0xFFFFFFFF which will be interpreted as -1 decimal.

    Best regards,

    Bob B

  • Thank you for the help Bob.  I am sure we will be talking more as I bring the ADS124S08 up.