Remote Car Starter Using Bluetooth


Introduction: Remote Car Starter Using Bluetooth

Welcome to a project of mine that has been in the works for a while. In this Instructable, I'll try to give you an idea of what I did to start my car using Bluetooth. First off, here is video to show what I have been able to accomplish.

Since I took this video, I have been able to put the Arduino chip onto its own board and fit everything into the little black box. I also bought a Bluetooth dongle for my computer so the range is significantly better.

In this Instructable, I'll do my best to step through the whole process I went through for this project.

Let's get started...

Step 1: Requirements

Because I started this project from scratch, I needed some guidelines before I started to design the system. Here are the requirements that I set for my system before getting started:

1) The remote start system shall appear transparent to (not affect the operation of) the the vehicle's starting/operating system.

2) Functionality of the key-start shall be available at all times.

3) After starting, the engine shall remain operational regardless of Bluetooth connectivity.

4) After turning off, the engine shall remain off regardless of Bluetooth connectivity.

5) The engine shall start only while the shifter is in the neutral position.

6) The engine shall only start if the engine is not currently running.

7) The starter shall be disengaged after the engine reaches idle RPM or after 4 seconds have passed, whichever comes first.

8) The engine shall turn off if the vehicle is moving and the key is not in the ignition. (Note: This is to prevent theft and also to eliminate the possibility of the engine shutting off due to a failure in this remote start system.)

9) After starting, the engine shall automatically shut down after 30 minutes of operation. (Note: This is to prevent the vehicle from running out of gas if the user forgets that it was started.)

Step 2: Data Collection (System Inputs)

Now that the basic requirements were set in place, it was time to collect the necessary data from my car's engine and ignition systems. Because of the requirements I had drawn up, I knew I needed to understand the inner workings of the signals that are sent to my car's engine control module (ECM).

The signals that would become inputs to my system included:
-Engine RPM sensor
-Shifter neutral position sensor
-Vehicle speed sensor

The first place I went to find information about these signals was the maintenance manual for my car. After finding the preliminary data on these signals (see the excerpts from the maintenance manual), I decided it would be smart to find these wires going into the ECM and make some measurements of my own. I figured doing this would help validate the information in the manual and also give me more specific information (more specific information being waveform frequency vs. RPM/speed ratios). Here is what I found:

Engine RPM Sensor Output
- Location: Connector B134, pin 30
- Wire Color: Green
- Voltage:
  Using oscilloscope: 5 Vp-p (including DC offset)
  Using multimeter: 6.7 Vdc
                                   7.4 Vac
   RPM         Period            Frequency
750 (Idle)     44ms               22.7 Hz
  1000           30ms               33.3 Hz
  1500           20ms               50.0 Hz
  2000          15ms                66.7 Hz
  2500          12ms                83.3 Hz

Shifter Neutral Position Switch:
- Location: Connector B135, pin 26
- Wire Color: Green/Black
- Voltage:
           In neutral position: 4.87 Vdc
           In any gear:  0.00 Vdc

Vehicle Speed Sensor
- Location: Connector B135, pin 24
- Wire Color: Green/Black
- Frequency:
    Speed        Period       Frequency
   10 mph        80 ms         12.5 Hz
   15 mph        60 ms         16.7 Hz

The process of using an oscilloscope to measure the vehicle speed signal was a bit comical. You probably would have enjoyed watching me trying to read the waveform period on the oscilloscope as I drove around the parking lot, trying not to crash into anything :-)

With this data about the inputs to my system, I was then ready to figure out what my system needed to output in order to function per my requirements.

Step 3: Data Collection (System Outputs)

The required system outputs were a bit easier to determine than the required system inputs. By disconnecting the connector at the ignition, I was able to use an ammeter to determine the amount of current flowing through the different parts of the ignition switch. This gave me an idea of the type of devices I should use to control the current flowing through the ignition switch. See the schematic from my maintenance manual for the location at which I took these measurements. Here is what I found:

Current flowing through the Accessory (ACC) part of the switch: 170 mA
Current flowing through the Ignition (IGN) part of the switch: 1.9 A
Current flowing through the Start (ST): 7.5 A

These values are all approximations. Some of them also change based on the system load. (For example, if the A/C fan was on while measuring the Ignition current, the current value was larger.)

The last output required of my system was the ability to ground the clutch safety switch. In order to start my car, the clutch has to be depressed. When the clutch is depressed, the clutch safety switch grounds a pin on the Engine Control Module (ECM). This type of signal made this safety feature easy to bypass -- simply grounding the this pin on the ECM allows the engine to be started. When disconnecting the connector and measuring current flow through this clutch safety switch, I found that approximately 150 mA flows from the ECM to ground when the pin is grounded.

Step 4: Flowchart

After writing out the requirements and collecting all the necessary data, the next step in the process was to draw up a flowchart based on my requirements. This gave me a starting point when writing the code. Prior to this project, I had only written code in Assembly language, so this flowchart helped give structure to the Arduino code and allowed me to write it fairly quickly.

The flowchart should be pretty straight forward. I don't think there is much explaining to do in this step.

Step 5: Arduino Code

Probably the most intimidating step for me in this whole process was writing the Arduino Code. As I mentioned earlier, this code writing stuff was all new to me. However, it went pretty quick with the flowchart in hand.

You'll notice in the first part of the code that two different signals can be used to initiate the car start command:

1) Sending an "s" to the Arduino via the bluetooth module (which is acting as a serial port) can be used to initiate the starting sequence. This is used when starting the vehicle from a terminal on a computer.

2) Setting a pin on the Arduino high will also initiate the starting sequence. This input pin on the Arduino is connected to the Bluetooth board. When using the Daisy On/Off app from an Android phone, the app will cause the pin on the Bluetooth board to be set high, which in turn will be seen by the Arduino and cause the starting sequence to begin.

Here is my code:

/* 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

int BT_on = 2;                                               //Bluetooth "ON" signal inputed to pin 2
int RPM_sens = 3;                                       //Vehicle RPM sensor inputted to pin 3
int neutral_sens = 4;                                    //Vehicle Neutral Position Sensor inputted to pin 4 (12 volts +/- 0.5 volts)
int speed_sens = 5;                                     //Vehicle Speed Sesor inputted to pin 5
int BT_off = 7;                                                //Bluetooth "OFF" signal inputed on pin 7

int ign_ctrl = 8;                                               //Ignition Control Relay controlled by pin 8
int start_ctrl = 9;                                             //Start Control Relay controlled by pin 9
int clutch_sfty = 10;                                       //Clutch Safety Swithc Relay controlled by pin 10
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

void setup()
  pinMode(BT_on, INPUT);                          //Define pin inputs and outputs
  pinMode(RPM_sens, INPUT);
  pinMode(neutral_sens, INPUT);
  pinMode(speed_sens, INPUT);
  pinMode(BT_off, INPUT);
  pinMode(ign_ctrl, OUTPUT);
  pinMode(start_ctrl, OUTPUT);
  pinMode(clutch_sfty, OUTPUT);
  pinMode(acc_ctrl, OUTPUT);
  Serial.begin(9600);                                     //Initialize the serial port with a baud rate of 9600


//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 =;                                //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
     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
    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
  neutral();                                          //Go to "neutral" funciton

//Neutral function: Check if the vehicle's transmission is in the neutral position.
// Continue if vehicle is in neutral. Exit start sequence if vehicle is in gear.
void neutral()
  if (digitalRead(neutral_sens) == HIGH )       //Continue only if vehicle is in neutral
    start();                                                                //Start vehicle if in neutral
    Serial.println("Vehicle Not in Neutral");       //If in gear, send "Vehicle Not in Neutral" error message
    vehicle_off();                                                     //Exit start sequence if in gear

//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(clutch_sfty, HIGH);             //"Depress" clutch
     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
     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
    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(clutch_sfty, LOW);               //"Release" the clutch
  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
  digitalWrite(clutch_sfty, LOW);                              //"Release" the clutch
  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+1800000 < 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 =;                                                      //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
    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)

Step 6: Hardware Schematic

Once I developed the Arduino code and had a chance to test it on a bread board, I was ready to move onto the next step of designing the hardware.

The first step in designing the hardware aspect of this project was to figure out how to make the Arduino chip (ATMEGA328) a standalone unit. With this figured out, I could save a lot of money (the chip with the Arduino bootloader on it is only $5.50, compared to an Arduino Uno that is $30) and make my board much smaller. I used this tutorial from the Arduino website to design the standalone Arduino unit:

Because I had measured the current that flows through the ignition switch of my vehicle, I found that a simple bi-polar junction transistor (BJT) did not have a high enough current rating for this application. Therefore, I used BJTs to control relays that are rated for 40 amps. This is very much over-designed, but I had the parts on hand. If I were to start over, I would probably try to find a high current MOSFET that would replace both the BJT and the relay. (Using a MOSFET would be a great possibility because MOSFETs require very little to no current for biasing purposes, yet can typically handle quite a bit of source/drain current.) All that to say, yes: the system is over-designed as far as current requirements are concerned. But, I would rather the system be over-designed than under-designed in this regard.

The one location that I was able to get away with just a simple BJT was in the clutch safety switch circuit. Because the ECM only outputs 150 mA for this signal, the BJT (rated at 200 mA maximum continuous current) was sufficient without an additional relay.

Step 7: Vehicle Wiring

With the system design pretty much completed, and the software tested as much as possible before testing in the car was required, I was ready to install the wiring needed in the car. 

I decided to use a DB-9 connector for all signals and control circuits. This makes install and removal of my system very easy. A plus to easy installation and removal is that I can quick get my system out of the car and into the house to make adjustments to software or hardware, if needed. If you look at the schematic in the previous step, you can see how the DB-9 connector in the car is wired. You'll notice that I have power from the Arduino and bluetooth module going from inside my box, out to the switch via the DB-9, and then back to the Arduino/Bluetooth board. This probably seems a bit weird, but by designing the system this way, I was able to put a fuse inside the box. Another feature of this design is that I used a switch with an LED that turns on when the switch is in the ON position and power is applied to the switch. If the switch is turned ON but the LED does not turn on, it is obvious very quickly that the box is not connected properly (or at all).

Soldering the wires into the DB-9 connector under the dash was a bit of a challenge, but doable. I could have used the crimp-type DB-9 connector, but didn't have any on hand. Plus, a little soldering practice never hurts anyone :-)

The most intimidating part of adding wiring into the car was cutting into the ignition leads. If you decide to make any modifications to your ignition system, make sure to DISCONNECT THE BATTERY first. I wasn't totally sure how to go about splicing a wire into the ignition leads, mostly because of their size (about 12 gauge wires). I ended up cutting the ignition leads and putting ring terminals on all three wires (the two original ends and the new wire I added). I then used a bolt and self-locking nut to attach the three ring terminals together. A little bit of plastic tubing cut appropriately, and some electrical tape, did the trick to insulate the splice connections from each other and other things. I used two 2-pin Molex connectors for the four ignition leads that I spliced in (Power, Accessory, Ignition, and Start).

Step 8: Conclusion

Thanks for looking at my project! It was a great learning experience for me.

Since building this little contraption, I had to sell my Forester. I have not tried to install this system on my new car. The range of the bluetooth signal was not as good as I was expecting, even with a modified antenna. Before I install this system on my new car, I want to see if I can increase the range to make it more useful. Also, I never got a new Android phone. My Droid Incredible has problems with the bluetooth feature, so I was only ever able to use my laptop to control my project, even though it should be possible to control it from an working Android device. Perhaps I will revisit this project if I get a new phone and find a way to increase the bluetooth range.




  • Oil Contest

    Oil Contest
  • Water Contest

    Water Contest
  • Clocks Contest

    Clocks Contest

42 Discussions

Saludos. Soy un estudiante de ingenio automotriz y la agradecería mucho que yo comparto su proyecto para poder trabajar en eso
Mi correo es

Saludos. Soy un estudiante de ingenieria automotriz y le agradeceria mucho que me comparta su proyecto para poder trabajar en eso
Mi correo es

very good project !! what if I stole the car and I need to turn it off remotely considering that the key is inside the car?? sorry for my bad english


1 year ago

That Could be modified the arduino module system using by laptop. Chek this out.

hi can i use this in my motorcycle?? do you have any DIY project for this?.. plz make a tutorial sir... tankz!! =)


2 years ago

Awesome.. thanks for sharing.. what kind of range did you get on your bluetooth?


2 years ago

One of my biggest worries getting this starter is that the engine will shut off as soon as the Bluetooth connection goes bad. What did you do to make sure the Bluetooth connection didn't affect the start? I have also never written any codes. Do you think I should ask for help from my computer savvy friends, or is it a really strait forward process?

1 reply

I would definitely learn the basics of arduino first. Start with a simply blinking an led.

You can find arduino compatible boards an eBay for nearly $3.00. Or you can buy a genuine arduino for about $20.00.

I would recommend a SIM (GSM or GPRS) shield. That way you could text it to start regardless of what phone you have.


2 years ago

Operating your car by Smarcard RFID/NFC, Bluetooth and USB/Mini USB for controlling door lock/unlocked, starter the engine, Alarm Panic, Beam Lamp and Hazzard.

Please see the link below.

So i installed a diy one 10 years ago. They used the brake sensor to disengage the autostart. This keeps people from stealibg your car because you have to hit the break to shift it into gear. So you get in and insert thr key to run. No need to wire into the speed sensor. You can also look at the input voltage to know when the car is running. Once the voltage goes up the engine is on.

diperdetail cara pembuatan projectnya.

saya kurang paham.


Great project, I just have one idea to add: you mentioned that you would prefer MOSFETs instead of relays. I would say that relays are much better for this application because they create virtually no voltage drop and negligible heat. On the other hand, MOSFETs have a ON resistance which is usually around 10 miliohms, which will create a voltage drop and also generate heat. For example, if the current is 30 amps, the voltage drop would be of 0.3V and 9W of heat will be dissipated.

could i use a raspberry pi with a blue tooth dongle to preform this or would i have to buy an Arduino board?

try using a GSM/GPRS shield on arduino, this way you will be able to turn your car on and off from anywere with sms messages, al you could set a GPS mdule on it for tracking

Hey I know its been a while that your project is on this, but I wanted to know how did you bypass the transponder?

If you used a bypass module which one did you use?

It would be very appreciated if you answer, I am doing this as school project. Thank you.

3 replies

Transponder is a little tube in which there is data written in it, it is generally inside the "rubber of the key". When starting the car this data is read from the ECU I think so that the car can stay on. Otherwise if you turn the car on without any transponder that can connect with the ECU then the car will shut down after 2 seconds.

I understand now. My car did not require a transponder in the key for starting, so I don't have any experience with this. Hope you are able to figure it out!

Hey chris I was wondering you used a standalone chip, but you could've still done it with the arduino board itself right?