Vyhledávání

GSM Playground Sketches

12.10.2009 23:12

Please look at the initial page - how to start with if you want to get thorough information.

 

There are described few sketches showing basic functions of the GSM Playground - GSM Shield for Arduino. All the sketches are based on the GSM library. 

The last version of GSM library and demo sketches are published at code.google.com - please make sure that all below is clear before going there.

 

GSMModuleOperations.pde

This is a global sketch that was created to show the general possibilities of GSM Playground - GSM Shield for Arduino.

After the module is successfully registered to the GSM network the User LED lights ON. It is possible to make a phone call to the first number stored on the SIM card using the User Button or the phone call can be automatically picked up in case of an incoming call. The incoming caller number is compared with SIM phonebook numbers at the position 1 to 3. It uses a hands free mode in both cases so it requires a loudspeaker connected. There are some functions implemented for controlling using DTMF signal. DTMF signalling is possible to use during active phone call by pressing of target button on your mobile phone keyboard. Using that way it is possible to switch ON or OFF general purpose I/O, switch ON or OFF the speaker, increase or decrease the volume of speaker. This sketch shows the basis features of the GSM Shield and especially the way they should be implemented.

A gsm object is created at the beginning and then there are some variables defined that are used in the sketch.

previous_timer together with the timer100msec are used for the main timing inside the loop()

answer_delay is used to make a delay (5 second) before picking up of an incoming call.

DTMF_value is used for a remembering of the last received DTMF value.

// variables used for timing
unsigned long previous_timer;
byte timer100msec;
byte answer_delay;
// current DTMF
byte DTMF_value;
// array for the phone number string
char phone_number[20];

The serial communication line is initialized with the speed 115200 baud in the setup(). GSM module is turned ON and initialized by some initialization AT commands. After this the DTMF receiver is enabled and general input/output pins 10 and 11 are set up as outputs.

void setup()
{
  // initialization of serial line
  gsm.InitSerLine(115200);

  // turn on GSM module
  gsm.TurnOn();

  // enable DTMF operations
  gsm.EnableDTMF();

  // set direction for GPIO pin
  gsm.SetGPIODir(GPIO10, GPIO_DIR_OUT);
  gsm.SetGPIODir(GPIO11, GPIO_DIR_OUT);
  
  // periodic timer initialization
  timer100msec = 0;
  previous_timer = millis();
}

The basic timing in the loop() is 100 milliseconds, 500miliseconds and 1second.

The program checks every 1 second whether the GSM module is already registered in the GSM network. If yes then call status is checked and in case there is no call User Button is enabled – this is signalized by the activation of User LED. The incoming call is also monitored and in case there is an active incoming call - 5 sec. delay is inserted to give the caller possibility to hear ringing tone. After this delay the call can be picked up by the GSM module. The incoming caller number is compared with SIM phonebook numbers at the position 1 to 3. User button is disabled during the phone call and a DTMF function is used for monitoring of DTMF signals.

    //*******************************
    //****** EVERY 1 sec. ***********
    // %10 means every 1000 msec. = 1sec.
    //*******************************
    if ((timer100msec+3) % 10 == 0) {

      gsm.CheckRegistration();
      if (gsm.IsRegistered()) {
      #ifdef DEBUG_PRINT
        gsm.DebugPrint("DEBUG GSM module is registered", 1);
      #endif
        // GSM modul is still registered:
        // So find out call status with authorization
        // with SIM phonebook at the positions 1..3
        //
        // In case we don't need authorization we can use
        // gsm.CallStatusWithAuth(phone_number, 0, 0) instead
        // and every incoming call will be authorized = picked up
        // ------------------------------------------------------
        switch (gsm.CallStatusWithAuth(phone_number, 1, 3)) {
          case CALL_NONE:
            // there is no call => enable user button
            gsm.EnableUserButton();
            gsm.TurnOnLED();
            answer_delay = 5; // 5 sec. delay before PickUp
            break;
          case CALL_INCOM_VOICE_AUTH:
            // there is incoming call from authorized phone number
            // make some small delay and pick it up
            // and disable user button until call is not finished
            if (--answer_delay == 0) {
              gsm.DisableUserButton();
              gsm.TurnOffLED();
              gsm.PickUp();
            }
            break;
          case CALL_INCOM_VOICE_NOT_AUTH:
            // there is incoming call from not authorized phone number
            // make some small delay and hang it up
            if (--answer_delay == 0) {
              gsm.HangUp();
            }
            break;
          case CALL_ACTIVE_VOICE:
            break;

This solution allows that the User Button is enabled every time the previous active call is finished and the program is ready to receive next call.

There is also a timing loop 500 milliseconds that is prepared for placing of your code.

    //*******************************
    //****** EVERY 500msec. *********
    // %5 means every 500 msec.
    // +2 means - 200msec. "before" a first 100msec. action
    // so the processor power is better spreaded
    //*******************************
    if ((timer100msec+2) % 5 == 0) {
      // here it is possible to place your code which will be executed
      // each 500 msec.
      // ---------------------------------------------------------
    }

Now we check every 100 msec. User Button that was enabled and in case the button is pushed then there is made a phone call to the first number stored on the SIM card, User Button is disabled and User LED is turned off for the time of active call.

    //*******************************
    //****** EVERY 100msec. *********
    //*******************************
    if (gsm.IsUserButtonEnable() && gsm.IsUserButtonPushed()) {
      // operation with the user button is enabled and user button
      // is pushed => make a call
      // and disable user button until call is not finished
      gsm.DisableUserButton();
      gsm.TurnOffLED();
      gsm.Call(1);  // call to the first SIM position
    }

During the active call every 100msec. a DTMF signal is checked and if valid signal is received desired actions are made:

DTMF signalling:

1 – GPIO10 is switched off and acknowledgement is made by sending one DTMF pulse with frequency “5” as a general ack. (this tone is generated automatically inside the function GetDTMFSignal()) and additional one DTMF pulse with frequency “1”(this is what we are hearing in the mobile phone after pushing key 1 on the phone keyboard during call) as confirmation output was turned off

2 – GPIO10 is switched on and again acknowledgement is made by sending one DTMF pulse with frequency “5” as a general ack. (this tone is generated automatically inside the function GetDTMFSignal()) and additional three DTMF pulses with frequency “9” – for better recognition as confirmation output was turned on

3 – GPIO11 is switched off and the same confirmation as for 1)

4 – GPIO11 is switched on and the same confirmation as for 2)

5 – speaker is switched off with general confirmation by sending one DTMF pulse with frequency “5”

6 – speaker is switched on with general confirmation by sending one DTMF pulse with frequency “5”

7 – speaker volume is decreased with general confirmation by sending one DTMF pulse with frequency “5”

8 – speaker volume is increased with general confirmation by sending one DTMF pulse with frequency “5”

    // DTMF output value is checked every 100 msec.
    // and in case there is a required value
    // corresponding action is made
    DTMF_value = gsm.GetDTMFSignal();
    switch (DTMF_value) {
      case 1:
        // GPIO10 off
        gsm.SetGPIOVal(GPIO10, 0);
        gsm.SendDTMFSignal(1);
        break;
      case 2:
        // GPIO10 on
        gsm.SetGPIOVal(GPIO10, 1);
        gsm.SendDTMFSignal(9);
        gsm.SendDTMFSignal(9);
        gsm.SendDTMFSignal(9);
        break;
      case 3:
        // GPIO11 off
        gsm.SetGPIOVal(GPIO11, 0);
        gsm.SendDTMFSignal(1);
        break;
      case 4:
        // GPIO11 on
        gsm.SetGPIOVal(GPIO11, 1);
        gsm.SendDTMFSignal(9);
        gsm.SendDTMFSignal(9);
        gsm.SendDTMFSignal(9);
        break;
      case 5:
        // switch off the speaker
        gsm.SetSpeaker(0);
        break;
      case 6:
        // switch on the speaker
        gsm.SetSpeaker(1);
        break;
      case 7:
        // decrease speaker volume
        gsm.DecSpeakerVolume();
        break;
      case 8:
        // increase speaker volume
        gsm.IncSpeakerVolume();
        break;
    }

 

GSMUserButtonAndLEDTest.pde

This is very easy sketch that demonstrates using of the User Button and User LED on the GSM Playground GSM Shield.

At the beginning the gsm object is created.

The serial communication line is initialized with the speed 115200 baud in the setup(). GSM module is turned ON and initialized by some initialization AT commands.

The User Button is checked in the loop() and in case it is pressed then the User LED is turned ON otherwise the user LED is kept switched OFF.

#include "GSM.h"

// definition of instance of GSM class
GSM gsm;


void setup()
{
  // initialization of serial line
  gsm.InitSerLine(115200);
  // turn on GSM module
  gsm.TurnOn();
  
  #ifdef DEBUG_PRINT
    // print library version
    gsm.DebugPrint("DEBUG Library version: ", 0);
    gsm.DebugPrint(gsm.LibVer(), 1);
  #endif
}

void loop()
{
  // in case user button is pushed turn on the user LED
  // otherwise turn off the user LED
  // --------------------------------------------------
  if (gsm.IsUserButtonPushed()) {
    gsm.TurnOnLED();
  }
  else gsm.TurnOffLED();
}

 

SMS.pde

This is a basic sketch about how to send and receive SMSs. 

Important: This sketch will step by step decode and erases all SMSs on your SIM card so if there are any important SMSs stored on your SIM card please make a backup before inserting of the SIM card.

If the GSM Module is registered to GSM network and the User Button is pressed (checked every 100msec.) then SMS with current temperature (“Temperature: 27 C”) is sent to the specified phone number.

    //*******************************
    //****** EVERY 100msec. *********
    //*******************************
    if (gsm.IsUserButtonEnable() && gsm.IsUserButtonPushed()) {
      // operation with the user button is enabled and user button
      // is pushed => send SMS
      // and disable user button until SMS is not sent
      gsm.DisableUserButton();
      gsm.TurnOffLED();

      // read temperature
      val = gsm.GetTemp();
      if (val > -1000) {
        // temperature is OK -> send SMS to the specified
        // phone number
        // ----------------------------------------------
        
        // prepare a string which will be send by the SMS:
        // "Temperature: 25 C"
        sprintf(string, "Temperature: %i C", val/10);

        // in case you want to send SMS to the specific number
        // change 123456789 to your phone number
        // gsm.SendSMS("123456789", string);

        // in case you want to send SMS to the specific SIM phonebook position
        // here we send to the first SIM phonebook position
        gsm.SendSMS(1, string);
      }
    }

There is checked  an incoming SMS every 3 sec. and in case SMS is received from authorized phone number (compared with SIM phonebook pos. 1, 2, 3) then it is decoded and specific action is made.

1. If SMS “Temp?” is received then SMS with current temperature is sent back

            // 1) e.g. text "Temp?"
            // --------------------
            ch = strstr(sms_text, "Temp?");
            if (ch != NULL) {
              // there is text Temp? => sends SMS with temperature back
              // read temperature
              val = gsm.GetTemp();
              sprintf(string, "Temperature: %i C", val/10);
              gsm.SendSMS(phone_number, string);
            }

2. If SMS “GPIO10 ON” is received then GPIO10 is turned ON and a validating SMS “GPIO10 turned on” is sent back  

            // 2) e.g. text "GPIO10 ON"
            // -------------------------
            ch = strstr(sms_text, "GPIO10 ON");
            if (ch != NULL) {
              // turn on the GPIO10
              gsm.SetGPIOVal(GPIO10, 1);

              // and send confirmation back
              strcpy(string, "GPIO10 turned on");
              gsm.SendSMS(phone_number, string);
            }

3. It is similar for switching OFF...     

            // 3) e.g. text "GPIO10 OFF"
            // -------------------------
            ch = strstr(sms_text, "GPIO10 OFF");
            if (ch != NULL) {
              // turn off the GPIO10
              gsm.SetGPIOVal(GPIO10, 0);


              // and send confirmation back
              strcpy(string, "GPIO10 turned off");
              gsm.SendSMS(phone_number, string);
            }

If SMS “GPIO10 OFF” is received then GPIO10 is turned OFF and a validating SMS “GPIO10 turned off” is sent back. After that the incoming SMS is deleted to free up memory for SMSs in the GSM module.

 

ATcommandsTest.pde

This sketch demonstrates how to send an AT command directly from the sketch and how to receive a response. It is also a good example about how to use advanced debugging possibilities using the serial terminal.

 

#include "GSM.h"

#ifndef DEBUG_PRINT
  #error "!!! It is necessary to enable DEBUG_PRINT macro in the GSM.h !!!"
#endif


// definition of instance of GSM class
GSM gsm;

// return variable
signed char ret_val;


void setup()
{
  // initialization of serial line
  gsm.InitSerLine(115200);
  // turn on GSM module
  gsm.TurnOn();
  
  #ifdef DEBUG_PRINT
    // print library version
    gsm.DebugPrint("DEBUG Library version: ", 0);
    gsm.DebugPrint(gsm.LibVer(), 1);
  #endif
}

void loop()
{
  // now we are sending some AT command
  // and waiting for the response
  //
  // the GSM module must start with sending response in 1000 msec.
  // and the response is taken as finished when there is no other
  // incoming character longer then 100 msec.
  // "" means that we are not expecting certain response string
  // so we will accept any response
  // 1 means that we will send AT command just one time
  // --------------------------------------------------
  ret_val = gsm.SendATCmdWaitResp("AT+CCLK?", 1000, 100, "", 1);

  // now we are waiting for response from the GSM module
  // ---------------------------------------------------
  if (ret_val != AT_RESP_ERR_NO_RESP) {
    // finaly we have received something - print out the internal
    // buffer
    // ----------------------------------------------------------
#ifdef DEBUG_PRINT
    // print out some explaining string
    // -------------------------------
    gsm.DebugPrint("Response on previous AT command is:\r\n", 0);
    gsm.DebugPrint("===================================\r\n", 0);
    // and now finally print out the internal communication buffer content
    // internal communication buffer is automatically finished by the 0x00
    // inside the library function SendATCmdWaitResp() so it is possible
    // to prints it out as the string

    // as the com_buf is defined as byte it is necessary to retype it
    // to (const char*) to be compatible with library function DebugPrint()
    // ------------------------------------------------------------------
    gsm.DebugPrint((const char*)gsm.comm_buf, 1);
#endif
  }
  else {
    // this should not happen - we have received nothing
    // so maybe previous AT command was not recognized
    // becuase we have made some syntax error
    // or GSM module is not working or......
    // ---------------------------------------------------
#ifdef DEBUG_PRINT
    gsm.DebugPrint("We have received nothing, something is wrong...", 1);
#endif
  }

  // now we finished so stay here for ever
  // if you don´t want to stay here following while(1) must not be commented by //
  // ---------------------------------------------------------------------
  //while (1);

  // or we can repeat previous AT command after some delay
  // -----------------------------------------------------
  delay(1000);
}

Zpět

© 2015 Všechna práva vyhrazena.

www.hwkitchen.com