Automatic Solar Grid Tie Switch v2.0

Posted on 31/07/2015 by Adam

I’ve been working on a new version of my automatic grid tie switch.  If you haven’t seen my previous post or video it’s a device which will switch my sheds solar panels from the battery charge controller to a micro grid tie converter depending on the battery voltage.  The idea is I want my solar panels to deliver everything they’ve got for as long as they can each day.

I’ve made some improvements to the first version.  One major hardware change, and one software.  Hardware wise I’ve added an LCD screen which tells me which mode the switch is in, and it shows me the current battery voltage.

The software has been improved to ensure that the grid tie invertor can be fed until the battery reaches a low level set in the code.  A previous state interger has been added to ensure that the switch can be in either state between a low and high battery level.

Watch the video – scrutinize the code below.  Feel free to comment and share.

 

 

[code]/*
* Automated Grid Tie Switch. 1602 LCD version
*
* Using a voltage sensor and a relay board this sketch allows solar panels to feed a charge controller or grid tie converter based on a batteries voltage.
*
* An 1602 LCD screen and a manual override switch add extra functionality.
*
* In this version you can set a minimum and maximum voltage for the battery by adjusting the battLow and battFull variables below.
*
* .
*
*/

#include <LiquidCrystal.h> //Include library for LCD display
LiquidCrystal LCD(10, 9, 5, 4, 3, 2); // Create Display Object called LCD

//Constant vars

const int gridSwitchPin = 7; //Declare arduino pin for manual grid switch pin
const int battSwitchPin = 8; //Delare arduino pin for manual battery switch pin
const int relayPositivePin = 11; //Declare arduino pin for positive relay
const int relayNegativePin = 12; //Declare arduino pin for negative relay
const int statusLEDPin = 13; //Decalre arduino pin for status LED
const int battAnalogPin = A1; //Declare arduino analog input pin for voltage sensor

// vars that will change

int gridSwitchState = 0; //Grid Tie manual switch initial value
int battSwitchState = 0; //Battery manual switch initial value
int voltReading = 0; //Voltage sensor initial value
int lastVoltReading = 0; //Voltage sensor averaging value
int previousState = 0; //previous switch mode. 0 is battery charge, 1 is grid tie
float battVoltage = 0.0; //set initial battery voltage
float battFull = 13.8; //Set your battery full voltage
float battLow = 12.6; //Set batt low voltage
float voltageReference = 4.98872180; //Using a multimeter check voltage between 5v and ground on arduino and state here
float voltageFactor = 1.0; //Factor used to calculate difference between 5 volts and real 5 volt rail. Initialize to 1
// Declare relays

#define RELAY_ON 0 //relay module active low – this helps readers understand what it going on
#define RELAY_OFF 1

void setup()
{
digitalWrite(relayPositivePin,RELAY_OFF); //Deafult relay off
digitalWrite(relayNegativePin,RELAY_OFF); //Default relay off
pinMode(statusLEDPin,OUTPUT); //initialize the led pin as output
pinMode(relayPositivePin,OUTPUT); //initialize the positive relay pin as output
pinMode(relayNegativePin,OUTPUT); //initialize the negative relay pin as output
pinMode(gridSwitchPin,INPUT); //initialize the manual Grid switch as input
pinMode(battSwitchPin,INPUT); //initialize the manual Battery switch as input
voltageFactor = (5.0 / voltageReference);
LCD.begin(16,2); //LCD screen is 16×2
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("AdmW Solar Shed "); //Print branding
LCD.setCursor(0,1); //Set LCD cursor to bottom left
LCD.print("GTI Switch v2.0 "); //Print version number
// Serial.begin(9600);
delay(2000);
}
/**********************************/
void loop()
{
digitalWrite(statusLEDPin,HIGH);//turn on status indicator LED
gridSwitchState = digitalRead(gridSwitchPin); //read state of GTI Switch
battSwitchState = digitalRead(battSwitchPin); //read the state of battery switch

//Start reading voltage

analogRead(battAnalogPin); //Read Voltage pin
delay(10); // Wait for pin to settle
voltReading = analogRead(battAnalogPin); //Read more accurate voltage pin reading
voltReading = (voltReading + lastVoltReading) /2; //Average last two results
lastVoltReading = voltReading;
battVoltage = (voltReading * voltageFactor * 25.0 / 1024.0); //calculate the voltage

//Display voltage on LCD row 1

LCD.setCursor(0,1); //Set LCD Cursor to bottom left
LCD.print("Battery: "); // Show battery
LCD.setCursor(10,1); //Set LCD cursor after battery:
LCD.print(battVoltage); //display calculated battery voltage.
LCD.setCursor(15,1); //Set LCD cursor after battVoltage
LCD.print("v"); //display v for volts.

if (battSwitchState == HIGH && gridSwitchState == LOW)
{

//Display mode on LCD
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("Manual – Charge "); //Print mode

//Switch relays
digitalWrite(relayPositivePin,RELAY_OFF); //send solar positive to Batt Charge
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_OFF); //send solar negative to Batt Charge

//Print information to Serial
Serial.print("Manual Battery Charge Mode!");//Serial print Auto Battery Charge Mode
Serial.print(" Battery Voltage: ");
Serial.print(battVoltage);
Serial.println("v");
delay(500);
}

else if (battSwitchState == LOW && gridSwitchState == HIGH)
{
//Display mode on LCD
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("Manual – Grid "); //Print mode

//Switch relays
digitalWrite(relayPositivePin,RELAY_ON); //send solar positive to Grid Tie
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_ON); //send solar negative to Grid Tie

//Print information to Serial
Serial.print("Manual Grid Tie Mode!");//Serial print Auto Battery Charge Mode
Serial.print(" Battery Voltage: ");
Serial.print(battVoltage);
Serial.println("v");
delay(500);
}

else if (battSwitchState == LOW && gridSwitchState == LOW)
{

if (battVoltage <= battLow )
{
//Display mode on LCD row 0
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("Auto – Charge "); //Print mode

//Switch relays
digitalWrite(relayPositivePin,RELAY_OFF); //send solar positive to Batt Charge
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_OFF); //send solar negative to Batt Charge

//Print information to Serial
Serial.print("Automatic Battery Charge Mode!");//Serial print Auto Battery Charge Mode
Serial.print(" Battery Voltage: ");//Print second line
Serial.print(battVoltage);
Serial.println("v");
previousState = 0; //Set previous mode to batt
delay(500);
}

else if (battVoltage > battLow && battVoltage < battFull && previousState == 0) //Battery voltage higher than battLow voltage but less than battFull voltage and previous state was charge – keep charging.
{
//Display mode on LCD row 0
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("Auto – Charge "); //Print mode

//Switch relays
digitalWrite(relayPositivePin,RELAY_OFF); //send solar positive to Batt Charge
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_OFF); //send solar negative to Batt Charge

//Print information to Serial
Serial.print("Automatic Battery Charge Mode!");//Serial print Auto Battery Charge Mode
Serial.print(" Battery Voltage: ");//Print second line
Serial.print(battVoltage);
Serial.println("v");
previousState = 0; //Set previous mode to batt
delay(500);
}

else if (battVoltage > battLow && battVoltage < battFull && previousState == 1) //Battery higher than battLow voltage but less than battery full voltage and previous state was grid tie – stay at grid tie.
{
//Display mode on LCD row 0
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("Auto – Grid Tie "); //Print mode

//Switch relays
digitalWrite(relayPositivePin,RELAY_ON); //send solar positive to Grid Tie
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_ON); //send solar negative to Grid Tie

//Print information to Serial
Serial.print("Automatic Grid Tie Mode!");//Serial print Auto Battery Charge Mode
Serial.print(" Battery Voltage: ");
Serial.print(battVoltage);
Serial.println("v");
previousState = 1; //Set previous mode to grid
delay(500);
}
else if (battVoltage >= battFull) //Battery high than battery full voltage – go to grid tie.
{
//Display mode on LCD row 0
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print("Auto – Grid Tie "); //Print mode

//Switch relays
digitalWrite(relayPositivePin,RELAY_ON); //send solar positive to Grid Tie
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_ON); //send solar negative to Grid Tie

//Print information to Serial
Serial.print("Automatic Grid Tie Mode!");//Serial print Auto Battery Charge Mode
Serial.print("Battery Voltage: ");
Serial.print(battVoltage);
Serial.println("v");
previousState = 1; //Set previous mode to grid
delay(500);
}
}
else
{
//Unkown state – protect system
LCD.setCursor(0,0); //Set LCD cursor to top left
LCD.print(" Unknown State! "); //Print mode

//Disconnect solar from both systems

digitalWrite(relayPositivePin,RELAY_OFF); //send solar positive to Batt Charge
delay(500); //wait half a second
digitalWrite(relayNegativePin,RELAY_ON); //send solar negative to Grid

digitalWrite(statusLEDPin,HIGH); //Turn on status LED
delay(100); //wait a tenth of a second
digitalWrite(statusLEDPin,LOW); //Turn off status LED
delay(100); //wait a tenth of a second
}
}

/************************************/

[/code]