Repetir una accion 1 sola vez, SIM900

Hola a todos, estoy trabajando en un proyecto con un sim900, el codigo funciona asi:
1-Mando un mensaje de texto con las letras H,L,A,B
2-Arduino lee y en base a esas letras actua sobre unos relees
3-Me reenvia un mensaje con la letra R, confirmando la recepcion
Mi problema esta en el punto 3, al estar dentro de un if, se repite muchas veces por segundo la seccion de envio de mensajes, y debido a esto la compañia digamos que bloquea el numero, supongo que lo debe tomar como un spam, no estoy seguro de esto ultimo.
Probe agregando un FOR, con inicio en 0, y final en 1, por ende se deberia repetir una sola vez, pero no pude solucionarlo!
Espero que alguien me pueda ayudar!

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);//Configarión de los pines serial por software
char caracter=0;// Variable para guardar los caracteres mensajes entrantes
int led=12;
int led1=11;
int i=0;
int i1=0;
int i2=0;
int i3=0;
String estado="";
void setup() {
   SIM900.begin(19200);//Arduino se comunica con el SIM900 a una velocidad de 19200bps
   //Serial.begin(19200);//Velocidad del puerto serial de arduino 
  
   digitalWrite(9,1);
   delay(2000);        // Inicio por software del sim900
   digitalWrite(9,0);
 
 pinMode(led, OUTPUT);
 pinMode(led1, OUTPUT);
 
  SIM900.print("AT+CMGF=1\r");// comando AT para configurar el SIM900 en modo texto
  delay(200);
  SIM900.print("AT+CNMI=2,2,0,0,0\r");//Configuramos el módulo para que muestre los SMS por el puerto serie.
  delay(200);
}
void loop() {  
  if(SIM900.available() >0) {//Verificamos si hay datos disponibles desde el SIM900
    caracter=SIM900.read(); // Leemos los datos y los almcanamos en la variable mensaje
  
    if(caracter=='H'){
      digitalWrite(led, HIGH);
      for ( i=0 ; i<2 ; i++){
      delay(1000);
      envio();
      }
      i1=0;
      i2=0;
      i3=0;
      }
    if(caracter=='L'){
      digitalWrite(led, LOW);
      for ( i1=0 ; i1<2 ; i1++){
      delay(1000);
      envio();
      }
      i=0;
      i2=0;
      i3=0;
      }  
 
    if(caracter=='A'){
      digitalWrite(led1, HIGH);
      for ( i2=0 ; i2<2 ; i2++){
      delay(1000);
      envio();
      }
      i1=0;
      i=0;
      i3=0;
      }
    if(caracter=='B'){
      digitalWrite(led1, LOW);
      for ( i3=0 ; i3<2 ; i3++){
      delay(1000);
      envio();
      }
      i1=0;
      i2=0;
      i=0;
      }  
  }
}

void envio() {

SIM900.print("AT+CMGF=1\r"); // Configuracion en modo mesnaje
delay(100);
SIM900.println("AT+CMGS=\"XXXXXXXXXXX\""); // XXXXXXXXXX numero de telefono
delay(100);
SIM900.println("R"); // Mensaje que reenvia
delay(100);
SIM900.println((char)26); //caracter ascii 26
delay(100);
SIM900.println();
}

No entiendo por qué lo envías dentro de un lazo for(), obviamente lo va a repetir las veces que se repita el lazo.
¿Por qué no haces un solo envío y listo?

if(caracter=='H'){
      digitalWrite(led, HIGH);
      delay(1000); // ¿es necesario?
      envio();

// y lo que sigue...

Saludos

Yo probaria con

if(caracter=='H'){
      caracter="";
      envio();
}

Lo pensé pero caracter se reasigna si hay mensaje y si no lo hay no llega a los if() así que no lo veo necesario.

Lo que sí haría es usar else if() o mejor switch()/case (y me desharía de los delay())

Saludos

Si, lo de los if lo voy a mejorar usando switch, fue para hacer una prueba rapida y como soy medio principiante no quise tocar mucho. El problema que vi es que una vez que llega el mensaje, se queda siempre ejecutando el bucle if y por ende el envio de mensajes y ahi la compañia no los envia. Porque si pruebo de enviar un mensaje cada 30 segundos funciona perfecto, ahi hice una modificacion en base a lo que me dijo @Jopapa

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);//Configarión de los pines serial por software
char caracter=0;// Variable para guardar los caracteres mensajes entrantes
int led=12;
int led1=11;
int i=0;
int i1=0;
int i2=0;
int i3=0;
String estado="";
void setup() {
   SIM900.begin(19200);//Arduino se comunica con el SIM900 a una velocidad de 19200bps
   //Serial.begin(19200);//Velocidad del puerto serial de arduino 
  
   digitalWrite(9,1);
   delay(2000);        // Inicio por software del sim900
   digitalWrite(9,0);
 
 pinMode(led, OUTPUT);
 pinMode(led1, OUTPUT);
 
  SIM900.print("AT+CMGF=1\r");// comando AT para configurar el SIM900 en modo texto
  delay(200);
  SIM900.print("AT+CNMI=2,2,0,0,0\r");//Configuramos el módulo para que muestre los SMS por el puerto serie.
  delay(200);
}
void loop() {  
  if(SIM900.available() >0) {//Verificamos si hay datos disponibles desde el SIM900
    caracter=SIM900.read(); // Leemos los datos y los almcanamos en la variable mensaje
  
    if(caracter=='H' && i==0){
      digitalWrite(led, HIGH);
      i=1;
      i1=0;
      i2=0;
      i3=0;   
      estado="Boyero On";
      envio();
      }
    
   
    if(caracter=='L' && i1==0){
      digitalWrite(led, LOW);
      i=0;
      i1=1;
      i2=0;
      i3=0;   
      estado="Boyero Off";
      envio();
      }  
 
    if(caracter=='A' && i2==0){
      digitalWrite(led1, LOW);
      i=0;
      i1=0;
      i2=1;
      i3=0;   
      estado="Alarma Off";
      envio();
      }
    if(caracter=='B' && i3==0){
      digitalWrite(led1, HIGH);
      i=0;
      i1=0;
      i2=0;
      i3=1;   
      estado="Alarma On";
      envio();
      }
  }
}

void envio() {

SIM900.print("AT+CMGF=1\r"); // Configuracion en modo mesnaje
delay(1000);
SIM900.println("AT+CMGS=\"XXXXXXXXXX\""); // XXXXXXXXXX numero de telefono
delay(1000);
SIM900.println(estado); // Mensaje que reenvia
delay(1000);
SIM900.println((char)26); //caracter ascii 26
delay(1000);
SIM900.println();
}

Con esto de las variables i, quiero lograr que solo 1 vez se ejecute el if, CREO que se lo conoce como variable bandera, no se si esta bien llevada a cabo la idea, es la mejor manera que se me ocurrio!

No debería mandar más de una respuesta salvo que el texto del mensaje tenga varias de las letras que tu usas para las órdenes.

Saludos

Que tal asi?

#include <SoftwareSerial.h>

SoftwareSerial SIM900(7, 8);//Configarión de los pines serial por software
char caracter=0;// Variable para guardar los caracteres mensajes entrantes
int led=12;
int led1=11;
int i=0;
int i1=0;
int i2=0;
int i3=0;
String estado="";

void setup() {
  SIM900.begin(19200);//Arduino se comunica con el SIM900 a una velocidad de 19200bps
  //Serial.begin(19200);//Velocidad del puerto serial de arduino 

  digitalWrite(9,1);
  delay(2000);        // Inicio por software del sim900
  digitalWrite(9,0);

  pinMode(led, OUTPUT);
  pinMode(led1, OUTPUT);

  SIM900.print("AT+CMGF=1\r");// comando AT para configurar el SIM900 en modo texto
  delay(200);
  SIM900.print("AT+CNMI=2,2,0,0,0\r");//Configuramos el módulo para que muestre los SMS por el puerto serie.
  delay(200);
}

void loop() {  
  if (SIM900.available() >0) {//Verificamos si hay datos disponibles desde el SIM900
      caracter=SIM900.read(); // Leemos los datos y los almcanamos en la variable mensaje
  
      switch(caracter) {
          case 'H':
                  if (i == 0) 
                      digitalWrite(led, HIGH);
                      i   = 1;
                      i1  = 0;
                      i2  = 0;
                      i3  = 0;   
                      estado="Boyero On";
                      envio();
                  }
                  break;
          case 'L': 
                  if (i1 == 0) {
                      digitalWrite(led, LOW);
                      i   = 0;
                      i1  = 1;
                      i2  = 0;
                      i3  = 0;   
                      estado="Boyero Off";
                      envio();
                  }
                  break;
          case 'A':
                  if (i2 == 0) {
                    digitalWrite(led1, LOW);
                    i   = 0;
                    i1  = 0;
                    i2  = 1;
                    i3  = 0;   
                    estado="Alarma Off";
                    envio();
                  }
                  break;
          case 'B': if (i3==0){
                        digitalWrite(led1, HIGH);
                        i   = 0;
                        i1  = 0;
                        i2  = 0;
                        i3  = 1;   
                        estado="Alarma On";
                        envio();
                    }
                    break;
  }
}

void envio() {
  SIM900.print("AT+CMGF=1\r"); // Configuracion en modo mesnaje
  delay(1000);
  SIM900.println("AT+CMGS=\"XXXXXXXXXX\""); // XXXXXXXXXX numero de telefono
  delay(1000);
  SIM900.println(estado); // Mensaje que reenvia
  delay(1000);
  SIM900.println((char)26); //caracter ascii 26
  delay(1000);
  SIM900.println();
}

@Surbyte probe el codigo que me pasaste, funciona perfectamente, el unico problema que es muy raro, es que al contestar manda el mensaje de la accion que efectuo, pero tambien manda el de Alarma On, no le encuentro sentido, probe cambiando los caracteres, tanto con B, con C, y siempre hace lo mismo...

Faltaba una llave { en el primer if

#include <SoftwareSerial.h>

SoftwareSerial SIM900(7, 8);//Configarión de los pines serial por software
char caracter=0;// Variable para guardar los caracteres mensajes entrantes
const int led     = 12;
const int led1    = 11;
int i  = 0;
int i1 = 0;
int i2 = 0;
int i3 = 0;
String estado = "";

void envio() {
  SIM900.print("AT+CMGF=1\r"); // Configuracion en modo mesnaje
  delay(1000);
  SIM900.println("AT+CMGS=\"XXXXXXXXXX\""); // XXXXXXXXXX numero de telefono
  delay(1000);
  SIM900.println(estado); // Mensaje que reenvia
  delay(1000);
  SIM900.println((char)26); //caracter ascii 26
  delay(1000);
  SIM900.println();
}

void setup() {
  SIM900.begin(19200);//Arduino se comunica con el SIM900 a una velocidad de 19200bps
  //Serial.begin(19200);//Velocidad del puerto serial de arduino 

  digitalWrite(9,1);
  delay(2000);        // Inicio por software del sim900
  digitalWrite(9,0);

  pinMode(led, OUTPUT);
  pinMode(led1, OUTPUT);

  SIM900.print("AT+CMGF=1\r");// comando AT para configurar el SIM900 en modo texto
  delay(200);
  SIM900.print("AT+CNMI=2,2,0,0,0\r");//Configuramos el módulo para que muestre los SMS por el puerto serie.
  delay(200);
}

void loop() {  
    if (SIM900.available() >0) {  // Verificamos si hay datos disponibles desde el SIM900
        caracter = SIM900.read(); // Leemos los datos y los almcanamos en la variable mensaje
    
        switch(caracter) {
            case 'H':   if (i == 0) {
                            digitalWrite(led, HIGH);
                            i   = 1;
                            i1  = 0;
                            i2  = 0;
                            i3  = 0;   
                            estado="Boyero On";
                            envio();
                        }
                        break;

            case 'L': if (i1 == 0) {
                            digitalWrite(led, LOW);
                            i   = 0;
                            i1  = 1;
                            i2  = 0;
                            i3  = 0;   
                            estado="Boyero Off";
                            envio();
                        }
                        break;
            case 'A': if (i2 == 0) {
                            digitalWrite(led1, LOW);
                            i   = 0;
                            i1  = 0;
                            i2  = 1;
                            i3  = 0;   
                            estado="Alarma Off";
                            envio();
                        }
                        break;

            case 'B': if (i3==0){
                            digitalWrite(led1, HIGH);
                            i   = 0;
                            i1  = 0;
                            i2  = 0;
                            i3  = 1;   
                            estado="Alarma On";
                            envio();
                        }
                        break;
        }
    }
}

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