Project tutorial

In This Tutorial, I will Show You How to Make an Arduino Based MPPT Charge Controller

• 10,173 views
• 15 respects

## Components and supplies

 Arduino Nano R3
×1

## Apps and online services

 Arduino IDE

### Arduino Based MPPT Charge Controller | Alternative energy |renewable energy sources | clean energy

What is Mppt ( Maximum power point tracking)?

We use MPPT algorithm to Extract the maximum available power from the Photovoltaic module under certain conditions. MPPT is a Most Popular tool that helps us to use Solar Energy (Renewable Energy Source) in an efficient way. If we want to Reduce the Graph of Carbon footprints then we must need to move towards clean Energy which is called Renewable Energy ( Energy we can get from Natural resources) Like SOLAR, HYDRO, WIND e.t.c otherwise we will directly move toward Global Warming.

Every Country needs to Move towards the Green Energy especially the CHINA because it is the Main contributor by producing 63% Co2.

How MPPT works? Why 150W solar panel does not equal to 150 w?

For example, you bought a new solar panel from the market which can deliver 7 amps current, under charge the setting of a battery is configured to 12 volts: 7 amps times 12 volts = 84w (P=V*I) You lost over 66 watts - but you paid for 150 watts. That 66 watt is not going anywhere, but it,s due to the poor match of the solar output current and battery voltage.

After using MPPT algorithm we can get the Maximum available power Battery gets is now 12 amps at 12 volts Output power is equal to p= V*I p=12*12=144w Now you still have almost 144 watts, and everyone is happy.

Specification of the project

2. LED indication to show the low mid and high level of charge stat

3. LCD (20x4 character ) display for displaying power,current,voltages etc

4. Lightning /Overvoltage Protection

5. Protection For Reverse power flow

6. Overload & Short Circuit Protection

7. Logging data through WiFi

Electrical specifications:

1.Rated Voltage= 12V

2.Maximum input current = 5A

3.Load current support up to =10A

4. Input Voltage = Solar panel 12 to 24V

5.power of Solar panel = 50 Watts

### PARTS REQUIRED:

• Resistors ( 3 x 200R ,3 x330R,1 x 1K, 2 x 10K, 2 x 20K, 2x 100k, 1x 470K )
• TVS diode ( 2x P6KE36CA )
• Arduino Nano
• ( ACS712-5A ) Current Sensor
• Buck Converter ( LM2596 )
• Wifi Module ( ESP8266 )
• LCD display ( 20x4 I2C )
• MOSFETs ( 4x IRFZ44N )
• MOSFET driver ( IR2104 )
• 3.3V Linear regulator ( AMS 1117 )
• Transistor ( 2N2222 )
• Diodes ( 2x IN4148 , 1 x UF4007 )
• Capacitors ( 4 x 0.1 uF, 3 x 10uF ,1 x100 uF ,1x 220uF)
• Inductor ( 1x 33uH -5A )
• LEDs ( Red, Yellow, Green )
• Fuses ( 5A)

Libraries Required For Arduino IDE :

Remember: Make a New Folder ( Folder name should be same as library names like TimerOne and LiquidCrystal_I2C. Paste these Two Folders in Arduino/LIbrary.

---------------------------------------------------------------------------------

### Model of Arduino Based MPPT Algorithm Charge Controller

Simulation of MPPT Charge Controller Project in Proteus software

This Simulation has been designed in Proteus Software 8.6 version. You can make your own by using Arduino Library for Proteus and a simulation tool known as Proteus. Kindly Contact Us if you want to Buy a proteus simulation source file for this project.

WiFi Data Logging by using a Wifi module ESP8266

After Reading The Above article I am assuming that you have successfully connected your ESP8266 module to your Wifi.

• Make a New Channel and write "Solar Panel Data" in Field 1 and leave other fields blanks and save it.
• You will Get API key, Copy that Api Key and Paste in Source Code.
• Done

Project Images

"Do not forget to install all the necessary libraries before uploading the code to Arduino Nano "

If you found any difficulty while making this project so don't hesitate to ask first we are here to help you 24 hours a day and 7 days a week 24/7 thanks

## Code

##### Source Code C/C++
```//----------------------------------------------------------------------------------------------------
// ARDUINO MPPT SOLAR CHARGE CONTROLLER (Version-3)
//  Author: Debasish Dutta/deba168
//          www.opengreenenergy.in
//
//  This code is for an arduino Nano based Solar MPPT charge controller.
//  This code is a modified version of sample code from www.timnolan.com
//  updated 06/07/2015
//
//  Mods by Aplavins 19/06/2015

////  Specifications :  //////////////////////////////////////////////////////////////////////////////////////////////////////
//
//    1.Solar panel power = 50W
//
//    2.Rated Battery Voltage= 12V ( lead acid type )

//    3.Maximum current = 5A                                                                                                //

//    4.Maximum load current =10A                                                                                            //

//    5. In put Voltage = Solar panel with Open circuit voltage from 17 to 25V                                               //

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "TimerOne.h"                // using Timer1 library from http://www.arduino.cc/playground/Code/Timer1
#include <Wire.h>
#include <SoftwareSerial.h>         // using the Software Serial library Ref : http://www.arduino.cc/en/Reference/SoftwareSerialConstructor
//----------------------------------------------------------------------------------------------------------

//////// Arduino pins Connections//////////////////////////////////////////////////////////////////////////////////

// A0 - Voltage divider (solar)
// A1 - ACS 712 Out
// A2 - Voltage divider (battery)
// A4 - LCD SDA
// A5 - LCD SCL
// D2 - ESP8266 Tx
// D3 - ESP8266 Rx through the voltage divider
// D5 - LCD back control button
// D8 - 2104 MOSFET driver SD
// D9 - 2104 MOSFET driver IN
// D11- Green LED
// D12- Yellow LED
// D13- Red LED

// Full scheatic is given at http://www.instructables.com/files/orig/F9A/LLR8/IAPASVA1/F9ALLR8IAPASVA1.pdf

///////// Definitions /////////////////////////////////////////////////////////////////////////////////////////////////

// Turn this on to use the ESP8266 chip. If you set this to 0, the periodic updates will not happen
#define ENABLE_DATALOGGER 0

// 0 - NIGHT LIGHT: Load ON when there is no solar power and battery is above LVD (low voltage disconnect)
// 1 - POWER DUMP: Load ON when there is solar power and the battery is above BATT_FLOAT (charged)

#define SOL_AMPS_CHAN 1                // Defining the adc channel to read solar amps
#define SOL_VOLTS_CHAN 0               // defining the adc channel to read solar volts
#define BAT_VOLTS_CHAN 2               // defining the adc channel to read battery volts

// ACS 712 Current Sensor is used. Current Measured = (5/(1024 *0.185))*ADC - (2.5/0.185)

#define SOL_AMPS_SCALE  0.026393581        // the scaling value for raw adc reading to get solar amps   // 5/(1024*0.185)
#define SOL_VOLTS_SCALE 0.029296875        // the scaling value for raw adc reading to get solar volts  // (5/1024)*(R1+R2)/R2 // R1=100k and R2=20k
#define BAT_VOLTS_SCALE 0.029296875        // the scaling value for raw adc reading to get battery volts

#define PWM_PIN 9                    // the output pin for the pwm (only pin 9 avaliable for timer 1 at 50kHz)
#define PWM_ENABLE_PIN 8            // pin used to control shutoff function of the IR2104 MOSFET driver (hight the mosfet driver is on)
#define PWM_FULL 1023                // the actual value used by the Timer1 routines for 100% pwm duty cycle
#define PWM_MAX 100                  // the value for pwm duty cyle 0-100%
#define PWM_MIN 60                  // the value for pwm duty cyle 0-100% (below this value the current running in the system is = 0)
#define PWM_START 90                // the value for pwm duty cyle 0-100%
#define PWM_INC 1                    //the value the increment to the pwm value for the ppt algorithm

#define TRUE 1
#define FALSE 0
#define ON TRUE
#define OFF FALSE

#define TURN_ON_MOSFETS digitalWrite(PWM_ENABLE_PIN, HIGH)      // enable MOSFET driver
#define TURN_OFF_MOSFETS digitalWrite(PWM_ENABLE_PIN, LOW)      // disable MOSFET driver

#define ONE_SECOND 50000            //count for number of interrupt in 1 second on interrupt period of 20us

#define LOW_SOL_WATTS 5.00          //value of solar watts // this is 5.00 watts
#define MIN_SOL_WATTS 1.00          //value of solar watts // this is 1.00 watts
#define MIN_BAT_VOLTS 11.00         //value of battery voltage // this is 11.00 volts
#define MAX_BAT_VOLTS 14.10         //value of battery voltage// this is 14.10 volts
#define BATT_FLOAT 13.60            // battery voltage we want to stop charging at
#define HIGH_BAT_VOLTS 13.00        //value of battery voltage // this is 13.00 volts
#define LVD 11.5                    //Low voltage disconnect setting for a 12V system
#define OFF_NUM 9                   // number of iterations of off charger state

//------------------------------------------------------------------------------------------------------
//Defining led pins for indication
#define LED_GREEN 11
#define LED_YELLOW 12
#define LED_RED 13
//-----------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------
// Defining lcd back light pin
#define BACK_LIGHT_PIN 5       // pin-5 is used to control the lcd back light

// ---------------------------For ESP8266--------------------------------------------------------------

// replace with your channel's thingspeak API key
String apiKey = "your Api key from thing speak";
const char* ssid = "your wifi name";

const char* server = "api.thingsspeak.com";

// connect 2 to TX of Serial USB
// connect 3 to RX of serial USB

SoftwareSerial ser(2,3); // RX, TX
//---------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------
/////////////////////////////////////////BIT MAP ARRAY//////////////////////////////////////////////////
//-------------------------------------------------------------------------------------------------------

byte battery_icons[6][8]=
{{
0b01110,
0b11011,
0b10001,
0b10001,
0b10001,
0b10001,
0b10001,
0b11111,
},
{
0b01110,
0b11011,
0b10001,
0b10001,
0b10001,
0b10001,
0b11111,
0b11111,
},
{
0b01110,
0b11011,
0b10001,
0b10001,
0b10001,
0b11111,
0b11111,
0b11111,
},
{
0b01110,
0b11011,
0b10001,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
},
{
0b01110,
0b11011,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
},
{
0b01110,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
}};
#define SOLAR_ICON 6
byte solar_icon[8] = //icon for termometer
{
0b11111,
0b10101,
0b11111,
0b10101,
0b11111,
0b10101,
0b11111,
0b00000
};
#define PWM_ICON 7
byte _PWM_icon[8]=
{
0b11101,
0b10101,
0b10101,
0b10101,
0b10101,
0b10101,
0b10101,
0b10111,
};
byte backslash_char[8]=
{
0b10000,
0b10000,
0b01000,
0b01000,
0b00100,
0b00100,
0b00010,
0b00010,
};
//-------------------------------------------------------------------------------------------------------

// global variables

float sol_amps;                       // solar amps
float sol_volts;                      // solar volts
float bat_volts;                      // battery volts
float sol_watts;                      // solar watts
float old_sol_watts = 0;              // solar watts from previous time through ppt routine
unsigned int seconds = 0;             // seconds from timer routine
unsigned int prev_seconds = 0;        // seconds value from previous pass
unsigned int interrupt_counter = 0;   // counter for 20us interrrupt
unsigned long time = 0;               // variable to store time the back light control button was pressed in millis
int delta = PWM_INC;                  // variable used to modify pwm duty cycle for the ppt algorithm
int pwm = 0;                          // pwm duty cycle 0-100%
int back_light_pin_State = 0;         // variable for storing the state of the backlight button
boolean load_status = false;          // variable for storing the load output state (for writing to LCD)

enum charger_mode {off, on, bulk, bat_float} charger_state;    // enumerated variable that holds state for charger state machine
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
LiquidCrystal_I2C lcd(0x38, 2, 1, 0, 4, 5, 6, 7, 3, NEGATIVE);  // Set the LCD I2C address

//------------------------------------------------------------------------------------------------------
// This routine is automatically called at powerup/reset
//------------------------------------------------------------------------------------------------------

void setup()                           // run once, when the sketch starts
{
pinMode(PWM_ENABLE_PIN, OUTPUT);     // sets the digital pin as output
TURN_OFF_MOSFETS;                    // turn off MOSFET driver chip
lcd.begin(20,4);                     // initialize the lcd for 16 chars 2 lines, turn on backlight

// create the LCD special characters. Characters 0-5 are the various battery fullness icons
// icon 7 is for the PWM icon, and icon 8 is for the solar array
lcd.backlight();
for (int batchar = 0; batchar <   6; ++batchar) {
lcd.createChar(batchar, battery_icons[batchar]);
}
lcd.createChar(PWM_ICON,_PWM_icon);
lcd.createChar(SOLAR_ICON,solar_icon);
lcd.createChar('\\', backslash_char);
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
Timer1.initialize(20);               // initialize timer1, and set a 20uS period
Timer1.pwm(PWM_PIN, 0);              // setup pwm on pin 9, 0% duty cycle
Timer1.attachInterrupt(callback);    // attaches callback() as a timer overflow interrupt
Serial.begin(9600);                  // open the serial port at 9600 bps:
ser.begin(9600);                     // enable software serial
ser.println("AT+RST");               // reset ESP8266
pwm = PWM_START;                     //starting value for pwm
pinMode(BACK_LIGHT_PIN, INPUT);
digitalWrite(BACK_LIGHT_PIN,LOW);    //  default LCd back light is OFF

// display the constant stuff on the LCD
lcd.setCursor(0, 0);
lcd.print("SOL");
lcd.setCursor(4, 0);
lcd.write(SOLAR_ICON);
lcd.setCursor(8, 0);
lcd.print("BAT");
}

//------------------------------------------------------------------------------------------------------
// Main loop
//------------------------------------------------------------------------------------------------------
void loop()
{
run_charger();                       // run the charger state machine
print_data();                        // print data
led_output();                        // led indication
lcd_display();                       // lcd display
#if ENABLE_DATALOGGER
wifi_datalog();                    // sends data to thingspeak
#endif
}

//------------------------------------------------------------------------------------------------------
// This routine reads and averages the analog inputs for this system, solar volts, solar amps and
// battery volts.
//------------------------------------------------------------------------------------------------------

int sum = 0;
int temp;
int i;

for (i=0; i<AVG_NUM; i++) {          // loop through reading raw adc values AVG_NUM number of times
sum += temp;                       // store sum for averaging
delayMicroseconds(50);             // pauses for 50 microseconds
}
return(sum / AVG_NUM);               // divide sum by AVG_NUM to get average and return it
}

//------------------------------------------------------------------------------------------------------
// This routine reads all the analog input values for the system. Then it multiplies them by the scale
// factor to get actual value in volts or amps.
//------------------------------------------------------------------------------------------------------

sol_watts = sol_amps * sol_volts ;                               //calculations of solar watts
}

//------------------------------------------------------------------------------------------------------
// This is interrupt service routine for Timer1 that occurs every 20uS.
//
//------------------------------------------------------------------------------------------------------
void callback()
{
if (interrupt_counter++ > ONE_SECOND) {        // increment interrupt_counter until one second has passed
interrupt_counter = 0;                       // reset the counter
seconds++;                                   // then increment seconds counter
}
}

//------------------------------------------------------------------------------------------------------
// This routine uses the Timer1.pwm function to set the pwm duty cycle.
//------------------------------------------------------------------------------------------------------
void set_pwm_duty(void) {

if (pwm > PWM_MAX) {					   // check limits of PWM duty cyle and set to PWM_MAX
pwm = PWM_MAX;
}
else if (pwm < PWM_MIN) {				   // if pwm is less than PWM_MIN then set it to PWM_MIN
pwm = PWM_MIN;
}
if (pwm < PWM_MAX) {
Timer1.pwm(PWM_PIN,(PWM_FULL * (long)pwm / 100), 20);  // use Timer1 routine to set pwm duty cycle at 20uS period
//Timer1.pwm(PWM_PIN,(PWM_FULL * (long)pwm / 100));
}
else if (pwm == PWM_MAX) {				   // if pwm set to 100% it will be on full but we have
Timer1.pwm(PWM_PIN,(PWM_FULL - 1), 20);                // keep switching so set duty cycle at 99.9%
//Timer1.pwm(PWM_PIN,(PWM_FULL - 1));
}
}

//------------------------------------------------------------------------------------------------------
// This routine is the charger state machine. It has four states on, off, bulk and float.
// It's called once each time through the main loop to see what state the charger should be in.
// The battery charger can be in one of the following four states:
//
//  On State - this is charger state for MIN_SOL_WATTS < solar watts < LOW_SOL_WATTS. In this state isthe solar
//      watts input is too low for the bulk charging state but not low enough to go into the off state.
//      In this state we just set the pwm = 99.9% to get the most of low amount of power available.

//  Bulk State - this is charger state for solar watts > MIN_SOL_WATTS. This is where we do the bulk of the battery
//      charging and where we run the Peak Power Tracking alogorithm. In this state we try and run the maximum amount
//      of current that the solar panels are generating into the battery.

//  Float State - As the battery charges it's voltage rises. When it gets to the MAX_BAT_VOLTS we are done with the
//      bulk battery charging and enter the battery float state. In this state we try and keep the battery voltage
//      at MAX_BAT_VOLTS by adjusting the pwm value. If we get to pwm = 100% it means we can't keep the battery
//      voltage at MAX_BAT_VOLTS which probably means the battery is being drawn down by some load so we need to back
//      into the bulk charging mode.

//  Off State - This is state that the charger enters when solar watts < MIN_SOL_WATTS. The charger goes into this
//      state when there is no more power being generated by the solar panels. The MOSFETs are turned
//      off in this state so that power from the battery doesn't leak back into the solar panel.
//------------------------------------------------------------------------------------------------------
void run_charger(void) {

static int off_count = OFF_NUM;

switch (charger_state) {
case on:
if (sol_watts < MIN_SOL_WATTS) {                      // if watts input from the solar panel is less than
charger_state = off;                                // the minimum solar watts then
off_count = OFF_NUM;                                // go to the charger off state
TURN_OFF_MOSFETS;
}
else if (bat_volts > (BATT_FLOAT - 0.1)) {            // else if the battery voltage has gotten above the float
charger_state = bat_float;                          // battery float voltage go to the charger battery float state
}
else if (sol_watts < LOW_SOL_WATTS) {                 // else if the solar input watts is less than low solar watts
pwm = PWM_MAX;                                      // it means there is not much power being generated by the solar panel
set_pwm_duty();			                    // so we just set the pwm = 100% so we can get as much of this power as possible
}                                                     // and stay in the charger on state
else {
pwm = ((bat_volts * 10) / (sol_volts / 10)) + 5;    // else if we are making more power than low solar watts figure out what the pwm
charger_state = bulk;                               // value should be and change the charger to bulk state
}
break;
case bulk:
if (sol_watts < MIN_SOL_WATTS) {                      // if watts input from the solar panel is less than
charger_state = off;                                // the minimum solar watts then it is getting dark so
off_count = OFF_NUM;                                // go to the charger off state
TURN_OFF_MOSFETS;
}
else if (bat_volts > BATT_FLOAT) {                 // else if the battery voltage has gotten above the float
charger_state = bat_float;                          // battery float voltage go to the charger battery float state
}
else if (sol_watts < LOW_SOL_WATTS) {                 // else if the solar input watts is less than low solar watts
charger_state = on;                                 // it means there is not much power being generated by the solar panel
TURN_ON_MOSFETS;                                    // so go to charger on state
}
else {                                                // this is where we do the Peak Power Tracking ro Maximum Power Point algorithm
if (old_sol_watts >= sol_watts) {                   // if previous watts are greater change the value of
delta = -delta;			            // delta to make pwm increase or decrease to maximize watts
}
pwm += delta;                                       // add delta to change PWM duty cycle for PPT algorythm (compound addition)
old_sol_watts = sol_watts;                          // load old_watts with current watts value for next time
set_pwm_duty();				            // set pwm duty cycle to pwm value
}
break;
case bat_float:

if (sol_watts < MIN_SOL_WATTS) {                      // if watts input from the solar panel is less than
charger_state = off;                                // the minimum solar watts then it is getting dark so
off_count = OFF_NUM;                                // go to the charger off state
TURN_OFF_MOSFETS;
set_pwm_duty();
}
else if (bat_volts > BATT_FLOAT) {                    // If we've charged the battery abovethe float voltage
TURN_OFF_MOSFETS;                                   // turn off MOSFETs instead of modiflying duty cycle
pwm = PWM_MAX;                                      // the charger is less efficient at 99% duty cycle
set_pwm_duty();                                     // write the PWM
}
else if (bat_volts < BATT_FLOAT) {                    // else if the battery voltage is less than the float voltage - 0.1
pwm = PWM_MAX;
set_pwm_duty();	                                    // start charging again
TURN_ON_MOSFETS;
if (bat_volts < (BATT_FLOAT - 0.1)) {               // if the voltage drops because of added load,
charger_state = bulk;                               // switch back into bulk state to keep the voltage up
}
}
break;
case off:                                               // when we jump into the charger off state, off_count is set with OFF_NUM
TURN_OFF_MOSFETS;
if (off_count > 0) {                                  // this means that we run through the off state OFF_NUM of times with out doing
off_count--;                                        // anything, this is to allow the battery voltage to settle down to see if the
}                                                     // battery has been disconnected
else if ((bat_volts > BATT_FLOAT) && (sol_volts > bat_volts)) {
charger_state = bat_float;                          // if battery voltage is still high and solar volts are high
TURN_ON_MOSFETS;
}
else if ((bat_volts > MIN_BAT_VOLTS) && (bat_volts < BATT_FLOAT) && (sol_volts > bat_volts)) {
charger_state = bulk;
TURN_ON_MOSFETS;
}
break;
default:
TURN_OFF_MOSFETS;
break;
}
}

//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------

// turn on loads at night when the solar panel is not producing power
// as long as the battery voltage is above LVD
load_on(sol_watts < MIN_SOL_WATTS && bat_volts > LVD);
#else
// dump excess solar energy into the load circuit
load_on(sol_watts > MIN_SOL_WATTS && bat_volts > BATT_FLOAT);
#endif
}

digitalWrite(LOAD_PIN, new_status ? HIGH : LOW);
}
}

//------------------------------------------------------------------------------------------------------
// This routine prints all the data out to the serial port.
//------------------------------------------------------------------------------------------------------
void print_data(void) {

Serial.print(seconds,DEC);
Serial.print("      ");

Serial.print("Charging = ");
if (charger_state == on) Serial.print("on   ");
else if (charger_state == off) Serial.print("off  ");
else if (charger_state == bulk) Serial.print("bulk ");
else if (charger_state == bat_float) Serial.print("float");
Serial.print("      ");

Serial.print("pwm = ");
if(charger_state == off)
Serial.print(0,DEC);
else
Serial.print(pwm,DEC);
Serial.print("      ");

Serial.print("Current (panel) = ");
Serial.print(sol_amps);
Serial.print("      ");

Serial.print("Voltage (panel) = ");
Serial.print(sol_volts);
Serial.print("      ");

Serial.print("Power (panel) = ");
Serial.print(sol_volts);
Serial.print("      ");

Serial.print("Battery Voltage = ");
Serial.print(bat_volts);
Serial.print("      ");

Serial.print("\n\r");
//delay(1000);
}

//-------------------------------------------------------------------------------------------------
//---------------------------------Led Indication--------------------------------------------------
//-------------------------------------------------------------------------------------------------
// light an individual LED
// we remember which one was on before in last_lit and turn it off if different
void light_led(char pin)
{
static char last_lit;
if (last_lit == pin)
return;
if (last_lit != 0)
digitalWrite(last_lit, LOW);
digitalWrite(pin, HIGH);
last_lit = pin;
}
// display the current state via LED as follows:
// YELLOW means overvoltage (over 14.1 volts)
// RED means undervoltage (under 11.9 volts)
// GREEN is between 11.9 and 14.1 volts
void led_output(void)
{
static char last_lit;
if(bat_volts > 14.1 )
light_led(LED_YELLOW);
else if(bat_volts > 11.9)
light_led(LED_GREEN);
else
light_led(LED_RED);
}

//------------------------------------------------------------------------------------------------------
//-------------------------- LCD DISPLAY --------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
void lcd_display()
{
static bool current_backlight_state = -1;
if (current_backlight_state != back_light_pin_State) {
current_backlight_state = back_light_pin_State;
if (back_light_pin_State == HIGH)
lcd.backlight();// finish with backlight on
else
lcd.noBacklight();
}

if (back_light_pin_State == HIGH)
{
time = millis();                        // If any of the buttons are pressed, save the time in millis to "time"
}

lcd.setCursor(0, 1);
lcd.print(sol_volts);
lcd.print("V ");
lcd.setCursor(0, 2);
lcd.print(sol_amps);
lcd.print("A");
lcd.setCursor(0, 3);
lcd.print(sol_watts);
lcd.print("W ");
lcd.setCursor(8, 1);
lcd.print(bat_volts);
lcd.setCursor(8,2);

if (charger_state == on)
lcd.print("on   ");
else if (charger_state == off)
lcd.print("off  ");
else if (charger_state == bulk)
lcd.print("bulk ");
else if (charger_state == bat_float)
{
lcd.print("     ");
lcd.setCursor(8,2);
lcd.print("float");
}

//-----------------------------------------------------------
//--------------------Battery State Of Charge ---------------
//-----------------------------------------------------------
int pct = 100.0*(bat_volts - 11.3)/(12.7 - 11.3);
if (pct < 0)
pct = 0;
else if (pct > 100)
pct = 100;

lcd.setCursor(12,0);
lcd.print((char)(pct*5/100));

lcd.setCursor(8,3);
pct = pct - (pct%10);
lcd.print(pct);
lcd.print("%  ");

//---------------------------------------------------------------------
//------------------Duty Cycle-----------------------------------------
//---------------------------------------------------------------------
lcd.setCursor(15,0);
lcd.print("PWM");
lcd.setCursor(19,0);
lcd.write(PWM_ICON);
lcd.setCursor(15,1);
lcd.print("   ");
lcd.setCursor(15,1);
if( charger_state == off)
lcd.print(0);
else
lcd.print(pwm);
lcd.print("% ");
//----------------------------------------------------------------------
//----------------------------------------------------------------------
lcd.setCursor(15,2);
lcd.setCursor(15,3);
{
lcd.print("On  ");
}
else
{
lcd.print("Off ");
}
spinner();
backLight_timer();                      // call the backlight timer function in every loop
}

void backLight_timer(){
if((millis() - time) <= 15000)         // if it's been less than the 15 secs, turn the backlight on
lcd.backlight();                   // finish with backlight on
else
lcd.noBacklight();                 // if it's been more than 15 secs, turn the backlight off
}
void spinner(void) {
static int cspinner;
static char spinner_chars[] = { '*','*', '*', ' ', ' '};
cspinner++;
lcd.print(spinner_chars[cspinner%sizeof(spinner_chars)]);
}

//-------------------------------------------------------------------------
//----------------------------- ESP8266 WiFi ------------------------------
//--------------------------Plot System data on thingspeak.com-------------
//-------------------------------------------------------------------------
void wifi_datalog()
{
// thingspeak needs 15 sec delay between updates
static int lastlogged;
if ( seconds - lastlogged < 16 )
return;
lastlogged = seconds;
// convert to string
char buf[16];
String strTemp = dtostrf( sol_volts, 4, 1, buf);

Serial.println(strTemp);

// TCP connection
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "184.106.153.149"; // api.thingspeak.com
cmd += "\",80";
ser.println(cmd);

if(ser.find((char *)"Error")){
Serial.println("AT+CIPSTART error");
return;
}

// prepare GET string
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr +="&field1=";
getStr += String(strTemp);
getStr += "\r\n\r\n";

// send data length
cmd = "AT+CIPSEND=";
cmd += String(getStr.length());
ser.println(cmd);

if(ser.find((char *)">")){
ser.print(getStr);
}
else{
ser.println("AT+CIPCLOSE");
Serial.println("AT+CIPCLOSE");
}
}
```

## Schematics

• 1 project
• 2 followers

#### Published on

November 27, 2017

#### Members who respect this project

and 9 others

See similar projects
you might like

#### Getting Started with Arduino Web Editor on Various Platforms

• 1,292,585 views
• 1,940 respects

#### Arduino Bluetooth Basic Tutorial

• 454,682 views
• 236 respects

#### DS18B20 (digital temperature sensor) and Arduino

• 323,491 views
• 100 respects

#### Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

• 289,739 views
• 677 respects

#### Security Access Using RFID Reader

• 229,864 views