Activity Charging The Batteries

In this experiment, we'll be charging our two AAA NiCad batteries. The battery's fully charged "operating" voltage is 2.4 volts when the two batteries are connected in series. The key word here is "operating", since this is the voltage that the batteries should be at immediately after a full charge to provide power to a "load". In this case our load is a small DC motor-fan. The purpose of our battery charger circuit and PBASIC program is to charge the batteries until they are at full capacity, which will actually cause the battery voltage to go beyond the 2.4 volt level, but not overcharge them. For now, let's get to the state where the batteries are charging and the Green LED is flashing.

V If BatteryCharger.bs2 isn't running, re-run the program.

V Note the COM port being used, then close the Debug Terminal.

V Open StampPlot Pro by clicking on Start ^ Programs ^ Parallax Inc ^ StampPlot ^ Experiments with Renewable Energy ^ sic_ewre_exp_1.spm.

V Set the COM port in StampPlot to the same one that was being used by the Debug Terminal.

V Click on the Connect button, and make sure the Enable Plotting box is checked.

V Press the Reset button until the Green LED is flashing.

Your StampPlot plot will look something like the one below. As the batteries charge, you will observe the blue plot, BV, or battery voltage, rising.

rilBlJj^l * gg IT -H^Fia +I-IEIHIW VI - IraiB'VBl Jl

rilBlJj^l * gg IT -H^Fia +I-IEIHIW VI - IraiB'VBl Jl

BCI BV BUI BLV

BCI BV BUI BLV

||||iimTm il ïiM^rfi» Ta* IÀ 'f fÛ" îttfittMTM

Figure 2-6: Plot of Programmable Battery Charger No-Load Voltage Output

||||iimTm il ïiM^rfi» Ta* IÀ 'f fÛ" îttfittMTM

Figure 2-6: Plot of Programmable Battery Charger No-Load Voltage Output

While the batteries are charging, let's take a look at how the programmable battery charger works.

Exp_1_Charge:

IF (doneCharging = True) THEN GOTO Exp_1_End

HIGH ChargeBatt LOW DrainBatt TOGGLE ChargeLed LOW DrainLED LOW ReplayLED

The first line of code checks the doneCharging flag. If it's True, the program simply exits. Otherwise, a high ChargeBatt activates Charge transistor circuit, which allows current to begin flowing into the batteries (refer to Figure 2-3). Correspondingly, the low DrainBatt deactivates the Discharge transistor circuit, disabling the batteries to drain or discharge. The toggle instruction causes the green charge LED to flash each time through this part of the subroutine. And finally, the last two instructions deactivate the other two LEDs. Now to the next group of instructions...

a2dMuxId = a2dMuxId3 GOSUB A2D

ch3 = (255-a2dResult) avgCurrent = avgCurrent+ch3

a2dMuxId = a2dMuxId2 GOSUB A2D ch2 = a2dResult avgVolts = avgVolts+ch2

IF (ch2 > BattFullChg) AND (dataPtr <10 ) THEN doneCharging = True HIGH ChargeLed LOW ChargeBatt ENDIF

counter = counter - 1 IF counter <> 0 THEN Exp_1_End

The first two instructions set the A/D Converter channel to ch3 and then take a voltage sample. While still a voltage sample, this is actually a measure of BCI, the battery charge current, based on the voltage drop across the 10 Q resistor connected to Vdd. The voltage drop across this resistor is the difference between Vdd, which is 5.00 volts (or 255 as it would be measured by the A/D converter) minus the sampled voltage (a2dResult). The third instruction computes this result and sets ch3 equal to it. The StampPlot macro further adjusts this voltage reading to the equivalent current value. Finally, the fourth instruction adds the value of ch3 to the avgCurrent. Recall that avgCurrent and avgVolts, coming up next, were both initialized to zero in the Exp_1_init subroutine, so we're starting off our averaging cycle with a clean slate.

The next four instructions sample the battery voltage directly and store the result to avgVolts, with A/D channel ch2 displayed as BV, or battery voltage, on StampPlot.

Following this, the if statement is placed here to protect from overcharging the batteries by comparing the current battery voltage to the value of BattFullChg (con 150 or 3.00 volts). However, this event must occur early in the charging cycle when dataPtr is less than 10. Or said another way, this event must occur within the first 256 seconds of the charge cycle. You'll see what we mean shortly. And setting codePtr=2 will cause the branch instruction to jump to the Exp_1_Drain subroutine the next time through.

The following instruction decrements the averaging counter (counter), which was initialized to zero in Exp_1_init. If this is the first time through this subroutine from power on or reset, the counter value will be 255, since decrementing a byte set to zero causes the value to "roll over" to 255. Therefore, it will take another 255 decrements until the counter value is again zero. And this will take just over 64 seconds.

Why?

Because every time we exit from this routine via Exp_1_End, the program returns to Main and eventually winds up calling (gosub) the Plot_it routine where there is a 250-millisecond delay (pause 2 5 0). So by multiplying 256 counter states times 250 milliseconds per state, the result comes out as 64 seconds. The reason it takes slightly longer than 64 seconds is because the Main routine must also call the other four routines (Exp_2 through Exp_5) before it calls the Plot_it routine. And since the other four routines just have return instructions at this time, the extra time is quite short. There is also a slight time delay within this routine, as well; that is, from the branch instruction to Exp_1_charge and then to the test for counter <> 0 where the jump is made to Exp_1_End. However, after 256 passes though Exp_1_charge, counter will again equal zero and the program will fall through to the code below.

WRITE dataPtr,avgVolts.HIGHBYTE dataPtr = dataPtr+1

WRITE dataPtr,avgCurrent.HIGHBYTE dataPtr = dataPtr+1

' IF avgVolts.HIGHBYTE > maxVolts THEN maxVolts=avgVolts.HIGHBYTE ' IF avgVolts.HIGHBYTE =< maxVolts-10 THEN codePtr=2:GOTO Exp_1_End avgVolts = 0 avgCurrent = 0

IF (dataPtr = DataPtrMax) THEN doneCharging = True HIGH ChargeLed LOW ChargeBatt ENDIF

GOTO Exp_1_End

The first instruction writes the "average" value of the current samples (avgCurrent.HIGHBYTE) to EEPROM at the current dataPtr. Then the dataPtr is incremented and the third instruction writes the "average" value of the battery voltage (avgVoits.HiGHBYTE) to EEPROM, followed by the dataPtr being incremented again. However, one might ask at this point why avgCurrent.HIGHBYTE and avgVoits.HiGHBYTE are the "average" of these values. Remember, avgcurrent and avgVolts are both 16-bit words, and we have been adding 8-bit bytes to them 256 times. So to get an average value, one would normally divide avgcurrent and avgVolts by 256. We could have done this, however it would have required two unnecessary divide instructions. Instead, we decided to use another programming trick and simply use the high byte of avgcurrent and avgVoits as the average. We know this will work because the average value of all 256 samples will appear in the upper (high) byte of the word. We will lose the remainder of the average, however this is not important to us since our average values must fit into the limits of an 8-bit byte such as ch3 and ch2 so that it can be displayed on StampPlot. If you're still not convinced, try adding up 256 byte values in hexadecimal and then see what the high byte comes to. Another neat programming trick!

Now back to the remainder of the charging part of the code.

Immediately following the writes to EEPROM, the next two instructions are "commented out".

' IF avgVolts.HIGHBYTE > maxVolts THEN maxVolts = avgVolts.HIGHBYTE ' IF avgVolts.HIGHBYTE =< maxVolts - 10 THEN codePtr=2:GOTO Exp_1_End

We did this intentionally since the code would have ended our charging cycle prematurely. Instead, we want to charge our batteries on a purely timed basis at first, and then uncomment these two lines of code when we know things are working as planned. We'll do this towards the end of this experiment.

The next two lines of code clear the aveCurrent and aveVolts for the next 256 samples, and the if...then statement checks dataPtr against DataPtrMax. If equal then doneCharging is set True along with the ChargeLed being constantly set to HIGH and the ChargeBatt pin set to low. Then the routine then exits to the Main loop again.

The final lines of code for the charge routine simply clear the avgCurrent and avgVolts for the next 256 samples. Then dataPtr is tested for maximum. If it is at our predefined DataPtrMax value, then codePtr is set to 2 so that the program will branch to Exp_1_Drain the next time through. Otherwise, codePtr is left where it's at (codePtr=1) and the program will once again branch to Exp_1_Charge.

Let's take a look at a sample plot of the charging cycle as illustrated in Figure 2-7 below.

Figure 2-7: Plot of Entire Battery Charge Cycle, with Adjusted Time Scale

This particular plot took almost four hours to generate, so the time scale was expanded to accommodate the necessary time (note the time axis at the bottom of the plot). As you can see, the battery voltage climbs from its normal 2.40 volt value to over 3.00 volts and then drops down again slightly. This is the normal charge cycle, and the voltage "hump" above the 3.00 volt level can be used to detect when the charge cycle is complete. In the code thus far we have purposely ignored detecting this "hump" and have, instead, opted for a timed charge cycle, exclusively. And we did this for a reason; that is, to portray the entire charge cycle without overcharging the batteries and, also, to determine just how an "end of charge" program could be done. This was done by your author with some amount of trial but, fortunately, no error. The time it takes to generate this charge cycle is based partly on the counter variable, the dataPtr variable as well as the 250-millisecond delay in the Plot_It routine. Here's how to compute the timed charge cycle:

• 256 counts (counter) x .25 s/count (Plot_It) x 200 (dataPtr) = 12,800 s

Also recall from a few sentences ago the "commented out" code. These two lines of code can be used to detect when the charge cycle is complete. Keep them commented out for now and we'll uncomment them near the end of the experiment.

DIY Battery Repair

DIY Battery Repair

You can now recondition your old batteries at home and bring them back to 100 percent of their working condition. This guide will enable you to revive All NiCd batteries regardless of brand and battery volt. It will give you the required information on how to re-energize and revive your NiCd batteries through the RVD process, charging method and charging guidelines.

Get My Free Ebook


Post a comment