Maximizing power output from solar panels is essential for efficient energy utilization, and this is where an MPPT (Maximum Power Point Tracking) Solar Charge Controller comes into play. In this article, we’ll explore how an MPPT Solar Charge Controller works and guide you through building one yourself. Whether you want to power your home or integrate it into a product with minor modifications, this project is versatile and practical. Let’s dive in!

Disclaimer:

Advertisements

What is Solar Power System?

Solar panel converting sunlight into electricity

Before everything we have to know what is a solar home system or what is a solar power system. Solar energy comes from Sun. The sunlight is converted into electricity with the help of a Solar panel which is made of Semi-conductors (P-N junction).

This electricity is DC and can be stored or used to drive appliances like lights, fans, etc. But as the power is DC we may need to convert it into AC to run our standard AC appliances at home. Anyway, the total system is consists of a Solar panel, Battery as storage, Inverters if required, and a charge controller.

MPPT Solar charge Controller
Solar Home System

What is Storage(Battery) in the solar home system?

Solar home systems or solar power systems use different types of batteries as storage devices. Most of the systems use a common Lead-Acid battery. But AGM and Lithium-Ion batteries are also popular in solar power systems. Among these three types, Li-ion is the best but costly as well. That is why Lead-Acid batteries are used in most small solar systems.

Now, whatever the battery is each battery has specific charging and discharging characteristics. Each battery has a higher charging point above which the battery should not be charged and a lower discharging point below which point no battery should not be discharged anymore.

Charge levels of battery:

solar battery
A solar lead acid battery

If we consider a lead-acid battery of 12V, a higher cut-off point will be 14.3V-14.6V (varies by different manufacturers). And a lower discharging point will be 11.5V-11.6V. That means, this battery should not be charged over 14.6V and should not be discharged below 11.5V.

That is why a charge controller is required in between the Solar panel and the battery.

More articles:

What is a solar panel?

The term solar panel is used colloquially for a photo-voltaic (PV) module.

A PV module is an assembly of photovoltaic cells mounted in a framework for installation. Photo-voltaic cells use sunlight as a source of energy and generate direct current electricity. A collection of PV modules is called a PV Panel, and a system of Panels is an Array. Arrays of a photovoltaic system supply solar electricity to electrical equipment. Know more about solar panels from the wiki.

Let’s see what is solar charge controllers. There are 3 types of charge controllers available in the market. Let’s check.

You can check these solar panels for your solar home system:

What is a solar charge controller?

The solar charge controller is a device that controls the charging and some of them also control discharging of the battery. Normally it consists of a switch between a solar panel and a battery. Controlling this switch, charging is regulated.

MPPT solar charge controller
Charge controller basic block diagram

Depending on the charging mechanism, charge controllers can be differentiated into 3 types.

  1. On/Off type charge controller
  2. PWM type charge controller
  3. MPPT type charge controller

What is an On/Off type charge controller?

An on/off type charge controller is the most basic one which has only an on/off switch like a MOSFET/Transistor/even relay and a controller (Analog circuit / micro-controller).

pros:

On/Off type solar charge controller
  1. Very easy circuit diagram
  2. Simple operation
  3. Low cost

cons:

  1. Very low efficiency
  2. Less charging

Due to very low efficiency, on/off type charge controllers are used in very limited systems. Especially where efficiency is not a factor this type of charge controller is used. If a solar panel is 12V, this panel generates an open-circuit voltage of 22V. As a 12V system have a battery of 12V, an on/off type charge controller can connect the PV to the battery almost directly. That means, 22-12 = 10V is not used. At the same time, if the panel provides 5A of current, the total loss will be 10×5 = 50 watts. Even if we consider the panel in its peak power point, at least (16.5V-12V)x5A = 22.5Watt loss of energy.

For this type of loss, an On/off type solar charge controller is used in limited systems.

What is a PWM type of solar charge controller?

solar charge controller
PWM type solar charge controller

PWM type is an advanced version of an on/off type solar charge controller. A PWM signal is used to control the switching rather than direct on/off. This type of charge controller is a little better than the on/off type charge controller but still can not use the maximum generated power.

A PWM charge controller has smoother control in battery charging. Which enlarges battery life.

pros:

  1. Smoother charging control
  2. Longer battery life
  3. Low price

cons:

  1. Low efficient than MPPT
  2. Power loss

What is an MPPT solar charge controller?

MPPT solar charge controller

The MPPT solar charge controller is one kind of DC/DC converter that can deliver the maximum power generated by the solar panel to the battery to store the charge. It is the most complex one among solar charge controllers. The MPPT solar charge controller mostly has only a charging part. That means, it only controls solar panels to battery charging. For load control, another device may be required depending on the power system.

pros:

  1. Highly efficient charging
  2. Best energy management
  3. Proper utilization of battery charging

cons

  1. High cost
  2. Complex circuitry.

We have known types of charge controllers, now let’s see more about MPPT solar charge controllers.

Why do we need MPPT solar charge controller?

An MPPT solar charge controller is necessary for any solar power systems that need to extract maximum power from the PV module; it forces the PV module to operate at a voltage close to the maximum power point to draw maximum available power. MPPT solar charge controller reduces the complexity of the system while the output of the system is highly efficient.

Each solar panel (PV) produces its maximum power near about 17V (16.5V in most cases). This point is known as MPP or Maximum PowerPoint. So the duty of the MPPT solar charge controller is to maintain PV voltage at this MPP so that the available maximum power can be harvested from that solar panel (PV).

MPPT solar charge controller algorithm
Maximum PowerPoint

MPPT charge Controller basic parts:

MPPT solar charge controller has a basic part DC/DC converter a sensing part and a controller. The controller senses PV voltage and current and sends these data to the controller. The controller calculates the recent power, compares this power with the previous power, and decides what to do next. Changing control pulses, control maintains the DC/DC conversion at that point where the maximum power can be obtained at that time.

Now we have some basic parts in the MPPT solar charge converter:

  1. A DC/DC converter
  2. Voltage and Current sensor and
  3. A controller
  4. Algorithm for MPPT.

Let’s see one by one next.

Find more:

What is a DC/DC converter?

A DC/DC converter is a converter where the output voltage can be lower or higher than the input voltage. Based on the configuration, DC/DC converters can be divided into these types:

  • Buck Converter
  • Boost Converter
  • Buck-Boost converter
  • Ćuk Converter

What is a Buck converter?

The buck converter is a step-down converter. Here Output voltage is lower than the input voltage. A basic diagram of a buck converter is:

Buck converter (Asynchronous)

Types of Buck converter?

Based on the switching configuration, buck converters can be divided into two types.

  1. Synchronous Buck converter
  2. Asynchronous Buck converter

We will discuss the Synchronous buck converter later.

What is a Boost converter?

The boost converter is one kind of step-up converter where the output voltage is higher than the input voltage. A basic diagram of the boost converter is:

Boost converter

What is a buck-boost converter?

The buck-boost converter is a combined dc/dc converter. Here the output voltage can be higher or lower than the input voltage. By controlling two PWM the output can be controlled. The basic diagram for the buck-boost converter is:

Buck-Boost converter

What is Ćuk Converter?

The Ćuk converter is a type of DC/DC converter that has an output voltage magnitude that is either greater than or less than the input voltage magnitude. It is essentially a boost converter followed by a buck converter with a capacitor to couple the energy.

Ćuk converter

What is a Synchronous Buck Converter?

Asynchronous buck converter

In an Asynchronous buck converter, there is a diode, connected inversely to wheel the current through the inductor. But as there is a forward voltage drop in the diode of 0.7V, a loss happens here. This loss decreases the total efficiency of a buck converter. If this diode is replaced by a MOSFET, the forward voltage drop can be reduced to 0.1V. Which increases total converter efficiency.

Use:

The synchronous buck converter is used to step a voltage down from a higher voltage to a lower voltage. Synchronous buck converters are very popular in the industry today and provide high-efficiency solutions for a wide range of applications. This application note gives the formulas to calculate the power stage of a synchronous buck operating in continuous conduction mode. An asynchronous buck converter produces a regulated voltage that is lower than its input voltage and can deliver a high current while minimizing power loss. As shown in Figure 1, the synchronous buck converter is comprised of two power MOSFETs, an output inductor, and input and output capacitors.

synchronous buck converter
Figure1: Basics of a synchronous Buck converter

Q1, the high-side MOSFET, is connected directly to the input voltage of the circuit. When Q1 turns on, IUPPER is supplied to the load through Q1. During this time the current through the inductor increases (charging L) and Q2 is off. When Q1 turns off, Q2 turns on and ILOWER is supplied to the load through Q2. During this time, the inductor current decreases (discharging L). Figure 2 shows the basic waveforms for the synchronous buck converter in continuous conduction mode.

synchronous buck converter switching
Synchronous buck converter waveform

To learn more about Synchronous buck converter design please read these documents:

Download Application Notes for the buck converter design guide.

Inductor design guide:

The Inductor is the most important part of a DC/DC converter. Selecting and designing an inductor is a little bit complex too. Here in our project, a toroidal code inductor is used. To calculate the inductor, I took help from coil32.net. You can check that online tool, it is pretty helpful. After making your inductor, you should check the inductance with an RLC meter. I had this meter, and I checked the inductance with it before circuit assembly.

Read more:

All-in-One Electronic tools and Calculators links

RLC meter

Voltage and current sensing unit:

Voltage can be sensed easily using a resistor voltage divider and capacitor filter like this circuit:

Resistor voltage divider circuit to sense voltage

But to sense current, using a hall-effect sensor is a more efficient way than using a series resistor. Here in this project, we’ll use ACS712-30 hall-effect-based current sensor.

ACS712
ACS712 Current sensor

This current sensor provides linear DC voltage corresponding to the current flow. Neutral point is 2.5V (where the supply voltage is 5V). Positive or negative current flow generates a linear voltage at the output terminal either higher than 2.5V or lower than 2.5V respectively.

ACS712-30A gives 66mV/Amp deflection according to the input current flow. We can easily integrate this current sensor into our circuit as the current sensor.

About the controller:

As the controller, we can use a microcontroller. Or we can say that we have to use a micro-controller to control everything. Here in this project, we will use the PIC16F877A microcontroller.

PIC16F877A as our controller

Algorithm:

For Maximum PowerPoint Tracking, an algorithm is very important. Depending on the algorithm, the total design can be changed. For MPPT charge controllers, There are the most common algorithms listed below:

  1. Perturbation and Observation (P&O)
  2. Incremental Conductance (IncCond)
  3. Ripple Correlation
  4. Constant Voltage
  5. Open-Circuit
  6. Current sweep
  7. Temperature Method
  8. Fractional open-circuit voltage

Discussing individually will be too lengthy. I’m requesting you to study this yourself.

Other parts of MPPT solar charge controller:

Besides the main parts of the MPPT solar charge controller, we also need to focus on other associated parts for our Project.

  1. Input and output protections
  2. Gate driver for MOSFETs
  3. Visualization of information
  4. Blue-tooth data logging
  5. SMPS mobile charging
  6. Power supply for circuit parts.
  7. Load control unit

Input and Output protection:

Input and output should be protected from reverse flow and a current limiting must be introduced.

For reverse flow, a Diode can be used. But as efficiency is an issue, we have to eliminate this diode by a MOSFET. The MOSFET also has a body diode. If we use the MOSFET in a reverse way, the body diode will work as a normal diode and while switching the upper MOSFET of the Synchronous buck converter, if we switch this MOSFET, it will short the diode. That means the voltage drop will be less than 0.1V. Thus, we can reduce loss as well as use a diode in an efficient way. This configuration in our project will be:

MOSFET as diode

For the current limit, we can use Fuses. Using a DC fuse is a good idea but if there is no DC fuse nearby, we can use common fuses.

Fuse

Gate Driver circuit:

MOSFET configuration

Most of the micro-controllers work at 5V supply and others are 3.3V or even 2.5V range. But the MOSFETs need at least 10V across the Gate and Source for switching. Otherwise, conductivity will be low which generates heat and in the end, MOSFET blows out. As our microcontroller can not provide more than 5V so to switch a MOSFET we must need a gate driving circuit. This circuit can be designed in multiple ways depending on circuit configuration.

In our circuit:

Here in this project, the DC/DC converter is Synchronous Buck type. In the synchronous buck converter, we already know that there are two MOSFETs. One is upper MOSFET and another other is lower MOSFET.

Gate driving circuit

Gate signals:

The gate signal of these two MOSFETs is inverted to each other type like this:

MOSFET Gate driving signal

Here the blue one on the top is the gate driving signal of the upper MOSFET and the red one on the bottom is the gate driving signal for the lower MOSFET. In this way, the back emf of the inductor can be passed through the lower MOSFET which was generated by the upper MOSFET switching. This way the synchronous buck converter works.

Why do we need a gate-driving IC?

As you see, the gate driving mechanism in the Synchronous buck converter is a little bit complex. A dedicated gate-driving IC can do this job efficiently. That is why we need a gate-driving IC.

Here IR2104 is one of the suitable gate-driving ICs for Synchronous buck converters.

About IR2104 gate driving IC:

IR2104 Gate driver IC

IR2104 is a dedicated gate driving IC for the half-bridge drivers which is actually a kind of Synchronous buck converter gate driver IC.

Check the datasheet of IR2104 here to understand this gate driver IC.

The IR2104(S) are high voltage, high-speed power MOSFET and IGBT drivers with dependent high and low side referenced output channels. Proprietary HVIC and latch-immune CMOS technologies enable ruggedized monolithic construction. The logic input is compatible with standard CMOS or LSTTL output, down to 3.3V logic. The output drivers feature a high pulse current buffer stage designed for minimum driver cross-conduction. The floating channel can be used to drive an N-channel power MOSFET or IGBT in the high-side configuration which
operates from 10 to 600 volts.

Connection diagram:

IR2104
Basic circuit for IR2104

In IR2104, the input signal is given to the INPUT (Pin#2) of the IC. An active-low signal at the SD pin stops the output from driving. A bootstrap capacitor of 0.1uF works fine but this capacitor must be of the best quality (low ESR).

Block diagram of IR2104

Visualization of information:

20×4 LCD display

For visualization, a very common device is an LCD display. In this project, we’ll use a 20×4 LCD to visualize information. Besides, LEDs are used to indicate the mode of operation.

This LCD needs 6 pins for communication and the pin diagram of the LCD is:

LCD pin diagram

Blue-tooth data logging:

For remote data logging, a blue-tooth module is used here. Although memory cards are used in most commercial devices as field data loggers, here in this project we are not logging data locally. We kept an option to monitor the charge controller data remotely. That is why a Bluetooth module HC06 is used.

bluetooth module
HC06 Bluetooth module

This is a very common Bluetooth module. Simple connection through UART module of micro-controller. Can be connected with an Android cell phone and an app on the phone can be used to monitor and log the data.

SMPS mobile charging:

A mobile charge was not so important as part of an MPPT solar charge controller but kept in design to make the project more useful and interesting. Here, a Switch Mode Power Supply circuit is designed with MC34063A IC which can supply 5V at 350mA very easily. The circuit diagram for our mobile charger is:

Mobile charger with MC34063A
Mobile charger circuit

You can download the datasheet for MC34063A from here.

Read more:

Power supply for circuit parts:

There are microcontrollers, ACS current sensors, Bluetooth modules, and LCDs all these devices need power to run. All these components need a 5V DC supply. This power supply is designed with an LM7805 voltage regulator IC. The circuit diagram is:

5V Power supply

Load control unit:

Although most of the MPPT solar charge controllers don’t have a load control unit, in our project we kept this part. Loads are supplied from our battery and switched by a MOSFET. A gate driver (Opto-coupler: P817C) is introduced as well to drive the MOSFET gate.

Load control unit

Combing all together:

So our MPPT solar charge controller has various parts that work in combination. If we shortlist again, we can make this:

  1. A DC/DC buck converter: Synchronous Buck Converter
  2. Gate driving circuit: IR2104
  3. Protecting Circuit: Fuse + Diode(MOSFET)
  4. Load control circuit: MOSFET & Gate driver
  5. Data-logging circuit: Blue-tooth Module (HC06)
  6. Sensing circuit: ACS712-30 & resistors
  7. Power supply circuit: LM7805 circuit
  8. Mobile charge circuit: MC34063A circuit

Block diagram:

The Block Diagram of our project is:

MPPT solar charge controller block diagram
Block Diagram

Circuit Diagram:

Here is the circuit diagram of this project:

Circuit diagram of MPPT solar charge controller

As this is a big power circuit, proteus is unsuitable for simulation. Error results in simulation is very common in this type of big project.

You can download the proteus file from here.

Simulation Result:

Coding:

I bought the mikroC license in 2014 as I work professionally. So all of my projects based on PIC microcontrollers are programmed using this compiler. Here is the mikroC code for this project.

Note: This code is written in a simplified, old-fashioned style to make it easier to understand. However, it can be compressed and reorganized for better efficiency and modern practices.

/*******************************************************************************
*     Program for, "MPPT Solar Charge Controller using Sync. Buck converter"   *
*                  Program Written by_ Engr. Mithun K. Das                     *
*                         MCU: PIC16F877A; X-Tal:8MHz                          *
*                               Date:17-01-2016                                *
*******************************************************************************/
// LCD module connections
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections
void Lcd_COut(char row, char col, const char *cptr)
{
  char chr = 0;             //first, it is used as empty string
  Lcd_Out(row, col, &chr);  //nothing to write but set position.
  for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in loop
  asm CLRWDT;
}
void UART_Write_CText(const char *cptr)
{
    char chr;
    for ( ; chr = *cptr ; ++cptr ) UART1_Write(chr);
}
const char character6[] = {0,29,21,21,21,21,23,0};
const char character5[] = {31,21,21,27,27,21,21,31};
const char character4[] = {14,17,17,17,17,17,17,31};
const char character3[] = {14,17,17,17,17,17,31,31};
const char character2[] = {14,17,17,17,17,31,31,31};
const char character1[] = {14,17,17,31,31,31,31,31};
const char character[] = {14,31,31,31,31,31,31,31};
void CustomChar(char pos_row, char pos_char,char num)
{
    char i;
    switch(num)
    {
      case 0:
           {
              Lcd_Cmd(64);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
            }
      case 1:
           {
              Lcd_Cmd(72);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character1[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
           }
      case 2:
           {
              Lcd_Cmd(80);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character2[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
           }
      case 3:
           {
              Lcd_Cmd(88);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character3[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
           }
      case 4:
           {
              Lcd_Cmd(96);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character4[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
           }
      case 5:
           {
              Lcd_Cmd(104);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character5[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
           }
      case 6:
           {
              Lcd_Cmd(112);
              for (i = 0; i<=7; i++)Lcd_Chr_CP(character6[i]);
              Lcd_Cmd(_LCD_RETURN_HOME);
              Lcd_Chr(pos_row, pos_char, num);
           }
    }
}
void Background()
{
  Lcd_COut(1,7,"|");Lcd_COut(2,7,"|");Lcd_COut(3,7,"|");Lcd_COut(4,7,"|");
  Lcd_COut(1,14,"|");Lcd_COut(2,14,"|");Lcd_COut(3,14,"|");Lcd_COut(4,14,"|");
  Lcd_COut(1,1,"SOL"); Lcd_COut(1,8,"BAT");Lcd_COut(3,15," LOAD");Lcd_COut(1,15," PWM");
  CustomChar(1,12,0);// Battery
  CustomChar(1,5,5);// Panel
  CustomChar(1,20,6);// PWM
}
long adc_rd=0;
unsigned int Battery=0,Solar=0,i;
unsigned int Battery1=0,Solar1=0;
unsigned int Charging_current=0,Battery_Current=0;
unsigned int Charging_Current1=0,Battery_Current1=0;
unsigned int Solar_Power = 0,Solar_Power1=0;
unsigned int Previous_power=0,Recent_power=0;
unsigned int parcentage=0,parcentage1=0;
int duty=0,duty1=0;
int d_prcnt=0,d_prcnt1=0;
short charging_mode=0;//0 = bulk by default
bit load;
void Get_Battery();
void Get_Solar();
void Get_Charging_Current();
void Get_Battery_Current();
void Get_Solar_power();
void Load_Control();
void Charging_Control();

#define    load_clk   RB7_bit
#define    Clock_EN   RC1_bit
#define    Bulk_LED   RB5_bit
#define    Float_LED  RB2_bit
#define    NoChar_LED RB1_bit
#define    ON         1
#define    OFF        0
short charge = 0;
unsigned int chr_cnt=0;
void main() 
{
 TRISA = 0xFF;//all input
 TRISE0_bit = 1;//set as input
 TRISE2_bit = 1;//set as input
 TRISC = 0x00;//all output
 TRISB = 0x00;//all output
 ADCON1 = 0x00;//all Analog ing
 Delay_ms(100);
 Lcd_Init();//initialize LCD
 Lcd_Cmd(_LCD_CLEAR);//clear display
 Lcd_Cmd(_LCD_CURSOR_OFF);//cursor off
 Lcd_COut(1,1,"MPPT Solar Charger");
 PWM1_Init(22500);// initialize PWM at 22.5 KHz
 PWM1_Start();//start PWM
 PWM1_Set_Duty(duty);// duty cycle = (duty/255) X 100 %
 UART1_Init(9600);
 Delay_ms(2000);
 Lcd_Cmd(_LCD_CLEAR);//clear display
 Background();
 load = 1;
 OPTION_REG = 0x0F;//enable WDT
 while(1)
 {
    asm CLRWDT;
    Get_Battery();
    Get_Solar();
    Get_Charging_Current();
    Get_Battery_Current();
    Get_Solar_power();
    Load_Control();
    Charging_Control();

 }//while(1)
}//void main

void Charging_Control()
{
    char pwm_prcnt[]="000%";
    if(Solar>125)
    {
       Clock_EN = ON;//enable clock
       NoChar_LED = OFF;
       
        if(Battery>143)charge = 1;
        if(Battery<136)charge = 0;
        
        if(charge==1)
        {
            charging_mode = 1;// go to float mode
            Float_LED = ON;
            Bulk_LED = OFF;
            UART_Write_CText("Charging mode: Float \r\n");
            if(Charging_current<50)
            {
               if(duty<254)duty++;
               else duty = 254;
            }
            if(Charging_current>50)
            {
               if(duty>1)duty--;
               else duty = 1;
            }
        }
        if(charge==0)
        {
            charging_mode = 0;
            Float_LED = OFF;
            Bulk_LED = ON;
            UART_Write_CText("Charging mode: Bulk \r\n");

            if(chr_cnt>300)
            {
                 Recent_power = Solar_Power;
                 if(Recent_power>=Previous_power)
                 {
                    if(duty<254)duty+=1;
                 }
                 else
                 {
                    if(duty>30)duty-=1;
                 }
                 Previous_power = Recent_power;
            }
            else
            {
                  if(Solar>145)
                  {
                     if(Battery<140 && Battery_Current<500)
                     {
                        if(duty<244)duty+=10;
                        else duty = 254;
                     }
                     else
                     {
                        if(duty>1)duty--;
                        else duty = 1;
                     }
                  }
                  else if(Solar<Battery)
                  {
                      if(duty>10)duty-=10;
                      else duty = 1;
                  }
                  chr_cnt++;
            }
        }
    }
    else if(Solar<105)
    {
       Clock_EN = OFF;//Disable clock  when Solar not available
       NoChar_LED = ON;
       Float_LED = OFF;
       Bulk_LED = OFF;
       duty = 0;
       UART_Write_CText("Solar not available. \r\n");
       chr_cnt = 0;
    }

    PWM1_Set_Duty(duty);
    d_prcnt = duty*100/255;
    pwm_prcnt[0] = d_prcnt/100 + 48;
    pwm_prcnt[1] = (d_prcnt/10)%10 + 48;
    pwm_prcnt[2] = d_prcnt%10 + 48;
    Lcd_Out(2,16,pwm_prcnt);
    UART_Write_CText("PWM:");

    UART1_Write_Text(pwm_prcnt);
    UART_Write_CText("\r\n");

    asm CLRWDT;
    Delay_ms(2);
}

void Get_Battery()
{
   char Bat[]="00.0V";
   char parcen[] = "000%";

   adc_rd = 0;//clear previous data
   ADCON0 = 0x01;//select channel 0
   for(i=0;i<100;i++)
   {
       adc_rd += ADC_Read(0);
       asm CLRWDT;
   }
   adc_rd/=100;
   Battery = (int)adc_rd*0.644922871516105;
   Bat[0] = Battery/100 + 48;
   Bat[1] = (Battery/10)%10 + 48;
   Bat[3] = Battery%10 + 48;
   Lcd_Out(2,8,Bat);

      UART_Write_CText("Battery:");
      UART1_Write_Text(Bat);
      UART_Write_CText("\r\n");

   asm CLRWDT;
   Delay_ms(2);
   adc_rd = 0;//clear all data
   if(Solar>120)//solar is available
   {
       if(Battery>116)parcentage = (Battery-116)*3.71;
       else parcentage = 0;
       if(parcentage>100)parcentage=100;
       if(parcentage<0)parcentage = 0;
   }
   else
   {
       if(Battery>116)parcentage = (Battery-116)*10;
       else parcentage = 0;
       if(parcentage>100)parcentage=100;
       if(parcentage<0)parcentage = 0;
   }
   parcen[0] = parcentage/100 + 48;
   parcen[1] = (parcentage/10)%10 + 48;
   parcen[2] = parcentage%10 + 48;
   Lcd_Out(4,8,parcen);

      UART_Write_CText("Charge:");
      UART1_Write_Text(parcen);
      UART_Write_CText("\r\n");

   asm CLRWDT;
   Delay_ms(2);
   if(parcentage>85)CustomChar(1,12,0);// Battery 100%
   else if(parcentage>65 && parcentage<=85)CustomChar(1,12,1);// Battery 75%
   else if(parcentage>35 && parcentage<=65)CustomChar(1,12,2);// Battery 75%
   else if(parcentage>25 && parcentage<=35)CustomChar(1,12,3);// Battery 75%
   else CustomChar(1,12,4);// Battery 75%
}
void Get_Solar()
{
   char Sol[]="00.0V";
   adc_rd = 0;//clear previous data
   ADCON0 = 0x39;//select channel 7
   for(i=0;i<500;i++)
   {
       adc_rd += ADC_Read(7);
       asm CLRWDT;
   }
   adc_rd/=500;
   Solar = (int)adc_rd*0.537634408602151;
   Sol[0] = Solar/100 + 48;
   Sol[1] = (Solar/10)%10 + 48;
   Sol[3] = Solar%10 + 48;
   Lcd_Out(2,1,Sol);
   UART_Write_CText("Panel:");
   UART1_Write_Text(Sol);
   UART_Write_CText("\r\n");
   asm CLRWDT;
   adc_rd = 0;//clear all data
}

void Get_Charging_Current()
{
   char Ccurr[]="0.00A";
   unsigned int crnt1=0;
   int k=0;
   adc_rd = 0;//clear previous data
   ADCON0 = 0x29;//select channel 5
   for(k=0;k<80;k++)
   {
       for(i=0;i<50;i++)
       {
           adc_rd += ADC_Read(5);
           asm CLRWDT;
       }
       adc_rd/=50;
       crnt1 = adc_rd*4.78515625;//convert into mV
       Charging_current += abs(crnt1-2500)/0.66;//convert into A
   }
   Charging_current/=80;//get avg value again
   UART_Write_CText("Solar Inpur Current:");
   if(crnt1>2500)
   {
      Lcd_COut(3,1,"-");
      UART_Write_CText("-");
   }
   else if(crnt1<2500)
   {
      Lcd_COut(3,1,"+");
      UART_Write_CText("+");
   }
   else Lcd_COut(3,1," ");
   
   Ccurr[0] = Charging_current/100 + 48;
   Ccurr[2] = (Charging_current/10)%10 + 48;
   Ccurr[3] = (Charging_current)%10 + 48;
   Lcd_Out(3,2,Ccurr);
   UART1_Write_Text(Ccurr);
   UART_Write_CText("\r\n");
   asm CLRWDT;
   Delay_ms(2);
   adc_rd = 0;//clear all data
}
void Get_Battery_Current()
{
   char Bcurr[]="0.00A";
   unsigned int crnt2=0;
   int b;
   adc_rd = 0;//clear previous data
   ADCON0 = 0x21;//select channel 4
   for(b=0;b<80;b++)
   {
       for(i=0;i<50;i++)
       {
           adc_rd += ADC_Read(4);
           asm CLRWDT;
       }
       adc_rd/=50;
       crnt2 = adc_rd*4.78515625;//convert into mV
       Battery_Current += abs(crnt2-2500)/0.66;//convert into A
   }
   Battery_Current/=80;//get avg value
   UART_Write_CText("Output current:");
   if(crnt2>2500)
   {
       Lcd_COut(3,8,"-");
       UART_Write_CText("-");
   }
   else if(crnt2<2500)
   {
       Lcd_COut(3,8,"+");
       UART_Write_CText("+");
   }
   else Lcd_COut(3,8," ");
   
   Bcurr[0] = Battery_Current/100 + 48;
   Bcurr[2] = (Battery_Current/10)%10 + 48;
   Bcurr[3] = (Battery_Current)%10 + 48;
   Lcd_Out(3,9,Bcurr);
   UART1_Write_Text(Bcurr);
   UART_Write_CText("\r\n");
   asm CLRWDT;
   Delay_ms(2);
   adc_rd = 0;//clear all data
}

void Get_Solar_power()
{
   char slpwr[]= "000.0W";
   Solar_Power = Solar*Charging_current/100;
   slpwr[0] = Solar_Power/1000 + 48;
   slpwr[1] = (Solar_Power/100)%10 + 48;
   slpwr[2] = (Solar_Power/10)%10 + 48;
   slpwr[4] = (Solar_Power)%10 + 48;
   Lcd_Out(4,1,slpwr);
   UART_Write_CText("Solar Power:");
   UART1_Write_Text(slpwr);
   UART_Write_CText("\r\n");
   asm CLRWDT;
   Delay_ms(2);
}

void Load_Control()
{
   if(Battery>126)load=1;//battery is over 12.6V
   if(Battery<116)load = 0;
   
   // load control
   if(load)
   {
      load_clk = ON;
      Lcd_COut(4,15," ON ");
      UART_Write_CText("Load ON");
      UART_Write_CText("\r\n");
   }
   else
   {
      load_clk = OFF;
      Lcd_COut(4,15," OFF");
      UART_Write_CText("Load OFF");
      UART_Write_CText("\r\n");
   }
   UART_Write_CText("\r\n");
   UART_Write_CText("\r\n");
   UART_Write_CText("\r\n");
}
//End

You can get the complete project files from here.


Note:

Here in this MPPT solar charge controller, I used the Perturbation and Observation (P&O) algorithm. This is an educational open-source project for learning purposes only. I’ve professional designs, where I use different algorithms as well as have other facilities. You can contact me for professional help on this issue.

PCB designing:

Here is the PCB design of this project.

MPPT solar charge controller PCB
PCB design

Testing the project in real life:

I made the project for practical testing. Here is the lab test result:

MPPT solar charge controller circuit
MPPT Charge controller test 1
MPPT solar charge controller circuit
MPPT Charge Controller test 2

If you want to test this PCB making of your own either you can design in your own way or use mine from here.


About the field test result:

I gave this MPPT solar charge controller to one of my students who is using this charge controller in his home solar power system. Hopefully, the device is still running.

Mejor component list for this project:

Here is a list of the major components that are used in this project. You can buy these components from amazon.com

Conclusion:

In the end, I hope you came this far. As it was a big project I omitted some theory parts that you should learn yourself. If I miss some important parts, please let me know. I’ll add that later on. If you still think you are not capable to make one for yourself but you need one to use then you can buy ready products from this link below:

If you have any questions feel free to comment below. And thank you for reading the article. For more useful articles, don’t forget to subscribe. Have a good day!

For Professional Designs or Help:

Loading

Read more:

Categories: Complete ProjectsElectronicsMicrocontrollerPICPower ElectronicsRenewable Energy

MKDas

Mithun K. Das; B. Sc. in EEE from KUET; Head of R&D @ M's Lab Engineering Solution. "This is my personal blog. I post articles on different subjects related to electronics in the easiest way so that everything becomes easy for all, especially for beginners. If you have any questions, feel free to ask through the contact us page." Thanks.

54 Comments

Sagheer Ahmad · 25/01/2021 at 4:28 pm

WILL THIS SOLAR Controller PCB board Operate charging at 24V volts. and I am a resident of Pakistan.
IN4917 is not available in Pakistan.what will be its replacement part?
Thank best Regard
Sagheer Ahmad

    Mithun K. Das · 28/01/2021 at 5:12 am

    Yes, But you need to configure the regulators first. If 1N4917 is not available then use equivalent.

      prasad rao bhupati · 04/03/2023 at 2:19 am

      sir i want mppt solar charger detail components list

        MKDas · 04/03/2023 at 11:52 am

        read the full article. you’ll find them.

Godwin · 26/02/2021 at 8:49 pm

Please,I need the professional type that can handle 12,24 and 48v solar panel and upto 40amp

prabhash kumar · 07/04/2021 at 4:29 pm

Please share 24volt input DC to dc boost converter ..with code..gain good knowledge.. good job

ROBERT · 09/05/2021 at 7:33 pm

sir please can u increase the current to up to 50amps. I try to increase it but not working for me and from the one provided it can increase to even 10amp. please help

    MKDas · 10/05/2021 at 5:29 am

    This design is not suitable for high amp. You need to convert it into N-Channel low side MOSFET type switching for high amp. See another article on low side MOSFET based buck converter on my blog.

Zahid · 10/05/2021 at 4:11 am

In the display the power shows maximum 65W, but current & voltage shows correctly, after 65w it shows 000W, please suggest me how to solve the problem.

    MKDas · 10/05/2021 at 5:29 am

    check the program, display power subfunction.

      Zahid · 13/05/2021 at 3:41 am

      I tried but didn’t succeed, please tell me which line i have change. I’m not expert in coding.

        MKDas · 13/05/2021 at 11:23 am

        Set Solar_Power as long. hope it works.

max · 03/06/2021 at 11:38 am

Dear sir
Can I use 1N4148 instead of 1N4917 .
Regards

    MKDas · 03/06/2021 at 11:51 am

    Check the datasheet of IR2104. 1N4148 works fine.

      max · 05/06/2021 at 12:40 am

      thank you so much sir

riahi baha · 16/06/2021 at 12:43 pm

what are the material reference used in this model ??

    MKDas · 16/06/2021 at 1:02 pm

    Kindly clarify what you are trying to express.

Joseph Oyewale · 27/09/2021 at 3:33 am

Thanks for sharing this, sir what is the range of solar panel input voltage to this charge controller design above

Kankie Allen · 16/01/2022 at 5:14 pm

Can i please get the necessary calculations for the capacitors inductors and resistors

    MKDas · 16/01/2022 at 5:44 pm

    Most of the calculations are given in clue or calculator.

David A · 26/01/2022 at 5:40 am

In the first MPPT Charge controller 1 picture, the LCD seems to show 103.35% efficiency (magic!) What conversion efficiency did you actually achieve?

    MKDas · 26/01/2022 at 4:34 pm

    As every piece of information is not being printed in the LCD at the same time, a minor information gap may happen and that image may be taken at that right moment. Besides, every component has a tolerance. So minor errors can be found very easily. You make one using the concept and make that 100% error-free. That will sound good.

Allen Kankie · 16/03/2022 at 3:04 am

For Q1 Q2 and Q3 why were multiple mosfets used and can it work with a different type pf battery

    MKDas · 16/03/2022 at 11:37 am

    Multiple MOSFETs to gain current capacity and share load and heat. For different types of batteries, just adjust charging level and cutoffs.

      G K · 23/11/2024 at 7:44 am

      Nonsense. Q1, Q2 & Q3 do NOT “share the load”. There is no current gain by using all three.

        MKDas · 25/11/2024 at 12:07 pm

        Q1 is used as a Diode, Q2 as the upper switch and Q3 as the Sync. Switch. You should study on Synchronous buck converter first Mr.

Kakama Mark · 31/03/2022 at 5:41 pm

What are the alternatives for the schottky sr580.
What are the consequences of only using one single mosfet, Schottky and capacitor at Q1 Q2 Q3 and d4 C? And C8

    MKDas · 02/04/2022 at 12:57 pm

    First, Google is always open to searching the alternatives.
    second, you can use single power devices, but if you use two 5A switches rather than one 10A, the heat dissipation as well as safety factor increase. That is why, we try to use more than one if necessary in power switching purpose.

Kakama Mark · 24/06/2022 at 5:33 pm

In the code and the proteus circuitnthe mosfet pins IN and SD are defined or connected what could the connections. If SD rc1 what is the PWM signal pin

ojie · 06/09/2022 at 9:48 pm

Thank you so much for this build. I have been able to study and trace your pcb to know how you made use of multiple mosfet. Which line(s) of code do I need to change to increase the charging level and cutoff for use with 24v battery (increase the charging current to like 50amps. )

    MKDas · 07/09/2022 at 4:10 pm

    yes, study on it and learn. Also try changing if you want. thanks.

Samin Zawad · 12/02/2023 at 10:40 pm

Sir,
is it possible to implement the same project in arduino uno ?
What are the changes required in code and schematics for that?

    MKDas · 14/02/2023 at 11:47 am

    First, understand the concept. Then you can use almost any microcontroller.

Walter Meurat · 04/03/2023 at 3:37 am

I read your article with great satisfaction.
Thank you very much for sharing your knowledge, I hope this helps readers to motivate them to investigate
Greetings from Argentina

Anandhu · 22/08/2023 at 11:54 pm

Pcb design & Gerber file please

    MKDas · 04/09/2023 at 8:29 pm

    will fix the link soon.

Paul · 10/01/2024 at 2:42 am

Please what is the maximum output current of this design?

Hamza · 23/03/2024 at 4:28 pm

Tell me the replacement of sr560

Hamza · 25/03/2024 at 6:24 am

Can we you use same circuit for 24v battery connection or panel supply?

    MKDas · 25/03/2024 at 12:11 pm

    maintain the ratio.

      Hamza · 25/03/2024 at 6:25 pm

      Tell me the range of Battery and panel to mantain the ratio to what extend in current circuit without changing a single component

        MKDas · 25/03/2024 at 8:42 pm

        First learn it, try to learn the concept of working. once you understand it well, then you can change the circuit or code for any different ranges. But if I keep mentioning where to change or what to do, it will be keep going forever. And I do not have that much time to teach you individually. So kindly try to capture the knowledge of the project. then use it as per your requirement.

ihsan · 24/06/2024 at 9:22 am

this design not working. where output battery voltage stabilized ? this is charging the battery with maximum voltage which is not good for battery life. what you say about this. if i am wrong then guide me so i will learn.

    MKDas · 24/06/2024 at 10:46 am

    If you measure the output voltage without connecting the battery then yes it must give unregulated voltage which can be higher to the battery voltage. If the converter can’t give extra voltage than the battery, it can not charge the battery. So measure with battery connection.

G K · 23/11/2024 at 7:48 am

Looks like the schematic is wrong. Q3 is not wired correctly. What else is wrong?

    MKDas · 25/11/2024 at 12:05 pm

    Hello Mr. You have not understood the buck converter configuration yet.

      G K · 25/11/2024 at 11:06 pm

      Actually, I do understand the Buck Converter. Take a good look at Q3 in your schematic diagram, again. This time without the condescending attitude. You should clearly see that Q3 is incorrectly, shorting out Capacitor C8. That is 100% wrong!!! The DRAIN of Q3 is connected to the wrong side of L1. Now … you can apologize for insulting my intelligence.

        MKDas · 26/11/2024 at 12:28 pm

        Ah! It’s my mistake while drawing the diagram. I’ll fix it. Thank you for your intelligence.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *