This will get you part way there:
/*
The arduino gets a serial command > fires the "ON" relay > Waits 5 seconds for the fuel pump to prime> then checks to see alternatorPin's state,
if the state is LOW, the ignition relay is fired until the alternatorPin goes HIGH, once the alternatorPin goes HIGH, the ignition relay shuts off.
Then the code waits 10 minutes, after ten minutes the code restarts, waiting for another serial input.
State0: onPin = off, ignitionPin = off, alternatorPin = LOW.
Upon recival of serial command, go to state 1.
State1: onPin = on, ignitionPin = off, alternatorPin = LOW.
after 5 seconds go to state 2.
State2: onPin = on, ignitionPin = on, alternatorPin = LOW.
once alternatorPin becomes HIGH, go to state 3, if alternator pin is alrady HIGH, go to state0 (in case if someone floods the serial)
State3: onPin = on, ignitionPin = off, alternatorPin = HIGH.
once 10 minutes has elapsed go to state 0
*/
// system states
#define STOPPED 0
#define STARTING 1
#define CRANKING 2
#define RUNNING 3
#define FUEL_PUMP_PRIME_TIME 5000
#define RUNNING_TIMEOUT 600000UL
const int ignitionPin = 12;
const int onPin = 11;
const int ledPin = 13;
const int alternatorPin = 4;
int state = STOPPED; // master variable for the state machine
unsigned long StartingTime; // When did we power up the engine? Need this to time the fuel pump priming
unsigned long RunningTime; // When did the engine start? Need this for the ten minute timeout
void setup()
{
pinMode(onPin, OUTPUT);
pinMode(ignitionPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(alternatorPin,INPUT);
Stop(); // Make sure everything is set correctly
Serial.begin(9600);
}
void loop()
{
switch(state)
{
case STOPPED:
HandleStoppedState();
break;
case STARTING:
HandleStartingState();
break;
case CRANKING: // Crank until the engine starts - shouldn't there be a timeout of some sort?
HandleCrankingState();
break;
case RUNNING:
if(millis()-RunningTime > RUNNING_TIMEOUT)
{
Serial.println("Running Timeout");
Stop();
}
break;
default:
Serial.print("Unknown State: ");
Serial.println(state);
Stop(); // Should never get here
break;
}
}
void Stop()
{
Serial.println("Stop");
digitalWrite(ignitionPin,LOW);
digitalWrite(onPin,LOW);
state=STOPPED;
}
void HandleStartingState()
{
if(millis()-StartingTime > FUEL_PUMP_PRIME_TIME)
{
if(digitalRead(alternatorPin)==HIGH)
{
Serial.println("Abort cranking");
Stop(); // Don't crank the engine - it's already running, something is wrong, let's just stop
}
else
{
Serial.println("Start cranking");
digitalWrite(ignitionPin,HIGH);
digitalWrite(onPin,HIGH);
state=CRANKING;
}
}
}
void HandleStoppedState()
{
if (Serial.available() > 0)
{
Serial.read(); // I wonder if this should be flush
Serial.println("Power up");
StartingTime=millis();
digitalWrite(ignitionPin,LOW);
digitalWrite(onPin,HIGH);
state=STARTING;
}
}
void HandleCrankingState()
{
if(digitalRead(alternatorPin)==HIGH)
{
Serial.println("Start Running");
digitalWrite(ignitionPin,LOW);
digitalWrite(onPin,HIGH);
RunningTime=millis();
state=RUNNING;
}
}
Compiled, not tested. You'll need to tweak it a bit - comment out the debugging stuff when you've tested it for example. I also thought that it ought to clear out the serial port when it reads it so it won't immediately start again after a timeout if there was extra stuff sent to the aurduino the first time (CRLF perhaps).
I'm not clear from the spec what to do if you receive a start order and the engine is already running. I chose to assume something's wrong and just stop.
Note that in every state transition I have set the ignition and on outputs to that which is appropriate for the new state. You can easily see that many of these are unnecessary (once the system is on, only the ignition varies until you stop it).
Code is not particularly good - those globals irk me, but I didn't want to start throwing in references to confuse you.
Also, how do you handle whether the car is in gear - I assume that's external to the arduino piece?
Good luck - I believe you owe me a beer ![]()