Pasos:
1. Código prueba para enviar mensajes de texto:
codigoGprs:
boolean flag1 = true;
void setup()
{
pinMode(13, OUTPUT);
pinMode(2, OUTPUT);
Serial.begin(9600); //velocidad de conexión con módulo GPRS
activarGprs(); //activar el módulo GPRS
}
void loop()
{
if(flag1)
{
SMS();
flag1 = false;
}
}
activarGprs:
//procedimiento para activar el módulo GPRS
void activarGprs()
{
for(int i = 0 ; i<6; i++)
{
delay(5000); //esperamos 20 segundos a que se active el módulo GPRS
}
digitalWrite(2, HIGH);
delay(5000);
digitalWrite(2, LOW);
for(int i = 0 ; i<8; i++)
{
delay(5000); //esperamos 20 segundos a que se active el módulo GPRS
}
digitalWrite(13,HIGH);
}
SMS:
void SMS()
{
Serial.println("AT+CMGF=1");//activamos el modo SMS
delay(1500);
Serial.print("AT+CMGS="); // comando AT para enviar SMS
Serial.write( byte(34)); // enviar caracter "
Serial.print("3007799491"); // numero de movil receptor del SMS
Serial.write( byte(34)); // enviar caracter "
Serial.println();
delay(1500);
//body
Serial.print("Envio de mensaje desde Arduino ElectivaI"); //texto del SMS
delay(10000);
//END OF SMS
Serial.write(0x1A);
Serial.write(0x0D);
Serial.write(0x0A);
}
Nota: Este código es el que permite enviar mensajes de texto, principalmente lo que hace es encender el modem SIM900. Este tarda en prender 45 segundos, después de estar prendido envía por medio de los comandos AT las ordenes para que se envíe el sms al numero de celular deseado.
2. Código de sensores:
sensorPir: //Sensor de movimiento
void sensorPir()
{
pinMode(12, OUTPUT); // Pin zumbador.
pinMode(8, INPUT);//Pin pir.
int PIR = digitalRead(8);//Lectura digital del estado del sensor (1 si hay movimiento 0 si no lo hay).
if (PIR == HIGH)
{
digitalWrite(12, HIGH);//Zumbador encendido.
delay(200);
digitalWrite(12, LOW);//Se apaga el zumbador a los 0,2 segundos.
}
}
sensorTemp: //Sensor de temperatura
void sensorTemp()
{
float temperatura = 0;
int valorSensor = 0;
pinMode(A0, INPUT);
valorSensor = analogRead(A0);//Lee lo el valor que esta arrojando el sensor.
temperatura = (5.0 * valorSensor * 100.0)/1024.0;//Convierte el valor que esta leyendo el sensor en grados centigrados.
}
Nota: Este es el código de los dos sensores, es el que permite guardar en las variables temperatura y pir que valores están leyendo los sensores.
3. Prueba para la conexión al servidor y envió de información a la base de datos:
conectarBd: //Se conecta al servidor y envía a la base de datos un registro en las tablas correspondientes según las variables asignándole a pir un '1' y a tem un 23.
void conectarBd()
{
Serial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"APN\",\"web.colombiamovil.com.co\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"USER\",\"\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"PWD\",\"\"");
delay(500);
Serial.println("AT+SAPBR=1,1");
delay(10000);
Serial.println("AT+HTTPINIT");
delay(2000);
Serial.println("AT+HTTPPARA=\"CID\",\"1\"");
delay(2000);
Serial.print("AT+HTTPPARA=\"URL\",\"http://190.248.13.124/sensor.php?pir=1&tem=23"\"");
delay(2000);
Serial.println("AT+HTTPACTION=0");
delay(10000);
Serial.println("AT+HTTPTERM");
delay(2000);
Serial.println("AT+SAPBR=0,1");
delay(2000);
}
Nota: Este código permite conectarse al servidor y enviar los dos datos requeridos por el método GET a la tabla correspondiente de la base de datos.
4. Código para verificar si hay una alarma:
checkAlarma:
void checkAlarma()
{
if(checkPir.equalsIgnoreCase("1"))
{
if(PIR == 1)//PIR es la variable en la que se carga el valor que se esta leyendo en el sensor de movimiento.
{
alarmaPir = 1;
}
else
{
alarmaPir = 0;
}
}
else
{
alarmaPir = 0;
}
if(checkTemp.equalsIgnoreCase("1"))
{
if(temperatura < limInfeTemp) //temperatura es la variable que lee el sensor.
{
alarmaTemp = 1;
digitalWrite(9, LOW); //Apaga el ventilador.
}
if(temperatura > limSupTemp)
{
alarmaTemp = 1;
activarVentilador();
}
else
{
alarmaTemp = 0;
}
}
else
{
alarmaTemp = 0;
}
}
Nota: Este código permite saber si hay una alarma, en el caso del sensor pir si se detecta movimiento la alarma se activa y en el caso del sensor de temperatura, de acuerdo a lo que este leyendo el sensor si la temperatura esta afuera del rango establecido (limite superior: 22°C, limite inferior: 18°C) se activa de igual forma la alarma.
5. Afinamiento de tiempos de las alertas tempranas y el envió de información a la base de datos:
codigoGprs:
String checkPir = "1";
int alarmaPir = 0;
String checkTemp = "1";
double limInfeTemp = 18;
double limSupTemp = 22;
int alarmaTemp = 0;
double PIR = 0;
double temperatura = 0;
boolean onceAlert = true;
boolean onceRegistro = true;
unsigned long smsMillis = 0;
unsigned long registMillis = 0;
unsigned long smsTime = 300000; // 5 minutos.
void setup()
{
pinMode(13, OUTPUT);
pinMode(2, OUTPUT);
Serial.begin(9600); //velocidad de conexión con módulo GPRS
activarGprs(); //activar el módulo GPRS
}
void loop()
{
leerSensores();
checkAlarma();
//Envia alertas tempranas y el registro de estas.
if(!onceAlert && (smsMillis + smsTime < millis()) )
{
onceAlert = true;
}
if( (alarmaPir == 1 || alarmaTemp == 1) && onceAlert == true)
{
onceAlert = false;
smsMillis = millis();
if(alarmaPir == 1)
{
smsPir();
conectarBd();
}
if(alarmaTemp == 1)
{
conectarBd();
smsTemp();
}
}
//Envia datos cada 5 minutos a la base de datos.
if((registMillis + smsTime < millis()) || onceRegistro)
{
onceRegistro = false;
registMillis = millis();
conectarBd();
}
}
Nota: Este es el código modificado que permite enviar los mensajes de texto(alertas tempranas) y la inserción de información a la base de datos con tiempos establecidos según el código de checkAlarma ya expuesto en el punto anterior.
6. Envió de información a la base de datos con variables:
conectarBD:
conectarBD:
void conectarBd()
{
Serial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"APN\",\"web.colombiamovil.com.co\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"USER\",\"\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"PWD\",\"\"");
delay(500);
Serial.println("AT+SAPBR=1,1");
delay(10000);
Serial.println("AT+HTTPINIT");
delay(2000);
Serial.println("AT+HTTPPARA=\"CID\",\"1\"");
delay(2000);
Serial.print("AT+HTTPPARA=\"URL\",\"http://190.248.13.124/sensor.php?pir=");
Serial.print(PIR);
Serial.print("&");
Serial.print("tem=");
Serial.print(temperatura);
Serial.println("\"");
delay(2000);
Serial.println("AT+HTTPACTION=0");
delay(10000);
Serial.println("AT+HTTPTERM");
delay(2000);
Serial.println("AT+SAPBR=0,1");
delay(2000);
}
{
Serial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"APN\",\"web.colombiamovil.com.co\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"USER\",\"\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"PWD\",\"\"");
delay(500);
Serial.println("AT+SAPBR=1,1");
delay(10000);
Serial.println("AT+HTTPINIT");
delay(2000);
Serial.println("AT+HTTPPARA=\"CID\",\"1\"");
delay(2000);
Serial.print("AT+HTTPPARA=\"URL\",\"http://190.248.13.124/sensor.php?pir=");
Serial.print(PIR);
Serial.print("&");
Serial.print("tem=");
Serial.print(temperatura);
Serial.println("\"");
delay(2000);
Serial.println("AT+HTTPACTION=0");
delay(10000);
Serial.println("AT+HTTPTERM");
delay(2000);
Serial.println("AT+SAPBR=0,1");
delay(2000);
}
Nota: Esta es la modificación del código que conecta al servidor y envía información a la base de datos según el valor que cada sensor este leyendo, esta inserción de datos ya no se hace de una manera estática si no que se hace dinámicamente ya que se esta enviando el valor correspondiente de la variable y no un dato en especifico ingresado desde la url.
7. Es importante recalcar que el código de conexión y envió de información a la base de datos requiere de un control de flujo el cual es el encargado de verificar que los comandos AT si hayan tenido una respuesta exitosa, si la respuesta captada del comando es un error este control de flujo enviara nuevamente los comandos hasta que haya una respuesta positiva, esto permitirá mayor fluides y eficiencia en el funcionamiento del sistema. En este caso el control de flujo que se diseño para este proyecto no sirvió de la forma adecuada ya que evitaba que el proyecto funcionara como se esperaba. De igual forma se dará a conocer a continuación:
imprimirLn: Este código es el que verifica si la respuesta del comando es positiva o negativa, si es buena retorna un true y si es un error retorna un false.
boolean ImprimirLn(String atCommand)
{
Serial.println(atCommand);
delay (5000);
int a=0;
do
{
a++;
delay(1000);
} while(!Serial.available() && a>30);
String response = "";
if(Serial.available() > 0)
{
response += (char)Serial.read();
}
String responseCutted = "";
response.trim();
response.replace(" ", "?");
response.replace("\n","?");
int n = response.length();
responseCutted = response.substring(n-2,n);
if(!responseCutted.equalsIgnoreCase("ok"))
{
responseCutted = response.substring(response.indexOf("+"),(response.lastIndexOf(",")+1));
if(responseCutted.equalsIgnoreCase("ok") || responseCutted.equalsIgnoreCase("+HTTPACTION:0,200,"))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
conectarBd: Este código es el control de flujo, es el que le da los tiempos a cada comando para imprimirlos, si hay un error en la respuesta este se encarga de volver a imprimirlos hasta que responda exitosamente.
void conectarBd()
{
String URLServidor="";
URLServidor="AT+HTTPPARA=\"URL\",\"190.248.13.124/sensor.php?";
URLServidor += "tem=";
char tmp1 [80];
String StringsensorTemp = dtostrf(temperatura, 1, 2, tmp1);
URLServidor += StringsensorTemp;
URLServidor += "&pir=";
char tmp2 [80];
String StringsensorAlar = dtostrf(PIR, 1, 2, tmp2);
URLServidor += StringsensorAlar;
URLServidor += "\"";
boolean flowOK = false;
int flowBucle=0;
Inicio:
if (flowBucle >= 5)
{
if(!ImprimirLn("AT"))
{
flowBucle++;
}
goto Fin;
}
if(!ImprimirLn("AT+SAPBR=3,1,\"Contype\",\"GPRS\""))
{
flowBucle++;
goto Inicio;
}
if(!ImprimirLn("AT+SAPBR=3,1,\"APN\",\"web.colombiamovil.com.co\""))
{
flowBucle++;
goto Inicio;
}
if(!ImprimirLn("AT+SAPBR=3,1,\"USER\",\"\""))
{
flowBucle++;
goto Inicio;
}
if(!ImprimirLn("AT+SAPBR=3,1,\"PWD\",\""))
{
flowBucle++;
goto Inicio;
}
if(!ImprimirLn("AT+SAPBR=1,1"))
{
flowBucle++;
goto CerrarGPRS;
}
if(!ImprimirLn("AT+HTTPINIT"))
{
flowBucle++;
goto CerrarHTTP;
}
if(!ImprimirLn("AT+HTTPPARA=\"CID\",\"1\""))
{
flowBucle++;
goto CerrarHTTP;
}
if(!ImprimirLn(URLServidor))
{
flowBucle++;
goto CerrarHTTP;
}
if(!ImprimirLn("AT+HTTPACTION=0"))
{
flowBucle++;
goto CerrarHTTP;
}
delay(20000);
//leerHTTP("AT+HTTPREAD=0, 200");
flowOK = true;
CerrarHTTP:
if (!ImprimirLn("AT+HTTPTERM"))
{
goto Inicio;
}
CerrarGPRS:
if((ImprimirLn("AT+SAPBR=0,1 ")) || (!flowOK))
{
if (flowBucle <= 5)
{
goto Inicio;
}
else
{
if(!ImprimirLn("AT"))
{
flowBucle++;
goto Inicio;
}
goto Fin;
}
}
delay (20000);
Fin:
URLServidor = "";
}
8. Integración total del código (código terminado):
codigoGprs:
String checkPir = "1";
int alarmaPir = 0;
String checkTemp = "1";
double limInfeTemp = 18;
double limSupTemp = 22;
int alarmaTemp = 0;
double PIR = 0;
double temperatura = 0;
boolean onceAlert = true;
boolean onceRegistro = true;
unsigned long smsMillis = 0;
unsigned long registMillis = 0;
unsigned long smsTime = 300000; // 5 minutos.
void setup()
{
pinMode(13, OUTPUT);
pinMode(2, OUTPUT);
Serial.begin(9600); //velocidad de conexión con módulo GPRS
activarGprs(); //activar el módulo GPRS
}
void loop()
{
leerSensores();
checkAlarma();
//Envia alertas tempranas y el registro de estas.
if(!onceAlert && (smsMillis + smsTime < millis()) )
{
onceAlert = true;
}
if( (alarmaPir == 1 || alarmaTemp == 1) && onceAlert == true)
{
onceAlert = false;
smsMillis = millis();
if(alarmaPir == 1)
{
smsPir();
conectarBd();
}
if(alarmaTemp == 1)
{
conectarBd();
smsTemp();
}
}
//Envia datos cada 5 minutos a la base de datos.
if((registMillis + smsTime < millis()) || onceRegistro)
{
onceRegistro = false;
registMillis = millis();
conectarBd();
}
}
activarGprs:
void activarGprs()
{
for(int i = 0 ; i<6; i++)
{
delay(5000); //esperamos 20 segundos a que se active el módulo GPRS
}
digitalWrite(2, HIGH);
delay(5000);
digitalWrite(2, LOW);
for(int i = 0 ; i<8; i++)
{
delay(5000); //esperamos 20 segundos a que se active el módulo GPRS
}
digitalWrite(13,HIGH);
}
leerSensores:
void leerSensores()
{
sensorTemp();
sensorPir();
}
sensorTemp:
void sensorTemp()
{
int valorSensor = 0;
pinMode(A0, INPUT);
valorSensor = analogRead(A0);
temperatura = (5.0 * valorSensor * 100.0)/1024.0;
}
sensorPir:
void sensorPir()
{
pinMode(12, OUTPUT);
pinMode(8, INPUT);
PIR = digitalRead(8);
if (PIR == HIGH)
{
digitalWrite(12, HIGH);
delay(200); digitalWrite(12, LOW);
}
}
checkAlarma:
void checkAlarma()
{
if(checkPir.equalsIgnoreCase("1"))
{
if(PIR == 1)
{
alarmaPir = 1;
}
else
{
alarmaPir = 0;
}
}
else
{
alarmaPir = 0;
}
if(checkTemp.equalsIgnoreCase("1"))
{
if(temperatura < limInfeTemp)
{
alarmaTemp = 1;
digitalWrite(9, LOW); //Apaga el ventilador.
}
if(temperatura > limSupTemp)
{
alarmaTemp = 1;
activarVentilador();
}
else
{
alarmaTemp = 0;
}
}
else
{
alarmaTemp = 0;
}
}
activarVentilador:
void activarVentilador()
{
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
}
smsPir:
void smsPir()
{
Serial.println("AT+CMGF=1");//activamos el modo SMS
delay(1500);
Serial.print("AT+CMGS="); // comando AT para enviar SMS
Serial.write( byte(34)); // enviar caracter "
Serial.print("3007799491"); // numero de movil receptor del SMS
Serial.write( byte(34)); // enviar caracter "
Serial.println();
delay(1500);
//body
Serial.print("¡ATENCION! Se detecto movimiento en la casa."); //texto del SMS
delay(10000);
//END OF SMS
Serial.write(0x1A);
Serial.write(0x0D);
Serial.write(0x0A);
}
smsTemp:
void smsTemp()
{
Serial.println("AT+CMGF=1");//activamos el modo SMS
delay(1500);
Serial.print("AT+CMGS="); // comando AT para enviar SMS
Serial.write( byte(34)); // enviar caracter "
Serial.print("3007799491"); // numero de movil receptor del SMS
Serial.write( byte(34)); // enviar caracter "
Serial.println();
delay(1500);
//body
Serial.print("La temperatura esta por encima o por debajo del rango de temperatura estimado."); //texto del SMS
delay(10000);
//END OF SMS
Serial.write(0x1A);
Serial.write(0x0D);
Serial.write(0x0A);
}
conectarBd:
void conectarBd()
{
Serial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"APN\",\"web.colombiamovil.com.co\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"USER\",\"\"");
delay(500);
Serial.println("AT+SAPBR=3,1,\"PWD\",\"\"");
delay(500);
Serial.println("AT+SAPBR=1,1");
delay(10000);
Serial.println("AT+HTTPINIT");
delay(2000);
Serial.println("AT+HTTPPARA=\"CID\",\"1\"");
delay(2000);
Serial.print("AT+HTTPPARA=\"URL\",\"http://190.248.13.124/sensor.php?pir=");
Serial.print(PIR);
Serial.print("&");
Serial.print("tem=");
Serial.print(temperatura);
Serial.println("\"");
delay(2000);
Serial.println("AT+HTTPACTION=0");
delay(10000);
Serial.println("AT+HTTPTERM");
delay(2000);
Serial.println("AT+SAPBR=0,1");
delay(2000);
}