#define BLYNK_TEMPLATE_ID "xxx"
#define BLYNK_DEVICE_NAME "xxx"
//#define BLYNK_AUTH_TOKEN "xxx"
#define BLYNK_PRINT Serial
#define BLYNK_FIRMWARE_VERSION "5.4"
#define APP_DEBUG
#define BLYNK_GREEN "#23C48E"
#define BLYNK_RED "#D3435C"
#define BLYNK_YELLOW "#ED9D00"
#define USE_WEMOS_D1_MINI
#include "BlynkEdgent.h"
int CEBsensor = 0;
int CEBstate = 0;
int Timerstate = 0;
int InvTimerstate = 0;
int inverterstate = 0;
//Voltage Sensor
int Vsensor = A0;
float correctionfactor = 7.40;
float vout = 0.0;
float vin = 0.0;
float fuelcon = 0.0;
float R1 = 30000;
float R2 = 7500;
int value = 0;
//Declare millis for timers
unsigned long msec = 0;
unsigned long msec2 = 0;
float times = 0.0;
float hourmeter = 0.0;
BlynkTimer timer;
//Blynk LED Widgets
WidgetLED led1(V3); //COIL LED
WidgetLED led2(V7); //FUEL LED
WidgetLED led3(V4); //STARTER LED
WidgetLED led13(V13); //GENERATOR SHUTOFF LED
WidgetLED led14(V14); //CEB STATUS LED
WidgetLED led15(V18); //INVERTER STATUS LED
WidgetLED led16(V20); //INVERTER SHUTOFF LED
WidgetLED led17(V24); //CHANGEOVER RELEASE INDICATOR
int newTimer = 1;
void setup()
{
Serial.begin(115200);
delay(100);
pinMode(D0, OUTPUT); //STARTER Relay
pinMode(D5, OUTPUT); //FUEL Relay
pinMode(D6, OUTPUT); //COIL Relay
pinMode(D7, OUTPUT); //INVERTER Relay
pinMode(D1, INPUT); //CEB LDR Sensor
pinMode(Vsensor, INPUT); //Voltage Sensor (A0)
{
digitalWrite(D0,HIGH);
digitalWrite(D5,HIGH); //(To prevent self-trigger during initial boot)
digitalWrite(D6,HIGH);
}
BlynkEdgent.begin();
timer.setInterval(1000L,CEBsensor1);
timer.setInterval(1000L,runtime);
timer.setInterval(1000L,invertertime);
timer.setInterval(10000L,Voltagesensor1);
}
void loop() {
BlynkEdgent.run();
timer.run();
}
BLYNK_CONNECTED() {
Blynk.syncVirtual(V10,V18); //Works, Doesn't get triggered when not on
}
void invertertime()
{
if(CEBstate == LOW){
if(inverterstate == HIGH){
led15.on();
Blynk.setProperty(V10, "color", "#23C48E");
Blynk.setProperty(V18, "color", "#23C48E"); //Inverter Status (ON) GREEN
digitalWrite(D7,HIGH); //INV RELAY ON
delay(100);
Blynk.setProperty(V2, "offLabel", "OFF Inverter Before Starting");
Blynk.setProperty(V2, "onLabel", "OFF Inverter!");
} else {
Blynk.setProperty(V18, "color", "#ED9D00"); //Inverter Status (OFF) Yellow
Blynk.setProperty(V10, "color", "#ED9D00");
digitalWrite(D7,LOW); //INV RELAY OFF
delay(100);
Blynk.setProperty(V2, "offLabel", "Hold to Start");
Blynk.setProperty(V2, "onLabel", "Release");
}
} else {
}
if(inverterstate == HIGH && CEBsensor ==LOW){
led16.on(); //Inverter Shutoff Indicator ON
yield();
} else {
led16.off(); //Inverter Shutoff Indicator OFF
yield();
}
}
void runtime()
{
if(CEBstate == HIGH && Timerstate == HIGH){
times = ((millis() - msec));
Blynk.setProperty(V16, "label", "Current Generator Run Time");
Blynk.setProperty(V17, "label", "Current Fuel Consumption");
{
String readableTime;
getReadableTime(readableTime);
Blynk.virtualWrite(V16, readableTime);
Blynk.virtualWrite(V17, 1.7 * ((millis() - msec)/1000)/3600);
delay(500);
}
} else {
}
if(InvTimerstate == HIGH && CEBstate == LOW && Timerstate == LOW){
times = ((millis() - msec2));
Blynk.setProperty(V16, "label", "Inverter Run Time");
{
String readableTime;
getReadableTime(readableTime);
Blynk.virtualWrite(V16, readableTime);
}
delay(500);
} else {
}
}
void getReadableTime(String &readableTime) {
unsigned long currentMillis;
unsigned long seconds;
unsigned long minutes;
unsigned long hours;
unsigned long days;
currentMillis = times;
seconds = currentMillis / 1000;
minutes = seconds / 60;
hours = minutes / 60;
days = hours / 24;
currentMillis %= 1000;
seconds %= 60;
minutes %= 60;
hours %= 24;
if (days > 0) {
readableTime = String(days) + " ";
}
if (hours > 0) {
readableTime += String(hours) + "H:";
}
if (minutes < 10) {
readableTime += "0";
}
readableTime += String(minutes) + "m:";
if (seconds < 10) {
readableTime += "0";
}
readableTime += String(seconds) + "s";
}
BLYNK_WRITE(V1)
//attach Button on virtual V1,
//it will control the Coil
{
if (param.asInt() == 1){
delay(100);
digitalWrite(D6,LOW); //COIL RELAY ON
delay(100);
led1.on();
msec = millis();
CEBstate = 1;
}
if (param.asInt() == 0){
delay(100);
digitalWrite(D6,HIGH); //COIL RELAY OFF
delay(100);
led1.off();
CEBstate = 0;
Blynk.setProperty(V16, "label", "Previous Generator Run Time");
Blynk.setProperty(V17, "label", "Previous Fuel Consumption");
//Blynk.setProperty(V23, "isDisabled", true);
delay(100);
Blynk.logEvent("generator_off");
}
}
BLYNK_WRITE(V2)
//attach Button on virtual V2,
//it will control the Starter
{
if(param.asInt()){
newTimer = timer.setTimeout(2000,Starter); // button pressed for >2Sec
}
else {
timer.disable(newTimer);
}
}
void Starter()
{
if(inverterstate == LOW){
led3.on();
digitalWrite(D0,LOW); //STARTER CRANK ON
delay(1200); //CRANK DURATION
digitalWrite(D0,HIGH); //STARTER CRANK OFF
led3.off();
Blynk.logEvent("generator_on");
//Blynk.setProperty(V23, "isDisabled", true);
}else{
}
}
BLYNK_WRITE(V9)
//attach Button on virtual V9,
//This will control the Fuel
{
if (param.asInt() == 1){
delay(100);
digitalWrite(D5,LOW); //FUEL RELAY ON
delay(100);
led2.on();
Timerstate = 1;
}
if (param.asInt() == 0){
delay(100);
digitalWrite(D5,HIGH); //FUEL RELAY OFF
delay(100);
led2.off();
Timerstate = 0;
}
}
BLYNK_WRITE(V10)
//attach Button on virtual V10,
//it will control the Inverter Relay
{
ESP.wdtFeed();
if (param.asInt() == 1){
inverterstate = 1;
msec2 = millis();
InvTimerstate = 1;
Blynk.logEvent("inverter_on");
Blynk.setProperty(V22, "isDisabled", true);
Blynk.setProperty(V23, "isDisabled", false);
}
if (param.asInt() == 0){
inverterstate = 0;
InvTimerstate = 0;
Blynk.logEvent("inverter_off");
Blynk.setProperty(V22, "isDisabled", false);
}
}
BLYNK_WRITE(V15)
//attach Button on virtual V15,
//This will update System Status
{
if (param.asInt() == 1){
Blynk.virtualWrite(V8, map(WiFi.RSSI(), -110, -30, 30, 100));
delay(100);
}
if (param.asInt() == 0){
}
}
BLYNK_WRITE(V19)
//attach Button on virtual V19,
//This will reset Coil/Fuel Status
{
if (param.asInt() == 1){
Blynk.virtualWrite(V1, 0);
led1.off();
Blynk.virtualWrite(V9, 0);
led2.off();
delay(100);
Blynk.setProperty(V16, "label", "Previous Run Time");
Blynk.setProperty(V17, "label", "Previous Fuel Consumption");
delay(100);
Blynk.logEvent("generator_off");
Timerstate = 0;
CEBstate = 0;
}
if (param.asInt() == 0){
}
}
void CEBsensor1()
//Run every second
{
CEBsensor = digitalRead(D1); //LDR Sensor
Blynk.virtualWrite(V12, CEBsensor);
//If COIL ON and CEBsensor LOW, Trigger "Grid Restored" Blynk Automation
if(CEBsensor == LOW && CEBstate == HIGH){
led13.on(); //Shutoff Indicator ON
yield();
} else {
led13.off(); //Shutoff Indicator OFF
yield();
}
//CEB STATUS LED
if(CEBsensor == HIGH){
led14.on();
Blynk.setProperty(V14, "color", "#D3435C"); //CEB Status (ON) RED
Blynk.logEvent("grid_failure");
Blynk.setProperty(V23, "isDisabled", false);
Blynk.setProperty(V22, "isDisabled", false);
yield();
} else {
Blynk.setProperty(V14, "color", "#23C48E"); //CEB Status (ON) GREEN
Blynk.setProperty(V23, "isDisabled", true);
Blynk.setProperty(V22, "isDisabled", true);
yield();
}
}
void Voltagesensor1()
//Run every 10 sec
{
int sdata = 0;
value = analogRead(Vsensor);
vout = (value * 5.0) / 1024.0;
vin = vout / (R2/(R1+R2));
vin = vin - correctionfactor;
Blynk.virtualWrite(V5, vin);
yield();
if(vin < 12.0){
Blynk.setProperty(V5, "color", "#D3435C"); //If UPS Voltage < 12.5v, Gauge RED
}else{
Blynk.setProperty(V5, "color", "#F7CE46"); //If UPS Voltage > 12.5v, Gauge ORANGE
}
}
//BETA
BLYNK_WRITE(V22)
//attach Button on virtual V22,
//it will control the GENtoINV
{
if(param.asInt()){
newTimer = timer.setTimeout(2000,GENtoINV); // button pressed for >2Sec
}
else {
timer.disable(newTimer);
}
}
void GENtoINV()
{
if(inverterstate == LOW){
{
led17.on();
//FUEL
Blynk.virtualWrite(V1, 0);
led1.off();
digitalWrite(D6,HIGH); //COIL RELAY OFF
delay(100);
CEBstate = 0;
Blynk.setProperty(V16, "label", "Previous Generator Run Time");
Blynk.setProperty(V17, "label", "Previous Fuel Consumption");
delay(100);
Blynk.logEvent("generator_off");
}
delay(1500);
{
//COIL
Blynk.virtualWrite(V9, 0);
led2.off();
digitalWrite(D5,HIGH); //FUEL RELAY OFF
delay(100);
Timerstate = 0;
}
delay(2000);
{
//INV Relay
Blynk.virtualWrite(V10, HIGH);
inverterstate = 1;
msec2 = millis();
InvTimerstate = 1;
Blynk.logEvent("inverter_on");
led17.off();
}
}else{
}
}
BLYNK_WRITE(V23)
//attach Button on virtual V23,
//it will control the INVtoGEN
{
if(param.asInt()){
newTimer = timer.setTimeout(2000,INVtoGEN); // button pressed for >2Sec
}
else {
timer.disable(newTimer);
}
}
void INVtoGEN()
{
{
//INV RELAY OFF
led17.on();
inverterstate = 0;
InvTimerstate = 0;
Blynk.logEvent("inverter_off");
{
Blynk.virtualWrite(V10, 0);
Blynk.setProperty(V10, "color", "#ED9D00");
Blynk.setProperty(V18, "color", "#ED9D00"); //Inverter Status (OFF) Yellow
digitalWrite(D7,LOW); //INV RELAY OFF
delay(100);
Blynk.setProperty(V2, "offLabel", "Hold to Start");
Blynk.setProperty(V2, "onLabel", "Release");
}
Blynk.setProperty(V22, "isDisabled", false);
}
delay(3000);
{
//FUEL
Blynk.virtualWrite(V9, 1);
digitalWrite(D5,LOW); //FUEL RELAY ON
led2.on();
Timerstate = 1;
}
delay(1500);
{
//COIL
Blynk.virtualWrite(V1, 1);
digitalWrite(D6,LOW); //COIL RELAY ON
led1.on();
msec = millis();
Blynk.setProperty(V23, "isDisabled", true);
CEBstate = 1;
}
delay(2000);
{
//STARTER
if(inverterstate == LOW){
led3.on();
digitalWrite(D0,LOW); //STARTER CRANK ON
delay(1200); //CRANK DURATION
digitalWrite(D0,HIGH); //STARTER CRANK OFF
led3.off();
Blynk.logEvent("generator_on");
led17.off();
}
}
}