• Skip to main content
  • Skip to primary sidebar

Homemade Circuit Projects

Need circuit help? Post them in the comments! I've answered over 50,000!

Blog | Categories | About | Contact | Calculators-online
You are here: Home / Arduino Projects / Real MPPT Solar Charger Circuit Using Arduino, LCD, and Manual/Auto Switch

Real MPPT Solar Charger Circuit Using Arduino, LCD, and Manual/Auto Switch

Last Updated on May 12, 2025 by Swagatam Leave a Comment

So in this article we are trying to make a true MPPT solar charger project using Arduino which will charge a 12V battery from a solar panel and will use MPPT logic to always extract maximum power from the solar panel. That means that even when sunlight changes, we try to adjust PWM duty cycle smartly so that the panel gives out optimum wattage all the time, not wastefully.

What we will need:

We are going to use these things:

  • Arduino Nano (or UNO)
  • Solar Panel (18V, 50W or similar)
  • Buck Converter circuit with N-channel MOSFET and diode
  • Current sensor (ACS712 or INA219)
  • 16x2 LCD Display
  • 10k pot for LCD contrast
  • Manual/Auto switch (SPDT)
  • Gate driver IC like IR2110 or direct drive for low frequency
  • Flyback diode for buck circuit (like 1N5822)
  • Capacitors and inductor for LC filter
  • 10k resistor for voltage divider (solar V measurement)
  • Misc: wires, perfboard, etc.

How it works:

We know that solar panel has one sweet spot where it gives max wattage. That spot changes if sunlight goes up or down. So we need to track that spot using code. That method is called Perturb and Observe (P&O). It means that we change duty cycle slightly and observe if power increased or decreased. If it increased then we go more in that direction. If it reduced then we go back. Very simple.

Manual and Auto switch:

We also want a manual override. That means user can stop MPPT and use fixed duty cycle if needed. So we use a switch connected to digital pin, if it is LOW = auto mode (MPPT running), if HIGH = manual mode (fixed PWM).

LCD display:

We show all info on LCD: solar volts, current, power, PWM duty, mode, etc. So we know what is going on live.

How we sense things:

Solar voltage is read via voltage divider (scaled down to 0-5V)

Current is read either by ACS712 or INA219 (user selects in code)

PWM control:

We use analogWrite (fast PWM pin) to generate switching signal to buck MOSFET. We can also use Timer1 library if more accuracy is needed later.

Basic Tracking Type MPPT Circuit Diagram

Real MPPT circuit

Circuit Connections

Solar panel positive goes to input of buck inductor.

Solar panel negative goes to Arduino GND.

Inductor connects to diode (cathode to output).

Output side goes to battery +ve.

Battery -ve goes to common GND.

MOSFET drain to solar panel positive (input), source to inductor input, inductor output to battery +ve.

For calculating the inductor value, you can take the help of this buck converter calculator.

Arduino PWM output (D3) goes to MOSFET gate through 100 ohm.

Pull-down 10k from gate to source.

Flyback diode across inductor input to GND.

Voltage divider: 100k and 10k from panel +ve to A0.

Current sensor:

  • For ACS712: Vout to A1, Vcc to 5V, GND to GND.
  • For INA219: connect via I2C (SDA, SCL to A4, A5).
  • Manual/Auto switch: center to D2, ends to GND and 5V.
  • LCD: RS, E, D4D7 to D9D4 (standard wiring).
  • LCD contrast pot center to V0, ends to GND and 5V.

LCD Pins and Their Connection Explanation:

LCD Pin No.LCD Pin NameConnects ToDescription (crude and simple)
1GNDArduino GNDThis is LCD negative supply. Connect to GND of Arduino.
2VCCArduino 5VThis is LCD positive. Connect to 5V from Arduino.
3V0Center of 10k potThis controls screen contrast. Pot ends go to 5V and GND, center goes here. Adjust for sharp text.
4RSArduino D7Register Select. Tells LCD if we are sending command or data. Connect to D7 of Arduino.
5RWGNDRead/Write pin. Tie to GND for always write mode (we never read from LCD).
6EN (E)Arduino D6Enable pin. Triggers the LCD to latch in the data. Connect to D6 of Arduino.
7 to 10D0 to D3Not UsedThese are only used in 8-bit mode. In 4-bit mode, we leave them unconnected.
11D4Arduino D5Data line 4. Connect to D5 of Arduino.
12D5Arduino D4Data line 5. Connect to D4 of Arduino.
13D6Arduino D3Data line 6. Connect to D3 of Arduino.
14D7Arduino D2Data line 7. Connect to D2 of Arduino.
15A (LED +)220 ohm to 5VLED backlight +. You can put 220 ohm resistor from here to 5V, or direct 5V if too dim.
16K (LED -)GNDLED backlight -ve. Connect to GND.

Buck Converter Connection Details

In the MOSFET buck converter stage, we do the connections in the following manner:

We take the solar panel positive, give it to the drain of the MOSFET. Then the source of MOSFET goes to the inductor input. After the inductor we connect to battery +ve. The MOSFET source side also connects with one side of flyback diode and its other side goes to battery -ve. That way when MOSFET turns OFF then diode gives path for inductor to dump energy into battery.

Full Program Code

//==================== MPPT Solar Charger Code by homemade-circuits.com ====================//
//== Dual Current Sensor Options: ACS712 or INA219
//== Manual/Auto Switch Control
//== LCD Display for Parameters

#include <LiquidCrystal.h>
#include <Wire.h>
#include <Adafruit_INA219.h>

//================ LCD Setup ===================//
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

//================ Constants ===================//
const int pwmPin = 3;           // PWM output to buck converter
const int potPin = A0;          // For manual duty cycle control
const int autoManualSwitch = 2; // Switch for manual/auto
const int voltagePin = A1;      // Panel voltage divider input (0 to 5V)
const int acsPin = A2;          // ACS712 analog output

#define SENSOR_ACS712 0
#define SENSOR_INA219 1
int currentSensorOption = SENSOR_INA219;  // Change to SENSOR_ACS712 if required

//================ INA219 Setup ===================//
Adafruit_INA219 ina219;

//================ Variables ===================//
float panelVoltage = 0;
float panelCurrent = 0;
float panelPower = 0;
float prevPower = 0;
float dutyCycle = 0.5; // Initial duty cycle
float delta = 0.01;     // Step size for perturb & observe

unsigned long lastMPPT = 0;
const unsigned long mpptInterval = 500; // in ms

void setup() {
  pinMode(pwmPin, OUTPUT);
  pinMode(autoManualSwitch, INPUT_PULLUP);
  lcd.begin(16, 2);
  analogWrite(pwmPin, (int)(dutyCycle * 255));

  if (currentSensorOption == SENSOR_INA219) {
    ina219.begin();
  }

  lcd.print("MPPT Solar Ready");
  delay(2000);
  lcd.clear();
}

void loop() {
  bool isManual = digitalRead(autoManualSwitch) == LOW;
  if (isManual) {
    manualControl();
  } else {
    autoMPPT();
  }
  showLCD();
  delay(200);
}

void manualControl() {
  int potValue = analogRead(potPin);
  dutyCycle = map(potValue, 0, 1023, 10, 95) / 100.0;
  analogWrite(pwmPin, dutyCycle * 255);
  readPanelParameters();
}

void autoMPPT() {
  if (millis() - lastMPPT >= mpptInterval) {
    lastMPPT = millis();
    readPanelParameters();

    if (panelPower > prevPower) {
      dutyCycle += delta;
    } else {
      dutyCycle -= delta;
      delta = -delta; // Reverse direction
    }

    if (dutyCycle > 0.95) dutyCycle = 0.95;
    if (dutyCycle < 0.1) dutyCycle = 0.1;

    analogWrite(pwmPin, dutyCycle * 255);
    prevPower = panelPower;
  }
}

void readPanelParameters() {
  panelVoltage = analogRead(voltagePin) * (25.0 / 1023.0); // Assuming 100k:10k divider for 25V max

  if (currentSensorOption == SENSOR_ACS712) {
    int sensorValue = analogRead(acsPin);
    float voltage = sensorValue * (5.0 / 1023.0);
    panelCurrent = (voltage - 2.5) / 0.1; // For ACS712 20A
  } else if (currentSensorOption == SENSOR_INA219) {
    panelCurrent = ina219.getCurrent_mA() / 1000.0; // mA to A
  }

  panelPower = panelVoltage * panelCurrent;
}

void showLCD() {
  lcd.setCursor(0, 0);
  lcd.print("V:"); lcd.print(panelVoltage, 1);
  lcd.print(" I:"); lcd.print(panelCurrent, 1);

  lcd.setCursor(0, 1);
  lcd.print("P:"); lcd.print(panelPower, 1);
  lcd.print(" D:"); lcd.print((int)(dutyCycle * 100));
}

Real MPPT Circuit Diagram with Current Sensor

Real MPPT circuit with current sensor

Step-by-Step Real MPPT Charger Wiring and Connection Explanation:

Basic Arduino Power Setup

  • We first give power to Arduino UNO or Nano board. You can use a 12V battery through the Vin pin or just use USB during testing.
  • Ground (GND) from Arduino will be the main 0V reference for all modules and parts.

2) LCD 16x2 Wiring (with LiquidCrystal Library)

LCD PinConnect to Arduino
VSSGND
VDD+5V
VOMiddle pin of 10k pot for contrast
RSD9
END8
D4D7
D5D6
D6D5
D7D4
RWGND
A (LED+)220 ohm to +5V
K (LED-)GND

We use pins D4 to D9 for LCD. A 10k preset is needed between +5V, GND, and LCD pin 3 to adjust contrast.

3) Solar Panel Input to Buck Converter

  • Your solar panel (say 18V/5A) will be connected to a buck converter MOSFET stage.
  • A powerful N-channel MOSFET like IRF3205 or IRLZ44N is used for switching.
  • The PWM pin D3 from Arduino connects to MOSFET gate via 100Ω resistor.
  • A fast freewheeling diode (like UF5408 or Schottky) is put across the inductor output.
  • You will need an inductor, say 47uH to 100uH and output capacitor (1000uF/35V) to complete the buck stage.

4) Current Sensor Options (ACS712 or INA219)

Option 1: Using ACS712 (e.g., 5A version)

  • VCC to +5V
  • GND to Arduino GND
  • OUT to A0 pin of Arduino
  • Insert ACS712 in series with battery negative line, so the load current passes through it.

Option 2: Using INA219

  • VIN+ and VIN– are in series with battery positive line
  • SDA to A4
  • SCL to A5
  • VCC to +5V
  • GND to GND

In the code, you can switch between ACS712 or INA219 by changing the flag useINA219 = true; or false;.

5) Manual / Auto Switch

  • Take a small SPDT or toggle switch.
  • Connect one side to GND.
  • Center terminal to D10 (this is our mode pin).
  • Use INPUT_PULLUP in code so switch LOW means Manual, HIGH means Auto mode.

In manual mode you can manually adjust duty cycle using the pot.

6) Manual Mode Potentiometer (10k)

  • Left pin to GND
  • Right pin to +5V
  • Middle pin to A1
  • This pot is used to manually vary the PWM duty in manual mode.

7) Battery Output

  • Output of the buck converter goes to the battery terminals
  • You can use a 12V lead acid or Li-ion battery.
  • Be sure to add a blocking Schottky diode (optional) to prevent backflow.

Table showing the main Arduino Pins:

Arduino PinFunction
D3PWM to MOSFET Gate
A0ACS712 output
A4SDA for INA219
A5SCL for INA219
A1Potentiometer for manual
D10Manual/Auto switch input
D4-D9LCD Display

How It All Works:

  • When the sun gets stronger then Arduino increases PWM duty in Auto mode, trying to reach MPP (Maximum Power Point).
  • It checks input power = V × I constantly.
  • If power increases then it continues adjusting PWM in same direction.
  • If power drops then it reverses PWM direction.
  • In manual mode, you take control using the pot to tune the PWM duty manually.
  • LCD will show voltage, current, power, and duty cycle live.

You'll also like:

  • 1.  Make this 7 Segment Digital Clock with Beep Alert Circuit
  • 2.  3 phase Solar Submersible Pump Inverter Circuit
  • 3.  I/V Tracker Circuit for Solar MPPT Applications
  • 4.  How to Connect Solar Panels in Series and Parallel
  • 5.  Solar Panel Enhancer Using Solar Mirror Concept
  • 6.  Wireless Office Call Bell Circuit

About Swagatam

I am an electronics engineer with over 15 years of hands-on experience. I am passionate about inventing, designing electronic circuits and PCBs, and helping hobbyists bring their projects to life. That is why I founded homemade-circuits.com, a website where I share innovative circuit ideas and tutorials. Have a circuit related question? Leave a comment.... I guarantee a reply!

Previous Post: « Do We Need a Freewheeling Diode Across the Inductor in Boost Converter?
Next Post: True MPPT Solar Controller Circuit using IC 555 »

Reader Interactions

Need Help? Please Leave a Comment! We value your input—Kindly keep it relevant to the above topic! Cancel reply

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

Primary Sidebar

Subscribe to New Circuit Ideas

Categories

  • Arduino Projects (87)
  • Audio and Amplifier Projects (132)
  • Automation Projects (17)
  • Automobile Electronics (101)
  • Battery Charger Circuits (82)
  • Datasheets and Components (102)
  • Electronics Theory (143)
  • Free Energy (37)
  • Games and Sports Projects (11)
  • Grid and 3-Phase (19)
  • Health related Projects (25)
  • Home Electrical Circuits (12)
  • Indicator Circuits (14)
  • Inverter Circuits (87)
  • Lamps and Lights (142)
  • Meters and Testers (69)
  • Mini Projects (46)
  • Motor Controller (64)
  • Oscillator Circuits (27)
  • Pets and Pests (15)
  • Power Supply Circuits (108)
  • Remote Control Circuits (50)
  • Security and Alarm (64)
  • Sensors and Detectors (100)
  • Solar Controller Circuits (59)
  • Temperature Controllers (42)
  • Timer and Delay Relay (49)
  • Transmitter Circuits (29)
  • Voltage Control and Protection (37)
  • Water Controller (36)

Calculators

  • Battery Back up Time Calculator
  • Capacitance Reactance Calculator
  • IC 555 Astable Calculator
  • IC 555 Monostable Calculator
  • Inductance Calculator
  • LC Resonance Calculator
  • LM317, LM338, LM396 Calculator
  • Ohm’s Law Calculator
  • Phase Angle Phase Shift Calculator
  • Power Factor (PF) Calculator
  • Reactance Calculator
  • Transistor Astable Calculator
  • Transistor base Resistor Calculator
  • Voltage Divider Calculator
  • Wire Current Calculator
  • Zener Diode Calculator
  • Filter Capacitor Calculator
  • Buck Converter Calculator
  • Boost Converter Calculator
  • Solar Panel, Inverter, Battery Calculator
  • Wire Current Calculator
  • SMPS Transformer Calculator
  • IC SG3525, SG3524 Calculator
  • Inverter LC Filter Calculator

People Also Search

555 Circuits | 741 Circuits | LM324 Circuits | LM338 Circuits | 4017 Circuits | Ultrasonic Projects | SMPS Projects | Christmas Projects | MOSFETs | Radio Circuits | Laser Circuits | PIR Projects |

Recent Comments

  • Swagatam on Simple Delay Timer Circuits Explained
  • Swagatam on The Role of Inductor Coil in SMPS
  • Swagatam on 7 Modified Sine Wave Inverter Circuits Explored – 100W to 3kVA
  • Swagatam on 7 Modified Sine Wave Inverter Circuits Explored – 100W to 3kVA
  • Victor on 7 Modified Sine Wave Inverter Circuits Explored – 100W to 3kVA

Company

  • Privacy Policy
  • Cookie Policy
  • About Me
  • Contact
  • Disclaimer
  • Copyright
  • Videos
  • Sitemap

Social Profiles

  • Twitter
  • YouTube
  • Instagram
  • Pinterest
  • My Facebook-Page
  • Quora
  • Stack Exchange
  • Linkedin
  • © 2025 · Swagatam Innovations