Nota: Este es un repost te mi articulo original, fechas y otros datos se pueden referir a cosas en el pasado. Algunas cosas pueden estar desactualizadas. Haré mi mejor esfuerzo en actualizarlo pero podría dejar una que otra cosa desactualizada por error o para dejar la narrativa intacta de cuando escribí originalmente el post.De mi post en el blog de mi antigua compañía
¡Es temporada de HACKD de nuevo en MeetMe! Para aquellos que no estan familiarizados con el concepto, los hackatones son eventos que algunas compañías, escuelas y otras organizaciones realizan donde permiten a sus empleados, estudiantes, etc., trabajar en proyectos personales como nuevas tecnologías, inventos, ideas, etc., para los cuales ellos normalmente no tienen tiempo. Personalmente he tenido un proyecto pendiente en el que he querido trabajar pero por falta de experiencia y conocimiento (basicamente falta de confianza en mi mismo) y tiempo, no me había animado a llevar a cabo.
MeetMe ofrece eventos HACKD cada dos meses y durante uno de los más recientes decidí finalmente trabajar en este proyecto, al cual yo llamo “Encendido Realmente Remoto”.
El problema
Hace aproximadamente 3 años, (Actualización del post original. ¡Ya son 6 años!) Solía vivir en el Noroeste de México, cerca de Arizona, Estados Unidos. Desde entonces me moví con mi esposa a la costa este de Estados Unidos. Así que básicamente me moví de aquí:

Para el final del primer invierno, quería desesperadamente un encendido remoto para mi auto. Pensé, “Estaría muy bien encender mi auto desde la comodidad de mi casa u oficina y luego solo caminar a mi auto, con el interior calientito y arrancar”. Luego, cuando le instalé un encendido remoto a mi carro, me di cuenta rápidamente que no iba a servir mucho.
En la oficina, el estacionamiento está localizado al final del centro de negocios, y se llena rápidamente. Me puede tomar unos buenos 5 a 10 minutos caminar hasta mi auto. Además en otros casos como estacionarse en centros comerciales, cines, etc. convierten al encendido remoto en algo practicamente inservible. ¿Porqué? Los encendidos remotos y las alarmas automotrices tienen controles remotos con señales RF, las cuales son muy limitadas en cuanto a alcance.
En mi otro carro, en México, tengo instalada una alarma de alto desempeño, con un control remoto RF 2-vias que promete una milla de alcance. Pues… si tiene una milla de alcance… en un lugar así:

La idea
Quería encender mi auto desde donde sea con mi teléfono celular, enviando a mi carro algun tipo de señal. No estaba seguro exactamente como lograr esto, así que me puse a investigar, vi varios videos de Youtube y leí varios tutoriales. Me dio gusto encontrar que no era el unico ni el primero en intentar esto y noté que la gran mayoría quería usar Bluetooth.Tiene sentido. Nuestros celulares tienen Bluetooth integrado y puedes usar un Arduino o Raspberry Pi con un módulo Bluetooth (actualización, ya hay varios modelos de RPI que tienen Bluetooth integrado) y voilá. Pero eso no era suficiente para mi porque eso no resolvía mi problema. Aunque Bluetooth podría tener mas alcance que RF, todavia tiene restricción de distancia. Yo queria algo que no importara que tan lejos estuviera yo de mi auto. Entonces pensé acerca de WIFI “¿Qué tal si pongo un módulo WIFI en el Arduino o Raspberry Pi?” No, eso tampoco iba a funcionar. Me iba a pelear con la cobertura WIFI en todas partes y luego habría que pelear con señales protegidas por contraseña, etc.
Lo mismo pasa con 3G o 4G no hay cobertura 100% en todas partes, y se convertiría una solución bastante cara porque los planes 3G/4G son bastante caros. ¿Pero que tal si le envío un mensaje SMS a mi encendido remoto?
Meditémoslo un momento: La cobertura celular es prácticamente 100% (solo en ciertos lugares remotos es deficiente) y los mensajes SMS pueden ser enviados o recibidos básicamente donde sea. Además, los planes muy basicos, son muy baratos. ¡Lo tengo!
La solución
Entonces el fin de semana de HACKD se acercaba. Investigué un poco más acerca de que controlador usar, hay muchas opciones, no solo el Arduino o el Raspberry Pi, pero decidí usar el Arduino básicamente por el precio en ese momento y era el nivel de complejidad del controlador correcto.Pasos
Luego deBOM
- Arduino Uno Rev 3
- GPRS Module (Geeetech SIMCOM SIM900 Quad-band GSM GPRS Shield )
- Proto y cables
- Kit de soldadura
- Multímetro
- Cables
- Regulador de voltaje
- Switch Relay
Regulador de voltaje. La documentación de Arduino dice que trabaja de 5V a 20V, pero puede volverse inestable bajo 7V y lo puedes freír por encima de 12V. El voltaje mas común en autos es 12V así que necesitaría convertir el voltaje hacia abajo para protejer el Arduino. Sin embargo, luego de usarlo 2 o 3 días a 5V, se volvió inestable. Cambié el regulador desde entonces a uno de 9V y resolvió el problema.Bueno, eso es todo lo que necesitaba. Ahora el proceso.
Proceso
Instalar unMi plan para







Software
El lenguaje que Arduino usa es un subset de C++. Arduino tiene un IDE que podemos utilizar, descargable de aquí. Yo lo usé para este proyecto y ayuda muy bien. Además necesitamos una Terminal Serial para comunicar con el Arduino y el módulo Geeetech SIMCOM SIM900 Quad-band GSM GPRS, para enviar y recibir mensajes SMS. En la documentación del módulo localizada aquí, ofrecen algunas opciones diferentes para diferentes plataformas, Yo bajé CoolTerm para mi Mac OSX de aquí y funcionó perfectamente. Hay algo de configuración que se tiene que hacer para comunicarse con el Arduino y el módulo GPRS. ¡Ah! También necesitas una SIM card instalada en el modulo y con un plan con SMS activo.Pre-configuración de la terminal
- Conectar el Arduino al puerto USB de la computadora con el módulo Geetech montado.
- Ir a CoolTerm y dar clic en opciones.
- Elegir el puerto, normalmente algo como usbmodemfd, si no aparece, dar clic en Re-Scan Serial Ports en la parte de abajo.
- Elegir 19200 Baud Rate.
- Listo para
enviar yrecibir comandos y leerlos.
Código de Arduino
// 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("nStartn"); //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("nOpenn"); //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("nClosen"); //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 foundn"); // 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;
}
Este código también lo pueden encontrar en mi Github aquí y va a estar corriendo en un ciclo sin fin en el Arduino. Básicamente espera por la SIM card que reciba un mensaje SMS. Una vez que el SMS llega, envía un doble pulso (necesitado por los botones del remoto) al botón deseado del control remoto, dependiendo del contenido del texto del SMS recibido. Después de eso, borra todos los mensajes para evitar llenar la SIM Card.Después de subir el código al Arduino, podemos enviar mensajes SMS manualmente a nuestra instalación y debe funcionar correctamente. Este es un pequeño video de cuando estaba probándolo:

- Quitar el numero de teléfono del código en la app y crear una página de configuración, donde el usuario pueda cambiar el número facilmente.
- Mejorar los botones, usando íconos en vez de texto.
- Obtener alertas del carro, cuando el carro haya sido encendido, cerrado o abierto, luego de haber recibido un mensaje SMS.

- Los íconos en la esquina superior izquierda son switches en las puertas, estos switches envían la señal a la computadora del auto, para avisarle si una puerta está abierta. Hay un testigo en los tableros de los autos que se prende al estar la puerta abierta. Estos son los responsables. Necesitamos conectar esos sensores al Arduino de alguna manera para obtener esa señal. Hay algunas consideraciones que hacer, estas son señales negativas y necesitamos diodos para enviarlas por un solo cable, pero evitar que la señal se vaya de un sensor a otro.
- Al centro (Doors Relay), es básicamente un convertidor de señal. Ese relay toma la señal negativa de cualquiera de las puertas y envía una señal positiva al regulador de voltaje.
- La señal de las
puertas esconvertida a 12V, espor eso que necesitamos elregulador devoltaje a 5V (convertimos a 5Vporque eso es loque el Arduinosoporta ).
// 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("nStartn");
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("nOpenn");
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("nClosen");
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 foundn"); // 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;
Éste código también está en mi Github y en esta ocasión tengo que agradecer a Drew Denardo también amigo y compañero de trabajo por ayudarme con este código además editando el código de la app de Android que ahora se ve así:

