//---------------------------------------------------------------------------------
-------------------
// 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 <LiquidCrystal_I2C.h> // using the LCD I2C Library from
https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
#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
// D6 - Load Control
// 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
// Load control algorithm
// 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 LOAD_ALGORITHM 0
#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
#define AVG_NUM 8 // number of iterations of the adc routine
to average the adc readings
// 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 load control pin
#define LOAD_PIN 6 // pin-2 is used to control the load
//---------------------------------------------------------------------------------
--------------------
// 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 = "DPK8RMTFY2B1XCAF";
// 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:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 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
charger_state = off; // start with charger state as off
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);
pinMode(LOAD_PIN,OUTPUT);
digitalWrite(LOAD_PIN,LOW); // default load state is OFF
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()
{
read_data(); // read data from inputs
run_charger(); // run the charger state machine
print_data(); // print data
load_control(); // control the connected load
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 read_adc(int channel){
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
temp = analogRead(channel); // read the input pin
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.
//---------------------------------------------------------------------------------
---------------------
void read_data(void) {
sol_amps = (read_adc(SOL_AMPS_CHAN) * SOL_AMPS_SCALE -13.51); //input of solar
amps
sol_volts = read_adc(SOL_VOLTS_CHAN) * SOL_VOLTS_SCALE; //input of solar
volts
bat_volts = read_adc(BAT_VOLTS_CHAN) * BAT_VOLTS_SCALE; //input of
battery volts
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;
}
}
//---------------------------------------------------------------------------------
-------------------------------------
/////////////////////////////////////////////LOAD
CONTROL/////////////////////////////////////////////////////
//---------------------------------------------------------------------------------
-------------------------------------
void load_control(){
#if LOAD_ALGORITHM == 0
// 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
}
void load_on(boolean new_status) {
if (load_status != new_status) {
load_status = new_status;
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;
back_light_pin_State = digitalRead(BACK_LIGHT_PIN);
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("% ");
//----------------------------------------------------------------------
//------------------------Load Status-----------------------------------
//----------------------------------------------------------------------
lcd.setCursor(15,2);
lcd.print("Load");
lcd.setCursor(15,3);
if (load_status)
{
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");
// alert user
Serial.println("AT+CIPCLOSE");
}
}