SIM900 shield stop all'invio di SMS

Buongiorno, utilizzo una SIM900 che invia SMS se alcune variabili sono maggiori del valore impostato. Funziona benissimo. Il problema: Poichè vengono letti degli ingressi gli if sono nel loop. Sino a quando le/la varibile non rientra nel range impostato la SIM900 continua a inviare SMS :upside_down_face:
E' possibile inviare un comando o fare qualsiasi altra cosa che fermi gli invii?
Grazie in anticipo per le risposte.

Credo che il problema sia nelle if() che hai scritto

Servirebbe salvare uno "stato" e mandare messaggi solo al cambio dello stesso

Ma senza programma...

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);//TX RX
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;
int pin8 = 8;
int pin9 = 9;
//

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("Inizializzazione");
  delay(1000);
  mySerial.println("AT+CSQ"); //segale rete da 0 a 31
  updateSerial();
  mySerial.println("AT+CCID"); //informazioni SIM
  updateSerial();
  mySerial.println("AT+CREG?"); //SIM registata in rete
  updateSerial();
  delay(1000);
  mySerial.println("AT+CMGF=1");//set GSM mode
  updateSerial();
  mySerial.println("AT+CMGS=\"+39xxxxxxxx\"");
  updateSerial();
  mySerial.print("Test SMS OK ");
  updateSerial();
  mySerial.write(26);

  pinMode(pin4, INPUT_PULLUP);
  pinMode(pin5, INPUT_PULLUP);
  pinMode(pin6, INPUT_PULLUP);
  pinMode(pin7, INPUT_PULLUP);
  pinMode(pin8, INPUT_PULLUP);
  pinMode(pin9, INPUT_PULLUP);
  delay (1000);
}
void loop()
{

  if (digitalRead (pin4) == HIGH)
  {
    Serial.println (pin4);
    mySerial.println("AT+CMGS=\"+xxxxxxxx\"");
    updateSerial();
    mySerial.println("AL UM ");
    mySerial.print( pin4);//text content
    updateSerial();
    mySerial.write(26);
    delay (10000);
  }


  if (digitalRead (pin5) == HIGH)
  {
    Serial.println (pin5);
    mySerial.println("AT+CMGS=\"+xxxxxxxxx\"");
    updateSerial();
    mySerial.println("AL TEMP DHT");
    mySerial.print(pin5);//text content
    updateSerial();
    mySerial.write(26);
    delay (10000);
  }

  if (digitalRead (pin6) == HIGH)
  {
    Serial.println (pin6);
    mySerial.println("AT+CMGS=\"+xxxxxxxxxxx\"");
    updateSerial();
    mySerial.println("AL TEMP DS1");
    mySerial.print(pin6);//text content
    updateSerial();
    mySerial.write(26);
    delay (10000);
  }

  if (digitalRead (pin7) == HIGH)
  {
    Serial.println (pin7);
    mySerial.println("AT+CMGS=\"+xxxxxxxx\"");
    updateSerial();
    mySerial.println("AL TEMP DS2");
    mySerial.print(pin7);//text content
    updateSerial();
    mySerial.write(26);
    delay (10000);
  }

  if (digitalRead (pin8) == HIGH)
  {
    Serial.println (pin8);
    mySerial.println("AT+CMGS=\"+xxxxxxxxxxx\"");
    updateSerial();
    mySerial.println("AL TEMP DS3");
    mySerial.print(pin8);//text content
    updateSerial();
    mySerial.write(26);
    delay (10000);
  }

  if (digitalRead (pin9) == HIGH)
  {
    Serial.println (pin9);
    mySerial.println("AT+CMGS=\"+xxxxxxxxxxx\"");
    updateSerial();
    mySerial.println("AL SUPPLY POWER");
    mySerial.print(pin9);//text content
    updateSerial();
    mySerial.write(26);
    delay (10000);
  }

  delay (10000);
}
void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());
  }
  while (mySerial.available())
  {
    Serial.write(mySerial.read());
  }
}

Ecco il codice. Grazie!!!

Come ti ha detto @Standardoil
devi mandare email NON quando il pin diventa HIGH ma quando da LOW diventa HIGH.
Perciò per ogni pin devi memorizzare lo stato precedente, e solo se pin==HIGH e statoprecdelpin==LOW allora mandi email

Limitandoci al caso del pin 4, proviamo un esempio

if (digitalRead (pin4) != stato4)
  {
    stato4=!stato4
    if (stato4) {
        Serial.println (pin4);
        mySerial.println("AT+CMGS=\"+xxxxxxxx\"");
        updateSerial();
        mySerial.println("AL UM ");
        mySerial.print( pin4);//text content
        updateSerial();
        mySerial.write(26);
        delay (10000);
      }
   }

così dovrebbe andare, se e solo se il pin cambia controlla se è diventato alto
se sì, trasmette
prova a vedere
naturalmente la variabile stato4 la devi dichiarare globale

PS
queste cose vengono bene in un ciclo che cicla un array di strutture, i programmi escono con complessità ciclomatica trascurabile e anche piuttosto brevi

PPS uno di questi giorni provo un ciclo di for-each
che vi risulti arduino li implemeta?

Ok, grazie ci provo. Alla domanda:

mi piacerebbe poterti rispondere, ma... Non ne ho la più vaga idea.

ah, grazie, mi sono appena auto-risposto...

arduino non ha gli iteratori, in particolare #include <vector> fallisce...

@Standardoil : Puoi però fare i "ranged loops" ...

int myDays[7] = { 1,2,3,4,5,6,7 };

void setup() {
   Serial.begin ( 115200 );
   //
   for ( auto i : myDays ) {
      Serial.print ( "numero: " );
      Serial.println ( i );
   }
}

void loop() {

}

Guglielmo

1 Like

Ah, pur non avendo i "vector"...
grazie

chissà se funziona anche con i VLA di 'C'...

adesso provo...

Ho provato: direi che funziona perfettamente. Continuo a fare un po' di prove e poi ti dico. Grazie mille per la risposta semplice.

Di nulla, è stato un piacere

Buongiorno Standardoil, come promesso ti tengo aggiornato. Ormai sono settimane che il codice "gira" e funziona tutto egregiamente. Ci sarebbero due cose che vorrei implementare. La prima è l'invio di un SMS quando il valore della variabile torna sotto la soglia di allarme quindi questa linea diventerà mySerial.println("UM OK ");
La seconda riguarda la cosi detta "esistenza in vita". Per chi legge e non conoscesse, non è nient'altro che un invio da parte del dispositivo ogni tot ore o giorni di un messaggio che dice: "esisto!" Si utilizza sui ponti radio mono (per i bidi basta interrogarli) o su schede di comunicazione con uno dei tanti protocolli tipo Ademco.
Grazie!!

Grazie per il feed-back

La prima parte è semplicissima

Basta un semplice ramo else alla if(stato4)

La seconda trovi esempi a bizzeffe sull'uso di millis()

Anche il semplice "blink without delay" sarebbe abbastanza

Ciao, tutto bene? Sono con il cellulare, sto facendo la spesa. In realtà ho escluso a priori else. Pensavo e ho scritto un ulteriore cambio di state. Per quanto riguarda time: la funzione la conosco, ma quando inizi a scrivere numeri importanti come 24 ore in millis lo sketch gira senza scatenare nessun evento. Ho un Arduino addirittura collegato sotto gruppo di continuità per verificare il famoso overflow. Visualizzo oscillazioni di tempo molto strane. Tra la teoria trita e ritrita alla pratica....

Sì, tutto bene, grazie

Questo è stato un errore...

Tutto sta a scrivere bene le condizioni
E usare i giusti tipi di dati...

No, qui no
La teoria va benissimo
Anche perché è usata, in pratica, da tutti i programmi ben funzionanti

Allora, due cose:

  1. se scrivi come si deve la condizione con millis(), l'overflow è un falso problema e lo abbiamo spiegato decine e decine di volte (eventualmente studia QUI)!

  2. su tempi molto lunghi indubbiamente l'oscillatore di Arduino UNO, NON essendo quarzato, ma avendo un risuonatore ceramico, lascia piuttosto a desiderare. La cosa dovrebbe essere meno evidente con schede che hanno veramente un quarzo a bordo, ma comunque, se veramente occorre precisione su tempi di giorni, un modulo RTC (basato du DS3231) è praticamente d'obbligo.

Guglielmo

Il gsm non da anche l'ora esatta?

Non ricordo più, ma mi sembrava...

Il GPS si, il GSM ... boh ... mai verificato se c'è una funzione per recuperarla ... :roll_eyes:

Guglielmo

Lo shield 900 ha a bordo un RTC con tanto di vano per CR.

Ottimo, allora puoi usare quello per le tempistiche molto lunghe ... :slight_smile:

Guglielmo