/* Program: Remote Car Start
* Author: Chris Johnson
* Revised: December 5th, 2011
*
* Inputs: BT Module "ON" signal
* BT Module "OFF" signal
* Vehicle RPM Sensor
* Vehicle Neutral Position Sensor
* Vehicle Speed Sensor
* Serial port
* Outputs: Ignition Control Relay
* Accessory Control Relay
* Starter Control Relay
* Clutch Safety Switch Relay
* Serial Port
*/
//EQUATES
//Inputs
int BT_on = 2; //Bluetooth "ON" signal inputed to pin 2
int RPM_sens = 3; //Vehicle RPM sensor inputted to pin 3
int speed_sens = 5; //Vehicle Speed Sesor inputted to pin 5
int BT_off = 7; //Bluetooth "OFF" signal inputed on pin 7
//Outputs
int ign_ctrl = 8; //Ignition Control Relay controlled by pin 8
int start_ctrl = 9; //Start Control Relay controlled by pin 9
int acc_ctrl = 11; //Accessory Control Relay controlled by pin 11
unsigned long start_time; //Variable used to store the time at which the starter is engaged
char data = 0; //Variable used to store data received via the serial port
//DEFINITIONS
void setup()
{
pinMode(BT_on, INPUT); //Define pin inputs and outputs
pinMode(RPM_sens, INPUT);
pinMode(speed_sens, INPUT);
pinMode(BT_off, INPUT);
pinMode(ign_ctrl, OUTPUT);
pinMode(start_ctrl, OUTPUT);
pinMode(acc_ctrl, OUTPUT);
Serial.begin(9600); //Initialize the serial port with a baud rate of 9600
}
//PROGRAM
//Loop function: Wait for a START command to be received (command via serial port or
//voltage applied to BT_on pin)
void loop()
{
if (Serial.available() > 0) //Check if any serial data is available
{
data = Serial.read(); //Set "data" variable to currently available serial data
check(); //Go to "check" funtion if serial data is available
}
else if (digitalRead(BT_on) == HIGH) //Check if BT Module has set pin high
{
begin(); //Begin start sequence if pin is high
}
else
{
loop(); //Repeat this function until a START command is received
}
}
//Check function: Test for proper character set from BT
void check()
{
if (data == 's') //Check if an "s" has been sent
{
begin(); //Begin start sequence if "s" has been sent
}
else
{
Serial.println("Invalid Command"); //If anything other than an "s" has been sent, send "Invalid Command" error message
loop(); //Return to beginning of program
}
}
//Begin function: Turn on accessory and ignition
void begin()
{
delay(500); // 0.5 second delay
digitalWrite(acc_ctrl, HIGH); //Turn accessory ON
digitalWrite(ign_ctrl, HIGH); //Turn ignition ON
delay(500); // 0.5 second delay
}
//Start function: Engage starter only if engine is not already running.
void start()
{
int RPM = pulseIn(RPM_sens, HIGH, 1000000); //Get RPM value
if(RPM == 0) //Continue start sequence only if vehicle is not running.
{
digitalWrite(acc_ctrl, LOW); //Turn accessory OFF
delay(500); //0.5 second delay
digitalWrite(start_ctrl, HIGH); //Engage starter
start_time = millis(); //Capture the time at which the starter was engaged
starter_engaged(); //Go to Starter_engaged function
}
else
{
Serial.println("Vehicle Already Running"); //Send "Vehicle Already Running" message if engine was previously started
vehicle_off(); //Exit start sequence if already running
}
}
//Starter_engaged function: Disengage starter after vehicle is starter or turn off starter if
//vehicle has not started within 4 seconds.
void starter_engaged()
{
int RPM = pulseIn(RPM_sens, HIGH); //Get RPM value
if (RPM > 1000) //Continue if engine has started (reached low idle)
{
Serial.println("Engine Running"); //Send "Engine Running" message after engine has started
disengage_starter(); //Go to disengage_starter after engine is running
}
else if ((start_time+4000) < millis()) //Test if 4 seconds has passed since the starter was engaged
{
disengage_starter_timeout(); //Go to disengage_starter if engine has not started within 4 seconds of starter engagement
}
else
{
starter_engaged(); //Repeat this function if engine has not started or 4 seconds has not elapsed
}
}
//Disengage_starter function: Disengage the starter.
void disengage_starter()
{
digitalWrite(start_ctrl, LOW); //Disengage the starter
digitalWrite(acc_ctrl, HIGH); //Turn accessory ON
vehicle_off_sense(); //Go to vehicle_off_sense function
}
//Disengage_starter_timeout function: Disengage the starter (used after 4 seconds has elapsed without an engine start)
void disengage_starter_timeout()
{
digitalWrite(start_ctrl, LOW); //Disengage the starter
Serial.println("Vehicle Start Unsuccessful"); //Send "Vehicle Start Unsuccessful"
vehicle_off(); //Exit start sequence
}
//Vehicle_off_sense function: Waits for an "off" signal to be sent while the engine is running.
//If no "off" signal is received, turns off the vehicle after 30 minutes has elapsed since the engine start.
void vehicle_off_sense()
{
int moving = pulseIn(speed_sens, HIGH); //Get vehicle speed
if (moving > 1000) //Check if vehicle is moving
{
Serial.println("Vehicle OFF -- Movement"); //Send "Vehicle OFF -- Movement" message ifvehcile is moving
vehicle_off(); //Turn vehicle off if it is moving
}
else if (start_time+600000 < millis()) //Check if 30 minutes has elapsed since engine start
{
Serial.println("Vehicle OFF -- Automatic Timeout"); //Send "Vehicle OFF -- Automatic Timeout" message if engine has been
//running for 30 minutes
vehicle_off(); //Turn vehicle off if engine is running for 30 minutes
}
else if (Serial.available() > 0) //Check if a signal has been sent via serial data
{
data = Serial.read(); //Store serial sent serial data
if (data == 'o') //Check if signal sent is an OFF command ("o")
{
Serial.println("Vehicle OFF -- User Commanded"); //Send "Vehicle OFF -- User Commanded" message if serial data is the OFF
//command ("o")
vehicle_off(); //Turn vehicle off if OFF command is sent via serial data
}
}
else if (digitalRead(BT_off) == HIGH) //Check if OFF command has been sent via BT module
{
Serial.println("Vehicle OFF -- User Commanded"); //Send "Vehicle OFF -- User Commanded" message if OFF
//command was sent
vehicle_off(); //Turn vehicle off if OFF command was sent via BT module
}
else
{
vehicle_off_sense(); //Repeat this function if none of the above conditions have been met
}
}
//Vehicle_off function: Turns the vechile off and starts the whole program over
void vehicle_off()
{
digitalWrite(ign_ctrl, LOW); //Turn ignition OFF
digitalWrite(acc_ctrl, LOW); //Turn accessory OFF
loop(); //Repeat program (look for start command)
}