View Full Version : Basic analog to digital calc volts subroutine
01-24-2010, 04:24 AM
Hey guys. Taking a look at this subroutine here to calculate voltage from the 8bit ADC I was thinking that technically the second IF statement and everything that follows
Isn't necessary correct?
Because when V2 reaches 100 the calculation for V already increments the ones place.
v = 5 * adcBits / 255
r = 5 * adcBits // 255
v2 = 100 * r / 255
v3 = 100 * r // 255
v3 = 10 * v3 / 255
IF (v3 >= 5) THEN v2 = v2 + 1
IF (v2 >= 100) THEN
v = v + 1
v2 = 0
Just making sure I'm not missing anything important.
01-24-2010, 05:45 AM
The subroutine finds voltage in two parts, v to the left of the decimal point and v2 for two digits to the right of the decimal point. Then v3 is a third digit to the right of the decimal point that is used to round off. The first IF statement decides whether to round up or round down. If it rounds up, there is a possible carry. But I am sure the program is incorrect, as v2 can never equal 100 or greater. The carry will occur IF (v2=99).THEN ... when v2 rolls over from 99 to 100, and the 1 has to be carried to v, the digit to the left of the decimal point.
That said, that subroutine is a roundabout way to do the calculation on a Stamp. Where did you find it and what is the ADC? Here is a method that uses the PBASIC */ operator...
v = adcBits */ 5000 ' v now holds the voltage in milliVolts
IF v // 10 < 5 THEN v = v / 10 ELSE v = v / 10 + 1 ' round off to 10 mV (note the carry is automatic)
v2 = v // 100 '2 digits to the right of the decimal point
v = v / 100 ' digit to left of decimal point
This assumes that the formula for conversion is V = adcbit / 256, rather than V = adcbits / 255. You will see a 255 there in a lot of texts, but I would argue that the denominator should in fact be 256 for ADCs such as the ADC0831, which has its final riser 1.5 bits below the maximum value.
01-24-2010, 10:56 AM
The ADC I am using is a TLC549IP
And this is from the Parallax Analog and Digital book.
what is this riser you speak of?
Post Edited (Campeck) : 1/24/2010 4:14:05 AM GMT
01-24-2010, 11:00 AM
I was thinking that technically the second IF statement and everything that follows
Isn't necessary correct?
Why not try it and see?
01-24-2010, 12:12 PM
well I did. and It seems like it's fine. But I just wanted to make sure I wasn't missing something minuscule.
01-25-2010, 02:21 AM
Looking at it again, I think the number v2 can never be greater than 98.. The reasoning is as follows.
The remainder from the first division is r = adcbits * 5 // 255. Because of the factor of 5 on both sides of the congruence, the value of r will also be a multiple of 5, and less than 255. So the highest value of r will be 250. Then moving to v2 = 100 * r / 255, if the maximum value of r is 250, we have, v3 = 100 * 250 / 255 = 98.04, which the Stamp rounds down to 98. The upshot is that the second IF statement is not only incorrect in the part about (v2>=100), but also the statement corrected to (v2=99) is superfluous, because v2 will never equal 99. The first IF statement however will be able to round up a 98 to 99, so that step does in fact improve the resolution.
01-25-2010, 08:41 AM
You asked aboujt the 1.5 bit riser. Let me see if I can explain that. I'm not sure about the TLC549, but this is a common feature of ADC transfer functions.
The transfer function relates the input voltage to the binary adc code, and that is often given as a graph in the data sheet. The code when the voltage equals zero is of course zero. The code becomes 1 when the voltage is 1/2 bit higher. So with converter that resolves 20 mV per bit, the code would go from 0 to 1 when the input is 10 mV, and it stays there until the voltage hits 30 mV, where it moves up to code 2. At the high end, the code moves from 254 to 255 when the input is 1.5 bits below maximum and stays there for the remaining 1.5 bits of the range. In this example, that would be the top 30 milliVolts of the input. There would in theory be a transition from 255 to 256 at 1/2 bit(10 mV) below maximum, but the converter cannot output a code of 256, because that wraps around to zero. The point is that the implied maximum of the transfer function is 256, not 255.
So what? Consider a simpler ADC, one that resolves only 2 bits, with output codes of 0,1, 2 and 3. Suppose this ADC has a full scale reference voltage of 4 volts. The diagram below shows the standard transfer function in black, with the input voltage on the x axis and the binary code from the ADC on the y axis. The binary code of course takes on only 4 distinct values, 0,1,2 & 3.. The first riser is at 0.5 bit, 0.5 volt, and the last riser is 1.5 bit below the maximum, at 2.5 volts.
If you use the formula, Va = 4 * adc / 4, then the 4 values of Va will be 0, 1, 2 and 3 volts, and the reading will be correct (meaning Va= true input voltage) at the points shown as red dots on the transfer function with error symetrical around those points. On the other hand, the formula Vb = 4 * adc / 3, will give output voltages of 0, 1.33, 2.67 and 4 volts, with a transfer function shown in blue, and the reading will be correct (again meaning Vb = actual input voltage) at the dots shown in blue. It is true that Vb will end up at the full scale 4 volts, but the match to the actual transfer function is not good. This is exactly the same as the situation with an 8 bit converter that outputs codes from 0 to 255. The best formula will be Va = Vfs * adc / 256, not Vb = Vfs = Vfs * adc / 255. The more bits there are, the lower the error, but an error it is. Not only that, math with the factor of 256 (or in general a power of two) is much easier to deal with.
I hope that helps.
Post Edited (Tracy Allen) : 1/25/2010 12:55:38 AM GMT