Shop OBEX P1 Docs P2 Docs Learn Events
voltage calculation for 12bit ADC using LTC1298 — Parallax Forums

voltage calculation for 12bit ADC using LTC1298

jonykkjonykk Posts: 17
edited 2012-05-16 20:12 in BASIC Stamp
Hi there,

Im using a 12bit ADC (LTC1298) for my project to display the output voltage. Im having problem which is the output get from the multimeter and the ADC output is different. Please correct me if im wrong on the calculation.Below are part of the calculation code.

Voltage calculation:
v= 5 * ADC / 4095
r = 5 * ADC // 4095
v2 = 100 * r / 4095
v3 = 100 * r // 4095
v3 = 10 * v3 / 4095
IF (v3 >= 5) THEN v2 = v2 + 1
IF (v2 >= 100) THEN
v = v + 1
v2 = 0
ENDIF
RETURN

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-05-14 21:08
    How about starting with a description of what you want to accomplish. Remember that:

    1) The ADC produces a value between 0 and 4095 for voltages from zero to the reference voltage (probably 5V here).

    2) All calculations have to be done using 16 bit integer values (from 0 to 65535). All intermediate results have to fit in 16 bits as well.
  • jonykkjonykk Posts: 17
    edited 2012-05-14 21:20
    Hi Mike,

    I'm doing a project on light intensity. Im using a LDR with a voltage divider to get the light voltage from 0 to 5V.... Im using LTC1298 as my ADC to convert the analog signal i get from the voltage divider and display the voltage output. The output voltage i get from the ADC and the output voltage using multimeter are slightly different. The below is my full ADC code. I would like to know the equation im using is correct? How to do calculation in 16bits where i only have 12bit in data? do i need to shift 4 to the right after shiftin data from ADC?

    ' {$STAMP BS2pe}
    ' {$PBASIC 2.5}

    ' ==========================================================
    ' ADC Interface Pins
    ' ==========================================================
    CS CON 0 ' Chip select pin number; 0 = active
    CLK CON 1 ' Clock to ADC pin number; out on rising, in on falling edge.
    DIO_n CON 2 ' Data I/O pin number.
    config VAR Nib ' Configuration bits for ADC.
    AD VAR Word ' Variable to hold 12-bit AD result.
    v VAR Word
    r VAR Word
    v2 VAR Word
    v3 VAR Word

    ' ==========================================================
    ' ADC Setup Bits
    ' ==========================================================
    startB VAR config.BIT0 ' Start bit for comm with ADC.
    sglDif VAR config.BIT1 ' Single-ended or differential mode.
    oddSign VAR config.BIT2 ' Channel selection.
    msbf VAR config.BIT3 ' Output 0s after data xfercomplete.

    ' ==========================================================
    ' Main Program
    ' ==========================================================
    HIGH CS ' Deactivate ADC to begin.
    HIGH DIO_n ' Set data pin for first start bit.
    again: ' Main loop.
    oddSign = 0 ' Select channel 0 only.
    GOSUB convert ' Get data from ADC.
    GOSUB calc_volts
    GOSUB display
    PAUSE 1000 ' Wait a half second.
    GOTO again ' Endless loop.

    ' ==========================================================
    ' ADC Subroutine
    ' ==========================================================
    convert:
    config = 11 ' Set configuration bits except for single ended, FOR channel 0, msbf, oddSign, sglDif, startB.
    LOW CS ' Activate the ADC.
    SHIFTOUT DIO_n,CLK,LSBFIRST,[config\4] ' Send config bits.
    SHIFTIN DIO_n,CLK,MSBPOST,[AD\12] ' Get data bits.
    HIGH CS ' Deactivate the ADC.
    RETURN ' Return to program.

    ' ==========================================================
    ' Volts Subroutine
    ' ==========================================================
    Calc_Volts:
    v = 5 * AD / 4095
    r = 5 * AD // 4095
    v2 = 100 * r / 4095
    v3 = 100 * r // 4095
    v3 = 10 * v3 / 4095
    IF (v3 >= 5) THEN v2 = v2 + 1
    IF (v2 >= 100) THEN
    v = v + 1
    v2 = 0
    ENDIF
    RETURN

    ' ==========================================================
    ' Display Subroutine
    ' ==========================================================
    display:
    DEBUG "channel ",DEC oddSign, ": ",BIN12 AD,CR ' Display DATA.
    DEBUG "Decimal value: ", DEC4 AD, CR
    DEBUG "DVM Reading: "
    DEBUG DEC1 v, ".", DEC3 v2, " Volts", CR, CR
    RETURN
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-05-15 08:31
    Try an alternate math:
    [SIZE=1][FONT=courier new]Calc_volts:
        v = AD + (AD ** 14464)    ' 5000 mV/4096 steps = 1.2207
        v2 = v  // 1000  ' fractional part
        v = v / 1000     ' integer part
    return
    [/FONT][/SIZE]
    

    In the original math, it seems to me that the step, v3=100* r//4095 could produce erroneous results.

    In the math here, the factor **14464 is equivalent to multiplying times 0.2207. (0.2207 = 14464/65536).
  • jonykkjonykk Posts: 17
    edited 2012-05-15 19:41
    Hi Tracy,

    Your code works great.....Thank you....By the way...can you please explain more about v2 = v // 1000 and v = v /1000...Why must divide 1000? Thank you...

    Does you mean if my Vref is 4 volts then my calculation will become v = AD + (AD ** 64) cause 4V / 4096 = 0.9765625 then (0.9765625 = 64/65536)
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-05-15 20:16
    The divide by 1000 is because this calculation,
    v = AD + (AD ** 14464) ' 5000 mV/4096 steps = 1.2207
    gives an answer in millivolts. But your print routine expects two values, whole number volts and separately the part to the right of the decimal point. v/1000 gives the whole number part, and v//1000 gives the factional part.

    If your reference were 4.096V, then the calculation would be easy, because then the result will be directly in millivolts. With a 4V reference, the multiplier is indeed as you say,
    4000 / 4096 = 0.9765625. For the BASIC Stamp, the ** multiplier would be, 0.9765625 * 65536 = 64000.
    v = AD ** 64000
    That is different from what you have. Understand that there is a division by 65536 implied in the ** operator. So you are really multiplying AD times 64000/65536=0.9765625.
  • jonykkjonykk Posts: 17
    edited 2012-05-15 23:09
    Hi Tracy,

    So if my Vref is 10V then my calculation will be 10000mV / 4096 = 2.4414. Therefore 0.44140625 * 65536 = 28928.
    The code will be
    v = AD + AD + (AD * 28929)
    Is this calculation correct?
    Thank you...
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-05-16 08:04
    Exactly. If you could power the LT1298 from 10V (don't try it!), the calculation would be correct.

    There is also the */ operator. Generally less accurate for this kind of thing than **. But with a reference of 4.0 volts, you would have,
    v = AD */ 250.
    where 256 * 4000/4096 = 250. The division by 256 is implied in the */ operator, and 250/256 = 4000/4096 exactly.
  • jonykkjonykk Posts: 17
    edited 2012-05-16 20:12
    Hi Tracy,

    ^_^ dont worry i wont power it up to burn my LTC1298....I'm just taking as a example to calculate the voltage to understand the equation....Thank you very much for the teaching....
Sign In or Register to comment.