Introduction: ARDUINO PWM SOLAR CHARGE CONTROLLER ( V 2.02)
If you are planning to install an off-grid solar system with a battery bank, you’ll need a Solar Charge Controller. It is a device that is placed between the Solar Panel and the Battery Bank to control the amount of electric energy produced by Solar panels going into the batteries. The main function is to make sure that the battery is properly charged and protected from overcharging.
As the input voltage from the solar panel rises, the charge controller regulates the charge to the batteries preventing any overcharging and disconnects the load when the battery is discharged.
Support me On Patreon:
If you enjoy my work here on Instructables, consider joining my Patreon, it will be a great help for me to make more interesting projects in the future.
Types of solar charge controllers
There are currently two types of charge controllers commonly used in PV power systems :
1. Pulse Width Modulation (PWM) controller
2. Maximum Power Point Tracking (MPPT) controller
In this Instructable, I will explain to you about the PWM Solar Charge Controller. I have posted few articles on PWM charge controllers earlier too. The earlier version of my solar charge controllers are quite popular on the internet and useful for people all around the globe.
By considering the comments and questions from my earlier versions, I have modified my existing V2.0 PWM Charge Controller to make the new version 2.02.
The following are the changes in V2.02 w.r.t V2.0:
1. The low efficient linear voltage regulator is replaced by buck converter MP2307 for 5V power supply.
2. One additional current sensor to monitor current coming from the solar panel.
3. MOSFET-IRF9540 is replaced by IRF4905 for better performance.
4. Onboard LM35 temp-sensor is replaced by a DS18B20 probe for accurate battery temperature monitoring.
5. USB port for charging smart devices.
6. Use of single fuse instead of two
7. One additional LED to indicate Solar Power Status.
8.Implementation of 3 stages charging algorithm.
9.Implementation of PID controller in the charging algorithm
10. Made a custom PCB for the project
1.Charge controller as well as energy meter
2. Automatic Battery Voltage Selection (6V/12V)
3.PWM charging algorithm with auto charge setpoint according to the battery voltage
4.LED indication for the state of charge and load status
5. 20x4 character LCD display for displaying voltages, current, power, energy, and temperature.
7.Reverse current flow protection
8.Short Circuit and Overload protection
9. Temperature Compensation for Charging
10. USB port for Charging Gadgets
You can order the PCB V2.02 from PCBWay
13.Bi-Color LED ( Amazon )
18.Fuse Holder and fuses ( Amazon )
22.Screw terminals 1x6 pin ( Aliexpress)
23.PCB Standoffs ( Banggood )
1.Soldering Iron ( Amazon )
2. Desoldering Pump ( Amazon )
2.Wire Cutter and Stripper ( Amazon )
3.Screw Driver ( Amazon )
Step 1: Working Principle of a PWM Charge Controller
PWM stands for Pulse Width Modulation, which stands for the method it uses to regulate charge. Its function is to pull down the voltage of the solar panel to near that of the battery to ensure that the battery is properly charged. In other words, they lock the solar panel voltage to the battery voltage by dragging the Solar panel Vmp down to the battery system voltage with no change in the current.
It uses an electronics switch ( MOSFET ) to connect and disconnect the solar panel with the battery. By switching the MOSFET at high frequency with various pulse widths, a constant voltage can be maintained. The PWM controller self-adjusts by varying the widths (lengths) and frequency of the pulses sent to the battery.
When the width is at 100%, the MOSFET is at full ON, allowing the solar panel to bulk charge the battery. When the width is at 0% the transistor is OFF open circuiting the Solar panel preventing any current from flowing to the battery when the battery is fully charged.
Step 2: How the Circuit Works ?
The heart of the charge controller is an Arduino Nano board. The Arduino senses the solar panel and battery voltages by using two voltage divider circuits. According to these voltage levels, it decides how to charge the battery and control the load.
Note : In the above picture, there is typographical error in power and control signal. The redline is for power and yellow line is for control signal.
The whole schematic is divided into the following circuits:
1. Power Distribution Circuit:
The power from the battery ( B+ & B- ) is step down to 5V by the X1 ( MP2307) buck converter. The output from the buck converter is distributed to
1. Arduino Board
2. LEDs for indication
3. LCD display
4. USB port to charge gadgets.
2. Input Sensors:
The solar panel and battery voltages are sensed by using two voltage divider circuits consisting of resistors R1-R2 & R3- R4. C1 and C2 are filter capacitors to filter out the unwanted noise signals. The output from the voltage dividers is connected to Arduino analog pins A0 and A1 respectively.
The solar panel and load currents are sensed by using two ACS712 modules. The output from the current sensors is connected to Arduino analog pin A3 and A2 respectively.
The battery temperature is measured by using a DS18B20 temperature sensor. R16 (4.7K ) is a pull-up resistor. The output of the temperature sensor is connected to Arduino Digital pin D12.
3. Control Circuits:
The control circuits are basically formed by two p-MOSFETs Q1 and Q2. The MOSFET Q1 is used to send the charging pulse to the battery and MOSFET Q2 is used to drive the load. Two MOSFET driver circuits are consist of two transistors T1 and T2 with pull-up resistors R6 and R8. The base current of the transistors is controlled by resistors R5 and R7.
4. Protections Circuits:
The input overvoltage from the solar panel side is protected by using a TVS diode D1. The reverse current from the battery to the solar panel is protected by a Schottky diode D2. The overcurrent is protected by a fuse F1.
5. LED Indication:
LED1, LED2, and LED3 are used to indicate solar, battery and load status respectively. Resistors R9 to R15 are current limiting resistors.
7. LCD Display:
An I2C LCD display is used to display various parameters.
8. USB Charging:
The USB socket is hooked up to 5V output from the Buck Converter.
9. System Reset:
SW1 is a push button to reset the Arduino.
You can download the schematic in PDF format attached below.
Step 3: Main Functions of Solar Charge Controller
The charge controller is designed by taking care of the following points.
1. Prevent Battery Overcharge: To limit the energy supplied to the battery by the solar panel when the battery becomes fully charged. This is implemented in charge_cycle() of my code.
2. Prevent Battery Over-discharge: To disconnect the battery from electrical loads when the battery reaches a low state of charge. This is implemented in load_control() of my code.
3. Provide Load Control Functions: To automatically connect and disconnect an electrical load at a specified time. The load will ON when the sunset and OFF when sunrise. This is implemented in load_control() of my code. 4.Monitoring Power and Energy: To monitor the load power and energy and display it.
5. Protect from abnormal Condition: To protect the circuit from the different abnormal situations like lightning, overvoltage, overcurrent, and short circuit, etc.
6.Indicating and Displaying: To indicate and display the various parameters
7.Serial Communication: To print various parameters in the serial monitor
8. USB Charging: To charge smart devices
Step 4: Voltage Measurement
The voltage sensors are used to sense the voltage of solar panel and battery. It is implemented by using two voltage divider circuits. It consists of two resistors R1=100k and R2=20k for sensing the solar panel voltage and similarly R3=100k and R4=20k for battery voltage. The output from the R1and R2 is connected to Arduino analog pin A0 and output from the R3 and R4 is connected to Arduino analog pin A1.
Voltage Measurement :
Arduino’s analog inputs can be used to measure DC voltage between 0 and 5V (when using the standard 5V analog reference voltage) and this range can be increased by using a voltage divider network. The voltage divider steps down the voltage being measured within the range of the Arduino analog inputs.
For a voltage divider circuit Vout = R2/(R1+R2) x Vin
Vin = (R1+R2)/R2 x Vout
The analogRead() function reads the voltage and converts it to a number between 0 and 1023
We’re going to read output value with one of the analog inputs of Arduino and its analogRead() function. That function outputs a value between 0 and 1023 that is 0.00488V for each increment (As 5/1024 = 0.00488V)
Vin = Vout*(R1+R2)/R2 ; R1=100k and R2=20k
Vin= ADC count*0.00488*(120/20) Volt // Highlighted part is Scale factor
Note: This leads us to believe that a reading of 1023 corresponds to an input voltage of exactly 5.0 volts. In practical you may not get 5V always from the Arduino pin 5V. So during calibration first measure the voltage between the 5v and GND pins of Arduino by using a multimeter, and use scale factor by using the below formula:
Scale factor = measured voltage/1024
Step 5: Current Measurement
For current measurement, I used a Hall Effect current sensor ACS 712 -5A variant. There are three variants of ACS712 Sensor based on the range of its current sensing. The ACS712 sensor reads the current value and converts it into a relevant voltage value, The value that links the two measurements is Sensitivity. The output sensitivity for all variant are as follows:
ACS712 Model - > Current Range- > Sensitivity
ACS712 ELC-05 - > +/- 5A - > 185 mV/A
ACS712 ELC-20 - > +/- 20A - > 100 mV/A
ACS712 ELC-30 - > +/- 30A - > 66 mV/A
In this project, I have used the 5A variant, for which sensitivity is 185mV/A and the middle sensing voltage is 2.5V when no current.
analog read value = analogRead(Pin);
Value = (5/1024)*analog read value // If you are not getting 5V from Arduino 5V pin then,
Current in amp = (Value – offsetVoltage) / sensitivity
But as per data sheets offset voltage is 2.5V and sensitivity is 185mV/A
Current in amp = (Value-2.5)/0.185
Step 6: Temperature Measurement
Why Temperature monitoring is Required?
The battery’s chemical reactions change with temperature. As the battery gets warmer, the gassing increases. As the battery gets colder, it becomes more resistant to charging. Depending on how much the battery temperature varies, it is important to adjust the charging for temperature changes. So it is important to adjust charging to account for the temperature effects. The temperature sensor will measure the battery temperature, and the Solar Charge Controller uses this input to adjust the charge set point as required. The compensation value is - 5mv /degC/cell for lead-acid type batteries. (–30mV/ºC for 12V and 15mV/ºC for 6V battery).The negative sign of temperature compensation indicates an increase in temperature requires a reduction in charge setpoint. For more details, you may follow this article.
Temperature Measurement by DS18B20
I have used an external DS18B20 probe for measuring the battery temperature. It uses a one-wire protocol to communicate with the microcontroller. It can be hooked up in port-J4 on the board.
You can read this article for more details on the DS18B20 sensor.
Step 7: USB Charging Circuit
The buck converter MP2307 used for power supply can deliver current up to 3A. So it has a sufficient margin for charging the USB gadgets. The USB socket VCC is connected to 5V and GND is connected to GND. You can refer to the above schematic.
Note: The USB output voltage not maintained to 5V when the load current exceeds 1A. So I would recommend limiting the USB load below 1A.
Step 8: Charging Algorithm
When the controller is connected to the battery, the program will start the operation. Initially, it checks if the panel voltage is sufficient for charging the battery. If yes, then it will enter into the charge cycle. The Charge Cycle consists of 3 stages.
Stage 1 Bulk charge:
Arduino will connect the Solar Panel to the battery directly ( 99 % duty cycle). The battery voltage will increase gradually. When the battery voltage reaches 14.4V, stage 2 will begin.
In this stage, the current is almost constant.
Stage 2 Absorption charge:
In this stage, Arduino will regulate the charging current by maintaining the voltage level at 14.4 for one hour. The voltage is kept constant by adjusting the duty cycle.
Stage 3 Float charge:
The controller generates the trickle charge to maintain the voltage level at 13.5V. This stage keeps the battery to be fully charged. If the battery voltage is less than 13.2V for 10mins.
The charge cycle will be repeated.
Step 9: Load Control
To automatically connect and disconnect the load by monitoring dusk/dawn and battery voltage, load control is used.
The primary purpose of load control is to disconnect the load from the battery to protect it from deep discharging. Deep discharging could damage the battery.
The DC load terminal is designed for low power DC load such as street light.
The PV panel itself is used as the light sensor.
Assuming solar panel voltage > 5V means dawn and when < 5V dusk.
ON Condition: In the evening, when the PV voltage level falls below 5V and the battery voltage is higher than the LVD setting, the controller will turn on the load and the load green led will glow.
OFF Condition: The load will cut off in the following two conditions.
1. In the morning when the PV voltage is larger than 5v,
2.When the battery voltage is lower than the LVD setting The load red led ON indicates that the load is cut off.
LVD is referred to as Low Voltage Disconnect
Step 10: Power and Energy
Power: Power is the product of voltage (volt) and current (Amp)
P=VxI Unit of power is Watt or KW
Energy: Energy is the product of power (watt) and time (Hour)
E= Pxt Unit of Energy is Watt Hour or Kilowatt Hour (kWh)
To monitor the power and energy above logic is implemented in software and the parameters are displayed in a 20x4 char LCD.
Image credit: imgoat
Step 11: Protections
1.Reverse polarity and reverse current protection for solar panel
For reverse polarity and reverse current flow protection a Schottky diode (MBR2045) is used.
2. Overcharge & Deep discharge protection
Overcharge and deep discharge protection are implemented by the software.
3. Short circuit and overload protection
Short circuit and overload protection is realized by a fuse F1.
4.Overvoltage protection at solar panel input
Temporary overvoltages occur in power systems for a variety of reasons, but lightning causes the most severe overvoltages. This is particularly true with PV systems due to the exposed locations and system connecting cables. In this new design, I used a 600-watt bidirectional TVS diode (P6KE36CA ) to suppress the lightning and overvoltage at the PV terminals.
image credit: freeimages
Step 12: LED Indications
1. Solar LED: LED1
A bi-color (red/green ) led is used for indicating the solar power staus i.e dusk or dawn.
Solar LED --------------------->Solar Status
GREEN -------------------------> Day
RED ---------------------------> Night
2. Battery State Of Charge (SOC) LED: LED2
One important parameter that defines the energy content of the battery is the State of Charge (SOC). This parameter indicates how much charge is available in the battery. RGB LED is used to indicate the battery state of charge. For connection refer to the above schematic.
Battery LED ------------>Battery Status
RED --------------------> Voltage is LOW
GREEN --------------------> Voltage is Healthy
BLUE --------------------> Fully Charged
2. Load LED: LED3
A bi-color (red/green) led is used for load status indication. Refer to the above schematic for connection.
Load LED --------------------->Load Status
GREEN -------------------------> Connected (ON)
RED ---------------------------> Disconnected (OFF)
Step 13: LCD Display
A 20X4 char LCD is used for monitoring solar panel, battery and load parameters.
For simplicity, an I2C LCD display is chosen for this project. It needs only 4 wires to interface with the Arduino.
The connection is below:
VCC--> 5V ,
Row-1: Solar panel voltage, Current and Power
Row-2: Battery Voltage, Temperature, and Charger status ( Charging / Not Charging )
Row-3: Load current, power, and load status
Row-4: Input Energy from Solar panel and Energy consumed by the load.
You have to download the library from LiquidCrystal_I2C.
Step 14: Prototyping and Testing
1. Breadboard :
First, I made the circuit on a Breadboard. The main advantage of a solderless breadboard is that it’s, solderless. Thus you can easily change the design just by unplugging components and leads as you need to.
2. Perforated Board:
After making the breadboard testing, I made the circuit on a Perforated Board. To make it follow the instruction below
i) First insert all the parts into the hole of the Perforated-Board.
ii) Solder all the component pads and trim the extra legs by a nipper.
iii) Connect the soldering pads by using wires as per the schematic.
iv) Use standoff to isolate the circuit from the ground.
The perforated board circuit is really strong and can be deployed in a project permanently. After testing the prototype, if everything works perfectly we can move to design the final PCB.
Step 15: PCB Design
I have drawn the schematic by using EasyEDA online software after that switched to the PCB layout.
All of the components you added in the schematic should be there, stacked on top of each other, ready to be placed and routed. Drag the components by grabbing on its pads. Then place it inside the rectangular borderline.
Arrange all the components in such a way that the board occupies minimum space. Smaller the board size, the cheaper will be the PCB manufacturing cost. It will be useful if this board has some mounting holes on it so that it can be mounted in an enclosure.
Now you have to route. Routing is the most fun part of this entire process. It’s like solving a puzzle! Using the tracking tool we need to connect all the components. You can use both the top and the bottom layer for avoiding overlap between two different tracks and making the tracks shorter.
You can use the Silk layer to add text to the board. Also, we are able to insert an image file, so I add an image of my website logo to be printed on the board. In the end, using the copper area tool, we need to create the ground area of the PCB.
Now the PCB is ready for manufacturing.
Step 16: Download the Gerber Files
After making the PCB, we have to generate the files that can be sent to a PCB fabrication company that will in due course send us back some real PCB.
In EasyEDA You can output the Fabrication Files(Gerber file) via Document > Generate Gerber, or by clicking the Generate Gerber button from the toolbar. The generated Gerber file is a compressed package. After decompression, you can see the following 8 files:
1. Bottom Copper: .gbl
2. Top Copper: .gtl
3. Bottom Soldering Masks: .gbs
4.Top Soldering Masks: .gts
5. Bottom Silk Screen: .gbo
6. Top Silk Screen: .gto
7. Drill: .drl
You can download the Gerber files from PCBWay
When you place an order from PCBWay, I will get a 10% donation from PCBWay for a contribution to my work. Your little help may encourage me to do more awesome work in the future. Thank you for your cooperation.
Step 17: PCB Manufacturing
Now it is time to find out a PCB manufacturer that can turn our Gerber files to a real PCB. I have sent my Gerber files to JLCPCB for manufacturing my PCB. Their service is extremely good. I have received my PCB in India within 10 days.
The BOM for the project is attached below.
Step 18: Soldering the Components
After receiving the board from the PCB fab house, you have to solder the components.
For Soldering, you will need a decent Soldering Iron, Solder, Nipper, Desoldering Wicks or Pump and a multimeter.
It is good practice to solder the components according to their height. Solder the lesser height components first.
You can follow the following steps to solder the components :
1. Push the component legs through their holes, and turn the PCB on its back.
2. Hold the tip of the soldering iron to the junction of the pad and the leg of the component.
3. Feed solder into the joint so that it flows all around the lead and covers the pad. Once it has flowed all around, move the tip away.
4. Trim the extra legs by using a Nipper.
Follow the above rules for soldering all the components.
Step 19: Mounting the ACS712 Current Sensor
The ACS712 current sensor I have received has a pre-soldered screw terminal for connection. To solder the module directly on the PCB board, you have to desolder the screw terminal first.
I desolder the screw terminal with the help of a desoldering pump as shown above.
Then I solder the ACS712 module upside down.
To connect the Ip+ and Ip- terminal to the PCB, I used the diode terminal legs.
Step 20: Adding the Buck Converter
To solder the Buck Converter module, you have to prepare 4 straight header pins as shown above.
Solder the 4 header pins at the X1, 2 are for output and the remaining two are for inputs.
Step 21: Adding the Arduino Nano
When you purchase the straight headers, they'll be too long for the Arduino Nano. You'll need to trim them down to an appropriate length. This means 15 pins each.
The best way to trim the female header pieces is to count out 15 pins, pull the 16th pin, then use a nipper to cut the gap between the 15th and 17th pin.
Now we need to install the female headers onto the PCB. Take your female headers and place them on the male headers on the Arduino Nano board.
Then solder the female header pins to the Charge Controller PCB.
Step 22: Preparing the MOSFETs
Before soldering the MOSFETs Q1 Q2 and diode D1 on to the PCB, it is better to attach the heatsinks to them first. Heat sinks are used to move heat away from the device in order to maintain a lower device temperature.
Apply a layer of heatsink compound over the MOSFET metal base plate. Then place the thermally conductive pad in between the MOSFET and heat sink and tighten the screw. You can read this article about why heat sink is essential.
Finally, solder them on to the charge controller PCB.
Step 23: Mounting the Standoffs
After soldering all the parts, mount the standoffs at 4 corners. I used M3 Brass Hex Standoffs.
The use of standoffs will provide sufficient clearance to the soldering joints and wires from the ground.
Step 24: Software & Libraries
First, download the attached Arduino Code. Then download the following libraries and install them.
1. One Wire
4. PID Library
The entire code is broken into a small functional block for flexibility. Suppose the user is not interested to use an LCD display and happy with the led indication. Then just disable the lcd_display() from the void loop(). That's all. Similarly, according to the user requirement, he can enable and disable the various functionality.
After installing all the above libraries, upload the Arduino Code.
Note: I am now working on the software for implementing a better charging algorithm. Please keep in touch to get the latest version.
Update on 02.04.2020
Uploaded a new software with an improved charging algorithm and implementation of the PID controller in it.
Step 25: Final Testing
Connect the Charge Controller battery terminals ( BAT ) to a 12V battery. Be sure the polarity is correct. After connection, the LED and LCD will start working immediately. You will also notice the battery voltage and temperature on the 2nd row of the LCD display.
Then connect a Solar Panel to the solar terminal ( SOL ), you can see the solar voltage, current, and power on the first row of the LCD display. I have used a Lab Power supply to simulate the Solar Panel. I used my Power Meters to compare the Voltage, Current and Power values with the LCD display.
The test procedure is shown in this demo video
In the future, I will design a 3D printed enclosure for this project. Keep in touch.
This project is an entry in the PCB Contest, please vote for me. Your votes are a real inspiration for me to do more hard work to write more useful projects like this.
Thanks for reading my Instructable.
If you like my project, don't forget to share it.
Comments and feedback are always welcome.
Runner Up in the
PCB Design Challenge