How do I get 2 decimals

Jacobsen

New Member
How do I get 2 decimals with the Basic codes below?
I have put "READADC10 3,w3" to 10 bit to get a wider resolution
I am using PICAXE-28X

I have tried to insert the following text at the end of the codes,
to make the second decimal appear in the display.
Byte = w3 // 1 | "0"
GOSUB SendDataByte

<code><pre><font size=2>
DisplayLine4:
READADC10 3,w3
byte = $D4; Start Line 4
GOSUB SendCmdByte
EEPROM 56,(&quot;Volt: &quot;) ;56..64
FOR get = 56 TO 64
READ get,byte
GOSUB SendDataByte
NEXT

let w3 = w3 / 20

SERTXD(&quot;Volt: &quot;,#w3,CR,LF)
1000Linie:
byte = w3 / 10000 | &quot;0&quot;
IF w3 &gt;= 10000 THEN Disp1000Digit4
byte = &quot; &quot;
Disp1000Digit4:
100Linie:
byte = w3 / 1000 // 10 | &quot;0&quot;
IF w3 &gt;= 1000 THEN Disp100Digit4
byte = &quot; &quot;
Disp100Digit4:
GOSUB SendDataByte
10Linie:
byte = w3 / 100 // 10 | &quot;0&quot;
IF w3 &gt;= 100 THEN Disp10Digit4
byte = &quot; &quot;
Disp10Digit4:
GOSUB SendDataByte
Units:
byte = w3 / 10 // 10 | &quot;0&quot;
GOSUB SendDataByte
DispDecimalPoint4:
byte = &quot;.&quot;
GOSUB SendDataByte
Decimal_1:
byte = w3 // 10 | &quot;0&quot;
GOSUB SendDataByte
Decimal_2:
byte = w3 // 1 | &quot;0&quot;
GOSUB SendDataByte
byte = &quot; &quot;
GOSUB SendDataByte
byte = &quot;V&quot;
GOSUB SendDataByte
byte = &quot;o&quot;
GOSUB SendDataByte
byte = &quot;l&quot;
GOSUB SendDataByte
byte = &quot;t&quot;
GOSUB SendDataByte
</font></pre></code>

In the display is shown e.g. 2.10 where I expeted it to show 2.18 ?
How du I get a wider resolution so the second decimal appear as well?
Would I get a more accurate result with the POKE og PEEK commands?
If so how isn't done in the codes?

<b> Best regards </b>
Monie
 

Jeremy Leach

Senior Member
If you're sending serially to an LCD then I think it's a lot easier than you think.

You've got a w3 word value that really is , say, 100 times the actual value.

To display the actual value you need to break w3 into whole and fractional part.

Whole = w3/100
Fraction = w3//100

Then use serout with #whole,&quot;.&quot;,#fraction

 

Jacobsen

New Member
Many thanks Jeremy Leach for you codes.
But I use parallelt display HD44780 with Hippy Basic codes display system.
In the display is shown e.g. 2.10 where I expeted it to show 2.18 ?
How du I get a wider resolution so the second decimal appear as well?

regards
Monie
 

Fowkc

Senior Member
If you're using Hippy's code, then Jeremy's method will work. If you want to display 2.18, send the LCD the data &quot;2&quot; &quot;.&quot; &quot;1&quot; &quot;8&quot;. The easiest way, as said, is to have the number 218 in memory.

If you're only getting 2.10, this suggests a problem with how you're manipulating the ADC value. I'll look through your code later. I'm doing something similar and have a four digit number (tens, units, two decimal places) showing fine.
 

MartinM57

Moderator
Forget the LCD and all the mod and div stuff...think simple and look at

LET w3 = w3 / 20

The PICAXE can only do integer maths, so w3 is always an integer value between 0 and 51 - I'll leave you to work out why.

So you're never going to get anything other than zero in the last digit

Edited by - MartinM57 on 2/24/2006 9:36:06 AM
 

Jacobsen

New Member
To Fowkc

With 0-5Volt in at ADC 0 and with a voltmeter I have set the voltage
to e.g. 2.56 V - then I want these two decimals to appear on the
parallel HD44780.
I have set &quot;READADC10&quot; to 10-bit to get a wider resolution.
I assume this is possile?
I ahve tried a lot of different approaches to get two decimals but with no luck.
So I would be really happy if you got someway to solve this problem
Id would really be helpful if you would put explanations in the codes,
to help my understanding of how they work

Best regards
Monie
 

Jacobsen

New Member
To MartinM57

I'm Ok with the fact that PICAXE only do integet maths with values
between 0 and 51.
But unfortunately II can't figure it out, No idea where to start. I'm
probably thinking way too complicated!
I have really gone through every bit of &quot;Basic commands sections 2 og 3
And in scktion 3 page 31 there is an overview of characters, but how
and where you find the figures between 0 og 51 I can't figure out!
Would it be possible for you to explain how to use these numbers and
how to insert them in my codes, to be able to read two decimals, if
possible with explanations as I would really like to how it is done!
I will get your explanations and examples translated to Danish. That
way I can always to back and make use them another time.

Best regards
Monie
 

Mycroft2152

Senior Member
Before you start pulling your hair ouT :)

One thing to remember is that the ADC uses the power supply (5 volts) as the reference voltage and breaks that into 256 or 1024 steps.

So your 2.56 volt input will not yield an exact value of of 128 or 512.

A stable power supply is needed to reduce jitter.

TANSTAAFL!

Myc
 

MartinM57

Moderator
OK - quite an interesting problem that I'm happy to solve as it's teaching me about ADC, whicjh I need to sort out for my next project.

READADC10 will return 1023 (ie binary 1111111111) when the input is 5 volts.

So, using proper maths, the real voltage for a reading = the READADC10 value * 5 /1023 (try it with some simple values - it works OK e.g reading = 512, volts = 512 * 5 / 1023 = 2.502v = 2.50v to 2 dp)

But PICAXE can't do proper maths, only integer maths. So you have to be clever in how you get it to do the maths for you.

So, in the above example, we will display 250 but put the decimal place after the 2, so it looks like 2.50

So how do we get 250 as the value to display from a READADC10 reading of 512. Well it's
(512 * 5 / 1023) * 100 (real maths again, not PICAXE maths)

So how do we do it in PICAXE maths, where we have two problems - it only does integer maths (so we might suffer rounding errors) and we can't let any intermediate value in the maths be greater than 65,535 'cos that the biggest number we can get in a word variable.

So with a bit of cleverness (and seeing that 1023 is very close to 32 * 32) we can rearrange the maths into

value = reading / 32 * 500 / 32

which when evaluated left to right, maximises accuracy but never overflows the 65535 limit

So change your

LET w3 = w3 /20

to

LET w3 = w3 / 32 * 500 / 32

and I reckon it might well work (untested of course!)

Let us know the results...
 

Jacobsen

New Member
<b> To MartinM57 </b>

Thank you very much for the very fine description, it is very instructive. ;-)

At 5Volt and 10-bit each step is step 5mV
And with 2.18V on the ADC 3 in, it will give steps: 2.18 / 0.00488 = 446

That means READADC10 446 * 5 /1023 is also 2.18V
And 446 / 32 * 500 / 32 = 218

<b> Bat there is anything wrong with the codes: </b>
1: With 1.58V in = 324 steps and show in the display 43.7 and shows too in SERTXD(&quot;Volt: &quot;,#w3,CR,LF)
2: With 2.18V in = 446 steps and show in the display 20.3 and shows too in SERTXD(&quot;Volt: &quot;,#w3,CR,LF)
3: With 4.50V in = 922 steps and show in the display 43.7 and shows too in SERTXD(&quot;Volt: &quot;,#w3,CR,LF)

Bat OK with:
1: With 2.50V in = 512 steps and show in the display 25.0
2: With 5.00V in = 1024 steps and show in the display 50.0

But it is only the first decimal that can be regulated, the second decimal doesn't work.
Do you have a sugegstion how I can get the second and last decimal to work?
My basic codes are below.

<code><pre><font size=2>
DisplayLine4:
'READADC10 3,w3
w3 = 446 ' = 2.18 Volt ind
byte = $D4; Start Line 4
GOSUB SendCmdByte

EEPROM 40,(&quot;ADC 3: &quot;) ;56..64
FOR get = 40 TO 48
READ get,byte
GOSUB SendDataByte
NEXT

LET w3 = w3 / 32 * 500 / 32
SERTXD(&quot;Volt: &quot;,#w3,CR,LF)

Disp1000Linie4:
byte = w3 / 10000 | &quot;0&quot;
IF w3 &gt;= 10000 THEN Disp1000Digit4
byte = &quot; &quot;
Disp1000Digit4:
Disp100Linie4:
byte = w3 / 1000 // 10 | &quot;0&quot;
IF w3 &gt;= 1000 THEN Disp100Digit4
byte = &quot; &quot;
Disp100Digit4:
GOSUB SendDataByte
Disp10Linie4:
byte = w3 / 100 // 10 | &quot;0&quot;
IF w3 &gt;= 100 THEN Disp10Digit4
byte = &quot; &quot;
Disp10Digit4:
GOSUB SendDataByte
DispUnits4:
byte = w3 / 10 // 10 | &quot;0&quot;
GOSUB SendDataByte
DispDecimalPoint4:
byte = &quot;.&quot;
GOSUB SendDataByte
DispDecimal4:
byte = w3 // 10 | &quot;0&quot; ' 1th decimal
GOSUB SendDataByte

byte = w3 // 1 | &quot;0&quot; ' 2th decimal
GOSUB SendDataByte
byte = &quot; &quot;
GOSUB SendDataByte
byte = &quot;V&quot;
GOSUB SendDataByte
byte = &quot;o&quot;
GOSUB SendDataByte
byte = &quot;l&quot;
GOSUB SendDataByte
byte = &quot;t&quot;
GOSUB SendDataByte
</font></pre></code>

Best regards
Monie
 

MartinM57

Moderator
Well, I'm afraid I can't begin to understand your code - the lines that do
// 10000
// 1
are a waste of time, and I haven't the time to sort it out for you completely.

However, progarm this into your PICAXE and you'll find it works well. Over to you to incorporate it into your LCD code (note I've changed the equation to be even more accurate - I said it was untested!)

w3 = 446 ' = 2.18 Volt ind
;w3 = 1023 ' = 4.99 Volt ind
;w3 = etc etc

LET w3 = w3 * 50 / 32 * 10 / 32
sertxd(&quot;1 - w3 = &quot;,#w3,13,10)

b0 = w3 / 100 // 10 | &quot;0&quot;
sertxd(&quot;2 - byte = &quot;,b0,13,10)

b0 = w3 / 10 // 10 | &quot;0&quot;
sertxd(&quot;3 - byte = &quot;,b0,13,10)

b0 = w3 // 10 | &quot;0&quot;
sertxd(&quot;4 - byte = &quot;,b0,13,10)

Edited by - MartinM57 on 2/25/2006 1:43:28 PM
 

Jacobsen

New Member
I have run yours code:

LET w3 = w3 * 50 / 32 * 10 / 32
sertxd(&quot;1 - w3 = &quot;,#w3,13,10)

b0 = w3 / 100 // 10 | &quot;0&quot;
sertxd(&quot;2 - byte = &quot;,b0,13,10)

b0 = w3 / 10 // 10 | &quot;0&quot;
sertxd(&quot;3 - byte = &quot;,b0,13,10)

b0 = w3 // 10 | &quot;0&quot;
sertxd(&quot;4 - byte = &quot;,b0,13,10)

Resultat:
1 - w3 = 158
2 - byte = 1
3 - byte = 5
4 - byte = 8

With this commands: LET w3 = w3 * 50 / 32 * 10 / 32
I can show in display: 15.8 Volt

All input volt is OK now :)
But it is only the first decimal that can be regulated, the second decimal doesn't work.
Do you have a sugegstion how I can get the second and last decimal to work?

Best regards
Monie
 

MartinM57

Moderator
I don't really know what you mean.

If you can display &quot;15.8 Volt&quot;, why can't you put the decimal point after the first digit and then the display will show &quot;1.58 Volt&quot; - which is the answer you want???????
 

Jacobsen

New Member
Hello MartinM57
I'm can't show disply 1.58 Volt only 15.5 Volt
I'm want 1.58 Volt show in display with me basic-codes
 

Fowkc

Senior Member
If you have the number 158 in location w3,
then send the number &quot;1&quot; ( = w3/100//10 | &quot;0&quot;),
then a decimal point,
then the number &quot;5&quot; ( = w3/10//10 | &quot;0&quot;),
then the number &quot;8&quot; ( = w3/10 | &quot;0&quot;)

If you mean you need 2-decimal place accuracy with tens and units as well (e.g. 15.87, 15.88 etc) I have code that works (as far as I'm aware, which I can e-mail to you, but I need to comment it and make some modifications to make it easier to understand. And that might take a while because I have a lot of other stuff to do...
 

MartinM57

Moderator
It's displaying 15.8 Volt because you are sending &quot;1&quot;, &quot;5&quot;, &quot;.&quot; and &quot;8&quot; to the display - completely under your control.

If you send &quot;1&quot;, &quot;.&quot;, &quot;5&quot; and &quot;8&quot; then it will show 1.58 Volt

...or am I the stupid one being trolled here?????
 

Jacobsen

New Member
To Fowkc
Yay now it works ;-)
I had to move parts of Hippy's code around, but now it works with two decimals.

You are sending the number &quot;8&quot; ( = w3/10 | &quot;0&quot;) and in the display a letter is written (?).
I'm sending this &quot;8&quot; ( = w3 // 10 | &quot;0&quot;) and this outputs &quot;8&quot; to the display as second and last decimal.
Is there a reason for the two different codes for the last decimal?

Best regards
Monie
 

Jacobsen

New Member
To MartinM57

Yay it's working nowt ;-)
I had to move parts of Hippy's code around, but now it works with two decimals.

A bit more math!
I have a large private solar heating system, which I would like to do some measurements on.
I have put a &quot;voltage-splitter&quot; on the ADC 0 (PICAXE-28X) in.
With a 22k resistor connected to leg 2 and +5V and a 1.6k resistor also from leg 2 but with the other and to Gnd

Hence at 60Vdc input, there is only 4.00V on ADC 0 in (leg 2)
I have calculated it like this: 60 / 15 = 4.00 V into the ADC 0
With you commando: LET w3 = w3 * 50 / 32 * 10 / 32
Other calculations and outputs to the display:
(Factor = 15)
<code><pre><font size=2>
Volt Volt ADC 0 Steps Display Comment
1: 60V 4.00 833 60.90 Shows 0.90 too much?
2: 50V 3.33 682 49.80 Shows 0.20 too little?
3: 40V 2.67 546 39.90 Shows 0.10 too little?
4: 10V 0.67 137 9.90 Shows 0.10 too little?
</font></pre></code>

Do you have a suggestion how I could get the measuremens above to be more accurate?
Some maths would be great and a description of the actions.

Best regards [smile]
Monie
 

Fowkc

Senior Member
I'm doing something very similar with lead-acid batteries. Firstly, have you checked that the voltage you expect (4V at 60V) is actually there, i.e. with a multimeter? Resistor tolerances can make a difference, maybe think about using precision resistors. Secondly, by my calculations you'll actually get 4.068V from 60V with those resistors, which means when you multiply it by 15, you get 61.02V, fairly close to your 60.90V reading. Try altering your resistor combination to get an exact 4.0V. You might (probably will) need a trimmer to tune it exactly.
 

MartinM57

Moderator
^^^^^I agree^^^^^

The calculation is as good as you can get...

... but you've got various inaccuracies all round the system - getting between 1-2% accuracy will be a great achievement and it looks like you're pretty much there already.

Innacuracies include, but not limited to:
- your calculations
- resistor tolerances
- ADC accuracy (it might be 10 bits for increased resolution, but how accurate is it?)
- temperature
- supply voltage (maybe? - not sure how PICAXEs get their ADC reference voltage)
- electrical noise

PS if you're playing around with 60V near a PICAXE, I hope you have a few spare ones for when they start emitting the magic smoke that they run on!
 
Top