SMS empfangen mit ITEAD GSM/GPRS Shield

Hi zusammen

Ich versuche gerade das GSM Board von itead http://imall.iteadstudio.com/im140318007.html mit einem Arduino MEGA 2560 zum laufen zu bekommen. Grundsätzlich funktioniert es auch, d.h. ich kann SMS senden, Anrufe tätigen, Anrufe empfangen inkl. Nummer abgleichen.... 2 Dinge wollen aber noch nicht so ganz. Zum einen kann ich den Inhalt einer empfangenen SMS nicht lesen. Da kommt irgendwie keine Anzeige im Serial Monitor, was denn im SMS steht. Er schreibt zwar, dass ein SMS empfangen wurde und auch, an welcher Stelle im Speicher der SIM-Karte es sich befindet, aber es wird kein Text angezeigt. Das andere was auch nicht funktioniert, ist auf DTMF Töne zu reagieren. Da bin ich aus der Library nicht so wirklich schlau geworden, wie das gehen soll....

Hat da jemand von euch Erfahrung mit dem Teil und kann mir etwas weiter helfen?

PS: Ich verwende den Beispielsketch...

Grüsee Peter

PS: Ich verwende den Beispielsketch...

Welchen? Auf der von Dir verlinkten Seite sind zwei Bibliotheken aufgeführt und beide enthalten mehrere Beispiele. Poste den Code, mit welchem Du testest!

Ist mir gar nicht aufgefallen, dass dort 2 Bibliotheken verlinkt sind, war da wohl etwas schnell…

Hier noch mein verwendeter Code

/* GSM Shield example
 
 created 2011
 by Boris Landoni
 
 This example code is in the public domain.

 
 http://www.open-electronics.org
 http://www.futurashop.it
 */

#include <SoftwareSerial.h> 
#include <GSM_Shield.h>

const byte PowerPin = 9;

//**************************************************************************
char number[]="+41796797104";  //Destination number 
char text[]="hello world";  //SMS to send
byte type_sms=SMS_UNREAD;      //Type of SMS
byte del_sms=0;                //0: No deleting sms - 1: Deleting SMS
//**************************************************************************

GSM gsm;
char sms_rx[122]; //Received text SMS
//int inByte=0;    //Number of byte received on serial port
char number_incoming[20];
int call;
int error;


void setup() 
{
  Serial.begin(9600);
  Serial.println("system startup"); 
  gsm.TurnOn(9600);          //module power on
  gsm.InitParam(PARAM_SET_1);//configure the module  
  gsm.Echo(0);               //enable AT echo 

}


void loop()
{ 
  char inSerial[5];   
  int i=0;
  delay(2000);
  
    Check_Call(); //Check if there is an incoming call
    Check_SMS();  //Check if there is SMS 
    //Check data serial com 
    
    if (Serial.available() > 0) 
    {             
       while (Serial.available() > 0) {
         inSerial[i]=(Serial.read()); //read data  
         i++;      
       }
       inSerial[i]='\0';
      Check_Protocol(inSerial);
    }
       
}  

void Check_Protocol(String inStr)
{   
       Serial.print("Command: ");
       Serial.println(inStr);
       
  Serial.println("Check_Protocol");
  
    switch (inStr[0])
      {
       case 'a' :  //Answer        
           if (gsm.CallStatus()==CALL_INCOM_VOICE){
             gsm.PickUp();
             Serial.println("Answer");
           }
           else
           {
             Serial.println("No incoming call");
           }
         break;
       
    
       case 'c': // C  //Call
         if (inStr.length()<2)  //To call variable 'number'    comand   c
         {
           Serial.print("Calling ");
           Serial.println(number);         
           gsm.Call(number);
         }
         if (inStr.length()==2)  //To call number in phone book position   comand   cx where x is the SIM position
         {
             error=gsm.GetPhoneNumber(inStr[1],number);
             if (error!=0)
             {
               Serial.print("Calling ");
               Serial.println(number);
               gsm.Call(number);
             }
             else 
             {
               Serial.print("No number in pos ");
               Serial.println(inStr[1]);
             }
         }
         break;
          
       case 'h': //H //HangUp if there is an incoming call
         if (gsm.CallStatus()!=CALL_NONE)         
         {
           Serial.println("Hang");
           gsm.HangUp();              
         }
         else
         {
           Serial.println("No incoming call");
         }    
         break;
         
         
       case 's': //S //Send SMS
         Serial.print("Send SMS to ");
         Serial.println(number);
         error=gsm.SendSMS(number,text);  
         if (error==0)  //Check status
         {
             Serial.println("SMS ERROR \n");
         }
         else
         {
             Serial.println("SMS OK \n");             
         }
         break;
              
       case 'p':  //Read-Write Phone Book
         if (inStr.length()==3)
         {
           
           switch (inStr[1])
           {
             case 'd':  //Delete number in specified position  pd2
               error=gsm.DelPhoneNumber(inStr[2]);
               if (error!=0)
               {
                 Serial.print("Phone number position ");
                 Serial.print(inStr[2]);
                 Serial.println(" deleted");
               }
               break;
               
               
               
             case 'g':  //Read from Phone Book position      pg2
               error=gsm.GetPhoneNumber(inStr[2],number);
               if (error!=0)  //Find number in specified position
               {
                 Serial.print("Phone Book position ");
                 Serial.print(inStr[2]);
                 Serial.print(": ");
                 Serial.println(number);
               }
               else  //Not find number in specified position
               {
                 Serial.print("No Phone number in position ");
                 Serial.println(inStr[2]);
               }
               break;
             case 'w':  //Write from Phone Book Position    pw2
               error=gsm.WritePhoneNumber(inStr[2],number);
               if (error!=0)
               {
                 Serial.print("Number ");
                 Serial.print(number);
                 Serial.print(" writed in Phone Book position ");
                 Serial.println(inStr[2]);
               }
               else Serial.println("Writing error");
               break;
               
               
               
           }
           
         }
         break;
         
       }
   
    delay(1500);
    
    return;
 }
 
 
 void Check_Call()  //Check status call if this is available
 {     
     call=gsm.CallStatus();
     switch (call)
     {    
       case CALL_NONE:
         Serial.println("no call");
         break;
       case CALL_INCOM_VOICE:
         gsm.CallStatusWithAuth(number_incoming,0,0);        
         Serial.print("incoming voice call from ");     
         Serial.println(number_incoming);
         break;
       case CALL_ACTIVE_VOICE:
         Serial.println("active voice call");    
         break;
       case CALL_NO_RESPONSE:
         Serial.println("no response");
         digitalWrite(PowerPin, HIGH);
         delay(1000);
         digitalWrite(PowerPin, LOW);
         break;
     }
     return;
 }
 
 
 void Check_SMS()  //Check if there is an sms 'type_sms'
 {
     char pos_sms_rx;  //Received SMS position     
     pos_sms_rx=gsm.IsSMSPresent(type_sms);
     if (pos_sms_rx!=0)
     {
       //Read text/number/position of sms
       gsm.GetSMS(pos_sms_rx,number_incoming,sms_rx,120);
       Serial.print("Received SMS from ");
       Serial.print(number_incoming);
       Serial.print("(sim position: ");
       Serial.print(word(pos_sms_rx));
       Serial.println(")");
       Serial.println(sms_rx);
       if (del_sms==1)  //If 'del_sms' is 1, i delete sms 
       {
         error=gsm.DeleteSMS(pos_sms_rx);
         if (error==1)Serial.println("SMS deleted");      
         else Serial.println("SMS not deleted");
       }
     }
     return;
 }

Grüsse
Peter

Es passiert hier gsm.GetSMS(pos_sms_rx,number_incoming,sms_rx,120);

In dem char array sms_rx sollte der Text drinstehen der mit Serial.println(sms_rx); angezeigt werde sollte.

Da pos_sms_rx ungleich null sein muss und sms_rx offensichtlich nur ein '\0' enthält klemmt es wohl in der Lib.

Welche Lib verwendest du genau ? - Link bitte

Ich verwende diese Library https://github.com/jgarland79/GSM_Shield

Auf dem Serial Monitor habe ich auch schon versucht den Inhalt von sms_rx auszugeben. Aber wenn ich das ganze Array ausgeben lasse kommt nur eine leere Zeile und wenn ich versuchshalber

Serial.println(sms_rx[0]);
Serial.println(sms_rx[1]);
Serial.println(sms_rx[2]);
.....

ausgeben lasse habe ich im Serial Monitor nur

NULL
NULL
NULL

Grüsse Peter

Dann steht in deinem Array nichts drin.

Ja, das ist mir klar.

Ich habe schon etliche SMS gesendet. Es wird dann angezeigt, dass ein SMS empfangen wurde und auch an welcher Stelle auf der SIM Karte es sich befindet, aber ich kann den Inhalt nie lesen...

Wenn ich den Code richtig interpretiere und nichts übersehen habe, müsste ein Aufruf von "CheckRegistration()" stattfinden, damit das GSM-Modul im richtigen Modus ist, die SMS überhaupt zu übertragen. Kriegst Du die sendende Telefonnummer angezeigt? Falls nicht, dürfte der fehlende Aufruf von "AT+CMGF=1" zum Problem führen.

Danke erstmal für deine Hilfe!

Die Nummer wird mir nicht angezeigt. Hier mal die Ausgabe vom Serial Monitor

system startup
no call
no call
no call
no call
Received SMS from (sim position: 29)

no call
no call

Versuchshalber habe ich mal in der Funktion void Check_SMS() die Zeile byte test = CheckRegistration(); hinzugefügt und mir im Seriellen Monitor die Variable test ausgeben lassen. Diese wird als 1 ausgegeben. Die Anzeige im Monitor betreffend SMS bleibt aber gleich.

Dann habe ich den Aufruf AT+CMGF=1 in der GSM_Shield.cpp bei der Funktion CheckRegistration hinzugefügt, das ändert aber auch nichts an der Ausgabe im Monitor...

Grüsse Peter

Meiner Meinung nach kommen vom Modul nicht die Daten rüber, die die Bibliothek erwartet. Ich würde also die Bibliothek testhalber so abändern, dass der Antwortstring auf das Kommando "AT+CMGR" auf die serielle Schnittstelle ausgegeben wird. Poste bitte das Ergebnis.

Irgendwie blicke ich da nicht ganz durch, wo ich das in der Library ändern muss...

Kannst du mir da evtl. etwas auf die Sprünge helfen?

Grüsse Peter

z.B. in Zeile 1733

Serial.println(comm_buf);

einfügen.

Ok, hab es mal so eingefügt. Die Ausgabe ist immer 84, unabhängig von der Länge der Nachricht...

Grüsse Peter

Habe jetzt mal schnell die Ausgabe von comm_buffer abgeändert in

for(int i = 0; i < 100; i++)
      {
        Serial.print(comm_buf[i]);
        Serial.print(":");
      }
      Serial.println("Habe fertig");

Dabei erhalte ich

no call
65:84:43:67:77:71:82:61:44:13:13:10:69:82:82:79:82:13:10:0:13:13:10:43:67:77:71:76:58:32:52:52:44:34:82:69:67:32:85:78:82:69:65:68:34:44:34:43:52:49:55:57:54:55:57:55:49:48:52:34:44:34:34:44:34:49:52:47:48:57:47:49:50:44:49:55:58:53:49:58:51:49:43:48:56:34:13:10:81:85:73:84:13:10:13:10:79:75:13:0:Habe fertig
Received SMS from (sim position: 44)

no call

Als SMS habe ich “QUIT” gesendet

Wenn ich “Test” sende erhalte ich

65:84:43:67:77:71:82:61:45:13:13:10:69:82:82:79:82:13:10:0:13:13:10:43:67:77:71:76:58:32:52:53:44:34:82:69:67:32:85:78:82:69:65:68:34:44:34:43:52:49:55:57:54:55:57:55:49:48:52:34:44:34:34:44:34:49:52:47:48:57:47:49:50:44:49:55:58:53:52:58:48:48:43:48:56:34:13:10:84:101:115:116:13:10:13:10:79:75:13:10:Habe fertig

Grüsse
Peter

Hi wenn du das in Ascii anschaust, steht da was von ERROR drin.

Die Ausgabe ist etwas umständlich, versuch es mal so:

 Serial.print( char(comm_buf[i]) );

Ja, wird wirklich etwas übersichtlicher damit :)

Hier die Ausgabe wenn ich "Test SMS" schicke.

no call
no call
AT+CMGR=[b]SOH[/b]
ERROR
[b]NUL[/b]
+CMGL: 1,"REC UNREAD","+41796797104","","14/09/12,21:55:28+08"
Test SMS

OK
Received SMS from (sim position: 1)

SMS not deleted
no call

Ich brauche das Modul eigentlich um per SMS einige Relais ein oder aus zu schalten. Den Text des SMS kann ich ja jetzt erkennen und auch mit if oder switch abfragen, aber wie übergebe ich jetzt bei positiver Überprüfung einen Befehl an mein Hauptprogramm?

Grüsse Peter

Hi,
Da funktioniert was im parser der Lib nicht so wie gewollt.
Du hast zwar einen “ERROR” im String was aber IHMO nur Auswirkung auf den return wert der Funktion hat.

SMS_text sollte trotzdem ermittelt werden.
Wie weit funkioniert es ? bekommst du die phone_number von der funktion zurück ?

Mit deinem Ausgabe Beispiel und dem Code, denke ich schon den vermeintlichen Fehler im parser zu finden.

  // extract phone number string
      // ---------------------------
      p_char = strchr((char *)(comm_buf),',');
      p_char1 = p_char+2; // we are on the first phone number character
      p_char = strchr((char *)(p_char1),'"');
      if (p_char != NULL) {
        *p_char = 0; // end of string
        strcpy(phone_number, (char *)(p_char1));
      }
        //Stimmt die phone number ?, dann arbeitet der Code bis hier richtig

      // get SMS text and copy this text to the SMS_text buffer
      // ------------------------------------------------------
      p_char = strchr(p_char+1, 0x0a);  // find <LF>
      if (p_char != NULL) {
        // next character after <LF> is the first SMS character
        p_char++; // now we are on the first SMS character 

        // find <CR> as the end of SMS string
        p_char1 = strchr((char *)(p_char), 0x0d);  
        if (p_char1 != NULL) {
          // finish the SMS text string 
          // because string must be finished for right behaviour 
          // of next strcpy() function
          *p_char1 = 0; 
        }
        // in case there is not finish sequence <CR><LF> because the SMS is
        // too long (more then 130 characters) sms text is finished by the 0x00
        // directly in the WaitResp() routine

        // find out length of the SMS (excluding 0x00 termination character)
        len = strlen(p_char);

        if (len < max_SMS_len) {
          // buffer SMS_text has enough place for copying all SMS text
          // so copy whole SMS text
          // from the beginning of the text(=p_char position) 
          // to the end of the string(= p_char1 position)
          strcpy(SMS_text, (char *)(p_char));
        }
        else {
          // buffer SMS_text doesn't have enough place for copying all SMS text
          // so cut SMS text to the (max_SMS_len-1)
          // (max_SMS_len-1) because we need 1 position for the 0x00 as finish 
          // string character
          memcpy(SMS_text, (char *)(p_char), (max_SMS_len-1));
          SMS_text[max_SMS_len] = 0; // finish string
        }
      }

Die Nummer wird mir auch nicht angezeigt.

Ich musste leider unverhofft ins Ausland und kann leider erst ab ca. Mitte nächster Woche wieder testen, werde dann aber berichten, wie es mit deinem angepassten Code läuft.

Danke und Grüsse Peter

Ich musste leider unverhofft ins Ausland und kann leider erst ab ca. Mitte nächster Woche wieder testen, werde dann aber berichten, wie es mit deinem angepassten Code läuft.

Hallo Peter, den Code habe ich nicht geändert ! Ich wollte nur wissen wie weit der Parser richtig arbeitet. Der Algo fängt quasi am Anfang an in dem String nach bestimmten Zeichen zu suchen. Und schiebt dann den Zeiger weiter.

Da es bei dir schon am Anfang phone_number schief geht ist der Fehler erstmal dort zu suchen.

Hallo,

habt Ihr eine Lösung für das Problem?

Ich habe auch das gleiche Board und auch das gleiche Problem.

Grüsse

Stefan