At the moment, the mechanism for switching between saturation and float is relatively simple. A counter ticks steadily upwards or downwards depending on whether the PWM duty cycle is at 100% or not. At each end of the range of this counter, the mode (saturation or float) is changed.
This technique works reasonably well and is simple to implement, but it doesn’t very accurately model what is happening inside the battery. We need to model the charging process more closely to determine when to switch between saturation and float charge modes.
Let’s assume that the battery is at equilibrium between 13.0 and 13.5 volts. Within this band it is neither charging nor discharging. Above this range, the battery is taking in charge and we must let our timer migrate toward the point where we switch to the float charge phase. At higher voltages, the timer can count more quickly.
The purpose of the charge controller is to fill the battery with charge as quickly as possible without causing any damage.
Letting the battery voltage rise to 13.5 volts, then holding it there using PWM is fine, but the battery saturates (fills with charge) slowly. Allowing the voltage to rise initially to 14.4 volts, then dropping back to 13.5 volts once the battery is full, speeds up the process. The battery should not be held at 14.4 volts indefinitely, nor should it be allowed to rise above 14.4 volts at any time.
So how do we know when the battery is fully charged? One method is to monitor current flow into the battery. During the saturation charge phase, the voltage is held at a constant 14.4 volts, but the current required to keep the voltage constant, gradually reduces. The reduction in current is not linear, but decays exponentially until a steady state current flow is reached.
We can’t measure current directly, but we can see it change by monitoring either PWM duty cycle change, or variations in the difference between voltage measurements taken when the FET is off and those when it is on.
A simpler, though less accurate approach is to use a timer. We can permit saturation charging at 14.4 volts for a number of minutes, then switch to float charging at 13.5 volts. However, the timer needs to be sophisticated enough to operate correctly regardless of external influences.
One such external influence is the grid-tied inverter. This device kicks in once the solar panel reaches about 14.2 volts, effectively preventing the battery ever going above this point. If the timer starts operating at 14.4 volts, it will fail to increment and the battery will be held at a high voltage for too long.
One approach would be to increment the timer slowly at voltages a little above 13.5 volts and more rapidly at voltages higher than this.
At the moment, battery voltage measurements are not synchronised to the 122Hz PWM switching frequency. In fact, an analogue to digital conversion is carried out just as soon as the previous conversion is completed. This results in dozens of samples being taken throughout the PWM cycle.
In the current firmware version, these voltage samples are written to a 16-byte FIFO (first in first out) buffer and processed to determine the highest and lowest values. The mean value of the last 16 samples is calculated and the last value sored is compared with this. It’s a complex (and time consuming) way of determining whether the voltage reading was taken with the FET on or off.
The point of all this is to try and circumvent an inherent problem with battery voltage measurement. When the FET is switched on, voltage measurement will be innacurate. The more current that’s flowing from the solar panel into the battery, the more innacurate the voltage measurement will be. This is because a significant voltage (or potential difference) can exist in the wire connecting the battery to the charge controller (the red wire).
The data processing described above attempts to differentiate between measurements taken when the FET is on, from thos taken when the FET is off. But is’t all a bit haphazard and the processing algorithm takes a lot of CPU time.
There is an alternative mechanism, but it will require a considerable number of changes to the firmware including a switch to ‘active low’ PWM mode and possible use of interrupts.
The idea is to take one voltage measurement during each PWM cycle, so that’s 122 measurements per second. The measurement would be taken immediately after the FET turns off, so that the measurement is accurate. During bulk charge the FET is always on, so a tiny measurement window would have to be introduced during which the FET is turned off. This might be 1% of the 8.2ms PWM period, performed once every 5 seconds.
The issues are:
The Timer2 interrupt flag is set when TMR2 is equal to PR2. This is the point at which the PWM output pin goes high. This is the wrong way round for accurate voltage measurement, but can be fixed by putting the PWM hardware into active-low mode.
The voltage measurement must be taken immediately and consistently after the FET switches off. This may require the use of the interrupt structure.
ADC conversion takes 10 clock cycles. That’s 20us at 500kHz clock frequency. The interrupt response will add a few more microseconds. The PWM period is 8.2ms (8,200us) made up of 256 lots of 32us. So theoretically, all duty cycle values below 255 would allow enough time to take a voltage measurement. It may be sensible to allow 64us.
Sequence of work:
- Subroutine out the data analysis code
- Switch to active-low PWM mode
- Enable interrupt on Timer2
- Define a mode flag for accurate/innaccurate
- Build a mechanism for periodic accurate voltage measurement
There is a silver lining here. During bulk charge (PWM at 100%), accurate voltage measurements are only needed for display purposes, so we can get away with doing this infrequently (once every 5 seconds is enough). The feedback control loop is not operating in bulk charge mode.
In PWM mode, accurate voltage measurements are needed every 8.2ms to keep the control loop stable. Unless the duty cycle is at 254 or 255 (which is almost never) accurate voltage measurements will be possible. Serendipity on our side!
This is the finished PWM5 Solar Charge Controller. Finished in the sense that this is how the product will finally look.
Also finished in terms of the circuitry, there are no further changes that I want to make. I consider this to be version 1.0.
As far as the firmware goes, I think I’ll have one more major programming session
The prototypes are ready - 3 of them, in their glossy black heatshrink covers - all looking good.
Now what’s needed is a small self-adhesive vinyl label which I can stick on the front to give the charge controller a really professional look. Fortunately, I know a bloke who’s got a machine that can both print the labels and cut rounded corners and a small hole for the LED.

PWM5 Label
So let’s have a go at a design! OK so it’s a bit of a mess, but he’s a graphic designer, so he’ll make it look the business.
The device is called the PWM5. The number 5 loosely relates to the 4.8 amp maximum current rating. The 1H01F0 means hardware version 1.0, firmware version 1.0 - the prototypes are actually 1H00F9 versions. The CE and wheelie bin logos will be put on the front too.
The 6mm hole is 3.8mm right of centre as this is 0.15 of an inch, the position of the LED relative to the centre of the PCB. Overall dimensions of the label are 30mm by 26mm.
For the packaging, I’m thinking of going for a retro look; a polyethene bag with a card label folded and stapled to the top. Also, I’ll need an instruction leaflet printed and inserted into the packaging.
I might even put Made in England on the label. I wonder if there’s a trade association for cottage industries in the UK.
I’m making up a small number of pre-production prototypes so I can test various configurations of multiple charge controllers. These will be:
- One solar panel, two charge controllers, two batteries - this was suggested by a boat enthusiast who wants to use a single solar panel to keep two batteries (used for different purposes) topped up.
- Two solar panels, two charge controllers, one battery - both panels in parallel would exceed the maximum current rating of the charge controller, so two would be used, one per panel.
- One solar panel, one charge controller, one battery and a grid tie inverter - surplus power from the panel would be diverted to the grid tie inverter once the battery is fully charged.

MOSFET and Protection Components
Here is the MOSFET circuit including protection and EMC related components.
Firstly that innocuous looking 10k resistor connected to the gate of the IRFZ44N MOSFET. This component makes a huge difference to the amount of RFI (Radio Frequency Interference) that the charge controller generates. Together with the FETs own gate capacitance, it slightly increases the rise and fall times as the FET switches from on to off and back again. This damps out the ringing at these switching transitions which is responsible for RFI generation. It’s highly effective; without it, an AM radio picks up the 122Hz switching tone easily, and at some distance. With the resistor, it’s very hard to pick up any signal at all, even with the radio pressed against the controller and/or its cables.
EMC regulations also require that the controller is not susceptible to interference from other sources. These would include motor vehicle engines, transmissions from police radios and the like, and noise spikes from lightning strikes. The P6KE30CE bidirectional transient suppression diode will absorb any spikes over 30 volts with an instantaneuos power of up to 600 watts. The bidirectional nature of this component works well with the reverse polarity protection that the controller offers.
Finally the TSR845 Schottky diode. This is purely for protection of the charge controller against shorting the solar panel connections while the controller is connected to a battery. Without this diode, the controller would be rapidly destroyed under such conditions. This component is a necessary inconvenience; it would be better if it weren’t needed at all. I’ve selected an advanced component with very low forward voltage and high current handling to minimise its impact.
These two diodes aren’t cheap, but for the protection and EMC compatibility they offer, are a necessary investment.
- Printed Circuit Board
- Microcontroller PIC 12F683
- MOSFET IRFZ44N
- LED blue 5mm
- Voltage Regulator 5v TSC2950-50
- Transistor 2N3904
- Transistor 2N3906 (x2)
- Diode 1N4007
- Diode 1N4148 (x4)
- Schottky Diode TSR845
- Transient suppression diode 1.5KE36CA
- Zener Diode 9.1v (selected for 0.5% accuracy)
- Resistor 220k 0.4W (x3)
- Resistor 10k 0.4W
- Resistor 220R
- Resistor 200k 1%
- Resistor 56k 1%
- Capacitor 1uF tantalum (x3)
- Capacitor 100nF
- Capacitor 47nF (x2)
- Capacitor 6.8nF
- Cable 14A red (250mm)
- Cable 14A yellow (250mm)
- Cable 14A black (250mm x2)
- Heat shrink red 3.2mm dia (15mm)
- Heat shrink yellow 3.2mm dia (15mm)
- Heat shrink yellow 4.8mm dia (50mm)
- Heat shrink black 3.2mm dia (15mm x2)
- Heat shrink clear 38.1mm dia (60mm)
- Heat shrink gloss black 38.1mm dia (70mm)
- Crimp butt connector blue (x2)
- EVA glue stick (30mm approx)
- Label (self-adhesive vinyl)
- Packaging
- Instruction leaflet
While I was looking for a solution to the EMC issue, I thought about turning the regular 122Hz PWM frequency into something more like white noise. The idea was to spread the spectrum of the emmited radiation so that at any one frequency, the signal would be weaker.
It didn’t work. The intended effect was minimal, and it played havoc with the feedback control loop, so the idea has been abandoned. However, it was an interesting exercise and the coding turned out to be remarkably simple.
The PIC 12F683 has a register called PR2 which is used to set the PWM frequency. However, it also affects PWM resolution, so I made the decision to set it to its maximum value, FF hex. This results in a very limited choice of PWM frequencies, 30.5Hz, 122Hz and 488Hz as Timer 2 has a rather coarse prescaler. Nevertheless, 122Hz felt about right, so the decision stood.
The spread spectrum idea would work by randomly altering the value of PR2 between 80 and FF hex on every cycle of the PWM. But how do you generate random numbers in PIC assembly language?
I vaguely remembered that shift registers could be used to generate random numbers and that this technique had been used in some synthesisers to generate white noise. Perhaps it could replace the annoying tone being picked up on my AM radio with a pleasant rushing sound.

Fibonacci Linear Feedback Shift Register
Wikipedia soon came up with the Linear Feedback Shift Register (LFSR) as the solution, and when I saw the word Fibonacci, that was it, my subroutine got that exotic name! All I had to do was Exclusive OR bits 6 and 5 of PR2 together and feed the result into bit zero as the register was shifted left. In addition, bit 7 had to remain set.
The first problem is that PIC Exclusive ORs don’t work like in the diagram. There’s no instruction to Exclusive OR two different bits of the same register. That’s solved by rotating PR2 left and putting the result into W, then exclusive ORing W with the unaffected PR2, like this:
rlf PR2,w
xorwf PR2,w
Now we have to take the result of the Exclusive OR and feed it into bit zero as we shift PR2 to the left. That requires that we copy bit 6 of W into the carry flag. This turned out to be relatively simple.
First, all bits in W other than bit 6 must be cleared. Then bit 6 needs to be copied to the carry flag, like this:
andlw 0×40
addlw 0xFF
Now PR2 can be shifted left and bit 7 set, like this:
rlf PR2,f
bsf PR2,7
And that’s it! Six instructions. PR2 is in the high bank, so we need a couple of ‘banksel’ instructions, and to make it a subroutine a ‘return’ is needed.
Amazingly, it worked first time, and on the AM radio white noise instead of that piercing 122Hz tone. This apparently simple process generates all 127 binary values in a pseudo random sequence.
But the flaws were soon apparent. White noise, sure, but no actual reduction in radio frequency interference. No spreading of the spectrum, just a different sound carried by the carrier. Not to mention the effect that modulating PR2 was having on the battery voltage feedback control loop.
It was a case of ‘nice solution, wrong problem’.
Electromagnetic Compatibility. This one has kept me busy recently.
At some point I’m going to have to address the issue of CE marking. That’s the little logo that electronic devices must have if they’re to be sold in the EEC. Two of the directives are of interest; the Low Voltage Directive and the EMC Directive.
Fortunately the Low Voltage Directive doesn’t apply to devices that won’t see more than 75 volts DC. The EMC Directive, however, definitely does apply. It states that the device musn’t interfere with other electrical devices and shouldn’t be susceptible to interference from other devices (or words to that effect).
There’s a lot to this subject, a lot to read and much to understand. But it got me thinking. What sort of interference is the charge controller chucking out? Best way to find out; an AM radio.
Ouch, it was pretty noisy. What to do? Compare it with the charge controller I bought. That was noisy too and it has a CE logo. I think we can do better.
First I tried a snubber. A capacitor and resistor in series connected across the switch contacts (the FET drain and source pins). Nothing. Absolutely nothing dispite trying a wide range of capacitances and variable resistors.
Then a crazy thought. What if I modulate the PWM frequency with a random number generator. Actually quite easy to do, but not very effective.
Finally I noticed a commercial SMPS chip featured slow rise and fall times to minimise RFI when driving MOSFETS. Let’s give that a try. Just one resistor in series with the FET gate did the trick (the gate itself being a capacitor of course).
There must have been ringing on each edge of the FET signal which my gate resistor effectively snubs out. Very effective too, just 1 metre up cable from the controller no interference at all (radio right against solar panel cable). I am confident this will fulfil the EMC requirements.