User Tools

Site Tools


mmbasic_original:battery_capacity_test

Battery Capacity Test

battery.gif battery2.pdf

This module is part of the original MMBasic library. It is reproduced here with kind permission of Hugh Buckle and Geoff Graham. Be aware it may reference functionality which has changed or is deprecated in the latest versions of MMBasic.

BATTERY.BAS

100 ' BATTERY.BAS
105 ' Program to test the capacity of a battery
110 ' See Silicon Chip May 2011 for circuit details
115 ' V1.0
120 '
125 '
130 ' Measured resistance of the four load resistors
135 ' These are constant values determined by measuring the actual resistance
140 ' with a digital multimeter.  They must be in descending order of values
145 R1 = 56.00
150 R2 = 22.00
155 R3 =  8.20
160 R4 =  3.33
165 '
170 ' Measured value of the 3.3 volt supply
175 Vdd = 3.29
180 '
185 '
190 ' Default terminating voltage level and test current
195 TerminatingVolts = 1.0
200 TestCurrent = 120
205 '
210 '
215 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
220 ' Configure the input and output pins
225 PIN(11) = 1 : PIN(12) = 1 : PIN(13) = 1 : PIN(14) = 1
230 SETPIN 11, 9 : SETPIN 12, 9 : SETPIN 13, 9 : SETPIN 14, 9
235 SETPIN 1,1
240 '
245 '
250 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
255 ' Get the operating parameters from the user
260 ' check each response to make sure that it is within acceptable range
265 '
270 CLS : PRINT "Battery test V1.0" : PRINT
275 DO
280   INPUT "Enter the approx test current in mA (600 to 25): ", TestCurrent
285 LOOP WHILE TestCurrent < 25 OR TestCurrent > 600
290 '
295 DO
300   PRINT "Enter the terminating voltage ";
305   PRINT "(default "; FORMAT$(TerminatingVolts, "%4.2f"); "): ";
310   INPUT "", TerminatingVolts
315 LOOP WHILE TerminatingVolts < 0.5 OR TerminatingVolts > 2
320 '
325 PRINT
330 IF PIN(1) / 3.3 * Vdd < TerminatingVolts THEN
335   PRINT "To start the test place the charged battery in the holder";
340   DO : LOOP WHILE PIN(1) / 3.3 * Vdd < TerminatingVolts
345   PRINT : PRINT
350 ENDIF
355 '
360 '
365 '
370 TIME$ = "0:0:0"
375 LASTTIME$ = TIME$
380 PRINT "TIME    ", "VOLTS   ", "CURRENT", "     ACCUMULATED"
385 PRINT "========================================================"
390 '
395 '
400 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
405 ' Main test loop
410 DO
415   BattV = PIN(1) / 3.3 * Vdd              ' measure the battery voltage
420   '
425   ' Calculate the setting required to draw the test current
430   PrevTC = BattV/R1 * 1000
435   FOR i = 2 TO 15
440     TC = 0
445     IF i AND &b0001 THEN TC = TC + BattV/R1
450     IF i AND &b0010 THEN TC = TC + BattV/R2
455     IF i AND &b0100 THEN TC = TC + BattV/R3
460     IF i AND &b1000 THEN TC = TC + BattV/R4
465     TC = TC * 1000
470     IF PrevTC + (TC - PrevTC) / 2 > TestCurrent THEN EXIT FOR
475     PrevTC = TC
480   NEXT i
485   i = i - 1
490   '
495   ' Set the reed relays to draw the test current
500   PIN(11) = NOT(i AND &b0001)
505   PIN(12) = NOT(i AND &b0010)
510   PIN(13) = NOT(i AND &b0100)
515   PIN(14) = NOT(i AND &b1000)
520   '
525   mAhours = mAhours + PrevTC/3600        ' accumulate the mAH reading
530   '
535   IF RIGHT$(TIME$, 2) = "00" THEN
540     PRINT TIME$,FORMAT$(BattV, "%5.3fV  "),FORMAT$(PrevTC, "%5.1fmA  "),; 
545     PRINT FORMAT$(mAhours, "%5.0fmAH")
550   ENDIF
555   '
560   ' wait for the next second
565   DO WHILE TIME$ = LASTTIME$ : LOOP
570   LASTTIME$ = TIME$
575   '
580 LOOP WHILE BattV > TerminatingVolts
585 '
590 PIN(11) = 1 : PIN(12) = 1 : PIN(13) = 1 : PIN(14) = 1
595 '
600 '
605 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
610 ' print the summary
615 PRINT : PRINT "Test complete.  ";
620 PRINT "Battery capacity is "; FORMAT$(mAhours, "%5.0fmAH")
625 PRINT : PRINT

BATTERY2.BAS

100 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
110 ' BATTERY.BAS
120 ' Program to test the capacity of a battery
130 ' V2.0   Geoff Graham   Jan 2011
140 '
150 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
160 '
170 ' This is an extended version of the battery test program described in
180 ' the May 2011 issue of Silicon Chip.  Additional features include:
190 '  - Will draw a graph of the battery voltage on the video output
200 '  - Choice of a constant current, power or resistance type of load
210 '  - Ability to save the data in an Excel compatible file
220 '  - Optional ability to use 5 relays for a finer level of load control
230 '
240 ' See the Silicon Chip article or the accompanying PDF for circuit details
250 '
260 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
270 '
280 ' Measured resistance of the five load resistors
290 ' These are constant values determined by measuring the actual resistance
300 ' with a digital multimeter.  They must be in descending order of values
310 ' if you only have 4 relays set the value of R5 to a very low value (eg, 0.0001)
320 '
330 R1 = 59.228
340 R2 = 29.789
350 R3 = 14.944
360 R4 =  7.516
370 R5 =  3.789
380 '
390 ' Correction for any error in measuring voltage (ie. actual V / Maximite V)
400 VCorrect = 1.019
410 '
420 ' default settings
430 DefaultType$ = "C"               ' constant current
440 DefaultBLoad = 200               ' load of 200 mA or mW
445 DefaultRLoad = 25                ' resistive load 25 ohms
450 DefaultThreshold = 0.9           ' cutout voltage to stop the test
460 '
470 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
480 MaxHist = 100 * 60        ' maximum history to be saved (in minutes)
490 Dim Hist(MaxHist)         ' array for holding the history data
500 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
510 ' Program Start
520 ' The program returns to here when the test has finished
530 '
540 ' Configure the input and output pins
550 Pin(11) = 1 : Pin(12) = 1 : Pin(13) = 1 : Pin(14) = 1 : Pin(15) = 1
560 SetPin 11, 9 : SetPin 12, 9 : SetPin 13, 9 : SetPin 14, 9 : SetPin 15, 9
570 SetPin 1,1
580 '
590 HScale = 2
595 mAhours = 0
600 '
610 Pin(0) = 1 : Print : Print : Cls
620 '
630 ' Get the test parameters from the user
640 Print "Battery capacity test utility V2.0"
650 ' define constants and arrays
655 Do
660   Print
670   Print "C = Constant current drain"
680   Print "P = Constant power drain"
690   Print "R = Constant resistive load"
700   Print "Select (default is "; DefaultType$; ") ";
710   Input Type$
715   If Asc(Type$) = 0 Then Type$ = DefaultType$
720   Type$ = Left$(UCase$(Type$), 1)
725 Loop Until Type$ = "C" Or Type$ = "P" Or Type$ = "R"
730 Print
740 '
750 If Type$ = "C" Then
760   Do
770     Print "Range is 600mA to 20mA"
780     Print "Enter current drain (default is"; DefaultBLoad; ") ";
790     Input BLoad
795     If BLoad = 0 Then Bload = DefaultBLoad
800   Loop While BLoad > 600 Or BLoad < 20
810 ElseIf Type$ = "P" Then
820   Do
830     Print "Range is 750mW to 25mW"
840     Print "Enter power drain (default is"; DefaultBLoad; ") ";
850     Input BLoad
855     If BLoad = 0 Then BLoad = DefaultBLoad
860   Loop While BLoad > 750 Or BLoad < 25
870 ElseIf Type$ = "R" Then
880   Do
900     Print "Range is 60 ohms to 1.8 ohms"
910     Print "Enter resistive load (default is"; DefaultRLoad; ") ";
920     Input BLoad
925     If BLoad = 0 Then BLoad = DefaultRLoad
930   Loop While BLoad > 60 And BLoad < 1.8
960 EndIf
970 '
975 Do
980   Print
990   Print "Enter the cutoff voltage (default is "; Format$(DefaultThreshold, "%3.1f"); ") ";
995   Print "Minimum cutoff is 0.5V"
1000   Input Threshold
1005   If Threshold = 0 Then Threshold = DefaultThreshold
1010 Loop While Threshold < 0.5 Or Threshold > 1.5
1020 Print
1030 '
1040 Do
1060   Input "Save the results to an Excel file (Y/N, default is N) ", SSave$
1070   SSave$ = Left$(UCase$(SSave$), 1)
1075   If Asc(SSave$) = 0 Then SSave$ = "N"
1080 Loop While Not(SSave$ = "Y" Or SSave$ = "N")
1089 '
1090 If SSave$ = "Y" Then
1100   Line Input "Filename (without an extension): "; FName$
1110   Open Left$(FName$, 8) + ".xls" For output As #1
1120   Line Input "Description of battery under test: "; R$
1130   Print #1, R$
1140   If Type$ = "C" Then Print #1, "Constant current of"; BLoad; "mA.  Cutoff at"; Threshold; "V"
1150   If Type$ = "P" Then Print #1, "Constant power of"; BLoad; "mW.  Cutoff at"; Threshold; "V"
1160   If Type$ = "R" Then Print #1, "Constant resistance of"; BLoad; " ohms.  Cutoff at"; Threshold; "V"
1170   Print #1 : Print #1, "Time", "Voltage", "Current", "mAH"
1180 EndIf
1190 '
1200 Print
1210 Line Input "Press ENTER to start the test "; T$
1220 Pin(15) = 0 : Pause 200                ' discharge any floating voltage
1230 Do While Pin(1) * VCorrect <= Threshold
1240   Print "Battery not inserted or not charged (voltage ="; Pin(1) * VCorrect; ")"
1250   Print "Insert battery to continue ";
1260   While Pin(1) * VCorrect <= Threshold : Wend
1270   Pause 750
1280 Loop
1290 '
1300 VScale = (Int(Pin(1) * VCorrect * 10) + 2)  ' set the vertical scale
1310 iHist = 0                                   ' zero the history
1320 GoSub 2790                                  ' draw the graph axies
1330 '
1340 Time$ = "00:00:00" : LASTTIME$ = "00:00:00" ' init the starting time
1350 BattV = Pin(1) * VCorrect                   ' initialise the battery voltage
1360 VStart = BattV
1370 VAverage = 0 : AveCnt = 0
1380 '
1390 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
1400 ' Main test loop
1410 Do
1420   '
1430   If Type$ = "C" Then
1440     ' Calculate the setting required to draw the test current
1450     PrevTL = (BattV/R1) * 1000
1460     For i = 2 To 31
1470       TL = 0
1480       If i And &b00001 Then TL = TL + BattV/R1
1490       If i And &b00010 Then TL = TL + BattV/R2
1500       If i And &b00100 Then TL = TL + BattV/R3
1510       If i And &b01000 Then TL = TL + BattV/R4
1520       If i And &b10000 Then TL = TL + BattV/R5
1530       TL = TL * 1000
1540       If PrevTL + (TL - PrevTL) / 2 > BLoad Then Exit For
1550       PrevTL = TL
1560     Next i
1570   ElseIf Type$ = "P" Then
1580     ' Calculate the setting required to draw the test power
1590     PrevTL = ((BattV * BattV)/R1) * 1000
1600     For i = 2 To 31
1610       TL = 0
1620       If i And &b00001 Then TL = TL + (BattV * BattV)/R1
1630       If i And &b00010 Then TL = TL + (BattV * BattV)/R2
1640       If i And &b00100 Then TL = TL + (BattV * BattV)/R3
1650       If i And &b01000 Then TL = TL + (BattV * BattV)/R4
1660       If i And &b10000 Then TL = TL + (BattV * BattV)/R5
1670       TL = TL * 1000
1680       If PrevTL + (TL - PrevTL) / 2 > BLoad Then Exit For
1690       PrevTL = TL
1700     Next i
1710   ElseIf Type$ = "R" Then
1720     ' Calculate the setting required to draw the test resistance
1730     PrevTL = R1
1740     For i = 2 To 31
1750       TL = 100000000
1760       If i And &b00001 Then TL = (TL * R1) / (TL + R1)
1770       If i And &b00010 Then TL = (TL * R2) / (TL + R2)
1780       If i And &b00100 Then TL = (TL * R3) / (TL + R3)
1790       If i And &b01000 Then TL = (TL * R4) / (TL + R4)
1800       If i And &b10000 Then TL = (TL * R5) / (TL + R5)
1810       If PrevTL - (PrevTL - TL) / 2 < BLoad Then Exit For
1820       PrevTL = TL
1830     Next i
1840     ' print "Selected nearest value of"; PrevTL; " ohms"
1850   Else
1860    Error "Invalid Type$"
1870   EndIf
1880   '
1890   i = i - 1
1900   '
1910   ' Set the reed relays to create the test load
1920   Pin(11) = Not(i And &b00001)
1930   Pin(12) = Not(i And &b00010)
1940   Pin(13) = Not(i And &b00100)
1950   Pin(14) = Not(i And &b01000)
1960   Pin(15) = Not(i And &b10000)
1970   '
1980   ' calculate the current drain at this setting
1990   TC = 0
2000   If i And &b00001 Then TC = TC + BattV/R1
2010   If i And &b00010 Then TC = TC + BattV/R2
2020   If i And &b00100 Then TC = TC + BattV/R3
2030   If i And &b01000 Then TC = TC + BattV/R4
2040   If i And &b10000 Then TC = TC + BattV/R5
2050   TC = TC * 1000                           ' current drain in mA
2060   mAhours = mAhours + TC/3600              ' accumulate the mAH reading for each second
2070   '
2080   ' every minute update the display
2090   If Right$(Time$, 2) = "00" Then
2100     Hist(iHist) = BattV : iHist = iHist + 1
2110     If iHist > MaxHist Then GoTo 2330
2120     If iHist > HScale * 60 Then
2130       HScale = HScale + 1
2140       GoSub 2790                           ' redraw the graph scale
2150     EndIf
2160     GoSub 2660                             ' add this reading to the graph
2170     GoSub 3090                             ' print the running summary
2180   EndIf
2190   '
2200   ' wait for the next second
2210   LoopCount = 1
2220   Do While Time$ = LASTTIME$
2230     BattV = BattV + Pin(1) * VCorrect      ' while we are waiting make many measurements
2240     LoopCount = LoopCount + 1              ' count the number of measurements
2250   Loop
2260   LASTTIME$ = Time$
2270   BattV = BattV/LoopCount                  ' and average
2280   '
2290 VAverage = VAverage + BattV : AveCnt = AveCnt + 1
2300 Loop While BattV >= Threshold
2310 '
2320 ' the test has finished - remove the load
2330 Pin(11) = 1 : Pin(12) = 1 : Pin(13) = 1 : Pin(14) = 1 : Pin(15) = 1
2340 '
2350 '
2360 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
2370 ' print the summary
2380 GoSub 3090                                 ' update the running summary
2390 Print : T$ = "Test complete.  "
2400 T$ = T$ + "Battery capacity is " + Format$(mAhours, "%1.0fmAH") + " at a constant "
2410 If Type$ = "C" Then T$ = T$ + "current of" + Str$(BLoad) + "mA."
2420 If Type$ = "P" Then T$ = T$ + "power of" + Str$(BLoad) + "mW."
2430 If Type$ = "R" Then T$ = T$ + "resistance of" + Str$(BLoad) + " ohms."
2440 If SSave$ = "Y" Then Print #1 : Print #1 : Print #1, T$
2450 Print "  " + T$
2460 T$ = "Start voltage = " + Format$(VStart, "%3.2f") + ".  End voltage = " + Format$(BattV, "%3.2f")
2470 T$ = T$ + ".  Average voltage = " + Format$(VAverage/AveCnt, "%3.2f") + "."
2480 If SSave$ = "Y" Then Print #1, T$
2490 Print "    " + T$
2500 If SSave$ = "Y" Then Close #1
2510 '
2520 Print "    Press ENTER to test again or CTRL-C to quit...";
2530 Do                                          ' flash LED while waiting
2540   Pause 200 : If Inkey$ = Chr$(&H0D) Then GoTo 500
2550   Pin(0) = 0 : Pause 100 : Pin(0) = 1 : If Inkey$ = Chr$(&H0D) Then GoTo 500
2560 Loop
2570 '
2580 '
2590 '
2600 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
2610 ' SUBROUTINES
2620 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
2630 '
2640 ' Subroutine to print the trend line on the graph
2650 '
2660 For i = 1 To iHist - 1
2670   x1 = margin + (width / (HScale * 60)) * (i - 1)
2680   x2 = margin + (width / (HScale * 60)) * (i)
2690   y1 = height - ((Hist(i - 1) * 10) / VScale) * height
2700   y2 = height - ((Hist(i) * 10) / VScale) * height
2710   Line (x1, y1) - (x2, y2), 1
2720 Next i
2730 Return
2740 '
2750 '
2760 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
2770 ' Subroutine to print the graph axies
2780 '
2790 height = MM.VRes - 100 : margin = 45 : width = MM.HRes - margin - 12
2800 '
2810 Cls
2820 Line (margin,height)-(margin, 0), 1 ' Draw the vert line
2830 Line (margin,height)-(margin + width ,height), 1  ' Draw the horiz line
2840 For i = 0 To VScale                        ' This loop draws the tick marks
2850   h = height - (height / VScale) * i
2860   t = margin - 5
2870   If i Mod 5 = 0 Then                      ' Special mark for a unit of 0.1V
2880     Locate margin - 42, h - 3
2890     If h - 3 < 0 Then Locate margin - 42, 0 ' fix if we are off the screen
2900     Print Left$(Format$(i/10,"%f"),3);"V"; ' Label the tick mark
2910     t = margin - 15
2920   EndIf
2930   Line (margin, h)-(t, h), 1               ' Draw the tick mark
2940 Next i
2950 For i = 0 To HScale
2960   t = margin + (width/Hscale) * i
2970   Line (t, height)-(t, height + 9), 1
2980   If i < 10 Then Locate t - 8, height + 14 Else Locate t - 11, height + 14
2990   Print i;
3000 Next i
3010 Locate margin + width/2 - 14, height + 25
3020 Print "Hours"
3030 Return
3040 '
3050 '
3060 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
3070 ' Subroutine to print the summary data below the graph
3080 '
3090 T$ = Left$(Time$, 5) + "    " + Format$(BattV, "%5.3fV  ") + "  " + Format$(TC, "%5.1fmA  ")
3100 T$ = T$ + " " + Format$(mAhours, "%5.0fmAH")
3110 Locate margin + (width - (Len(T$) * 6)) / 2, height + 40
3120 Print t$
3130 If SSave$ = "Y" Then Print #1, (iHist - 1)/60, BattV, TC, mAhours
3140 Return
3150 '
mmbasic_original/battery_capacity_test.txt · Last modified: 2024/01/19 09:39 by 127.0.0.1