Display SD21 Voltage

BillyGreen1973

Senior Member
I'm using an 18M2 in the SD21 servo module, running off 4x1.5v AA cells. This will be the backbone of a 19 servo robot I am building.
So far everything is set up fine, I2C works great and I can control all the servos.

The problem I am having is a maths one really.

If you read register 65 on SD21 it returns a number between 0 and 255 relating to battery voltage. Each devision is equal to 39mV so for example if register 65=159...

159 x 39 = 6201

This is 6.201v

I am displaying this info an the AXE033 using this sub routine

Code:
ReadBatt:
hi2cin 65, (b9)   'Read Battery Voltage
  w5=b9*39	'multiply register 65 by 39 to get voltage in mV
  w6=w5/1000	'returns the voltage whole number into w6
  w7=w5//100	'returns the decimal places of volts into w7
  serout 7,N2400,(254,128)
  pause 10 
  serout 7,N2400,("    Batt= ",#w6,".",#b14,"V  ")'send batt voltage to LCD
  pause 10
  'sertxd ("batt= ",#w6,".",#w7,"V  ",#b9,CR, LF) 'send batt voltage to terminal
Return
This works ok as long as the decimal place is more than 100 (ie 0.100)
if the voltage drops (for example register 65= 156, ie, battery voltage is 6.084), the leading '0' in the decimal is dropped to give a reading of 6.84v

First how can I get just 1 or 2 decimal place accuracy?
and how can I keep the leading 0?

AS you can see I'm a newbie at PicaxeBasic, so any help would be much appreciated.
 

westaust55

Moderator
Read up on and then use the BINTOASCII command

That will break the value down into the individual digits each already in ASCII encoded format so there is no need for the # symbol in front of the variables.
Then send the first digit, a period ( "." ) then the remaining 3 digits.
Since you only need four digits you can skip sending the first digit (ie the first variable returned from the BINTOASCII of the word variable
 

hippy

Ex-Staff (retired)
BINTOASCII as westaust55 suggests is the easiest way to format individual numbers into priintable digits and to insert decimal points.

The other technique is to print leading zeroes ( and leading spaces ) to explicitly to adjust the display depending on value -

Code:
IF b9 < 10 Then
  SerTxd( "00" )
Else
  If b9 < 100 Then
    SerTxd( "0" )
  End If
End If
SerTxd( #b9 )
Code:
Select Case b9
  Case < 10  : SerTxd( "00", #b9 )
  Case < 100 : SerTxd( "0", #b9 )
  Case Else  : SerTxd( #b9 )
End Select
 

BillyGreen1973

Senior Member
Thanks Westaust55 and Hippy

I had a look at the BCDTOASCII as you suggested West, however it didnt give the correct figures. BUT this put me on the right track!
I then tried BINTOASCII, this worked flawlessly. Many thanks.

Here is the snippet i used in the simulator to check things out

Code:
w7=6201
main: 
	inc w7
	bintoascii w7,b1,b2,b3,b4,b5; convert to ascii
	debug 		; debug values for testing
	serout 7,n2400,("batt = ",b2,".",b3,b4,b5,"V",cr,lf)
goto main
I think it is easier to implement than using the modulas and then formatting the text for printing. It's also less code than I had before!

Simple really, perhaps I should have thought about it a bit harder :rolleyes:
So once again, many thanks
:D
 
Last edited:
Top