// =======================================================
// Automatic reserve gasoline generator start controller
// © OBO email: [email protected]
// ver. 0.0
// =======================================================
//
// Program to be used for automatic reserve gasoline generator start, where control of chock needed.
//
// Autostart is designed to be used together with UPC. Generator is started automatically when city power cut (CityVPin) and
// UPC battery discharged (BatteryPin). If city power comes back or UPC battery fully charged - generator will be stopped.
// Also generator could be started/stopped by button (ButtonPin).
//
// After power on the controller yellow "Idle" indicator is light up showing that generator is idle and ready to be started.
// If gasoline level (GasolinePin) is low - yellow indicator will blink, and generator will not start.
// When city power is shut down and UPC battery level became low - generator will be started:
// 1) ignition is on (IgnitionPin relay) 2) chock is full close (ChockOnPin relay) 3) attempt to start generator.
// If after three atempts generator is not started - red "Error' indication is light up.
// When generator started successfully - chock is fully open (ChockOffPin relay), load switch on (SwitchPin relay), green "Work" indicator is light up.
// If during generator work gasoline level became low - green indicator starts blinking.
// While generator running oil level (OilPin), temperature (TemperaturePin) and power (GenVPin) are controlled and generator will be stopped if oli level low, or temperature is too high.
// If motor stalls - Autostart will try to start it again.
// If generator is stopped due to low oil level or too high temperature or power cut - red "Error" indicator is light up.
// Errors could be reset by button.
// Generator will be shut down if city power comes back, or UPC battery is fully charged. In any case generator will be shut down after set time (workTimePermit) and will be started again after set period (idleTime).
// Extetnal time relay could be used for schedule maintain start of generator (SchedulePin)
// Cooling fan could be connected to (FanPin relay).
#include <OneWire.h> //onewire protocol external library
#include <DallasTemperature.h> //dallas temperature sensor external library
OneWire oneWire(3); //temperature sensor pin
DallasTemperature sensor(&oneWire);
#define GreenLed 11 //running successfully led indicator
#define RedLed 12 //error indicator
#define YellowLed 13 //standby indication
#define BatteryPin A7 //UPS battery level probe
#define GasolinePin A6 //gasoline level probe
#define OilPin A3 //oil pressure probe
#define CityVPin A2 //city energy probe
#define GenVPin A1 //generator energy probe
#define GenRunPin A0 //generator runner probe (for example 12V outlet)
#define ChockOnPin 10 //chocke close actuator relay
#define ChockOffPin 9 //chocke open actuator relay
#define IgnitionPin 8 //generator ignition
#define StarterPin 7 //generator starter relay
#define SwitchPin 6 //genarator load switch relay
#define ButtonPin 5 //button - start/stop, reset
#define SchedulePin 4 //external time relay to periodic servise run
#define FanPin 2 //generator external cooling fan relay
unsigned int chockDelay = 1000; //time to generator run with chock full closed
unsigned int startOnTime = 500; //time of starter activation
unsigned int startPause = 500; //pause between attempts to start
unsigned long warmCoolTime = 1000; //cooling time - time to run genarator withou load
unsigned long startTime = 0; // time, when generator was started
unsigned long stopTime = 0; // time, when generator was stopped
unsigned long workTimePermit = 10000; //maximum permitted time for generator to work
unsigned long idleTime = 10000; //idle pause
unsigned long workTimeSchedule = 5000; //time to run by schedule (genirator will work this amount of time + cooling time)
unsigned long tempReadTime = 0; //temparature reading time
unsigned long previousMillis = 0; //varible for using with millis delay code
bool timerStop = false;
bool genError = false;
bool genIsRunning = false;
bool genPower = false;
bool runBySchedule = false;
bool tempError = false;
bool gasError = false;
byte ignitionState = LOW;
byte ledState = LOW;
void setup() {
Serial.begin(9600);
sensor.begin(); //startup temperature sensor library
pinMode(GenRunPin, INPUT_PULLUP); //generator run probe
pinMode(CityVPin, INPUT_PULLUP); //city power probe
pinMode(GenVPin, INPUT_PULLUP); //generator power probe
pinMode(ButtonPin, INPUT_PULLUP); //button
pinMode(OilPin, INPUT_PULLUP); //oil sensor
pinMode(GasolinePin, INPUT); //gasoline tank level probe
pinMode(BatteryPin, INPUT); //UPC battery charge level
pinMode(ChockOnPin, OUTPUT); //chock close
pinMode(ChockOffPin, OUTPUT); //chock open
pinMode(IgnitionPin, OUTPUT); //ignition switch
pinMode(StarterPin, OUTPUT); //starter switch
pinMode(SwitchPin, OUTPUT); //generator load switch
pinMode(FanPin, OUTPUT); //cooling fan relay
pinMode(GreenLed, OUTPUT);
pinMode(RedLed, OUTPUT);
//inital set relays OFF
digitalWrite(ChockOnPin, LOW);
digitalWrite(ChockOffPin, LOW);
digitalWrite(IgnitionPin, LOW);
digitalWrite(StarterPin, LOW);
digitalWrite(SwitchPin, LOW);
digitalWrite(FanPin, LOW);
//initial standby indicator ON
digitalWrite(YellowLed, HIGH);
}
void loop() {
//stop on error
if (genError == true) {
digitalWrite(SwitchPin, LOW); //load OFF
ignitionState = LOW;
digitalWrite(IgnitionPin, ignitionState); //ignition OFF
digitalWrite(RedLed, HIGH); //error indicator ON
digitalWrite(GreenLed, LOW); //run indicator OFF
digitalWrite(YellowLed, LOW); //standby indicator OFF
genIsRunning = false;
genPower = false;
}
//reset errors by button
if (digitalRead(ButtonPin) == LOW) {
digitalWrite(RedLed, LOW); //error indicator OFF
digitalWrite(YellowLed, HIGH); //standby indicator ON
genError = false;
}
//generator normal work routine
while (genError == false) {
//idle generator temperature control
sensor.requestTemperatures();
if (sensor.getTempCByIndex(0) >= 60 || sensor.getTempCByIndex(0) <= -15) { //temperature is out of range
if (millis() - previousMillis >= 500) { //error indicator blinking
previousMillis = millis();
ledState = (ledState == HIGH) ? LOW: HIGH;
digitalWrite(RedLed, ledState);
}
tempError = true;
} else {
digitalWrite(RedLed, LOW);
previousMillis = 0;
tempError = false;
}
//cooling fan OFF while generator is idle
if (sensor.getTempCByIndex(0) <= 30) {
digitalWrite(FanPin, LOW);
}
//gasoline level controlling
if (genIsRunning == false) { //check for proper idle indication
if (analogRead(GasolinePin) >= 1000) {
if (millis() - previousMillis >= 500) {
previousMillis = millis();
ledState = (ledState == HIGH) ? LOW: HIGH;
digitalWrite(YellowLed, ledState);
}
gasError = true;
} else {
digitalWrite (YellowLed, HIGH);
previousMillis = 0;
gasError = false;
}
}
while (genIsRunning == true) {
//generator stop routine
if (((digitalRead(CityVPin) == LOW || analogRead(BatteryPin) <= 10) && runBySchedule == false) || timerStop == true || gasError == true) { //check if city power is ON or button pressed
digitalWrite(SwitchPin, LOW); //switch load OFF
delay (warmCoolTime); //run without load for alternator cooling
ignitionState = LOW;
digitalWrite(IgnitionPin, ignitionState); //ignition OFF
digitalWrite(GreenLed, LOW); //run indicator OFF
digitalWrite(YellowLed, HIGH); //standby indicator ON
stopTime = millis();
genIsRunning = false;
genPower = false;
runBySchedule = false;
}
//oil level sensor error
if (digitalRead(OilPin) == HIGH) {
genIsRunning = false;
genError = true;
}
//engine stall
if (ignitionState == HIGH && digitalRead(GenRunPin) == HIGH) {
digitalWrite(GreenLed, LOW); //run indicator OFF
genIsRunning = false;
genPower = false;
//genError = true; //comment to try to start normally after stall
}
//generator power cut while it is still running
if (genPower == true && digitalRead(GenVPin) == HIGH && digitalRead (GenRunPin) == LOW && runBySchedule == false) {
digitalWrite(GreenLed, LOW); //run indicator OFF
genIsRunning = false;
genError = true;
}
//stop by timer
if (millis() - startTime >= workTimePermit) {
timerStop = true;
}
if (runBySchedule == true && (millis() - startTime >= workTimeSchedule)) {
timerStop = true;
}
//stop by button
if (digitalRead(ButtonPin) == LOW) {
genIsRunning = false;
genError = true;
}
//running generator temperature control
if (millis() - tempReadTime >= 2000) { //read temparature each minute
tempReadTime = millis();
sensor.requestTemperatures();
Serial.print (sensor.getTempCByIndex(0));
}
//cooling fan ON
if (sensor.getTempCByIndex(0) >= 50) {
digitalWrite(FanPin, HIGH);
}
//cooling fan OFF
if (sensor.getTempCByIndex(0) <= 30) {
digitalWrite(FanPin, LOW);
}
//stop by temperature
if (sensor.getTempCByIndex(0) >= 75) {
genIsRunning = false;
genError = true;
}
//gasoline level controling
if (analogRead(GasolinePin) >= 800) {
if (millis() - previousMillis >= 500) {
previousMillis = millis();
ledState = (ledState == HIGH) ? LOW: HIGH;
digitalWrite(GreenLed, ledState);
}
}
if (analogRead(GasolinePin) >= 1010) {
gasError = true;
}
} //generator is running end
//button idle time override
if (digitalRead(ButtonPin) == LOW) {
timerStop = false;
}
//run by external schedule relay
if (digitalRead(SchedulePin) == HIGH) {
runBySchedule = true;
}
//generator start routine
if (((digitalRead(CityVPin) == HIGH && analogRead(BatteryPin) >= 800) || digitalRead(ButtonPin) == LOW || runBySchedule == true) && digitalRead(GenRunPin) == HIGH && timerStop == false && tempError == false && gasError == false) {
while (genError == false && genIsRunning == false) { //generator is not running and ready to start
ignitionState = HIGH;
digitalWrite(IgnitionPin, ignitionState); //ignition ON
digitalWrite(ChockOnPin, HIGH); //close chock
delay(500); //chock actuator runnig time
digitalWrite(ChockOnPin, LOW);
delay(500); //timeout before start attempt
//try to start generator for i times, each time 5 sec longer starter run and 5 sec longer pause between attempts
for (int i = 3; i > 0; i = i - 1) {
delay (startPause+(3-i)*500); //pause between attempts to start generator
digitalWrite(StarterPin, HIGH); //starter run
delay(startOnTime+(3-i)*500); //starter running time
digitalWrite(StarterPin, LOW);
delay(500); //timeout before check if generator is started successfully
if (digitalRead(GenRunPin) == LOW) { //check if generator is running
delay(chockDelay); //run with chock full closed
digitalWrite(ChockOffPin, HIGH); //open chock
delay(500);
digitalWrite(ChockOffPin, LOW);
i = 0; //stop trying to start genarator
startTime = millis();
genIsRunning = true;
}
if (digitalRead(GenRunPin) == HIGH && i == 1) { //error if generator doesnt start after all attempts
genError = true;
}
}
}
// switch load ON
if (digitalRead(GenRunPin) == LOW && digitalRead(CityVPin) == HIGH) { //check if generator is runnig ok with open chock & city power still off
delay(warmCoolTime); //run without load
digitalWrite(SwitchPin, HIGH); //swich load ON
delay (500);
if (digitalRead(GenVPin) == HIGH) { //no power from generator
genError = true;
genPower = false;
} else {
genPower = true;
}
}
} //generator start procedure end
//check if generator is running
if (digitalRead(GenRunPin) == HIGH) {
digitalWrite(GreenLed, LOW); //run OK indication
genIsRunning = false;
} else {
digitalWrite(GreenLed, HIGH);
digitalWrite(YellowLed, LOW);
genIsRunning = true;
}
//reset stop timer
if (millis() - stopTime >= idleTime) {
timerStop = false;
}
} //generator normal work routine end
}