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.

ADS1282: ADC Input Voltage

Part Number: ADS1282
Other Parts Discussed in Thread: REF5025,

I am having trouble calculating the input voltage to the ADS1282. I am using a REF5025 as a voltage reference. 

The ADS1282 is connected to a TI TIva TM4C1231D5PMT MCU.

The voltage on the input of the ADS1282 is approximately 0.5V. 

I am getting the following reading on DOUT,

The data is read from the adc by the MCU using the adc_read() function,

int read_adc() {

unsigned int adc[6];
//0. Toggle the chip select line low (active low).
//ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_3, 0);
//ads1282_rdata();
adc[0] = rx_spi0();
adc[1] = rx_spi0();
adc[2] = rx_spi0();
adc[3] = rx_spi0();

//1. Toggle the chip select line low (active low).
//ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_PIN_3);

int data = adc[0] << 24 | adc[1] << 16 | adc[2] << 8 | adc[3];
unsigned char pol_bit = data >> 31;
if (pol_bit == 0)
{
return data;
}
else
{
data = data - 1;
data = ~data;
data = -1*data;
return data;
}

}

The adc reading (data) is send to a computer through uart. 

if (CH > 0){
//usprintf(&status, ">-%d<", abs(data));
status[0] = '>';
status[1] = '-';
status[2] = abs(data) >> 24;
status[3] = abs(data) >> 16;
status[4] = abs(data) >> 8;
status[5] = abs(data) >> 0;
status[6] = '<';
}
else {
//usprintf(&status, ">+%d<", abs(data));
status[0] = '>';
status[1] = '+';
status[2] = abs(data) >> 24;
status[3] = abs(data) >> 16;
status[4] = abs(data) >> 8;
status[5] = abs(data) >> 0;
status[6] = '<';
}
UARTSend(status, 7);

The ADC data is put back together in a c# program,

public int adc_count()
{
port.Write("M");

byte[] adc_count_byte = new byte[7];

System.Threading.Thread.Sleep(1);

port.Read(adc_count_byte, 0, 7);

string result = System.Text.Encoding.UTF8.GetString(adc_count_byte);
//Trace.WriteLine(result);

int adc_count = 0;

if (adc_count_byte[1] == '-')
{
adc_count = -1 *( adc_count_byte[2] << 24 | adc_count_byte[3] << 16 | adc_count_byte[4] << 8 | adc_count_byte[5]);
Trace.WriteLine($"-ADC COUNT -> {adc_count}");
Trace.WriteLine($"adc_count_byte[2] = {adc_count_byte[2]}");
Trace.WriteLine($"adc_count_byte[3] = {adc_count_byte[3]}");
Trace.WriteLine($"adc_count_byte[4] = {adc_count_byte[4]}");
Trace.WriteLine($"adc_count_byte[5] = {adc_count_byte[5]}");

}

if (adc_count_byte[1] == '+')
{
adc_count = adc_count_byte[2] << 24 | adc_count_byte[3] << 16 | adc_count_byte[4] << 8 | adc_count_byte[5];
Trace.WriteLine($"+ADC COUNT -> {adc_count}");
Trace.WriteLine($"adc_count_byte[2] = {adc_count_byte[2]}");
Trace.WriteLine($"adc_count_byte[3] = {adc_count_byte[3]}");
Trace.WriteLine($"adc_count_byte[4] = {adc_count_byte[4]}");
Trace.WriteLine($"adc_count_byte[5] = {adc_count_byte[5]}");
}

return adc_count;
}

The ADC voltage is calculated by,

public double adc_volage()
{
int adc_c = adc_count();

double voltage = (double)(adc_c * 2.5 / Math.Pow(2, 30));
//double voltage = (double)(adc_c * 2.328e-9);

Trace.WriteLine($"ADC Voltage -> {voltage}");

return voltage;
}

The output of this is,

-ADC COUNT -> -842794107
adc_count_byte[2] = 50
adc_count_byte[3] = 60
adc_count_byte[4] = 4
adc_count_byte[5] = 123
ADC Voltage -> -1.96228294400498

I can't seem to figure out what I am doing wrong. Any suggestions would be appreciated.

Thanks,

Allan

  • Hi Allan!

    Can you tell us what your PGA gain setting is and how you have the ADS1282 filter configured?  Can you also include DRDY in your logic analyzer capture?

  • Hi Allan,

    Calculation:

    You almost have the calculation correct. For the double voltage calculation, the value is actually:

    • double voltage = code * LSB_size
      • This is the basis for all ADC code to voltage translations
    •  = (2 * x_FilterType * adc_c) * (y_FullScaleRange / 2^30)
      • x_FilterType is a bit confusing to explain. Essentially, whether you're using the FIR or just the SINC, will give you different values (see 30 vs 31 length depending on the one you select in diagram below). 
        • The way I would do it, is x_FilterType = 1 if SINC, and x_FilterType = 1/2 or 0.5 for FIR.
      • As for the floating 2, we have to manipulate from 32 bits to the filter bits somehow.  
      • FullScaleRange will be explained below

    Assuming G = 1 (which is why Tom asked for your PGA settings) and FIR mode, I get -0.9811... Volts, which is half your value. 

    So is the calculation the issue?

    From what I can tell, no. And if I translate the logic analyzer shot into hex and do the calculation I get -> adc_c = 0xCD84CBD3 --> -0.9859V. So pretty close to what you're already seeing.

    I would ground both inputs and tie them together to see what value you get at the output. Then, I'd like to see an oscilloscope screenshot of ADC_INPUT to ADC_GND, as well as ADC_VREFP to ADC_GND, to verify the voltage you want is what you expect. It is really suspicious that you're getting a negative number when the inputs are clearly single ended.

    We're making other assumptions that your data is settled, and as Tom alluded to, you're following DRDY timing but we'll tackle those once we verify some more basic assumptions about the ADC.

    Best,

    -Cole