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.

ADS1232: ADC Output code is not accurate as per the input weight

Part Number: ADS1232

Hello E2E Experts,

Good day.

I am using ADS1232 for my weighing application. The ADC Output is not as per the input. Can you assist me? 

AVDD = 5 V, VREF = 5 V, Data Rate = 10 SPS

Below is my code.

unsigned long ADS1232_read()
{
signed long adc_val = 0;
char cy_count = 0;

while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13));
HAL_Delay(4);

for(cy_count = 0; cy_count < 24; cy_count++)
{
adc_val = adc_val << 1;

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); //clk high
HAL_Delay(4); // min 100ns

if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13)) //data low /high
{
adc_val += 1;
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); //clk low
HAL_Delay(4);
}

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
HAL_Delay(2);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(2);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_Delay(2);

adc_val &= 0x7fffc0;
adc_val = adc_val >>6;

return adc_val;

}

The output code is not accurate as per the input weight.

  • Hello,

    I assume that you are getting results that are wrong by a large amount, and not a few percent.  It would also be helpful to use a logic analyzer or scope to capture the /PDWN, /DRDY/DOUT, and SCLK pins to confirm proper timing and expected waveforms.

    Looking through the code, it appears that you are bit-banging the SPI port, which should work well.  I did notice that you are sending a 25th SCLK to force /DRDY/DOUT pin high after data retrieval.  However, you are writing to the /DRDY/DOUT pin, which is a digital output pin on the ADS1232 and should only be read from and not forced high.  I suggest changing the following code from:

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
    HAL_Delay(2);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
    HAL_Delay(2);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_Delay(2);

    to the following:

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
    HAL_Delay(4);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_Delay(4);

    The 25th SCLK will force /DRDY/DOUT output high after data retrieval and will only go low when the next data is ready to be retrieved from the ADC.

    Also, it appears that you are forcing the sign bit to 0 in your adc_val result.  If the ADC result is a positive value, then you should get expected result, but if it is negative (due to offset or noise), then forcing the sign bit to 0 will result in a small negative value near 0 appear to be a near full scale value, due to the binary two's complement format of the ADS1232.  I suggest keeping the ADC result as a long signed integer and left shifting the adc_val by 8.  You will then get a 32b signed integer with the 8 LSBs equal to zero.  You can easily scale this later in your code to produce the correct weight measurement.

    CHANGE from:

    adc_val &= 0x7fffc0;
    adc_val = adc_val >>6;

    to the following:

    adc_val = adc_val <<8;

    Regards,
    Keith Nicholas
    Precision ADC Applications

  • Hello Keith,

    Good day.

    1. For  5v reference and 128 gain noise-free resolution bit is 18 bits which are mentioned in the datasheet. So I have used adc_value  =adc_value & 0x7fffc0.this is adc_value is noise free count. My statement is right. Why do I need to do leftshift 8 times?
    2. Even though I used 18 bits noise-free count for calculation still the count is not stable.
    3. Please suggest me hardware circuit for the input side for filtering the noise.
    For 5v reference 128 gain
    The signal input range is +/-19.5mv
    so for +19.5mv 8388607 (0x7FFFFF)
    so only I put adc_value = 0x7FFFFF
    for 18bit  adc_value  = 0x7FFFE0;
    the maximum count I get when applying 19.5 mv is 8388544 is the noise-free count is it correct what I am saying?
    for 0.125mv I am getting a count 53772. and approximately 100 counts are oscillating.
    How to rectify this?
    Regards,
    CSC

  • Hello,

    1.  If you want a signed 32b integer with an 18b noise free result, then you first need to left shift by 8 to preserve the sign bit.  Then after left shift of 8, you can right shift 14.  The result will be a 32b signed integer that represents the full scale range of the ADS1232 to 18b, with decimal values ranging from +131,071 to -131072.

    2.  The 18 noise free bits are the internal noise of the ADS1232 with inputs shorted.  When connecting an external bridge sensor, you will then also get the noise of the bridge sensor, and additional noise of the cable connections.  The bridge sensor will have internal noise, plus any external noise pickup such as vibration, air movement, and so forth.

    3.  You should add input filters to the REF inputs and the Analog inputs.  This will help filter any noise picked up by the cables.  You can increase the below capacitor values by 10x, 10nF+100nF+10nF, if needed to improve filter performance.  The resistor values should be 0.1% tolerance and the capacitors should be C0G/NPO ceramic capacitors with 1% tolerance.

    The ADC will have offset and gain errors.  Depending on the sign and magnitude, you may need to apply more than 19.5mV to get to full scale.  Also, any order to get 18b noise free performance, you need a good PCB layout, with bypass capacitors placed as close to the supply pins as possible.  In addition, it is very important that the PGA bypass 0.1uF CAP across pins 9 and 10 be placed as close as possible to the IC pins.  In addition, this capacitor needs to be a high quality C0G/NPO capacitor.  Following the board layout in Figure 11-1, with a solid ground plane beneath the top layer will provide best performance.

    I suggest you look at the application note  A Basic Guide to Bridge Measurements which discusses different bridge configurations and offset/gain calibration concerns.

    Regards,
    Keith

  • Hello Keith,

    Good day.

    Can you explain in detail about extracting the digital counts from 24-bit data?

    Regards,

    CSC

  • Hello,

    Let me explain this with an example referring to Table 8-7 in the datasheet.

    If the ADC input voltage is positive by 1LSB, then the output code will be 00000000 00000000 00000001b in binary, or +1 in decimal.

    When you clock this data into a 32b signed integer that is pre-set to 0, the first 8b will be 0, followed by the 24b conversion result.

    00000000 00000000 00000000 00000001b

    Doing a left shift of 8b will result in the following:

    00000000 00000000 00000001 00000000b

    Next, right shift by 8b, and you will have the correct positive value, which in this case is the same value before shifting the data.

    00000000 00000000 00000000 00000001b

    However, when the ADC input voltage is negative by 1LSB, the output code of the ADS1232 will now be 11111111 11111111 11111111b, which represents a decimal value of -1.

    Clocking this data into a 32b signed integer that is pre-set to 0, the first 8b will still be 0, followed by the 24b conversion result.

    00000000 11111111 11111111 11111111b

    If you do not shift this data, the processor will interpret this as a positive number (+16777215 decimal).  In order to convert the 24b signed integer from the ADS1232 to a 32b signed integer, you first left shift by 8b which will result in the following value:

    11111111 11111111 11111111 00000000b

    Next, right shift by 8b.  In this case, the processor will preserve the MSB sign bit, and you will get the following result:

    11111111 11111111 11111111 11111111b.

    This is now the correct 32b code for decimal -1 value.

    Regards,
    Keith