Need some help CALIBRATING RCTime results for 12V SLA battery monitor circuit
DavidM
Posts: 630
Hi,
I have an RCTime circuit, using an 18NF Green cap & a 680K resistor to do RCTime to measure the voltage of a 12V SLA battery.
I am very close but i cant seem to work out from the data that I am getting, how to "CALIBRATE" or work out some king of formula to scale the RCTime data to REAL voltages I am measuring.
its the last 3 lines of code ( the TEMP variable adjustments) that i need to sort out. everything else is OK and working.
I am using an ADJUSTBLE LAB POWER SUPPLY , so i can dial in any voltage I want to. I have the debugger running ( elsewhere) to view the results on my PC monitor.
the return voltage FORMAT is for example "125" for 12.5 volts
Here is the code that I am currently using..
Sample results ( showing VOLTAGE IN, RCTime result and difference +/-)
16.0V = 155 -5
14.0V = 140
13.5V = 136 +1
13.0V = 131 +1
12.5V = 126 +1
12.0V = 120
11.5V = 114 -1
11.0V = 108 -2
10.5V = 100 -5
10.0V = 93 -7
9.5V = 83 -12
9.0V = 72 -18
8.5V = 62 -23
8.0V = 48 -32
as you can see my results between 14.0v and about 11.0v is almost spot on, But i believe a 12v SLA battery gets "LOW" below 11v and this is where my RCTIME values start to drift off, dont ask me why the result for 16V goes the other way?????
So,
Can anyone help with how I can calibrate this. NOTE: I do not want to use a LOOKUP TABLE that would be cheating! .
Regards
Dave M
I have an RCTime circuit, using an 18NF Green cap & a 680K resistor to do RCTime to measure the voltage of a 12V SLA battery.
I am very close but i cant seem to work out from the data that I am getting, how to "CALIBRATE" or work out some king of formula to scale the RCTime data to REAL voltages I am measuring.
its the last 3 lines of code ( the TEMP variable adjustments) that i need to sort out. everything else is OK and working.
I am using an ADJUSTBLE LAB POWER SUPPLY , so i can dial in any voltage I want to. I have the debugger running ( elsewhere) to view the results on my PC monitor.
the return voltage FORMAT is for example "125" for 12.5 volts
Here is the code that I am currently using..
PRI GetVoltage: BatteryVoltage | Temp Temp := 0 'Initialise Temp DIRA[noparse][[/noparse]BatteryPin] := 1 'Make CAP pin an OUTPUT OUTA[noparse][[/noparse]BatteryPin] := 0 'Set CAP pin LOW to CHARGE capacitor WAITCNT(CLKFREQ/500+CNT) 'PAUSE for 2ms DIRA[noparse][[/noparse]BatteryPin] := 0 'Make CAP pin an INPUT to Discharge the CAP Temp := CNT 'TRAP the current Time in Temp WAITPEQ( |<BatteryPin, |<BatteryPin , 0 ) 'WAIT until a change occurs on CAP pin Temp := || ( CNT - Temp ) 'Calculate the time LAPSED Temp := 1_000_000 - Temp 'Invert the value Temp := Temp / 1000 'get rid of some precision Temp := Temp - 752 'adjust to suit values ?????? BatteryVoltage := Temp RETURN BatteryVoltage
Sample results ( showing VOLTAGE IN, RCTime result and difference +/-)
16.0V = 155 -5
14.0V = 140
13.5V = 136 +1
13.0V = 131 +1
12.5V = 126 +1
12.0V = 120
11.5V = 114 -1
11.0V = 108 -2
10.5V = 100 -5
10.0V = 93 -7
9.5V = 83 -12
9.0V = 72 -18
8.5V = 62 -23
8.0V = 48 -32
as you can see my results between 14.0v and about 11.0v is almost spot on, But i believe a 12v SLA battery gets "LOW" below 11v and this is where my RCTIME values start to drift off, dont ask me why the result for 16V goes the other way?????
So,
Can anyone help with how I can calibrate this. NOTE: I do not want to use a LOOKUP TABLE that would be cheating! .
Regards
Dave M
Comments
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
So How do I "CORRECT" this? the use of an ADC in this case is NOT an option.
Thanks
Dave M
After messing around on the site·I found a relatively simple equation thats a decent fit:
y = 1.0 / (a + bx + cx2)
where
a =· 1.5180026697294174E-01
b = -5.4288518673659548E-04
c = -2.1622767946101787E-07
x is the·pulse width·and y is the voltage
Not much help unless you plan on including the floating point library. But you can use the equation to generate a lookup table to provide a quick conversion from pulse width to voltage. I would use offseted integers to represent the voltage, say x100 so 12.52V is stored as 1252.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 9/21/2008 10:45:35 AM GMT
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
This seems to be getting a bit complicated, would using a larger capacitor value make for a more linear values ?
thanks
Dave M
The technique you're using to measure voltage is inherently non-linear.
You want a specific accuracy over a voltage range that's not achievable
without compensating for the non-linearity.
in is input value
in -= 48 ' remove smallest value
lsb2 := in & 3 ' save lsb 2 bits
in >>= 2 'remove 2 bits from lookup
in := table[noparse][[/noparse]in]
in += lsb2 ' add interopolation
this gives a small 32 byte table. You can proabably just hand pick the table values rather than calculating them.
I have tried something similar to what you did with a rctime but found the results varied too much dependant on temperature and other variables.
finding a fitting function can be done with Office-software too.
In Mixrosoft-Excel and in openOffice there is a diagramtype called "XY-Diagramm"
see attached screenshot
Inside the options you can add a regression function
You can choose from different function-types as linear, logarithmic, exponential, potentional
The value R^2 is some kind of an indicator how good the regression-function does fit with
the explizit given values
use the regessionfunction to create two columm of X-Y-Data with a constant stepwidth
next thing is to create a lookuptable with values fom the regression-function
best regards
Stefan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
If that is the case, a better formula for the inverse RCTime would be:
The reason is that when you model the RC circuit, it looks like a pretty good current source when the battery voltage is much greater than the 1.65 volt Prop threshold (as it is here), and if it were a perfect current source the time would bes directly proportional to K/Temp. This is not a perfect current source, more like the inverse polynomial that Paul posted above, but the cx^2 term may (probably) be neglected. A simple procedure can find the two constants K1 and K2 based on two measurements. I have a BS2 article on the calibration procedure here.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
thnaks everyone for the input,
To Erik Friesen, I already have my circuit boards made, in the future I may do this the way you suggested, but I am stuck with RC Time method for now.
To Paul Baker, It was late at night, so anything to me at that time was going to be complicated, no offence
to Tracy Allen, Yes that the way I have it, I got the idea from your website.
Your idea is that I need to work out the 2 constants and then use your code.
Temp := K1 / Temp + K2
so according to your website is this what I use??
V1: HIGH voltage applied to circuit
RCT1: corresponding raw RCtime value
V2: LOW voltage applied to circuit
RCT2: corresponding raw RCtime value
K1 = 10 * (V1 - V2) * ( RCT1 * RCT2 ) / ( RCT2 - RCT1 )
K2 = 10 * V1 - ( K1 / RCT1)
The spin code should be then,,
BatteryVoltage := K1 / Temp + K2
I will try this out
Thnaks to all
regards
Dave M
For some reason I NOW GET EXACT RESULTS accurate to about 1 tenth of a volt ( +/- 0.1v) with the following code..
PRI GetVoltage: BatteryVoltage | Temp
Temp := 0 'Initialise Temp
DIRA[noparse][[/noparse]BatteryPin] := 1 'Make CAP pin an OUTPUT
OUTA[noparse][[/noparse]BatteryPin] := 0 'Set CAP pin LOW to CHARGE capacitor
WAITCNT(CLKFREQ/500+CNT) 'PAUSE for 2ms
DIRA[noparse][[/noparse]BatteryPin] := 0 'Make CAP pin an INPUT to Discharge the CAP
Temp := CNT 'TRAP the current Time in Temp
WAITPEQ( |<BatteryPin, |<BatteryPin , 0 ) 'WAIT until a change occurs on CAP pin
Temp := || ( CNT-Temp) 'Calculate the time LAPSED
Temp:= 15500 / ( Temp / 1000 )
BatteryVoltage := Temp + (( 100 - Temp ) / 9 )
RETURN BatteryVoltage
I have tested this between 5.5volts up to 16.0 volts well within the range I need to check out my 12V SLA battery level.
I dont know why this works but it does
Thanks
Dave M
That math reduces by collecting terms to,
Temp := || ( CNT-Temp) 'Calculate the time LAPSED
BatteryVoltage := 13777778 / Temp + 11
When I plug the values from your first post into my calibration formulas, the ones you set out two posts back, I come up with,
BatteryVoltage := 14527241 / temp + 4
or
BatteryVoltage := 14527241 / (temp/10) + 38 ' one more decimal digit, xx.xx at reference points
That using 16.0=V1 and 10.0=V2 and 93000=RCT1 and 151000=RCT2 as the reference points. (back calculated RCT=CNT-CNT values, some loss of precision)
The Prop allows those nice big 32 bit integers!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
When I tried to use the formulas you suggested I must have "Stuffed-up" my caculation because my results came out nothing like yours, but..
I did come up with my own formula that gives me greate results, check my last post before this one..
did you have a look at this new formula?
regards
Dave M
Thank you for referring my site! Don't forget that the actual curvefitting source code is available at
http://code.google.com/p/pythonequations/downloads/list
if you'd like to use it.
James Phillips
http://zunzun.com