[GSM/GPRS Shield] Librerie GSM.h Funzioni troppo lente

Ciao a tutti.

Vi sottopongo il mio problema. Sto progettando un mini sistema domotico per la mia abitazione. Si tratta principalmente di un Arduino Mega, con una Arduino GSM Shield, vari shift register sia PISO che SIPO, e relè per comandare tutti gli utenti di potenza. La GSM Shield, al momento, è configurata solo per lavorare con gli sms: se ne riceve uno in particolare, setta le uscite così come viene richiesto nel testo del sms. Inoltre, se riceve una chiamata, attacca subito e risponde con un sms contenente lo status del sistema.

Il codice della parte in questione (edulcorato da tutto ciò che non è di interesse) è il seguente:

...
// initialize the library instance
GSM gsmAccess;
GSMVoiceCall vcs;
GSM_SMS sms;
...

void setup()
{
  //Niente di interessante
}

void loop()
{
  //Leggo due SR contemporaneamente (piano terra e primo piano), e metto i risultati dentro gli array opportuni
  shiftIn(PTdataInPin, P1dataInPin, clockInPin, PTswitchState, P1switchState);
  
  //Faccio altra roba

  //Controlla la presenza di chiamate, ed agisce in modo opportuno
  switch (vcs.getvoiceCallStatus()) 
  {
    case IDLE_CALL:
      break;
      
    case RECEIVINGCALL:
      vcs.retrieveCallingNumber(numtel, 20);
      delay(1000);
      vcs.hangCall();
      //La funzione seguente provvede ad inviare un sms di status
      sendStatus();
      break;
            
    case TALKING:
      vcs.hangCall();
      break;
  }
  
  //Adesso controllo la presenza di sms in arrivo, ed agisco in modo opportuno
  if (sms.available())
  {
    char c;
    String msgsms = "";
    
    while(c=sms.read())
      msgsms = msgsms + String(c);
      
      //A seconda del comando, eseguo l'azione
      if (msgsms.indexOf("comando1") != -1)
      {
        //Azione1
        delay(1000);
        //Mando sms di acknowledge
        sendACK();
      }
      else if (msgsms.indexOf("comando2") != -1)
      {
        //Azione2
      }
      else if...

    // A questo punto, cancello l'sms dalla memoria
    sms.flush();
  }
  
  //Ora che ho gli array di uscita aggiornati (o dagli ingressi o dai comandi tramite sms), invio tutto agli SR SIPO
  shiftOut(PTdataOutPin, P1dataOutPin, clockOutPin, PToutputState, P1outputState);  
}

Arriviamo al dunque. Senza la parte dei comandi tramite sms, quindi solo con la sequenza:

  • Leggo SR PISO
  • Modifico array di uscita a seconda dello stato degli ingressi letti
  • Scrivo SR SIPO

dalla pressione di un pulsante per l'accensione delle luci all'accensione della luce passa una frazione di secondo, come ovviamente deve avvenire. Aggiungendo la parte "controlla la chiamata" e "controlla gli sms", il delay tra la pressione del pulsante e l'accensione della luce è di circa 1 secondo. Praticamente, per accendere o spegnere questa benedetta luce, devo rimanere con il pulsante premuto per 1 secondo circa. Mooooolto fastidioso. Dato per scontato che il problema è quello che combinano le funzioni vcs.getvoiceCallStatus() e sms.available() (il delay c'è anche se non ci sono chiamate o sms, quindi anche quando i cicli di quei due if non vengono eseguiti), come posso ovviare al problema?

Ulteriori info: non serve, ma se qualcuno è curioso circa lo "strano" numero di argomenti passati alle funzioni shiftin e shiftout, vi dico che tali funzioni sono state modificate in modo da utilizzare un solo LatchPin ed un solo ClockPin per i vari SR PISO, così come un solo LatchPin ed un solo ClockPin per i vari SR SIPO. I DataPin, ovviamente, rimangono differenti. In questo modo, posso lavorare con x SR-PISO e y SR-SIPO utilizzando solo (2+x+2+y) pin al posto di (3*x+3*y) pin.

E questo è quanto. A disposizione per i chiarimenti del caso, e ringrazio in anticipo chiunque voglia darmi uno spunto per risolvere la questione.

togli quel "delay(1000);" e tutti gli altri delay() e usa la millis() nel modo mostrato in "blinkWhitoutDelay". una revisione della logica potrebbe essere necessaria.

Ciao.

Non risolvo nulla togliendo i "delay"... Il ritardo non voluto c'è anche se siamo nel caso "IDLE_CALL" e nel caso sms.available()=FALSE (e quindi c'è anche quando i cicli con i delay [u]non[/u] vengono eseguiti).

A parte questo, la sostituzione dei delay con la procedura if(currentMillis-previousMillis) mi comporta solo un incasinamento della logica (come tu stesso hai evidenziato), a fronte di un vantaggio nullo (chiamate o messaggi non arrivano così frequentemente, ed il 99% delle volte ciò accade quando non c'è nessuno in casa, quindi un delay di un secondo nell'accensione di una luce o nell'esecuzione di qualche altro comando non reca fastidio).

Grazie comunque di aver dato uno sguardo al mio problema.

Se il problema è anche con l'assenza di chiamate, allora il problema è qui:

switch (vcs.getvoiceCallStatus())

Apri la lib e controlla che dentro non abbia un ciclo di uscita basato su un timeout. Se è così, prova a ridurre quel timeout in modo che esca da quella verifica in anticipo rispetto a quanto fa ora.

Ciao,

grazie innanzitutto dell'interessamento.

Che il problema fosse lì (e nell'altra funzione) mi era chiaro. Volevo sapere se qualcuno, utilizzando queste librerie, aveva trovato una soluzione di comodo senza mettere le mani nella libreria, oppure aveva già pronta la modifica per sistemare le cose. In fondo, utilizzare una scheda come questa implica all'80% la chiamata a quelle funzioni, quindi non dovrei essere l'unico a cui reca fastidio questo ritardo.