Shield GSM, Non accetta SMS di seguito

Salve ragazzi, :slight_smile:
dopo aver fatto diverse figuracce su questo forum ho imparato a maneggiare le librerie in c per la mia shield gsm.
Il mio obiettivo è semplicemente di ricevere un sms, ed in caso quelli successivi, senza perdermene nessuno.

Nota bene: Invio sempre dal mio cellulare e ricevo sempre da arduino, non invio mai da arduino.

Quel che succede è che li ricevo TUTTI se tra il primo e il secondo sms aspetto qualche minuto (circa 3 minuti).

Se invece dopo un sms che ricevo, ne invio un altro poco dopo (tipo 20 secondi) questo sembra non venga ricevuto dalla libreria.

Nonostante il valore atteso di comunicazione è +CMGL continuano ad arrivare solo degli OK e il +CMGL non si vede.

E' come se la shield non processasse gli sms arrivati poco dopo perchè impegnata a fare altro, ma in realtà gli OK li ricevo quindi la comunciazione funziona.

Se invece aspetto (i famosi 3 minuti) e mando un nuovo sms, allora tutto regolare, lo ricevo e lo leggo.

Sto impazzendo. Vi viene in mente qualche suggerimento?

Sketch:

#include "SIM900.h"
#include <SoftwareSerial.h>
//If not used, is better to exclude the HTTP library,
//for RAM saving.
//If your sketch reboots itself proprably you have finished,
//your memory available.
//#include "inetGSM.h"

//If you want to use the Arduino functions to manage SMS, uncomment the lines below.
#include "sms.h"
SMSGSM sms;

//To change pins for Software Serial, use the two lines in GSM.cpp.

//GSM Shield for Arduino
//www.open-electronics.org
//this code is based on the example of Arduino Labs.

//Simple sketch to send and receive SMS.

int numdata;
boolean started=false;
char smsbuffer[160];
char n[20];
char phone_number[20];
char sms_text[100];
int i;

void setup()
{
     //Serial connection.
     Serial.begin(9600);
     Serial.println("GSM Shield testing.");
     //Start configuration of shield with baudrate.
     //For http uses is raccomanded to use 4800 or slower.
     if (gsm.begin(2400)) {
          Serial.println("\nstatus=READY");
          started=true;
     } else Serial.println("\nstatus=IDLE");
    if(started) 
    {
      for (i=1;i<=20;i++)
      {
        sms.DeleteSMS(i);
      }
       
    }
    
};

void loop()
{
     if(started) {
      int position = sms.IsSMSPresent(SMS_UNREAD);
      Serial.print("SMS postion:");
      Serial.println(position);
        
        if (position) 
        {
            Serial.print("LETTURA SMS IN POSIZIONE: ");
            Serial.println(position);
            sms.GetSMS(position, phone_number, 11, sms_text, 100); //Arguments to GET SMS. See SMS.h line12:(byte position, char *phone_number,byte max_phone_len, char *SMS_text, byte max_SMS_len)
            Serial.print("*************NUMERO MITTENTE: ");
            Serial.println(phone_number);
            Serial.print("*************TESTO MESSAGGIO: ");
            
            Serial.println(sms_text);
            sms.DeleteSMS(position);
        }      
        delay(5000);
     }
};

Funzione Libreria in sms.cpp:

char SMSGSM::IsSMSPresent(byte required_status)
{
     char ret_val = -1;
     char *p_char;
     byte status;

     if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val);
     gsm.SetCommLineStatus(CLS_ATCMD);
     ret_val = 0; // still not present

     switch (required_status) {
     case SMS_UNREAD:
     	  Serial.println("##########################################CHIEDO I NON LETTI:");
          gsm.SimpleWriteln(F("AT+CMGL=\"REC UNREAD\""));
          break;
     case SMS_READ:
          gsm.SimpleWriteln(F("AT+CMGL=\"REC READ\""));
          break;
     case SMS_ALL:
          gsm.SimpleWriteln(F("AT+CMGL=\"ALL\""));
          break;
     }

     // 5 sec. for initial comm tmout
     // and max. 1500 msec. for inter character timeout
     gsm.RxInit(5000, 1500);
     // wait response is finished
     do {
          if (gsm.IsStringReceived("OK")) {
               Serial.println("gsm.IsStringReceived()= OK");
               // perfect - we have some response, but what:

               // there is either NO SMS:
               // <CR><LF>OK<CR><LF>

               // or there is at least 1 SMS
               // +CMGL: <index>,<stat>,<oa/da>,,[,<tooa/toda>,<length>]
               // <CR><LF> <data> <CR><LF>OK<CR><LF>
               status = RX_FINISHED;
               break; // so finish receiving immediately and let's go to
               // to check response
          }
          status = gsm.IsRxFinished();
     } while (status == RX_NOT_FINISHED);

     Serial.println("*************************Status:");
     Serial.println(status);
      Serial.println("*************************FINE Status:");
    



     switch (status) {
     case RX_TMOUT_ERR:
     	   Serial.println("Status Timeout Error");
          // response was not received in specific time
          ret_val = -2;
          break;

     case RX_FINISHED:
      	  Serial.println("Status RX Finished");
          // something was received but what was received?
          // ---------------------------------------------
          if(gsm.IsStringReceived("+CMGL:")) {
          		Serial.println("Ho ricevuto +CMGL Chiedo posizione");
               // there is some SMS with status => get its position
               // response is:
               // +CMGL: <index>,<stat>,<oa/da>,,[,<tooa/toda>,<length>]
               // <CR><LF> <data> <CR><LF>OK<CR><LF>
               //JET
	            int pos;

	            char *str;
	            str = (char *)gsm.comm_buf;

	            p_char=strchr(str,':');
	            while (p_char != NULL) {
	                            ret_val = atoi(p_char+1);                                 
	                            pos = p_char-str+1;
	                            if(ret_val!=0 && str[pos+2]==',') break;
	                            p_char=strchr(p_char+1,':');
	            }
                    //END JET
          	   ///// START COMMENT CDP 	
               //p_char = strchr((char *)gsm.comm_buf,':');
               //if (p_char != NULL) {
               //		Serial.println("Pchar è diverso da null");
                //    ret_val = atoi(p_char+1);
                 //   Serial.println("RETVAL");
                  //  Serial.println(atoi(p_char+1));
                //}
         		///// END COMMENT CDP

          } else {
          	   Serial.println("Ho ricevuto o OK o ERRORE e non +");
               // other response like OK or ERROR
               ret_val = 0;
          }

          // here we have gsm.WaitResp() just for generation tmout 20msec. in case OK was detected
          // not due to receiving
          gsm.WaitResp(20, 20);
          break;
     }

     gsm.SetCommLineStatus(CLS_FREE);
     return (ret_val);
}

Funzione Libreria in gsm.cpp che guarda nel buffer di comunicazione:

byte GSM::IsStringReceived(char const *compare_string)
{
     char *ch;
     byte ret_val = 0;

     if(comm_buf_len) {
          /*
          	#ifdef DEBUG_GSMRX
          		DebugPrint("DEBUG: Compare the string: \r\n", 0);
          		for (int i=0; i<comm_buf_len; i++){
          			Serial.print(byte(comm_buf[i]));
          		}

          		DebugPrint("\r\nDEBUG: with the string: \r\n", 0);
          		Serial.print(compare_string);
          		DebugPrint("\r\n", 0);
          	#endif
          */
#ifdef DEBUG_ON
          Serial.print("ATTESO: ");
          Serial.println(compare_string);
          Serial.print("RICEVUTO: ");
          Serial.println((char *)comm_buf);
#endif
          ch = strstr((char *)comm_buf, compare_string);
          if (ch != NULL) {
               ret_val = 1;
               
                Serial.println("nDEBUG: expected string was received");
               
            
          } else {

                Serial.println("nDEBUG: expected string was NOT received");
           
          }
     } else {
#ifdef DEBUG_ON
          Serial.print(F("ATTESO: "));
          Serial.println(compare_string);
          Serial.print(F("RICEVUTO: NO STRINGA RICEVUTA COMM_BUF_LEN A ZERO"));
#endif
     }

     return (ret_val);
}

prova a leggere questo

in particolare:

You could also change your CNMI settings to (2,2,0,0,0) i think, if you want the content of the messages to be sent by the modem, and not the notifications alone.

Ciao, e grazie per la risposta ma il codice della libreria già si comportava in questo modo attraverso la funzione seguente:

char GSM::InitSMSMemory(void)
{
     Serial.println("STO INIZIALIZZANDO SMS");
     char ret_val = -1;

     if (CLS_FREE != GetCommLineStatus()) return (ret_val);
     SetCommLineStatus(CLS_ATCMD);
     ret_val = 0; // not initialized yet

     // Disable messages about new SMS from the GSM module
     SendATCmdWaitResp(F("AT+CNMI=2,0"), 1000, 50, str_ok, 2);

     // send AT command to init memory for SMS in the SIM card
     // response:
     // +CPMS: <usedr>,<totalr>,<usedw>,<totalw>,<useds>,<totals>
     if (AT_RESP_OK == SendATCmdWaitResp(F("AT+CPMS=\"SM\",\"SM\",\"SM\""), 1000, 1000, "+CPMS:", 10)) {
          ret_val = 1;
     } else ret_val = 0;

     SetCommLineStatus(CLS_FREE);
     return (ret_val);
}

non so che altro dirti però...

SendATCmdWaitResp(F("AT+CNMI=2,0"), 1000, 50, str_ok, 2);

e questo (2,2,0,0,0) sono diversi, non so cosa significhi il secondo 2.... prova a verificare

Giusto, non mi ero accorto della differenza.
Comunque ho fatto la prova ma c'è lo stesso problema.
Quel che cambia è che anzichè arrivare +CMGL arriva con +CMT, ma al solito, se ne mandi uno e dopo 20 secondi un altro, il secondo non appare proprio.

+CMT: "+393342231238","","18/06/06,17:17:39+08"
Ssu

queste sono di una libreria sms che ho trovato

sms.cpp
char SMSGSM::GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len)
sms.h
char GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len);

questa è la tua richiesta, c'è quell'11 di troppo con la lib qui sopra

sms.GetSMS(position, phone_number, 11, sms_text, 100); // Arguments to GET SMS. See SMS.h line12:
                                                                                           // (byte position, char *phone_number,
                                                                                           // byte max_phone_len, char *SMS_text, 
                                                                                           // byte max_SMS_len)

prova a controllare che libreria stai usando e la funzione getsms nel sms.cpp, casomai prova a cambiarla...

Grazie Patrick,
ho provato, ma anche cambiando completamente la libreria con un ultimissima versione trovata in rete che ha le funzioni esattamente come da te suggerito si manifesta lo stesso problema.
il primo sms arriva, quello dopo 20 secondi no. Se faccio passare un paio di minuti torna a riceverli.

Hai qualche sketch funzionante a riguardo dove posso mettere mano?

no, mi dispiace non ho mai avuto occasione di provare i moduli gsm

Ciao, al tuo post #1 il codice da te postato sembra apparentemente ben scritto a parte il fatto che dopo il
void setup() {} e il void loop() {} non ci va il ;

#include "SIM900.h"
#include <SoftwareSerial.h>
//If not used, is better to exclude the HTTP library,
//for RAM saving.
//If your sketch reboots itself proprably you have finished,
//your memory available.
//#include "inetGSM.h"

//If you want to use the Arduino functions to manage SMS, uncomment the lines below.
#include "sms.h"
SMSGSM sms;

//To change pins for Software Serial, use the two lines in GSM.cpp.

//GSM Shield for Arduino
//www.open-electronics.org
//this code is based on the example of Arduino Labs.

//Simple sketch to send and receive SMS.

int numdata;
boolean started=false;
char smsbuffer[160];
char n[20];
char phone_number[20];
char sms_text[100];
int i;

void setup()
{
     //Serial connection.
     Serial.begin(9600);
     Serial.println("GSM Shield testing.");
     //Start configuration of shield with baudrate.
     //For http uses is raccomanded to use 4800 or slower.
     if (gsm.begin(2400)) {
          Serial.println("\nstatus=READY");
          started=true;
     } else Serial.println("\nstatus=IDLE");
    if(started) 
    {
      for (i=1;i<=20;i++)
      {
        sms.DeleteSMS(i);
      }
       
    }
    
}; //VA TOLTO QUESTO

void loop()
{
     if(started) {
      int position = sms.IsSMSPresent(SMS_UNREAD);
      Serial.print("SMS postion:");
      Serial.println(position);
        
        if (position) 
        {
            Serial.print("LETTURA SMS IN POSIZIONE: ");
            Serial.println(position);
            sms.GetSMS(position, phone_number, 11, sms_text, 100); //Arguments to GET SMS. See SMS.h line12:(byte position, char *phone_number,byte max_phone_len, char *SMS_text, byte max_SMS_len)
            Serial.print("*************NUMERO MITTENTE: ");
            Serial.println(phone_number);
            Serial.print("*************TESTO MESSAGGIO: ");
            
            Serial.println(sms_text);
            sms.DeleteSMS(position);
        }      
        delay(5000);
     }
}; // VA TOLTO QUESTO

Trova i commenti VA TOLTO QUESTO ed elimina i punti e virgola in corrispondenza.
Fammi sapere.