Arduino PWM solar charge controller

Arduino PWM solar charge controller

How to make very small, simple and cheap PWM solar charge controller with Arduino Pro Mini for 12V off-grid installations. The size of circuit board is the same as size of Pro Mini board, so they can be sandwiched together. PCB plans are for universal prototype board.

Arduino PWM solar charge controller circuit 4

Connection and usage of this Arduino solar charge controller is very simple – there are 2 input leads from solar panel (+ and -) and 2 output leads going to the lead acid battery. Ground of solar panel and battery is joined together. Any load should be connected directly on battery terminals and charge controller will automatically handle the rest.

Arduino PWM solar charge controller circuit

Arduino regularly measures lead acid battery voltage and according to detected value, switches the MOSFET on to charge battery from solar panel and switches MOSFET off when the battery is full. When your load pulls power from the battery, controller detects the voltage drop and immediately starts to charge battery again. During the night, when solar panel stops producing, controller waits until panel starts to output again.

Arduino PWM solar charge controller circuit 2

Arduino PWM solar charge controller circuit 3 bottom view

Positive lead to the solar panel needs Schottky protection diode placed directly on the cable (wrapped in heat-shrink tubing). It’s not included in main PCB as this makes it easier to replace it and cool down at the same time. You could easily make the board a bit longer to fit in a different type of diode.

 

Schematic & function description:

Arduino PWM solar charge controller schematic

Arduino PWM solar charge controller Pro Mini used pins

Function is based on N-Channel MOSFET IRF3205 in the high-side of circuit. This requires gate voltage higher than 12V to open the MOSFET properly. To omit the need for external MOSFET driver, it is driven by charge pump created with diodes, 2 capacitors and two Arduino PWM output pins (3 and 11). Pin A1 is measuring battery voltage and pin 9 controls MOSFET ON/OFF cycle. Arduino Pro Mini integrated LED connected to pin 13 is used to show off current PWM duty cycle.

Delete the code line analogWrite(13, 255 - pulseWidth); // pwm to LED if blinking LED bothers you too much.

Voltage Regulator and all the capacitors around (C6, C5 and C4) could possibly be excluded as there is a regulator included in the Arduino Pro Mini. However because I used cheap clone board, I am not willing to count on its ability to sustain higher voltages than 12V for longer time periods. LP2950 is very cheap and effective up to 30 Volts, so it’s worth to have it on board in any case.

 

PCB – top & bottom view:

Arduino PWM solar charge controller PCB top view parts placement

Arduino PWM solar charge controller PCB bottom view

 

Parts List:

  • Low-Power Voltage Regulator
    • LP2950ACZ-5.0
  • Transistors
    • 2N3904
    • 2N3906 x 2
  • N-channel mosfet
    • IRF3205
  • Resistors
    • 82K (1%)
    • 20K (1%)
    • 220K x3 (0,4W is enough)
    • 4K7 (0,4W is enough)
  • Diodes
    • 1N4148 x 5
    • P6KE33CA
    • 90SQ035 or any similar Schottky diode 35V minimum 9A (10A 45V from eBay: https://goo.gl/6WDnYq or 20A 45V from eBay: https://goo.gl/xUKvGu)
  • Capacitors
    • 47N/50V x2 ceramic
    • 220P/100V ceramic
    • 100nF/50V ceramic
    • 4M7/10V tantalum
    • 1M/35V tantalum x 2

Arduino code – basic version 1:

void setup() {
TCCR2A = TCCR2A | 0x30;
TCCR2B = TCCR2B & 0xF8 | 0x01;
analogWrite(11, 117);
analogWrite(3, 137);
// Serial.begin(9600);
}
 
const int setPoint = 13.5 * 20 / (20+82) * 1024 / 5;
int measurement = 0;
int pulseWidth = 0;
int difference = 0;
int stepSize = 0;
 
void loop() {
measurement = analogRead(A1);
difference = abs(setPoint - measurement);
stepSize = difference;
if (measurement < setPoint) { pulseWidth += stepSize; if (pulseWidth > 255) pulseWidth = 255;
}
if (measurement > setPoint)
{
pulseWidth -= stepSize;
if (pulseWidth < 0) pulseWidth = 0; } // Serial.println(pulseWidth); analogWrite(9, pulseWidth); analogWrite(13, 255 - pulseWidth); // pwm to LED delay(10); }

Version 1.1 code with better blinking of pin 13 integrated LED according to PWM pulses:

const int setPoint = 13.5 * 20 / (20+82) * 1024 / 5;
int measurement = 0;
int pulseWidth = 0;
int difference = 0;
int stepSize = 0;
int calculation = 0;
int led = 13;

void setup() {
TCCR2A = TCCR2A | 0x30;
TCCR2B = TCCR2B & 0xF8 | 0x01;
analogWrite(11, 117);
analogWrite(3, 137);
// Serial.begin(9600);
pinMode(led, OUTPUT);
}

void loop() {
measurement = analogRead(A1);
calculation = setPoint - measurement;
difference = abs(calculation);
stepSize = difference;

if (measurement < setPoint) { pulseWidth += stepSize; if (pulseWidth > 255) pulseWidth = 255;
analogWrite(led, 0); // pwm to LED
}
if (measurement > setPoint)
{
pulseWidth -= stepSize;
if (pulseWidth < 0) pulseWidth = 0; analogWrite(led, 255); // pwm to LED } // Serial.println(pulseWidth); analogWrite(9, pulseWidth); delay(10); }

Arduino code download: arduino-pwm-solar-charge-controller.ino
Version 1.1 code download: arduino-pwm-solar-charge-controller-v1.1.ino

Schematic and code of this charge controller is by Julian Ilett, he is the mastermind behind this clever thing. All this is just a refined documentation and a suitable PCB design to perfectly fit Arduino Pro Mini board. He is sharing videos of more effective Arduino MPPT charge controller, but its construction is much more complicated and the project is not finished yet.

If you improve the code or construction in any way, please share your improvement in the comments :-)

  1. Hi.
    How mich power may the solarpanel provide for this circuit? Is it suitable for a 100watts 12-18 volts panel?

    • Hi, 100watts panel is OK, maximum for shottky diode 90SQ035 is 150W, there will still be operational reserve. Just make sure cables soldered to mosfet leads are copper and thick enough (at least 1mm automotive cable).

  2. I have a substantial bank of batteries in an RV and am going to install solar panels. I have an Onan Gen to otherwise charge the batteries but it is manual turn on an turn off. Can a controller such as yours be added to the Gen to start it when the batteries fall below acceptable levels at (i.e. at night) and then turn it off when they reach the required voltage level – maybe through the use of a relay.?
    Thank you
    Steve Lukinuk

  3. can you design same controller with 12v 2A and which show the charging current, Voltage power, remaining charging all about this on LCD also wifi data transmit….. Reply please…..

  4. C4 is 100nF not 1000nF. Watch here: https://www.youtube.com/watch?v=MdgYXxQW0hA

  5. Hello,

    Can this charge controller to use for the solar panel 240 w/p , maximun voltage 31v and 7,8 Amp.
    Of not what must be the component to change to use this solar panel.

    Thanks
    Danbo

  6. hi,
    what modification is possible for 300w solar panel, battery 12v,
    change only 90SQ035 or more components
    big thanks,
    tornier

    • Hi, correct you need to change 90SQ035 for a stronger Schottky rectifier (35A or more – 60CIQ045, 80CPQ150 or whatever you have available) mounted on a heatsink. Mosfet is rated for 110A, can handle 300W solar panel easily but needs aluminum heatsink too.

      Here is a list of Schottky rectifiers from IRF, sortable by Amps:

      http://www.irf.com/product/HiRel-Products-HiRel-Schottkys-Rectifiers-HiRel-Schottkys/_/N~1nje2p

  7. Hello.

    Many thanks for the work you’ve done in laying out the components in such a clever way. I’ve put it together and it works brilliantly. I’ve popped a video up on youtube with thanks to you and Julian Ilett for your hard work!

    https://youtu.be/db1JZUecYlI

  8. Lambros frantzeskakis November 27, 2015 at 5:14 pm

    can we change the mosfet with a logic level mosfet ?the circuit will became a lot easier .. I believe we can :-) and also for the voltage regulator we can use an lm317 .. it’s also easier to find . For current mesurement and data export we can make a new version

  9. hy frnds an i use this circut for a 150 watt panel where short crcut current is 9.08 ampere , is it charge the battery safly and prevent the overchargng and reverse chargng or not

  10. is P6KE33CA Diodes is necessary ??

    • It’s there to protect mosfet and voltage regulator in case of voltage spike from solar panel. Not really necessary, but its cheap and it will ensure long life cycle of charge controller.

  11. Can I use this code for arduino uno or arduino nano or arduino Leonardo pro micro?

  12. hi Julian quick question would you be able to explain where each of these values came from just cant figure out where they came from:

    const int setPoint = 13.5 * 20 / (20+82) * 1024 / 5;

    thank you ryan

  13. hi arduined

    mbr2045
    can i use the as replacement for the 90SQ035. ?

  14. Do you know if there is any variants of what you have created that can be used with wind turbines instead of solar. I am looking for a 24V system that should be able to handle up to 700Watts

  15. can we use Arduino Uno instead??

  16. Hi, I’m going to do this this weekend. Can I use a DC adapter as a power source instead of solar panel ?

  17. How would this cope with more than one controller on the chip.
    Could the outputs from different mosfets be chained together

    • Yes they can be chained, it should work as long as each mosfet has its own R6 4k7 resistor. Mosfet chaining is often used in 12V to 220V converters, like this one http://www.eleccircuit.com/wp-content/uploads/2015/03/The-schematic-diagram-of-this-projects.jpg

  18. Can it be connected to 100 watts solar panel and 60amp battery for running a load of 60watt/hr.
    And if yes how much time it would support that load.

  19. void setup() {
    TCCR2A = TCCR2A | 0×30;
    TCCR2B = TCCR2B & 0xF8 | 0×01;
    analogWrite(11, 117);
    analogWrite(3, 137);
    // Serial.begin(9600); }

    May I know whats the purpose of this code? thaanks

    • Code starts the internal oscillator on output pins 3 and 11. This is used for charge pump circuit consisting of D1, D2, D3 and C1, C2. When input (VBATT) is 12V, the output from charge pump (measured on D3) is around 20V.
      Charge pump multiplies the voltage so mosfet works more effectively, with no overheating without the heatsink. It also allows N-Channel mosfet to switch positive side of the circuit, because voltage on mosfet Gate is much higher (20V) than voltage on mosfet Source-Drain (12V).

      • thanks for that! may I know the full ratings of your charge controller? and can i still use this when the voltage max output from solar panel is 24V? thanks

  20. Is this circuit can be used for charging a 24V battery? Help me modifying this circuit

    • 24V panel will max around 37 – 38V. Mosfet should handle 55V but LP2950 only up to 30V. 7805 alternative is even worse so you will need to use some voltage divider before LP2950 or scrap the 5V linear stabiliser circuit completely (including C6, LP2950, C5 and C4) and use LM2596 step-down DC-DC converter module to power the arduino instead.

      2N3906 should also be replaced for some higher voltage generic PNP transistor, 2N3904 for generic higher voltage NPN transistor. All capacitors will need to have higher voltage rating, C7 should be rated for 60-70V. P6KE33CA needs to be removed or replaced with P6KE50CA.

  21. const int setPoint = 13.5 * 20 / (20+82) * 1024 / 5;

    can you tell me what is 13.5 , 20 , 20+82 ?
    thank you

    • Its voltage divider formula, two resistors R1 and R2 take a higher voltage (more than 12 Volts) and covert it to lower voltage (less than 5 Volts).

      Voltage divider output is calculated by
      Vout = Vsource x R2 / (R1 + R2)

      Vsource is the target charging voltage for lead acid battery – 13,5 Volts
      Vout is measuring voltage on Arduino analog pin A1

      Vout = 13.5 Volts x 20 kOhm / (20 kOhm + 82 kOhm)
      Vout = 270 / 102
      Vout = 2.64 Volts

      So voltage of 13.5 Volts will result in 2.64 Volts at analog pin A1. Maximum 5 Volts measuring voltage will be reached at battery voltage of 25.5 Volts.

  22. hi arduined,

    can i use an ultrafast recovery diode (MUR1560) as replacement for the 90SQ035 ? ( 90SQ035 is not available to me )

    • Yes you can but its not Schottky diode so it has higher voltage drop, it might get a bit hot and will most likely need a heatsink. Schottky diodes have very low forward voltage drop and they will be much more effective in this circuit. I now use this cheap alternative 5pcs 10A 45V Schottky Rectifiers from ebay https://goo.gl/6WDnYq

      For more powerful solar panels this one 20A 45V 20SQ045 https://goo.gl/xUKvGu

Leave a Reply to Adam Welch Cancel reply

*
*

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>