Falla con fecha en programa que usa SIM808

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.");
}


La respuesta a este comando depende de su proveedor de servicios local. Por ejemplo, donde vivo, hay tres operadores móviles principales y ninguno de ellos admite el comando CCLK.

¿Has intentado enviar esta solicitud manualmente, desde la terminal, y ver qué módem recibe una respuesta de la red?

Gracias, si es eso era, ya no soporta la fecha mi red celular, hay otra forma de obtener la fecha, o solo eso seria lo que puedo hacer para obtener la hora?

El GPS debería enviarte la fecha y la hora, ojo que es UTC, tenés que convertirlas a hora local.

Gracias, lo revisare, ya lo revise encontré un comando AT+CGNSINF, ahora lo convertiré a mi zona horaria, que es menos tantas horas, los días igual, mes y año.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.