evening all
i am having trouble with a sketch i found online and modified to suite my project
its an auto start 12v generator.
it starts the engin when the battery voltage falls below 12v.
i put in the code to shutdown when the voltage reaches 14v, but despite this, it shuts down at 12.1v.
im a newb to code so im not sure where i have gone wrong. i can edit existing code but i would be lost to start a new code from scratch.
i will have to post the code in more than 1 go
#include "DS3231.h" //github.com/NorthernWidget/DS3231
#include <Wire.h> //used with ds3231.h for the i2c
#include <Servo.h> //Choke Servo Library
int VOLTS = A0;
//int SDA = A4; //This is not needed but makes it human readable to know the SDA i2c channel is A4
//int SCL = A5; //This is not needed but makes it human readable to know the SCL i2c channel is A5
int GEN = 3; //generator RPM pin
//int Choke = 4; //This is not needed but makes it human readable to know choke servo is on pin 4
int IGN = 6; //Ignition Pin
int SW = 2; //Starter Pin
int ALT = 7; // alternator feed relay
int PUSHBUTTON = 5; //Button Pin
int AlternatorOn = 1; //alternator on
int StopLed = 9; //Safe to stop generator LED
int IgnLed = 10; //Ignition on LED
int StartLed = 11; //Starter on LED
int GenLed = 12; //Generator run LED
Servo ChokeServ;
uint32_t Start_Time = 10000; //10 seconds to allow starter to run per attempt
uint32_t Wait_Time = 15000; //30 seconds to wait between start attempts to allow starter to cool
const unsigned long sampleTime = 1000;
int long Gen_Shutdown_Time = 0;
int long Gen_Test_Time = 0;
int long Now_Test_Time = 0;
int long Now_Stop_Time = 0;
int long Stop_Time = 0;
int Current_Time = 0;
int Time_Left = 0;
int ButtonTimeLeft = 0;
int IGN_Attempt = 0;
int SwState = 0;
int IgnState = 0;
int GenRpm = 0;
int GenState = 0;
int ButtonState = 0;
int StopState = 0;
int TestState = 0;
int Volts = 0;
int readIndex = 0;
int AutoState = LOW; //this is to indicate if generator manual started or automated.
DateTime now;
RTClib RTC;
void setup() {
Serial.begin(115200); //enable serial connection for debug. Switch any oled.print to serial.print to send to serial
pinMode(VOLTS,INPUT);
pinMode(GEN,INPUT);
pinMode(ALT,OUTPUT);
pinMode(IGN,OUTPUT);
pinMode(SW,OUTPUT);
pinMode(GenLed,OUTPUT);
pinMode(StopLed,OUTPUT);
pinMode(IgnLed,OUTPUT);
pinMode(StartLed,OUTPUT);
pinMode(AlternatorOn,OUTPUT);
pinMode(PUSHBUTTON,INPUT);
digitalWrite(ALT,HIGH); //alternator relay
digitalWrite(IGN,HIGH); //Starter off
digitalWrite(SW,LOW); //Ignition off
digitalWrite(AlternatorOn,LOW); // alternator led
digitalWrite(GenLed,LOW); //LED off
digitalWrite(StopLed,LOW); //LED off
digitalWrite(IgnLed,LOW); //LED off
digitalWrite(StartLed,LOW); //LED off
ChokeServ.attach(4); //Choke servo on pin 4
ChokeServ.write(80);
Wire.begin();
}
void gen_status() { //generator loop to look at current generator state
GenRpm = getRPM();
Serial.print("RPM");
Serial.println(GenRpm);
if(GenRpm>=700) { //Check the RPMs of the generator and 300 or higher is running
digitalWrite(GenLed,HIGH); //turn on LED if generator is running
GenState = HIGH; //Set Gen state to high indicating generator is running
}
else {
digitalWrite(GenLed,LOW); //turn off LED if generator is not running
GenState = LOW; //Set GenState to low indicating generator is not running
}
}
void volt_status() { //check on voltage to see battery is low
int analog_value = analogRead(A0);
float Volts= (analog_value *25) / 1023;
}
void genstart() { //Generator start sequence
if(IGN_Attempt<3 && GenState==LOW) { //Try this for 3 attempts with Generator at low and less than as starts with attempt 0
IGN_Attempt++; //add one count to start attempts
Serial.print(IGN_Attempt);
Serial.println(" of 3 attempts");
Serial.println("Gen not running");
delay(200); //wait 200ms to let choke get to set
Serial.println("Ignition on");
digitalWrite(IGN,LOW); //Ignition On
digitalWrite(IgnLed,HIGH); //Ignition LED on
ChokeServ.write(15);
Serial.println("choke on");
delay(200); //wait 1 second before starter attempt
Serial.println("Starter on");
for( uint32_t timer = millis(); (millis()-timer) < Start_Time; ) { //start a timer in milliseconds called timer and compare to time set against Start_Time
digitalWrite(SW,HIGH); //Starter On
digitalWrite(StartLed,HIGH); //Starter LED on
gen_status();
if(GenState==HIGH) { //generator running
Serial.println("Starter off");
digitalWrite(SW,LOW); //Starter off
digitalWrite(StartLed,LOW); //Starter LED off
digitalWrite(ALT,LOW); // alternator on
digitalWrite(AlternatorOn,HIGH); // alternator led
delay(4000);
ChokeServ.write(80);
Serial.println("Generator running");
Serial.print("choke off");
AutoState = 1;
break;
}
delay(1);
}
Serial.println("Starter off");
digitalWrite(SW,LOW); //Starter Off
digitalWrite(StartLed,LOW); //Starter LED off
gen_status();
//if Start loop complete and genrator not running wait 30 sec before next attempt but if 3rd attempt no reason to delay since wont try start attempt again
if(GenState==LOW && Volts<=12 && IGN_Attempt < 3) {
Serial.println("Tried for 10 seconds");
Serial.println("Failed to start");
Serial.println("Wait 30 seconds");
for( uint32_t timer2 = millis(); (millis()-timer2) < Wait_Time; ) {
}
}
}
else {
if(GenState==HIGH) { //change to RPM to indicate generator running
Serial.println("Generator running");
IGN_Attempt=0;
}
else { //Generator did not start so shutdown everything
genshutdown();
Serial.println("Failed to start!");
Serial.println("Please check");
Serial.println("generator!");
}
}
}
void loop() {
int analog_value = analogRead(A0);
float Volts= (analog_value / 1023.00) * 24;
Serial.print("volts");
Serial.println(Volts);
DateTime now = RTC.now();
volt_status();
gen_status(); //get generator run status
GenRpm = getRPM(); //check RPM on generator
SwState = digitalRead(SW); //current SW relay state
IgnState = digitalRead(IGN); //current IGN relay state
ButtonState = digitalRead(PUSHBUTTON); //current button state
StopState = digitalRead(StopLed); //current state of the system safety LED
testrun(); //check to see if we should run the monthly test run
if (Volts<=12) { //This indicates the BATTERY voltage LOW
genstart();
}
else { //if AC power from the pole is available
if (Volts>=14.3) {
genshutdown();
}
Serial.print("Good ");
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.println(now.second(), DEC);
if(GenState==HIGH && AutoState==HIGH) { //if generator is running in an auto fashion
if(TestState == HIGH) { //check if running generator test
if(Gen_Test_Time <= now.unixtime()) { //use generator test time to decide if we shutdown
genshutdown();
TestState = LOW;
AutoState = LOW;
delay(1);
}
else {
Serial.print("Run test for ");
Serial.print(Gen_Test_Time - now.unixtime());
Serial.println(" s");
}
}
if(TestState == LOW) { //not running generator test
if(Stop_Time <= now.unixtime() && StopState==LOW) { //5 minute count down for cool down before begin shutdown and Red LED is off
genshutdown();
AutoState = LOW;
delay(1);
}
else {
Gen_Shutdown_Time = Stop_Time - now.unixtime();
Serial.print("Shutdown in ");
Serial.print(Gen_Shutdown_Time);
Serial.println(" s");
delay(1);
}
}
}
if(GenState==HIGH && AutoState==LOW) {
Serial.println("Generator manual run");
}
delay(800);
IGN_Attempt=0; //reset ignition attempts
}
}
stockleys:
i will have to post the code in more than 1 go
If the program is too long to include in a Post then add your .ino file as an attachment. I'm not going to join pieces together in case I introduce errors.
Better still make a short program that illustrates the problem and post that.
How did the program get so long before you noticed the problem? It's much better to develop a big program in very small stages.
You may have to allow for the fact that the voltage will be higher while the generator is running compared to the battery voltage when the generator is turned off. If you are using a lead-acid battery then to know the true battery voltage you need to leave the battery unused for about 12 hours to allow it to settle - which is almost certainly an impractical requirement.
You have 3 separate variables all named Volts, one global int and the others floats local to either loop() or volt_status(). Oh and another called VOLTS but that just names a pin and isn't ever used when reading that pin.
i did not build this code from scratch.
it was freely available online.
it was written to fire up a back up generator when mains power failed.
but i have changed it from ac mains voltage to dc 12v and no change over.
with regards to the voltage climbing while the engine is running, i realise this, but it is only intended to fire up while a heavy load is on (kettle at 2.2kw over 160amps at 12v) and the alternator is only 60amps so its never going to shoot up to over 14v untill the kettle has finished boiling. but it is capable of increasing the voltage to close to 12v while the engine is running, but its shutting down at 0.1v above the startup set voltage.
if im honest, i dont understand all the terms used for different aspects i.e "int", "const int"
with the float volts, i wasnt getting a voltage reading so i put the float into the void loop and it showed the voltage
I suggest you go through the program and change the names of the variables called Volts (in various character styles) into names that are recognisably different and meaningful.
for example VOLTS might be changed to VoltageMeasurePin
And you seem to be using the same name Volts for an int in one place and a float in another - why?
Then it just might be possible to figure out how the program works.