Simple Battery Capacity Meter

BeanieBots

Moderator
This is a very simple and basic battery capacity meter.
It uses the volt-drop of the 0v line as a current sense and an analog integrator to avoid 'lost' current signals.
After calibration it should be OK for about 3% accuracy.
I've included a circuit description but feel free to ask if you have any questions.
The code is crude and could be optimised but it fits an 08M and does the job.
I've tarted up the diagram and since since the original so appologies if any errors have crept in.
Enjoy.

Code:
'08M based battery capacity meter
'by BeanieBots Sep2007

symbol TicksPer_10mAHr=21	'adjust accordingly to suit Rsense
symbol IntegratorMaxV=822	'resets integrator @ ~4v
symbol ResetPulse=71		'resets to ~1v (reducing value will increase mAHr rate)
symbol BatterySize=3800		'Battery capacity in mAHr/10 (eg 3800=38AHr)
symbol Adjustment=38		'Amount each button press decreases capacity (typ Ahr*10)
symbol FSD=963			'PWM value that gives full meter deflection with pwmout 2,255,FSD


symbol IntegratorV=W0		'Raw output voltage of integrator
symbol Capacity=w1		'remaining battery capacity mAHr/10
symbol TickCounter=b6		'number of integrator resets per 10mAHr.
symbol MeterReading=w2		'PWM value to drive meter
symbol UpDown=b7			'Push button drives up or down


Capacity=BatterySize		'initialise reading to 100% 

main:

readadc10 4,w0
if IntegratorV > IntegratorMaxV then	
	pulsout 1,ResetPulse		
	gosub UpdateCapacity
endif

MeterReading=Capacity/10*96/38	'adjust values for your meter
pwmout 2,255,MeterReading		'ideally Capacity*FSD/BatterySize but watch for overflow

If pin3=0 then gosub AdjustCapacity

goto main

UpdateCapacity:
If Capacity>0 then
	TickCounter=TickCounter+1
	if TickCounter=TicksPer_10mAHr then
		Capacity=Capacity-1
		TickCounter=0
	endif
endif
return

AdjustCapacity:
pause 100
If pin3=0 then
	capacity=capacity-Adjustment max BatterySize
	else
	return
endif
Return
 

Attachments

BeanieBots

Moderator
Login to what?
You need to be logged in to the forum to upload/view attachments.
There seems to be some inconsistancy but I think it depends on file type.
 

Michael 2727

Senior Member
Hmmm, seems you have to hit the refresh button after re-logging
in to the forum.
(although it's saying Welcome Michael 2727 when I arrived originally )
The PDF file ended up comming in as text and garbled, first try after
re-login and a page refresh, the second attempt opened up Acrobat and all was OK.
 

hippy

Technical Support
Staff member
Re : Diagram.pdf

The pins on the download connectror don't match what they would be for the 3-pin Molex. Serial Out to PC should be furthest from 0V (top), Serial In from PC in the middle.

The diagram is technically correct because it doesn't say it's a 0.1" 3-pin molex download connector, but I'd have assumed it was.

Other than that minor issue, superb project.
 

BeanieBots

Moderator
Hippy, I agree about the download pinout and it's good to point it out.
I have actually made mention about it in the description document.
The reasoning behind my pinout is because MY circuits use three pin servo connectors and for my own safety I keep to the 'standard' that they use which is more 'normal' for my personal use.
 
Last edited:

BeanieBots

Moderator
That's the second time my edits have gone into the ether after posting:mad:
So, new post.

Hippy (or anyone), I have a line of code which I'm not happy with:-
MeterReading=Capacity/10*96/38

I would like it to be:-
MeterReading=Capacity*FSD/BatterySize

but that would cause horrible overflow problems.
The current line requires the user to alter the code rather than just change a value in the symbol list for different battery sizes and/or meter calibration. This sort of defeats the object of having the symbol def.
Even the existing line results in quite a granular display change which is a shame when the PWMout has a 10-bit resolution which is not being fully utilised. It's just the maths that lets it down.
 

hippy

Technical Support
Staff member
Hippy, I agree about the download pinout and it's good to point it out.
I have actually made mention about it in the description document.
Dontchajusthateit when people haven't read all the documentation :)

That's the second time my edits have gone into the ether after posting:mad:
So, new post.

Hippy (or anyone), I have a line of code which I'm not happy with:-
MeterReading=Capacity/10*96/38

I would like it to be:-
MeterReading=Capacity*FSD/BatterySize

but that would cause horrible overflow problems.
The trick is to find what the maximum multiplier value could be before overflow kicks in ( capacity*multiplier <= 65535 ), then find a divisor ( = FSD / multiplier ), giving I think, but check ...

multiplier = 65535 / capacity
divisor = FSD / multiplier
meterReading = capacity * multiplier / batterysize / divisor

Beyond that, it's multi-word arithmetic, and Jeremy is probably our resident expert on that.

There's a handy trick to remember, and that's if an lsb is zero you can divide by two without losing any precision so by shifiting devision top/bottom pairs ( when both have zero lsb's ) you can minimise the resulting maximum value, or shift the top or bottom noting to multiply or divide by a power-of-two later. Plus you can do the exact opposite, shift left to maximise a value and stay within overflow. Not sure how you'd use these, but they're there. It's often used in floating point normalisation to maximise accuracy/resolution, so Jeremy may be familiar with it.
 

manie

Senior Member
Hippy and BB: For that kind of complex calculations, would the additional Floating Point co-processor not be a better option ? I've battled through calculation overflow errors like this a few times myself and I'm starting to think about using the FPuP to help out. Will it though ?
Manie
 

BCJKiwi

Senior Member
PICAXE to X1 does 32 bit math. been discussed before.

From a previous post of mine (not the only one on the subject)

word variables actually work in a similar manner but are a bit harder to sort out.

i.e. the intermediate result of two word calculations (16 bit) is 32 bit. However as there is no direct access to this 32 bit intermediate result, the upper and lower parts are stored into separate places but can be retrieved.
The calculation has to proceed in two separate 16 bit portions which can be combined again at the end.

So PICAXE does do 32 bit math!

See Manual 2 (varaibles - mathematics), and, discussions in these threads;
http://www.picaxeforum.co.uk/showthread.php?t=8624

http://www.picaxeforum.co.uk/showthread.php?t=10165
__________________
BCJ
 

BeanieBots

Moderator
The uFPU probably would help but would be serious overkill for an app such this. The title is "simple...".

In reallity, again applying to this app, the resolution does not need to be very high. A very quick glance at a moving coil meter in a moving and vibrating vehical does not warrant such accuracy in practice.

However, the code posted by Jeremy for 32 bit maths would solve the issue if it really is required.
 

westaust55

Moderator
Alternative Maths

@BB,

try this:

Axefactr = BatterySize / 64 + 1 ; Battery size in mAh
temp = BatterySize / Axefactr
MeterReading = Capacity / Axefactr * FSD / temp

Will still incur some error due to PICAXE integer maths

Axefactr can be a byte variable for batteries up to 16Ah then need to change to a word variable to handle bigger batteries (lmax is 65Ah)

If the value of FSD is bigger than 1023 then the "64" in the maths for the variable Axefactr needs to change ( = 65535/FSD)
 
Last edited:
Top