Allarme con arduino problema ciclo bloccato

Buon Giorno :grinning: questa mattina sono mattiniero perché ho passato la notte in bianco su arduino :laughing:
Sto costruendo un impianto d'allarme e di domotica insieme è da poco che mi cimento in arduino e non sono un asso nella programmazione...
Il progetto è quasi finito se non per il fatto che ho qualche problema con l'utilizzo del modulo sim 800l per l'invio del messaggio d'allarme. Penso che il mio sia un modello leggermente difettoso, provvederò a sostituirlo. Il fatto è che quando apro la porta della casetta dove ho montato l'allarme e l'allarme è attivo si avvia la procedura di allarme correttamente ma a volte il modulo sim 800l non invia il messaggio. Il problema è che blocca l'intera esecuzione del programma e quando compongo il codice per disattivare l'allarme arduino non lo legge perchè impegnato interminabilmente nell'invio del messaggio.
Per il progetto ho utilizzato tre schede arduino nano che comunicano via seriale (sono matto lo so :sweat_smile:) , ma in questione ce ne sono solo due... quella del tastierino e quella dell'allarme...
nella mia ignoranza avevo pensato di tirare un ulteriore cavo per dare un segnale alto all'arduino allarme in modo che interrompa ogni azione.
La mia domanda è questa... SI PUO' FARE ?
Esiste una funzione che può attivarsi indipendentemente da quello che sta facendo il programma principale ?
Altrimenti datemi un consiglio.
Vi ringrazio in anticipo... sono sulle vostre mani :pray:

Forse il programma è pensato male, bisogna evitare di creare cicli nel codice, se necessita di ripetere qualcosa, considerare che la funzione loop() è un ciclo, e se studi macchine a stati finiti con arduino, si può fare ripetere qualcosa senza bloccare il programma.

Comunque esistono interrupt arduino, una funzione richiamata al cambiamento di stato di un pin, interrupt interrompe ogni esecuzione e esegue la sua funzione.

ti ringrazio :relaxed: approfondirò questa funzione...
Il problema che ho avuto non è un ciclo che si ripete ma una funzione del modulo che serve alla lettura degli sms ricevuti... devo ancora capire perché ma rimane piantata... magari allego un semplice codice riassuntivo che magari mi potete aiutare...
Io l'ho più o meno copiato e incollato non ho approfondito di molto l'utilizzo del sim 800l.
questo è un breve codice che invia un messaggio ripetitivamente ma che funziona:

//send a message 
#include <SoftwareSerial.h>
SoftwareSerial sim(2, 3);//rx e tx
int _timeout;
String _buffer;
String number = "+393333333333";
void setup() {
  delay(7000); //delay for 7 seconds to make sure the modules get the signal
  Serial.begin(9600);
  _buffer.reserve(50);
  Serial.println("Sistem Started...");
  sim.begin(9600);
  delay(1000);
}
void loop() {
  SendMessage();
  delay(10000);
}
void SendMessage()
{
  Serial.println ("Sending Message");
  sim.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);
  Serial.println ("Set SMS Number");
  sim.println("AT+CMGS=\"" + number + "\"\r"); //Mobile phone number to send message
  delay(1000);
  String SMS = "Allarme sta suonando";
  sim.println(SMS);
  delay(100);
  sim.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  _buffer = _readSerial();
}
String _readSerial() {
  _timeout = 0;
  while  (!sim.available() && _timeout < 12000  )
  {
    delay(13);
    _timeout++;
  }
  if (sim.available()) {
    return sim.readString();
  }
}

Il programma viene eseguito correttamente, il messaggio viene inviato, entra in readSerial() e esce dopo 5 minuti...
Per risolvere ho omesso _buffer = _readSerial(); che mi sembra di capire che serva solamente per leggere i messaggi ricevuti che poi teoricamente in questo codice non è nemmeno utilizzata e cosi funziona... se non per il fatto che il modulo è difettoso e devo cambiarlo: a volte il messaggio lo invia a volte no.
Spero di non aver detto troppe cavolate :laughing:

Per esempio, io farei così:

byte fase=0;
unsigned long t;

void SendMessage() // Per farla iniziare bisogna porre fase=1.
{
switch (fase)
  {
  case 1:
  t=millis();
  Serial.println ("Sending Message");
  sim.println ("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  fase=2;
  break;

  case 2:
  if (millis()-t>999) // 1000ms
    {
    Serial.println ("Set SMS Number");
    sim.println("AT+CMGS=\"" + number + "\"\r"); //Mobile phone number to send message
    fase=3;
    }
  break;

  case 3:
  if (millis()-t>1999) // 1000ms
    {
    String SMS = "Allarme sta suonando";
    sim.println(SMS);
    fase=4;
    }
  break;

  case 4:
  if (millis()-t>2099) // 100ms
    {
    sim.println((char)26);// ASCII code of CTRL+Z
    fase=5;
    }
  break;

  case 5:
  if (millis()-t>3099) // 1000ms
    {
    _buffer = _readSerial();
    fase=0;
    }
  break;
  } // END switch
}