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.





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 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.

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:

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:

Parts List:

Arduino Pro Mini ATmega328P 5V 16Mhz

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 smile