Note: this is a repost of my original article, dates and other data can refer to stuff in the past or things might be outdated. I’ll try to do my best on updating it but I may leave something by mistake or keep the narrative intact from when I originally wrote the article.From my post in my former company blog
It’s HACKD season again at MeetMe! For those of you that are not familiar with the concept, hackathons are events that some companies, schools, and other organizations put together where people work on the projects they want, like new technologies, inventions, ideas, etc., that they usually don’t have time to spend on. I’ve had a project on the back burner for a while that I wanted to work on but, because lack of experience and knowledge (a.k.a self-confidence) and time, I never went forward with it.
MeetMe offers HACKD every couple of months and during one of the recent events, I decided to finally work on this project, which I call “Really Remote Starter”.
The problem
About 3 years ago, (update from the original post. It’s been 6 years now!) I used to live in Northwest Mexico, near Arizona, US. Since then I moved to the US East Coast. So I basically moved from here: …to here: I found out that in this weather I needed to sit in my car for a while until it gets warm. Sitting in the car does not provide an ideal comfort level. Even if you turn the heat on, it’s useless for those first few minutes.By the end of the first winter season, I desperately wanted a remote starter for my car. I thought, “it would be nice to start my car just from the warmth of my home or office and then just go to my car into a warm interior and go”. Then, when I got a remote starter for my car, I quickly realized that it wasn’t always going to be that useful.
At work, the parking lot is located at the back of the business center, and it fills pretty quickly. It can take you a good 5 to 10 minutes to walk to your car. Also, in other cases like parking at malls, movie theaters, etc. makes the Remote Starter less useful. Why? Remote starters and car alarms have RF remotes, which are very limited in terms of reach.
In my other car, in Mexico, I have a high end car alarm with a two-way RF remote that promises a one mile reach. Well it has a one mile reach in a place like this: If you start adding cars, walls, and other barriers, the reach decreases dramatically. So, I came up with the idea to make my remote starter to start from wherever, without a distance restriction.
The idea
I wanted to start my car from wherever with my cellphone, sending the car some kind of signal. I wasn’t sure exactly how to achieve this, so I did some research and looked at a bunch of Youtube videos and written tutorials. It seemed that I wasn’t the first one to try this. It seemed that everyone wanted to use Bluetooth.It makes sense. Your cell phone has Bluetooth and you can use an Arduino or a raspberry pi with a Bluetooth module and voilá. But that wasn’t enough for me because that doesn’t solve my problem. Although Bluetooth could have a longer reach than RF, it still has that distance restriction. I wanted something that doesn’t care how far are you from your car. Then the WIFI idea came to me. “What if I put a WIFI module in the Arduino or the raspberry pi?” Nope, that is not going to work either. It should have WIFI coverage everywhere and there’s no WIFI coverage everywhere; you also have to deal with password-protected networks and stuff like that.
Same happens with 3G or 4G there’s no 100% 3G/4G coverage everywhere, and it will turn this to a very expensive solution since 3G/4G mobile plans are expensive. But, what if I send an SMS to my starter?
Let’s think about it: cellular signal coverage is pretty much 100% (only remote places are deficient) and SMS can be received pretty much everywhere. Also, very basic, cheap plans can give you this advantage. Got it!
The solution
Then HACKD weekend was approaching. I researched a little bit about which board to use, there’s a bunch of options out there, not just the Arduino and the raspberry pi, but settled on the Arduino basically because it was the right price and the complexity level required.How to
After deciding what to use and how to use it, I got everything I thought I would need.BOM
- Arduino Uno Rev 3
- GPRS Module (Geeetech SIMCOM SIM900 Quad-band GSM GPRS Shield )
- Breadboard and Jumper wires
- Soldering Kit
- Multimeter
- Cables
- Voltage Regulator
- Switch Relay
Voltage regulator. Arduino documentation says that it works with 5V to 20V, but it can become unstable under 7V and you can burn it over 12V. Common car voltage is 12V so I needed this to convert down the voltage to turn on the Arduino. However, after 2 or 3 days @ 5V, it became unstable. I switched since then to a 9V Voltage Regulator and that solved the problem.Well that’s pretty much everything I needed. Now the process.
Process
Installing a remote starter to a modern car isn’t an easy task. There are now transponders in the keys that you have to know how to bypass, you need to know different signals for several different instruments of the car, and you also need some security restrictions, like make it so the car shuts off some time after being started without a key (you could forget it was started, for example) or make it so the car can’t be driven without a key. (A thief could take advantage of the remote starter to just jump in and drive.) Because all of that logic was already implemented on the remote starter my car already had and the hackathon was a 3-day event, I decided just to hang my stuff off the installation already there.My plan then was that I would send an SMS from my cell to the Arduino (received via the GPRS Module). Then the Arduino would send a signal thru a cable to the remote starter via its remote control. All of this would be located in a hidden place inside the car. Here’s the diagram. So I took out the remote from it’s case and connected one cable on each pole of each button. Then I connected one switch relay to each button on the switches I had on the COM and N.O. pins Then, all three switches connected to all three buttons of the remote need to connect one of their left pins to the negative of the Arduino and each of the left pins on each of the three switches have to be connected to the three 5v pins that we are going to use to send the signals to it. So at the end all connected looked like this: This module has to be connected to a continuous power source from the car; each car is different so anyone else trying has to figure that out. I added a voltage regulator because the reasons I already stated above.
Software
The language Arduino uses is a subset of C++. Arduino has an IDE that we can use, downloadable from here. I used it for this project and it helps and works fine. Then we also need a Serial Terminal Software to communicate with the Arduino and the Geeetech SIMCOM SIM900 Quad-band GSM GPRS Shield, to send and receive SMS messages. On the Shield documentation located here, they offer some different options for different platforms, I downloaded CoolTerm for my Mac OSX from here and it worked perfectly. There’s some setup you need to do in it to communicate with the Arduino and the Shield. Ah! You also need a SIM Card with a plan installed on the Geeetech Shield.Terminal Pre-setup
- Connect to the computer USB port and turn on Arduino (with the Geeetech Shield mounted).
- Go to CoolTerm and click options.
- Pick port, usually usbmodemfd something, if doesn’t appear click Re-Scan Serial Ports at the bottom.
- Pick 19200 Baud Rate.
- Ready to send and receive commands and read them.
Arduino Code
// Setup to talk to the Serial Terminal when connected to the computer
#include <SoftwareSerial.h>
SoftwareSerial GPRS(7, 8);
unsigned char buffer[256];
int count=0;
// Iniciating communication with the Serial Terminal and the PINS that are going to send the pulses to the remote
void setup()
{
GPRS.begin(19200);
Serial.begin(19200);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
void loop()
{
delay(10000);
if (GPRS.available()) // If there's data in the SIM Card
{
delay(5000);
readPrint();
clearBufferArray();
delay(1000);
GPRS.println("AT+CMGR=1"); //Get the message received
delay(2000);
readPrint();
// After getting the content of the message we look for the text
String str1 = (const char*)buffer;
int index = str1.lastIndexOf("\"");
String text = str1.substring(index+1, str1.length()-1);
String str2 = "Turn On";
String str3 = "Open";
String str4 = "Close";
if (text.indexOf(str2) != -1) //If text was Turn On
{
Serial.write("\nStart\n"); //Send text "Start" to the Serial Terminal
//Then do the double pulse to the PIN 2
for (int x=0; x<2;x++)
{
digitalWrite(2, HIGH);
delay(800);
digitalWrite(2, LOW);
delay(1500);
}
}
else
{
if (text.indexOf(str3) != -1) //If text was Open
{
Serial.write("\nOpen\n"); //Send text "Open" to the Serial Terminal
//Then do the double pulse to the PIN 3
for (int x=0; x<2;x++)
{
digitalWrite(3, HIGH);
delay(600);
digitalWrite(3, LOW);
delay(600);
}
}
else
{
if (text.indexOf(str4) != -1) //If text was Open
{
Serial.write("\nClose\n"); //Send text "Close" to the Serial Terminal
//Then do the double pulse to the PIN 4
for (int x=0; x<2;x++)
{
digitalWrite(4, HIGH);
delay(600);
digitalWrite(4, LOW);
delay(600);
}
}
else
Serial.write("\nnot found\n"); // If none was found print "not found" to the Serial Terminal
}
}
clearBufferArray();
delay(1000);
GPRS.println("AT+CMGD=1,4"); //Delete all messages in the SIM Card
delay(1000);
readPrint();
clearBufferArray();
}
}
//This function reads and puts together everything on the SIM Card and prints it to the Serial Port
void readPrint()
{
while(GPRS.available())
{
buffer[count++]=GPRS.read();
if(count == 256)break;
}
Serial.write(buffer,count);
}
void clearBufferArray() // function to clear buffer array
{
for (int i=0; i<count;i++)
{ buffer[i]=NULL;}
count = 0;
}
That code can be also viewed here and is going to be running in a neverending loop in the arduino and basically waits for the SIM card to get an SMS. Once the SMS arrives, it sends a double pulse (needed by the remote buttons) to the desired remote button, depending of the content of the SMS received. After that it deletes all the messages to avoid filling up the SIM Card.Well, after “uploading” that to our Arduino, we can manually send SMS messages to our installation and it should work. This is a little video when I was testing it:
This is with the car already connected to the module:
I have to thank for this part of the code to my friends and coworkers Bob Dauth and Diana Shkolnikov, who helped me a lot with C++ because I had no C++ coding experience at all. After that, it was mostly done, however, I wanted an app that with a tap of a button I could tell my car to start or to open and close the door locks. I asked my also friend and coworker David Breneisen to help me with that. He came up in less than half hour with a very simple app that does the work. Here’s a screenshot: Pretty much what it does is to send the SMS when you tap the button and that’s it. It also gets confirmation and shows a toast message when the SMS has been sent. Because its so many files you can find the code here. After putting that together, we finished our project.
I was able to use it all winter long and it was awesome! Now, for this most recent HACKD, I wanted to improve on it. I projected the following changes:
- Remove the phone number from the code in the app and put a settings page so the user can change the phone number of the car.
- Get better-looking buttons with icons instead of just text.
- Get reporting back from the car when the car has been started, closed, or opened after the SMS is received.
- Add an alert to be sent by the car when a door has been opened.
- The icons on the top left corner are switches on the doors, this switches send the signal to the car computer to let it know a door has been opened, you can see a light coming off on your dashboard when a door is open, these are the responsibles. We need to connect those sensors to the Arduino somehow to get the signal. There’s some considerations to make — these are negative signals, and we need diodes in order to avoid the signal to go between them.
- To the center (Doors Relay), it’s basically a signal converter. That relay basically takes the negative signal from any of the doors and sends a positive signal to a voltage regulator.
- The signal from the Doors Relay is converted to a 12V signal so that’s why we need a voltage regulator, to convert the 12V to a 5V signal that is going to be connected to an input pin on the Arduino (we convert it to 5V because that’s what the Arduino supports).
// Setup to talk to the Serial Terminal when connected to the computer
#include <SoftwareSerial.h>
SoftwareSerial GPRS(7, 8);
unsigned char buffer[256];
int count = 0;
// Setting up inicial door state
int last_door_value = -1;
int current_door_value = -1;
int total_delay = 0;
// Iniciating communication with the Serial Terminal and the PINS that are going to send and receive the pulses to the remote
void setup()
{
GPRS.begin(19200);
Serial.begin(19200);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, INPUT);
}
void loop()
{
current_door_value = digitalRead(5);
if (last_door_value == -1) {
// This will initialize our "What was the last thing we read?" variable
last_door_value = current_door_value;
}
delay(1000);
total_delay += 1000;
// This will send the SMS letting me know that a Door has been opened or closed
if (current_door_value != last_door_value) {
if (current_door_value == 0) {
GPRS.println("AT+CMGF=1");
delay(100);
GPRS.println("AT+CMGS = \"+12674671270\"");
delay(100);
GPRS.println("Door Closed");
delay(500);
GPRS.println((char)26);
delay(500);
GPRS.println();
delay(500);
readPrint();
clearBufferArray();
delay(3500);
} else {
GPRS.println("AT+CMGF=1");
delay(100);
GPRS.println("AT+CMGS = \"+12674671270\"");
delay(100);
GPRS.println("Door Opened");
delay(500);
GPRS.println((char)26);
delay(500);
GPRS.println();
delay(500);
readPrint();
clearBufferArray();
delay(3500);
}
last_door_value = current_door_value;
}
// Next several lines are for receiving the SMS and sending the signal to the Arduino to Start the car, Close or Open the door locks
if (total_delay > 5000 && GPRS.available())
{
total_delay = 0;
delay(5000);
readPrint();
clearBufferArray();
delay(1000);
GPRS.println("AT+CMGR=1");
delay(2000);
readPrint();
String str1 = (const char*)buffer;
int index = str1.lastIndexOf("\"");
String text = str1.substring(index + 1, str1.length() - 1);
String str2 = "Start";
String str3 = "Open";
String str4 = "Close";
if (text.indexOf(str2) != -1)
{
// Serial.write("\nStart\n");
for (int x = 0; x < 2; x++)
{
digitalWrite(2, HIGH);
delay(800);
digitalWrite(2, LOW);
delay(1500);
}
GPRS.println("AT+CMGF=1");
delay(100);
GPRS.println("AT+CMGS = \"+12674671270\"");
delay(100);
GPRS.println("Started");
delay(500);
GPRS.println((char)26);
delay(500);
GPRS.println();
delay(500);
readPrint();
clearBufferArray();
delay(3500);
}
else
{
if (text.indexOf(str3) != -1)
{
// Serial.write("\nOpen\n");
for (int x = 0; x < 2; x++)
{
digitalWrite(3, HIGH);
delay(600);
digitalWrite(3, LOW);
delay(600);
}
GPRS.println("AT+CMGF=1");
delay(100);
GPRS.println("AT+CMGS = \"+12674671270\"");
delay(100);
GPRS.println("Unlock Succesful");
delay(500);
GPRS.println((char)26);
delay(500);
GPRS.println();
delay(500);
readPrint();
clearBufferArray();
delay(3500);
}
else
{
if (text.indexOf(str4) != -1)
{
// Serial.write("\nClose\n");
for (int x = 0; x < 2; x++)
{
digitalWrite(4, HIGH);
delay(600);
digitalWrite(4, LOW);
delay(600);
}
GPRS.println("AT+CMGF=1");
delay(100);
GPRS.println("AT+CMGS = \"+12674671270\"");
delay(100);
GPRS.println("Lock Succesful");
delay(500);
GPRS.println((char)26);
delay(500);
GPRS.println();
delay(500);
readPrint();
clearBufferArray();
delay(3500);
}
else
Serial.write("\nnot found\n"); // If none was found print "not found" to the Serial Terminal
}
}
clearBufferArray();
delay(1000);
GPRS.println("AT+CMGD=1,4"); //Delete all messages in the SIM Card
delay(1000);
readPrint();
clearBufferArray();
}
}
void readPrint() // This function reads and puts together everything on the SIM Card and prints it to the Serial Port
{
while (GPRS.available())
{
buffer[count++] = GPRS.read();
if (count == 256)break;
}
Serial.write(buffer, count);
}
void clearBufferArray() // function to clear buffer array
{
for (int i = 0; i < count; i++)
{
buffer[i] = (unsigned char)0;
}
count = 0;
This code is also on my Github and I have to thank Drew Denardo also friend and coworker for helping me with this code and putting together the new version of the Android app that now looks like this:
The code for this version can be also viewed here. After presenting and wrapping up the new version of the remote starter in the HACKD event, I realized an issue on the way it is programmed now; it sends me an SMS when a door has been opened or closed, even when I open or close the door. Obviously I don’t need an SMS telling me a door has been opened/closed if I’m the one doing it. I need to add some kind of logic to tell it when it is me doing or not. But I guess that’s going to be for the next HACKD?