Search code examples
smsembeddedarduinogsmgprs

Sending/Receiving SMS via Arduino


I have a GBoard which contains a SIM900 GSM/GPRS module, a XBEE Shield and an SD Card Slot.

This is the link of the GBoard product.

I want the Arduino to send and receive SMS on the SIM900 module. To be specific, I want to read SMS mostly, and take some action based on the content of the SMS and then delete it from the SIM card.

How do I accomplish that?


Solution

  • Here's what I have working to turn an LED on/off via SMS. You might need to adjust the code for you setup.

    #include <SoftwareSerial.h>
    
    SoftwareSerial mySerial(7, 8);
    
    // EN: String buffer for the GPRS shield message
    // FR: Mémoire tampon de type string pour les messages du shield GPRS 
    String SmsStorePos = String("");
    String msg = String("");
    String snTmp = String("");
    String snFull = String("");
    
    // EN: Set to 1 when the next GPRS shield message will contains the SMS message
    // FR: Est mis à 1 quand le prochain message du shield GPRS contiendra le contenu du SMS
    int SmsContentFlag = 0;
    
    // EN: Pin of the LED to turn ON and OFF depending on the received message
    // FR: Pin de la LED a allumer/éteindre en fonction du message reçu
    int ledPin = 5;
    
    void setup()
    {
      mySerial.begin(19200);               // the GPRS baud rate   
      mySerial.print("\r");
      delay(1000);
      Serial.begin(19200);                 // the GPRS baud rate
      Serial.println("Started!");
    
      pinMode( ledPin, OUTPUT ); 
      digitalWrite( ledPin, LOW ); 
    }
    
    void loop()
    {
        char SerialInByte;
    
        if(Serial.available())
        {
           mySerial.print((unsigned char)Serial.read());
         }  
        else  if(mySerial.available())
        {
            char SerialInByte;
            SerialInByte = (unsigned char)mySerial.read();
    
            // EN: Relay to Arduino IDE Monitor
            // FR: Relayer l'information vers le moniteur Serie Arduino
            Serial.print( SerialInByte );
    
            // -------------------------------------------------------------------
            // EN: Program also listen to the GPRS shield message.
            // FR: Le programme écoute également les messages issus du GPRS Shield.
            // -------------------------------------------------------------------
    
            // EN: If the message ends with <CR> then process the message
            // FR: Si le message se termine par un <CR> alors traiter le message 
            if( SerialInByte == 13 ){
              // EN: Store the char into the message buffer
              // FR: Stocké le caractère dans le buffer de message
              ProcessGprsMsg();
             }
             if( SerialInByte == 10 ){
                // EN: Skip Line feed
                // FR: Ignorer les Line Feed 
             }
             else {
               // EN: store the current character in the message string buffer
               // FR: stocker le caractère dans la mémoire tampon réservé au message
               msg += String(SerialInByte);
             }
         }   
    }
    
    // EN: Make action based on the content of the SMS. 
    //     Notice than SMS content is the result of the processing of several GPRS shield messages.
    // FR: Execute une action sur base du contenu d'un SMS.
    //     Notez que le contenu du SMS est le résultat du traitement de plusieurs messages du shield GPRS.
    void ProcessSms( String sms ){
      sms.toLowerCase();
      Serial.print( "ProcessSms for [" );
      Serial.print( sms );
      Serial.println( "]" );
    
      if( sms.indexOf("on") >= 0 ){
        digitalWrite( ledPin, HIGH );
        Serial.println( "LED IS ON" );
        return;
      }
      if( sms.indexOf("off") >= 0 ){
        digitalWrite( ledPin, LOW );
        Serial.println( "LED IS OFF" );
        return;
      } else {
        mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
        delay(1000);
        mySerial.print("AT+CMGS=\"");
        mySerial.print(snFull);
        mySerial.print("\"\r");
        delay(1000);
        mySerial.print("Unknown Command: ");
        mySerial.print(sms);
        mySerial.print("\r");
        delay(1000);
        mySerial.write(0x1A);  //Equivalent to sending Ctrl+Z     
        return;
      }
    }
    // EN: Request Text Mode for SMS messaging
    // FR: Demande d'utiliser le mode Text pour la gestion des messages
    void GprsTextModeSMS(){
      mySerial.println( "AT+CMGF=1" );
    }
    
    void GprsReadSmsStore( String SmsStorePos ){
      // Serial.print( "GprsReadSmsStore for storePos " );
      // Serial.println( SmsStorePos ); 
      mySerial.print( "AT+CMGR=" );
      mySerial.println( SmsStorePos );
    }
    
    // EN: Clear the GPRS shield message buffer
    // FR: efface le contenu de la mémoire tampon des messages du GPRS shield.
    void ClearGprsMsg(){
      msg = "";
    }
    
    // EN: interpret the GPRS shield message and act appropiately
    // FR: interprete le message du GPRS shield et agit en conséquence
    void ProcessGprsMsg() {
      Serial.println("");
      Serial.print( "GPRS Message: [" );
      Serial.print( msg );
      Serial.println( "]" );
    
      if( msg.indexOf( "Call Ready" ) >= 0 ){
         Serial.println( "*** GPRS Shield registered on Mobile Network ***" );
         GprsTextModeSMS();
      }
    
      // EN: unsolicited message received when getting a SMS message
      // FR: Message non sollicité quand un SMS arrive
      if( msg.indexOf( "+CMTI" ) >= 0 ){
         Serial.println( "*** SMS Received ***" );
         // EN: Look for the coma in the full message (+CMTI: "SM",6)
         //     In the sample, the SMS is stored at position 6
         // FR: Rechercher la position de la virgule dans le message complet (+CMTI: "SM",6) 
         //     Dans l'exemple, le SMS est stocké à la position 6
         int iPos = msg.indexOf( "," );
         SmsStorePos = msg.substring( iPos+1 );
         Serial.print( "SMS stored at " );
         Serial.println( SmsStorePos );
    
         // EN: Ask to read the SMS store
         // FR: Demande de lecture du stockage SMS
         GprsReadSmsStore( SmsStorePos );
      }
    
      // EN: SMS store readed through UART (result of GprsReadSmsStore request)  
      // FR: Lecture du stockage SMS via l'UART (résultat de la requete GprsReadSmsStore)
      if( msg.indexOf( "+CMGR:" ) >= 0 ){
        // get number of sender
        int snPos = msg.indexOf("+1");
        Serial.print("SMS From: ");
        snTmp = msg.substring(snPos+1);
        snFull = "";
        for (int i = 0; i < 11; i++){
          snFull += snTmp[i];    
        }
        Serial.println(snFull);
    
        // EN: Next message will contains the BODY of SMS
        // FR: Le prochain message contiendra le contenu du SMS
        SmsContentFlag = 1;
        // EN: Following lines are essentiel to not clear the flag!
        // FR: Les ligne suivantes sont essentielle pour ne pas effacer le flag!
        ClearGprsMsg();
        return;
      }
    
      // EN: +CMGR message just before indicate that the following GRPS Shield message 
      //     (this message) will contains the SMS body
      // FR: le message +CMGR précédent indiquait que le message suivant du Shield GPRS 
      //     (ce message) contient le corps du SMS 
      if( SmsContentFlag == 1 ){
        Serial.println( "*** SMS MESSAGE CONTENT ***" );
        Serial.println( msg );
        Serial.println( "*** END OF SMS MESSAGE ***" );
        ProcessSms( msg );
        delSMS();
      }
    
      ClearGprsMsg();
      // EN: Always clear the flag
      // FR: Toujours mettre le flag à 0
      SmsContentFlag = 0; 
    }
    void delSMS() {
      mySerial.print("AT+CMGD=");
      mySerial.println(SmsStorePos);
    }