voltage calculation for 12bit ADC using LTC1298
jonykk
Posts: 17
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
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
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.
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
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).
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)
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.
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...
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.
^_^ 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....