Go Down

Topic: Arduino Uno + Sim900+ time Alarms (Read 3171 times) previous topic - next topic

jazpiroz

Estimados, buenos días!, les consulto por el siguiente problema:

Estoy desarrollando un proyecto que mediante un sms prende o apaga un relé. Como estoy usando sms, tengo un mensaje donde habilita o no las notificaciones, esto es: el sistema me contesta con el un sms por ejemplo el estado del mismo.
El flujo correcto debería ser:
Se envía sms para setear alarma que prende relé
El sistema prende relé
Se envía sms para saber estado, el sistema devuelve estado
La habilitación de las notificaciones se debería poder hacer en cualquier momento.

Si el flujo es:
1) Envio de sms para setear alarma que prende rele
2) Alarma se ejecuta correctamente

Si ejecuto el siguiente flujo, la alarma no se dispara.

1) Envio de sms para habilitar notificaciones, el sistema me devuelve NOTI ONN, esto es correcto
2) Envío de sms para setear alarma que prende relé, la alarma no se dispara nunca

Si ejecuto el siguiente flujo

1) Envio de sms para setear alarma que prende rele, alarma se está ejecutando por X tiempo
2) Envio de sms para habilitar notificaciones, el sistema me devuelve NOTI ONN, esto es correcto
3) Envío de sms para consultar estado, el sistema contesta correctamente

Desde ya muchas gracias!!

Adjunto código en Mensaje Siguiente:

jazpiroz


Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);
#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>

#include "RTClib.h"


//------------ gsm
char incoming_char=0;
String smsRecibo;
int largo;
String mensaje;
String buffer;
String mensajeRecibido;
int automatico;
int notificaciones;
String nroDetectado;

int myReleeA = 13; //releA
int myReleeB = 6; //releB
int myReleeC;
int myReleeD;
int rele2;

//-programar Alarmas
RTC_DS1307 rtc;
AlarmID_t alarmaA1Onn;
AlarmID_t alarmaA1Off;
AlarmID_t alarmaA1Onn8;
AlarmID_t alarmaA1Off8;

int hora;
int minuto;
String horaDetectada;
String salida;
String dia;

String HoraEnviada;
String diaSemana;
String accionSalida;
int tiempoEnv;
int diaEnviado;
String tiempoEnviado;
String programRecibido;

int horaApagado;
int minutoApagado;
int resto;
int resta;
int divide;

String estadoAlarmaA1;
String estadoAlarmaA2;

void setup()
{
   Serial.begin(9600);
   Alarm.delay(3000);  
   alarmaA1Onn = Alarm.alarmRepeat(hora,minuto,0, enciendeReleA1);
   alarmaA1Off = Alarm.alarmRepeat(horaApagado,minutoApagado,0, apagaReleA1);  
  
   powerUpOrDown(); //enciende sim900  
 
  mySerial.begin(19200); // for GSMshield
  Alarm.delay(1000);
  mySerial.print("AT+CMGF=1\r");  // set SMS mode to text
  Alarm.delay(1000);
  mySerial.print("AT+CNMI=2,2,0,0,0\r");    
  
  Alarm.delay(100);  
  pinMode(13, OUTPUT);
 
  pinMode(myReleeA, OUTPUT);
  pinMode(myReleeB, OUTPUT);
  digitalWrite(myReleeA, LOW);
  digitalWrite(myReleeB, HIGH);
    
  buffer = "";
  automatico=0;
  notificaciones = 0;

 if (! rtc.begin()) {
 Serial.println("No hay un módulo RTC");
 while (1);
 }
  DateTime now = rtc.now();
  setTime(now.hour(), now.minute(), now.second(), now.month(), now.day(), now.year()); 
 Serial.println(now.day(), DEC);
 Serial.println(now.month(), DEC);
 Serial.println(now.year(),DEC);
}
void loop()
{    
  char SerialInByte;  
  if(mySerial.available() >0)
  {
   Serial.println("disponible");
   buffer = "";
   readSIM900A();
  
    //Habilita las notificaciones por SMS
    int elenotion = buffer.indexOf("NOTI-ON"); //para encender notificaciones
  
      if (elenotion>=0)
      {      
      notificaciones = 1; //habilita notificaciones
      mensaje = "NOTIF ON";
      mensaje_sms(mensaje);
      }

      int elementoNotiOf = buffer.indexOf("NOTI-OFF"); //para encender notificaciones
    
      if (elementoNotiOf>=0)
      {
      mensaje = F("NOTIF OFF");  
      mensaje_sms(mensaje);
      notificaciones = 0; //deshabilita notificaciones      
      }    
    
    int elementoTiempo = buffer.indexOf("IA1");                                       
    if (elementoTiempo>=0)
      {
        capturaEvento();
        mensaje= programRecibido;        
        mensaje_sms(mensaje);               
        armoHoras();        
        setAlarmaIA1();        
      }

    int elementoTiempoA2 = buffer.indexOf("IA2");                                      
    if (elementoTiempoA2>=0)
      {        
        estadoAlarmaA2="";
        capturaEvento();
        mensaje= programRecibido;        
        mensaje_sms(mensaje);               
        armoHoras();        
        setAlarmaIA2();        
      }
   //consultas estado
  int elementoConsultaA1 = buffer.indexOf("CA1");                                       
    if (elementoConsultaA1>=0)
      {
        Serial.println(buffer);
        mensaje= estadoAlarmaA1; mensaje_sms(mensaje);        
      }      
  }   
}

//lee los characteres del mensaje y los mete en un buffer
String readSIM900A()
{
  buffer = "";
   while (mySerial.available())
    {      
        char c = mySerial.read();
        buffer.concat(c);      
        Alarm.delay(10);        
    }    
    mensajeRecibido = buffer;
    return buffer;    
}

void enciendeReleA1()
{
  Serial.println("Enciende rele A1-------------------------------");
  digitalWrite(myReleeA, HIGH);  
  setEstadoAlarmaA1();  
}

void enciendeReleA2()
{
  Serial.println("Enciende rele A1--------------por alarma 2-----------------");
  digitalWrite(myReleeA, HIGH);
  setEstadoAlarmaA2();  
}

// Apaga Reles ----

void apagaReleA1()
{
  Serial.println("Apaga rele A1 ++++++++++++++++++++++++++++++");
  digitalWrite(myReleeA, LOW);    
  duermeEstadoAlarmaA1();
  
}

void apagaReleA2()
{
  Serial.println("apaga rele A1--------------por alarma 2-----------------");
  digitalWrite(myReleeA, LOW);    
  //duermeEstadoAlarmaA2();
  //duermeEstadoAlarmaB2();
}



void mensaje_sms(String mensaje)
   {
    
      capturaNroEnviado();      
      String nroEnvio2 = "AT+CMGS=\"+" + String(nroDetectado);
      nroEnvio2.concat("\"");          
      if (notificaciones == 1)
      {    
      Serial.println("Enviando SMS...");    
      mySerial.print("AT+CMGF=1\r");  //Configura el modo texto para enviar o recibir mensajes
      Alarm.delay(1000);
      //mySerial.println("AT+CMGS=\"+11111111111\"");  //Numero al que vamos a enviar el mensaje
      mySerial.println(nroEnvio2);  //Numero al que vamos a enviar el mensaje
      Alarm.delay(1000);
      mySerial.println(mensaje);  // Texto del SMS
      Alarm.delay(100);
      mySerial.println((char)26); //Comando de finalización ^Z
      Alarm.delay(100);
      mySerial.println();
      Alarm.delay(5000);  // Esperamos un tiempo para que envíe el SMS    
      }
    
   }

void capturaNroEnviado()
{
  int elementoComilla = mensajeRecibido.indexOf('5');  
  int elementoSegundaComilla =  mensajeRecibido.indexOf('"',elementoComilla);
  
  nroDetectado = mensajeRecibido.substring(elementoComilla,21);  
  Alarm.delay(100);
  }

void powerUpOrDown()
{
    pinMode(9, OUTPUT);
    digitalWrite(9,LOW);
    Alarm.delay(1000);
    digitalWrite(9,HIGH);
    Alarm.delay(5000); //era 5000
    digitalWrite(9,LOW);
    Alarm.delay(3000);
}

void capturaEvento()
{
  //int elementoAsterisco = mensajeRecibido.indexOf('#');  
  accionSalida = mensajeRecibido.substring(49,53);
  diaSemana = mensajeRecibido.substring(54,55);
  HoraEnviada = mensajeRecibido.substring(56,60);
  tiempoEnviado = mensajeRecibido.substring(61,63);

  programRecibido = "#S"+accionSalida+"#D"+diaSemana+"#H"+HoraEnviada+"#T"+tiempoEnviado;
    
}


void armoHoras(){
  hora  = HoraEnviada.substring(0,2).toInt();
  minuto  = HoraEnviada.substring(2,4).toInt();
  tiempoEnv = tiempoEnviado.toInt();
  diaEnviado = diaSemana.toInt();
    
  
  if (diaEnviado >=0 and diaEnviado <=9){
  //  Serial.println("dia entre 1 y 7");
  resta = 60 - tiempoEnv;
  if (resta < 60){
    Serial.println("resta menor de 60");
    horaApagado = HoraEnviada.substring(0,2).toInt();
    minutoApagado = HoraEnviada.substring(2,4).toInt()+tiempoEnv;
  }
  if (tiempoEnv >= 60 and tiempoEnv <=900){
    Serial.println("tiempo enviado mayor de 60");
      resto = tiempoEnv % 60;
      divide = tiempoEnv / 60;
      horaApagado = HoraEnviada.substring(0,2).toInt() + divide;
      minutoApagado = HoraEnviada.substring(2,4).toInt()+ resto;
      
      if (horaApagado = 23 and minutoApagado >59){
        minutoApagado = 59;
      }
      if (horaApagado > 24){
        horaApagado = 24;
        minutoApagado = 0;
      }
  }
  
}
}


 void setAlarmaIA1(){  //Salida 1 : Alarma1
   //guardo valores: hora,minuto y hora minuto apagado
   //guard dia
    
    Serial.println("-----------");
    Serial.println(horaApagado);
    Serial.println(minutoApagado);
    Serial.println("-----------");
    
    if (diaEnviado == 0){
    Serial.println("Cerooooo");  
    Alarm.disable(alarmaA1Onn);
    Alarm.free(alarmaA1Onn);
    Alarm.disable(alarmaA1Off);
    Alarm.free(alarmaA1Off);            
    alarmaA1Onn = Alarm.alarmRepeat(hora,minuto,0, enciendeReleA1);
    alarmaA1Off = Alarm.alarmRepeat(horaApagado,minutoApagado,0, apagaReleA1);
    }
}


void setEstadoAlarmaA1(){
  estadoAlarmaA1 = "#S"+accionSalida+"#D"+diaSemana+"#H"+HoraEnviada+"#T"+tiempoEnviado;
 
}

void duermeEstadoAlarmaA1(){  
  estadoAlarmaA1 = "Espera "+accionSalida+ "/" + diaSemana +"/"+ HoraEnviada +"/"+ tiempoEnviado;
}

void liberarAlarmas(){

}

jazpiroz

Puede ser que está influyendo los momentos que modifco la velocidad del serial??, ya que para el sim900 es 115200 ....

surbyte

#3
May 23, 2018, 01:30 am Last Edit: May 23, 2018, 01:31 am by surbyte
Tengo errores con los procedimientos


Code: [Select]
setEstadoAlarmaA2();
 dice que no esta definido

setAlarmaIA2() tampoco

jazpiroz

Comentalos, serían para la segunda alarma,
Gracias,
Saludos
Juan

surbyte

Es curioso, vienes con un problema y colocas un código que no compila. Entonces no entiendo qué has comprobado o hasta donde poder creer lo que dices en el primer post?

La compilación arrojó que no ocupa mas del 50% de la RAM de modo que si hay problemas se debe ha algun error de creación de objetos.
Hasta que valor has permitido que TimeAlarms genere alarmas, o mejor dicho que valor has puesto en le .h de TimeAlarms?

jazpiroz

Estimado, el código que tengo tiene mas de 1068 líneas, donde el sitio no me deja subir por la cantidad de caracteres que tengo, por este motivo hice un recorte. Esa es la parte curiosa.

Pruebas he realizado muchas y por este motivo como última opción salí a pedir ayuda a gente que evidentemente sabe mucho mas que uno.


Ahora bien, como comentaba en los post anteriores, si utilizo el flujo 1 y 3 funciona correctamente, pero lo ideal sería que en cualquier momento, el usuario habilite o no las notificaciones. Para esta realidad, si el usuario lo primero que hace es habilitar las notificaciones.
Luego setear alarmas, la alarma no funciona.

En la h de time alarms, hoy en la mañana probé dejando solamente 6, la que tenia hasta ayer era 20.

Gracias por tu tiempo



surbyte

Ahh ok o sea que lo que hice no sirvió para nada!!

Sube el código completo como adjunto, vamos que cuando un código no puede subirse se sube como adjunto y claro que esta bien asi hacerlo.

Sin el código no se puede evaluar nada.

jazpiroz

ok, adjunto el código, lo pasé  como un txt.
gracias

surbyte

Bueno, he logrado compilar el código agregando al comienzo las funciones que me daban error que te señalé antes.

El reporte de mi compilador dice

Code: [Select]

Program:   14218 bytes (43.4% Full)
(.text + .data + .bootloader)

Data:       1106 bytes (54.0% Full)
(.data + .bss + .noinit)
 [SUCCESS] Took 5.17 seconds


Lo que indica que estas al 54% de RAM en uso.

Necesito saber que Arduino usas, por lo visto es un UNO o un NANO no?

Estoy viendo el código.

jazpiroz


surbyte

Lo primero que no me gusta es la cantidad de Strings que usas y no veo que en ningún sitio los inicialices.

Code: [Select]
String horaDetectada;
String salida;
String dia;

String HoraEnviada;
String diaSemana;
String accionSalida;

String tiempoEnviado;
String programRecibido;

String estadoAlarmaA1;
String estadoAlarmaA2;

String estadoAlarmaB1;
String estadoAlarmaB2;

String estadoAlarmaC1;
String estadoAlarmaC2;

String estadoAlarmaD1;
String estadoAlarmaD2;


Posibildad de problemas conforme el código funciona.

Tienes comentados lugares donde los Strings eran puestos a 0 como este

Code: [Select]
if (elementoTiempo>=0)  {
      //Serial.println("llego mensaje");     
      //estadoAlarmaA1="";                   // <=== NO se porque lo comentaste
      capturaEvento();
      mensaje= programRecibido;       
      mensaje_sms(mensaje);
             
      armoHoras();       
      setAlarmaIA1();       
    }

jazpiroz

ese caso de la variable comentada, era para una vez que lee el sms, el estado vuelva a vacío.

surbyte

Bueno, yo encararía varias cosas de otro modo pero no se si eso resuelve el problema y no se como probarlo sin tener que armar todo lo que tu tienes.
Ejemplo no usaría Strings al menos no tantos como tu usas.
Y si usaría vectores fijos de dimensión establecida y luego los armo con sprintf similar a tu composición de concatenación de datos usando + como por ejemplo acá

Code: [Select]
programRecibido = "#S"+accionSalida+"#D"+diaSemana+"#H"+HoraEnviada+"#T"+tiempoEnviado;

Se me dificulta probar el código y ver en que falla.

Veré si me hago un tiempo y monto la placa SIM para comprobarlo.


jazpiroz

Entiendo lo que decis, pero como tu dices no creo que esto solucione el problema, gracias de todos modos

Go Up