Shop OBEX P1 Docs P2 Docs Learn Events
Possible ratiometric bipolar confusion? ADS1252 Propeller — Parallax Forums

Possible ratiometric bipolar confusion? ADS1252 Propeller

bookworm1706bookworm1706 Posts: 14
edited 2011-09-20 16:54 in Propeller 1
I am converting ratio-metric voltage output of a VTI SCA103T inclinometer to digital using ADS1252 and feeding it into the propeller The output of the inclinometer ranges from 0 to 5 volts. When the inclinometer is tilted to its maximum in one direction output 1 of the inclionometer reads 5 Volts and output 2 reads 0 volts, tilted the other direction the voltages flip in reverse of the description previously. When level they both read around 2.5 volts which should mean the adc will perform 2.5-2.5 equals zero.

The ADC is supposed to take the difference of these and convert it to digital. So at zero degree inclination, I should see zero volts (the offset value) come out of the ADC. I can measure the outputs of the inclinometer with a multi-meter which are both at 2.36 and 2.42. Close enough to zero for right now.

These go into the V+ and V- inputs of ADC1252. The ADC is giving me -2.26 volts out. Not 0.06 volts out as my multimeter would imply. What is going on here? The Vref on the ADC1252 is tied to VDD which is 5 volts. The ADC is hooked up as shown in the data-sheet. I am not too worried about noise yet as I cannot even get close to the right value out. This is the second ADC1252 chip I have tried and I am still having the same issue of it not seeming to be converting the difference between the two terminals and giving me a value that is way off.

To convert from the digital offset twos complement from the ADC I subtract the offset which is (2^24)/2 from the ADC value This removes the offset. Then I multiply by the VperLSB which is around 5V/2^24 and then convert result to decimal and display. It seems the bits coming out of the ADC are wrong.

One place where things may be wrong is that I am using the propeller which is 32 bits thus the 24 bits from the ADC are padded with zeros at the MSB of the value when the ADC value is stored. However, in all my boolean algebra run throughs this should not cause a problem.

The only other thing I can think of is that in reading the data sheet again last night and on page 7, I saw this statement:
"The bipolar input range is from -4.096V to +4.096V when the reference input voltage equals +4.096V; the bipolar range is with respect to -Vin, and not with respect to GND."

I had ignored it previously because I am not using a bipolar signal, however, now I am thinking that perhaps since I am only using half the range and the range of the adc may be centered at zero bipolar input, while I am centered at 2.5V thus I need to do some more manipulation with the output data to get it to correlate with the actual voltages coming out of the inclinometer. Any ideas? I am using the ADS1252 routine found in the OBX.

Here is a sample of the Inputs to and Outputs of the ADC and my program:
Vref = 4.79 V
VperLSB := %00110100100110010100011110101110
which is 4.72V/2^24 in IEEE-754 format
Vper LSB in decimal = 2.813339 E-07
At close to zero degree angle:
V+2.37 VDC
V- 2.38 VDC
Raw ADC Value: 00000000000001101101000101100110
ADC Value - Offset: 11111111100001101101000101100110
Vout = -2.26743 V
*I converted ADC value to voltage by multiplying the signed decimal equivalent of the( ADC Value - Offset) as calculated above by the VperLSB
As one can see the Vout value is quite large. Hopefully someone who is more knowledgeable then me in this can help me?

Here is some exerpts of the code:
CON
  halfnum = %00000000100000000000000000000000 '8388608       '0 number for 24 bit adc result  
VAR
  long rawadcval    'Variable to hold the initial ADC value
  long adcval     'Signed variable to hold signed ADC value
 
PRI ReadADC |  adcvalholder, flag
    
    ADCob.sample            'Go read sample from ADC
    rawadcval:= ADCob.sample   'Store ADC sample into adcval
    pst.Newline
     pst.Str(String("Vout raw:  ")) 
     pst.bin(rawadcval,32)
    rawadcval := rawadcval + ( !halfnum + %1 )  'Now subtract the offset (zero value),  
                                                                      '(1/2 of2^24)  from adcval to get true result
         pst.Newline
         pst.Str(String("Voutnonof: "))
         pst.bin(rawadcval,32)
                            'Need to check for sign, since output of ADC is two's complement 1 in MSB is Neg
    if ( rawadcval >> 31) == 1  'Shift out all 23 LSB if leftover bits are 1
      Sflag := 1             'Then set Sign flag high meaning negative
      adcval := - (! rawadcval + 1) 'Take absolute value of negative, then allow compiler to negate to get in system neg format.
    elseif ( rawadcval >> 31 ) == 0  'Shift out all 23 LSB if leftover bits is 0
      Sflag := 0              'then set sign flag low meaning positive
      adcval :=rawadcval
    else
      errorflag := 1             'If test fails set error flag high 
    adcval := fmath.FFloat(adcval)     'Convert ADC value to float value
    'if flag == 0
    '  adcvalholder := fmath.Fadd(adcvalholder , adcval)
    'elseif flag == 1
    ' adcvalholder := adcval
    ' flag:=0
 ' adcval := fmath.Fdiv(adcvalholder, fmath.FFloat(30))   
  result := adcval
    
 VperLSB :=     %00110100100110010100011110101110  '5V/2^24 in IEEE-754 format
 'VperLSB := fmath.FFloat(VperLSB)
    Vout := fmath.FMul(adcval, VperLSB)   'Vout of Inclinometer = adcval * Voltage per LSB

If someone actually has the chip on hand and would like to test this I can send the whole code. These are just exerpts so they will not probably work as is since I cut and pasted bits out of different routines. I have pasted all the parts having to do with the conversion process.

Jonathan

Comments

  • LawsonLawson Posts: 870
    edited 2011-09-18 09:31
    I've used 4x ADS1251 in a controller of mine. To sign extend the 24-bit data ( "RawData" ) I use a shift left ( << ) followed by a shift arithmetic right ( ~> ). The first shift puts the sign bit in the MSB position, the second shift then restores the original magnitude of the raw value while sign extending it.

    I.e.
    IntegerData := (RawData << 8) ~> 8
    

    When I convert the given raw data into a voltage I get a different result.
    Raw long = 00000000000001101101000101100110
    Decimal value = 446822
    Vref = 4.79 [volts]
    Voltage = (446822 / 2^23) * Vref = .255141
    (The division by 2^23 (aka 2^24 / 2)is because in inputs to the ADS1252 can have a differential voltage of +Vref to -Vref. )

    Short code implementing a full sign extend and conversion into micro-volts is below.
    con
      Vref = 4.79
      scale = round( Vref * 1000000.0 / float( 1<<23) * float(posx))
    
    pub adc2uV(RawData):uV | IntegerData
      IntegerData := (RawData << 8) ~> 8
      uV := IntegerData ** scale
    

    Lawson
  • magdropmagdrop Posts: 13
    edited 2011-09-19 06:48
    I had ignored it previously because I am not using a bipolar signal...


    I think you described the output from the inclinometer as being a bipolar signal. Is either output from the inclinometer or either input to the ADS1252 grounded?
  • bookworm1706bookworm1706 Posts: 14
    edited 2011-09-20 14:26
    Thanks for responding,

    @Lawson

    Thanks so much for the code samples, they are working great. I now want to know how they are working though. In order to gain some knowledge and hopefully contribute to the forum and not just use code, I will post up my explanation of your routine on this thread in a couple days and if you do not mind, you can verify my understanding of it.

    @magdrop

    The output from the inclinometer is not bipolar as I understand bipolar it is negative to positive swing. The inclinometer outputs 0 to Vdd

    Thanks again
    Jonathan
  • LawsonLawson Posts: 870
    edited 2011-09-20 16:54
    One big problem with your old code is that you were subtracting the voltage offset from the what the ADC gave you when you didn't have to. I.e. the signal form the inclinometer is differential, where the voltage difference between V+ and V- carries the data. If these signals are wired up to In+ and In- on the ADS1252, the ADC directly measures this voltage difference.

    Also, double check the scale value I use in my code example. It may be low by a factor of two depending on how the ** operator is implemented. (my code ended up doing this all in floating point)

    Lawson

    P.S. get a better reference on that ADS1252, these little ADC's can produce super clean data. I have a +-10 volt input using an example circuit from the data sheet that shows a ~30uV noise floor. (sampling at 4 Ksps divided down with a CIC filter to output at 31.25 Hz)
Sign In or Register to comment.