Editado por Moderador:
Hola, buenas tardes, estoy utilizando el SIM808, Me funciona las llamadas, mensajes y el gps, pero la fecha: 04/01/01,00:02:14+00, que esta mal
Mensaje anterior
El problema es que me sale la fecha como vieron en el título, funciona las llamdas, mnesajes hasta el gps, la altiud y la longitud, el problema esta en la fecha, no me trae la fehca actual, que problema estoy cometiendo e mi código, no soy un experto en arduino, talvez son los delay que me falta, porfa si alguien me puede ayudar gracias de antemano.
#include <SoftwareSerial.h>
// Definir los pines para la comunicación con el SIM808 y el pin del relé
//Objeto llamado sim808, que es una instancia de SoftwareSerial
SoftwareSerial sim808(18, 19); // RX, TX (ajusta estos pines para la comunicación)
//18, es el pin de recepción y 19 es el pin de transmisión
const int relePin = 5; // Pin donde está conectado el relé
//const int relePin2 = 4; // Pin donde está conectado el relé
const int botonEmergencia = 4; //pin asociado al boton de emergencia
//Pines donde estan conectados sensores PIR(Passive Infrared), sensores que detectan movimiento
const int pirPin = 25; // Pin donde está conectado el sensor PIR1
const int pirPin2 = 26; // Pin donde está conectado el sensor PIR2
const int pirPin3 = 27; // Pin donde está conectado el sensor PIR3 -- Ahora puerta 2
const int pirPin4 = 14; // Pin donde está conectado el sensor PIR4 -- Ahora puerta 3
const int puertaPin = 22; // Pin donde está conectado el sensor de Puerta, abierta o cerrada
const int ledEncendido = 15;
const int ledApagado = 2;
//Variables estado, si es 0= sin detección y es 1 = detección de movimiento
int estadoPir = 0;
int estadoPir2 = 0;
int estadoPir3 = 0;
int estadoPir4 = 0;
int estadoPuerta = 0;
int estadoEmergencia = 0;
bool pirActivado = false; // Variable para verificar si algún PIR está activo
bool activarSistema = false; //Variable para controlar si activar o no el sistema
bool habilitarPir = false; //Variable para controlar los sensores PIR, habilitados o no
String data[6]; // declaración de un arreglo con valor fijo de 6 elementos o tamaño
String estado, tiempogps, latitud, longitud, altitud, fix; //Variables para almacenar los diferentes datos de tipo String
//setup es una función especial que se ejecuta una sola vez al inicar el programa
void setup() {
// Inicializa la comunicación serial entre el Arduino y la computadora
Serial.begin(9600); //Inicializa la comunicación serial entre el arduino y la computadora atraves del puero USB
//Velocidad de comunicación 9600 baudios por segundo, es una velocidad estandar, nos permitira enviar y recivir datos
//por el monitor serial Interfaz De Desarrollo (IDE de Arduino) para depurar o interacción con el programa
//Comunicación entre el Arduino y el módulo sim808, utilizando los pines configurados en SoftwareSerial 18 y 19
sim808.begin(9600); //Inicializa el objeto sim808, y su velocidad debe coincidir con la configuración del módulo
//pinMode(pin, value): Configurarmos los pines del relé como salida, para controlar dispositivos conectados
//OUTPUT: Salida
pinMode(relePin, OUTPUT);
pinMode(ledEncendido, OUTPUT);
pinMode(ledApagado, OUTPUT);
//digitalWrite(pin, value): establece el estado inicial de los pines de salida,
//LOW: Apaga el dispositivo conectado al pin
digitalWrite(ledEncendido, LOW); // Led verde
digitalWrite(ledApagado, LOW); // Led Apagado
digitalWrite(relePin, LOW); // Relé apagado inicialmente
//definimos los pines como entrada input, para leer las señales externas, sensores y botones
pinMode(pirPin, INPUT);
pinMode(pirPin2, INPUT);
pinMode(pirPin3, INPUT);
pinMode(pirPin4, INPUT);
pinMode(puertaPin, INPUT);
pinMode(botonEmergencia, INPUT);
// Esperar a que el SIM808 esté listo
delay(21000); //21 segundos
// Mostramos un mensaje en el monitor serial del IDE de Arduino
Serial.println("Iniciando módulo SIM808...");
// reiniciarSIM808();
limpiarBufferSim808();
//Configuraciones del módulo SIM808
// Configurar el SIM808 para modo texto
sendData("AT+CMGF=1", 1000); // AT+CMGF=1: Comando AT, para activar modo texto, enviar y recibir mensajes SMS, con retraso de 1segundo
// Configura el módulo SIM808 para que notifique automáticamente al Arduino cuando se reciba un nuevo mensaje SMS
sendData("AT+CNMI=2,2,0,0,0", 1000);
// Configurar el SIM808 para activar el GPS, activa el gps
sendData("AT+CGNSPWR=1", 1000);
//Verfiica el estado de la red
sim808.println("AT+CREG?");
delay(1000);
String cregResponse = sim808.readString();
Serial.println("Respuesta AT+CREG?: " + cregResponse);
sim808.println("AT+CLTS=1");
delay(2000);
limpiarBufferSim808();
sim808.println("AT+CLTS?");
delay(2000);
String response = sim808.readString();
Serial.println("Respuesta AT+CLTS:"+ response);
digitalWrite(ledApagado, HIGH); // Enciende el led conectado al pin ledApagado
//Estado iniciarl forzado (hardcoded), asignamos el estado de LOW, a las variables
/* estadoPir = LOW;
estadoPir2 = LOW;
estadoPir3 = LOW;
estadoPir4 = LOW;
estadoPuerta = LOW; */
Serial.println("Listo para recibir mensajes SMS y controlar pines."); // Mostramos mensaje en el monitor serial IDE Arduino
}
//Función loop de arduino destinado a repetirse constantemente
void loop() {
//Estado iniciarl forzado (hardcoded), asignamos el estado de LOW, a las variables
estadoPir = LOW;
estadoPir2 = LOW;
estadoPir3 = LOW;
estadoPir4 = LOW;
estadoPuerta = LOW;
// Verificar si hay datos disponibles desde el SIM808, si hay mensajes en el SIM808
if (sim808.available()) {
//digitalWrite(relePin2, LOW);
Serial.println("Va a empezar a leer");
String message = leerMensajeSim808();
delay(100);
// Mostrar el mensaje recibido en el monitor serial
Serial.println("Mensaje completo:");
Serial.println(message);
//Pregunta si hay un mensaje enviado de la aplicación al SIM808
if (message.indexOf("activar sistema") != -1) {
activarSistema = true;
habilitarPir = true;
Serial.println("Sistema activado");
digitalWrite(ledEncendido, HIGH);
digitalWrite(ledApagado, LOW);
delay(5000);
//message="";
}
if (message.indexOf("desactivar sistema") != -1) {
// delay(15000);
delay(3000);
activarSistema = false;
digitalWrite(relePin, LOW);
digitalWrite(ledEncendido, LOW);
digitalWrite(ledApagado, HIGH);
}
//busca si message tiene un mensaje "enviar gps", si tiene entra a la condicional
if (message.indexOf("enviar gps") != -1) {
//Enviamos el comando AT+CGNSINF, a la función sendTabData2
sendTabData2("AT+CGNSINF", 1000); // AT, es un comando que obtiene información desde el SIM808,
//incluye datalles como latitud, longitud, velocidad y estado del GPS
//Enviar las coordenados por SMS
sendSMSubi("63871155", latitud, longitud);
//message="";
delay(10000);
//Leer los estados de los sensores digitalRead, estados de los pines conectados al sensor PIR
//HIGHT: hay movimiento, LOW: no hay movimiento
//Esto actualiza las variables con los estados actuales de los sensores
estadoPir = digitalRead(pirPin);
estadoPir2 = digitalRead(pirPin2);
estadoPir3 = digitalRead(pirPin3);
estadoPir4 = digitalRead(pirPin4);
estadoPuerta = digitalRead(puertaPin);
} else {
Serial.println("Mensaje no reconocido.");
}
}
//Verificar si el sistema esta activo
if (activarSistema == true) {
//Iniciarliza los estados de los sensores en LOW, no detectan movimientos, ni intrusos
estadoPir = LOW;
estadoPir2 = LOW;
estadoPir3 = LOW;
estadoPir4 = LOW;
estadoPuerta = LOW;
//Lee el estado del botón de emergencia, si el botón esta presionado sera HIGHT,
// esto permitira desactivar el sistema manualmente
estadoEmergencia = digitalRead(botonEmergencia);
//Verifica si los sensores PIR estan habilitados
if (habilitarPir) {
//Leer los estados de los sensores PIR y de la puerta
//digitalWrite(relePin2, HIGH);
estadoPir = digitalRead(pirPin);
estadoPir2 = digitalRead(pirPin2);
estadoPir3 = digitalRead(pirPin3);
estadoPir4 = digitalRead(pirPin4);
estadoPuerta = digitalRead(puertaPin);
Serial.println("Entro a true");
//Detectar movimiento o intrusos, pirActivado impide que el sistema reacciones repetidamente, mientras el sensor sigue detectando movimientos
if ((estadoPir == HIGH || estadoPir2 == HIGH || estadoPir3 == HIGH || estadoPir4 == HIGH || estadoPuerta == HIGH) && !pirActivado) {
pirActivado = true; // Marcar queya se detecto un evento para evitar multiples llamadas
habilitarPir = false; // Desactiva los sensores temporalmente
digitalWrite(relePin, HIGH); //Activamos el relé
Serial.println("Movimiento detectado. Llamando al número...");
//Enviar mensaje al celular, de que se detecto movimientos
String dateTime = getDateTime();
String mensajeAlerta = "ALERTA!!!, ALERTA!!!, alarma activada!!!, alarma activada!!!, Fecha y hora" + dateTime;
sendSMS("63871155", mensajeAlerta);
delay(1000);
makeCall("63871155");
}
// Si el sensor PIR no detecta movimiento
//Restablece el sensor PIR
if (estadoPir == LOW) {
pirActivado = false;
}
}
//Acción al presionar el boton de emergencia, se desactiva el sistema, se apaga los leds y el rele,
// se actualizan los estados de los sensores para evitar reacciones posteriores
if (estadoEmergencia == HIGH) {
digitalWrite(relePin, LOW);
//Finalizamos el sistema tras emergencia
activarSistema = false;
digitalWrite(relePin, LOW); //Apagea el relé
digitalWrite(ledEncendido, LOW);
digitalWrite(ledApagado, HIGH);
delay(10000);
//Actualizamos los esados de los sensores
estadoPir = digitalRead(pirPin);
estadoPir2 = digitalRead(pirPin2);
estadoPir3 = digitalRead(pirPin3);
estadoPir4 = digitalRead(pirPin4);
estadoPuerta = digitalRead(puertaPin);
}
}
// Verificar si el monitor serial tiene datos para enviar al SIM808
//Verifica si hay datos disponibles para leer en el puerto serial(enviados desde la computadora, por ejemplo atrasves del monitor serial IDE Arduino)
if (Serial.available()) {
delay(10);
sim808.write(Serial.read());
}
Serial.println("pir1: " + String(estadoPir));
Serial.println("pir2: " + String(estadoPir2));
Serial.println("pir3: " + String(estadoPir3));
Serial.println("pir4: " + String(estadoPir4));
Serial.println("puerta: " + String(estadoPuerta));
Serial.println("emergencia: " + String(estadoEmergencia));
delay(1000);
}
// Función para limpiar el buffer, los datos nodeseados o residuales del SIM808
void limpiarBufferSim808() {
while (sim808.available()) {
sim808.read(); // Leer y descartar todos los datos no deseados en el buffer, como el dato no se almacena ni se utiliza, se descarta al leerlo cada byte
}
}
/* void reiniciarSIM808() {
sendData("AT+CFUN=1,1", 5000); // Reiniciar el módulo SIM808
delay(10000); // Esperar a que el módulo se reinicie completamente
} */
// Función para leer los datos recibidos del SIM808
String leerMensajeSim808() {
String message = ""; //Inicializamos un String vacio para almecenar los datos
while (sim808.available()) { // mientras haya datos en el buffer o memoria
char c = sim808.read(); //Leer un caracter del buffer o memoria
message += c; //Agregar el caracter al message
}
return message; //retornar todo el mensaje
}
//Función para extraer 2 valores especificos, latitud y longitud
void sendTabData2(String comando, const int timeout) {
sim808.println(comando);
long int time = millis();
int i = 0;
String data = "";
while ((time + timeout) > millis()) {
while (sim808.available()) {
char c = sim808.read();
data += c;
}
}
// Buscar los valores de latitud y longitud
int indexLat = data.indexOf(',') + 1; // Buscar la primera coma
indexLat = data.indexOf(',', indexLat) + 1; // Saltar al segundo campo
indexLat = data.indexOf(',', indexLat) + 1; // Saltar al tercer campo (latitud)
int indexLon = data.indexOf(',', indexLat) + 1; // Saltar al cuarto campo (longitud)
// Extraer latitud y longitud del mensaje
latitud = data.substring(indexLat, data.indexOf(',', indexLat));
longitud = data.substring(indexLon, data.indexOf(',', indexLon));
Serial.print("Latitud: ");
Serial.println(latitud);
Serial.print("Longitud: ");
Serial.println(longitud);
}
String sendData(String comando, const int timeout) {
limpiarBufferSim808();
String response = "";
sim808.println(comando); // Enivar el comando al módulo SIM808, ejemplo este comando: AT+CGNSINF,
//el módulo lo procesará y devolverá una respuesta. El módulo SIM808 devuelve al respuesta tipicamente en texto,
//a veces con multiples lineas
long int time = millis();
int i = 0;
while ((time + timeout) > millis()) {
while (sim808.available()) {
char c = sim808.read(); // Si hay datos lee carácter por carácter
response += c;
}
}
Serial.print(response); //Imprime el mensaje en el monitor
return response; // Devuelve la respuesta completa
}
// Función par aenviar un mensaje SMS, AL CELULAR
void sendSMS(String phoneNumber, String message) {
sim808.print("AT+CMGS=\""); //Envía el comando al módulo SIM808
sim808.print(phoneNumber); //El número destinatario
sim808.println("\""); // Establecer el número del destinatario
delay(1000);
sim808.println(message); // Contenido del mensaje
delay(1000);
sim808.write(26); // Código ASCII para Ctrl+Z (fin del mensaje SMS), inidica al módulo SIM808, que ya no se enviaran más datos
delay(3000); // Esperar un poco para asegurar que el mensaje se haya enviado
}
String getDateTime() {
sim808.println("AT+CCLK?"); // Solicitar la fecha y hora al módulo
delay(1000); // Esperar la respuesta
String response = "";
while (sim808.available()) {
char c = sim808.read(); // Leer carácter por carácter
response += c;
}
Serial.println("Respuesta AT+CCLK?: " + response); // Depuración
int startIndex = response.indexOf("+CCLK:"); // Buscar el inicio de la respuesta
if (startIndex != -1) {
startIndex = response.indexOf('"', startIndex) + 1; // Buscar la primera comilla
int endIndex = response.indexOf('"', startIndex); // Buscar la segunda comilla
if (startIndex != -1 && endIndex != -1) {
return response.substring(startIndex, endIndex); // Extraer la fecha y hora
}
}
return "Fecha no disponible"; // Si no se pudo obtener la fecha
}
//Función para enviar la latitud y longitud al celular
void sendSMSubi(String phoneNumber, String latitud, String longitud) {
sim808.print("AT+CMGS=\""); //El comando AT+cmgs, requier que el número este en comillas dobles
sim808.print(phoneNumber);
sim808.println("\""); // Establecer el número del destinatario
delay(1000);
sim808.print("http://maps.google.com/maps?q=loc:");
sim808.print(latitud);
sim808.print(",");
sim808.print(longitud);
delay(200);
sim808.write(26); // Código ASCII para Ctrl+Z (fin del mensaje SMS)
delay(200); // Esperar un poco para asegurar que el mensaje se haya enviado
sim808.println();
delay(20000);
sim808.flush(); //Vaciar el buffer del módulo después de enviar el mensaje
}
//Función para realizar la llamada
void makeCall(String phoneNumber) {
sim808.print("ATD"); // Comando para marcar
sim808.print(phoneNumber);
sim808.println(";"); // Llamada de voz
delay(3000); // Espera inicial para establecer la llamada
Serial.println("Llamada iniciada, monitoreando estado...");
delay(9000);
// Monitorear el estado de la llamada
while (true) {
sim808.println("AT+CLCC"); // Consultar el estado de la llamada
delay(1000); // Esperar un segundo entre consultas
if (sim808.available()) {
String response = sim808.readString(); // Leer respuesta del SIM808
Serial.println(response); // Mostrar en el monitor serial
// Verificar si no hay llamadas activas
if (response.indexOf("+CLCC:") == -1) {
Serial.println("La llamada ha finalizado.");
break; // Salir del bucle porque la llamada ha terminado
}
}
}
// Colgar la llamada si sigue activa
sim808.println("ATH"); // Colgar la llamada
Serial.println("Llamada colgada.");
}