readadc and decimal places

vk6kci

New Member
Hi All,

I did take a look at the forum in order to resolve the following, but can't easily find a definative thread!

I have a standard voltage devider set up and can reliably get an 8/10 bit resolution over the 0-5v range using readadc and readadc10

I understand how the readadc10 provides 10 bit resolution in the two byte blocks that make up the word (W0) etc.

What I can't figure is how to get and display the result to one or more decimal places.

So far.... I can only display a whole number with rounding up or down. i.e. 15v, 16v, 17v etc.

What I am after is a reading with at least 1 decimal places i.e. 15.1, 15.2, 15.3 etc. 2 decimal places would be good!!

I'm sure it's been done.... and I'm probably the only person in the picaxe world that doesn't know :))

can anyone point me in the right direction??

Kind regards
Maarten
VK6MP
 

hippy

Technical Support
Staff member
If you have a reading 'N' which represents "15.1" you need to convert "N" so it becomes "151" and then display the number with a decimal point placed before the last digit. Similar to ...

ReadAdc10 0, w5
w6 = w5 ...
BinToAscii w6, b1,b2,b3,b4,b5
SerTxd( b1, b2, b3, b4, ".", b5, CR, LF )

How you would calculate 'w6' from 'w5' depends on your hardware configuration.
 

vk6kci

New Member
Thanks Hippy,

I have used your code and with a calibration factor I can now get the desired voltage reading in b3, b4 and b5. i.e. if my actual voltage reading is 12.6 volts, b3=1, b4=2 and b5=6. (b1 and b2 are zero because there are no ten thousands or one thousands)

However.... instead of using SerTxd, I have used the following code because I am using an AXE033 serial LCD:
__________________________________________
init:
pause 500
main:
readadc10 0,w5
w6 = w5/4 ;calibration factor
bintoascii w6,b1,b2,b3,b4,b5
serout 0,N2400,(254,128,#b3,#b4,".",#b5," volts")
pause 500
goto main
________________________________________

Problem is.... I now get a readout of 4,948.50 volts for an actual input of 10 volts.... so it is not displayng the true values of b3, b4 and b5.

If I do a debug after the bintoascii, the bits 3,4 and 5 show the correct voltage as a whole number. As you suggested, displaying the same with a "." decimal point after b4 should display the correct voltage.

But it doesn't!! For 10 volts I get "4948.50 volts" on the LCD display. This is obviously not correct.

I am using a 20k/10k voltage divider and when using readadc10 and debug, I get a linear 0 - 1024 for the input voltage range of 0 - 5 volts. The actual voltage across the divider is 0 - 20 volts..... hence the calibration factor of /4.

I'm a bit stumped and am wondering if you can see any glaringly obvious errors on my part??

Kind regards
Maarten
VK6mp
 

premelec

Senior Member
Hi OM, without addressing your exact problem I'd like to mention that since the PICAXE readadc is ratiometric to the supply voltage you can simplify your math some by using supply voltage so that the volts per numeric is exact - i.e. running at 4.092 volts the READADC10 divisions are 4.092/1023 = 4 millivolts per unit of the read number - if you then have a 1/5 input divider you've got 20mv per unit read... it's evident this same effect can be had by varying the input divider ratio instead of supply voltage... however then it's harder to use the input divided voltage for other purposes - anyhow That's how I've approached this business ! AJ0J
 

vttom

Senior Member
I am using a 20k/10k voltage divider and when using readadc10 and debug, I get a linear 0 - 1024 for the input voltage range of 0 - 5 volts. The actual voltage across the divider is 0 - 20 volts..... hence the calibration factor of /4.
Something doesn't sound right to me with your voltage divider. The formula for a voltage divider is Vout = Vin (R1/(R1+R2)). So, if R1=10k, and you want 20V in to yield 5V out, then we get:

5 = 20 (10/(10+R2)) = 200/(10+R2)
=> 10+R2 = 200/5 = 40
=> R2 = 40-10 = 30 kOhms
 

nbw

Senior Member
simple maths on a voltage divider is a very easy way to manage things. Work out the min and max voltages you're likely to get, calculate your voltage divider so the min and max will fall within 0 and 5V, and then yes - basically 5mV = 1 ADC 'step' (1024 x 4.96mV will give you the 5V).

If you see 512 steps on the ADC pin, that's 2.5V. If your voltage divider was a clean 1:10, you'd had 25V on the input source.

So you could rearrange the equation to get 512 steps / 25V = x
therefore x = 20.4

You could do a simple ADC / 20 = V e.g. 383 steps / 20 = 19V

Then if you want an extra dp, you could multiply the steps by 10, then divide by 204 (or * 5, /102). Being mindful of the 65,535 2-byte limit, you could multiply by 50, then divide by 102

So, 512 * 50 = 25600
25600 / 102 = 250

If you divide your result by 10, you get volts: 25
If you take your volts, * 10, and subtract that from your result - that's your first decimal place. OK, it's zero for this but imagine you had a reading of 669 steps;

669 * 50 = 33450
33450 / 102 = 327.94 (PICAXE will ignore .094)

327 / 10 = 32 (volts)
327 - (10 * 32) = 7 (decivolts)

Therefore, you have 32.7V.
 

vk6kci

New Member
Thanks all,

Thanks Hippy:
I now have the display reading fine! I used the #bx (rather than just bx) as a variable because the AXE033 manual provides an example of the same. Obviously it aint so!!!

Thanks premelec and nbw for your input. Whilst I have a standard 20k/10k voltage divider, both legs are multi turn trimmers, so I can easily adjust out any error. Having said that..... I rather like some of the stuff that nbw put up and I am going to experiment some more with that.

Yay for the day goes to vttom for spotting an error!!! You are right..... it doesn't sound right because my source voltage is in fact 0-25 volts.... not 20 volts as I mentioned in a previous post.

What a fantastic forum!!!

Thanks to you all.

Regards
Maarten
VK6MP
 
Top