bclose

SEND AND RECEIVE CALLS AND SMS

Objectives

 

 

    • Optimize GPRS programming.
    • Provide it with greater autonomy.
    • Create a function to send AT commands.
    • Group the sending and receiving of calls and SMS in a single program.
 

Material requerido.

OPTIMIZE THE PROGRAM

 

In the previous sessions dedicated to the GRPS we have seen how to connect it correctly and the AT commands necessary to send and receive calls and SMS in a very simple way. However, for the one that has been fixed, although the AT commands are sent correctly and the module fulfills the function we are looking for, there are some things that can be improved.

And it seems that the SoftwareSerial library does not get along quite well with the GPRS module and the AT commands; and by simply sending these commands with SIM900.println () function; some answers remain in limbo.

To this we could add that, being the GPRS a module oriented towards autonomous projects and without supervision, we will not have access to the serial monitor (until now we have supervised it from there), we will not be sure that things are going well and we are really connected to the mobile network.

And finally, it could be that during the period that we have running our project lost the power of the Arduino or the GPRS, or disconnected from the mobile network for some reason. So we are also going to implement a series of functions so that it is able to restart and configure itself autonomously, and to ensure that we are connected to the network before sending calls or SMS.

To restart it in this way and provide it with autonomy, it is essential to have made the welding that enables the software power-up of the GPRS module by means of a pulse on pin 9, and connect it to pin 9 of Arduino that we will use for it (we already talked about this in the previous sessions).

gprs

FUNCTION TO SEND COMMANDS AT

 

Apparently the error in receiving some responses from the AT commands by the serial monitor is because we send the following command before receiving the response, and the “delays” do not seem to solve it, but quite the opposite (as almost always).

Therefore we will create a sendAT function with the following objectives:

  • Send the AT command.
  • Wait for a response from the SIM900.
  • Check that the answer is correct.
  • Show the received response by the serial monitor.

The programming of the function is as follows:

int sendAT(String ATcommand, char* correct_answer, unsigned int time)
{

  int x = 0;
  bool correct = 0;
  char answer[100];
  unsigned long previous;

  memset(answer, '\0', 100); // Initialize String
  delay(100);
  while ( SIM900.available() > 0) SIM900.read(); // Clean buffer
  SIM900.println(ATcommand); // Sends AT command
  x = 0;
  previous= millis();
  // Wait for and answer
  do {
    // Read buffer and search for answer
    if (SIM900.available() != 0)
    {
        answer[x] = SIM900.read();
        x++;
      // Check if the answer is correct
      if (strstr(answer, correct_answer) != NULL)
      {
        correct = 1;
      }
    }
  }
  // Wait for an answer
  while ((correct == 0) && ((millis() - previous) < time));
  Serial.println(answer);

  return correct;
}

This function will be used whenever we send an AT command, and if we want to verify the answer, we will simply include it in an if it verifies that the module has returned the answer we are looking for.

This conditional structure will be used to verify that we are really connected to the mobile network, although we could use it in all the AT commands so that, should something fail, it will take us a message on the screen indicating where the error is. Really not totally necessary since reading the serial monitor you can see where it fails just by looking at the answers to the AT commands.

TURN ON THE MODULE BY SOFTWARE

 

We have already talked about how to turn the module on and off without having to press the GPRS button, sending a one-second pulse from Arduino to pin 9 of the card. However, imagine that we sent the instructions to turn it on and it turns out that it was already on. What we would do would be to turn it off.

So let’s also create a function to turn on the module but checking before it is not already on. It is very simple, if we send the command “AT” and it returns us OK it was on. If it does not return anything we will have to send the pulse to turn it on.

void power_on()
{
  int answer = 0;

  // Check if SIM900 is running
  if (sendAT("AT", "OK", 2000) == 0)
  {
    Serial.println("Powering on GPRS...");

    pinMode(9, OUTPUT);
    digitalWrite(9, HIGH);
    delay(1000);
    digitalWrite(9, LOW);
    delay(1000);

    // Wait for SIM900 answer
    while (answer == 0) {
      // Sends AT command every 2 seconds until an answer is received
      answer = sendAT("AT", "OK", 2000);
      SIM900.println(answer);
    }
  }
}

In addition to this function we are going to create two very simple ones, one that turns off the module and another that includes two that to restart the module, and that we will use if we lose the connection to the network.

void power_off()
{
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(1000);
}

void restart()
{
  Serial.println("Connection lost. Restarting...");
  power_off();
  delay (5000);
  power_on();
}

FUNCTIONS TO CONFIGURE THE MODULE AND SEND CALLS AND SMS

 

We also have functions that we have used previously, but that we have to adapt to the philosophy of this session. That is, we will send the AT commands using the function that we have created and we will verify that we are correctly connected to the mobile network.

These functions are the ones we use to configure the module correctly and those that properly perform the sending of calls and SMS.

void start()
{
  sendAT("AT+CPIN=\"1867\"", "OK", 1000);
  Serial.println("Connecting...");
  delay (5000);

  //Wait until GPRS is connected to the net
  while ( send("AT+CREG?", "+CREG: 0,1", 1000) == 0 )
  {
  }
  Serial.println("Connected.");
  sendAT("AT+CLIP=1\r", "OK", 1000); // Activate call identification
  sendAT("AT+CMGF=1\r", "OK", 1000); // Configure text mode to send and receive SMS
  sendAT("AT+CNMI=2,2,0,0,0\r", "OK", 1000); // Configure SIM900 to show SMS in the Serial monitor
  Serial.println("Prepared.");
}

void sms_message()
{
  if (sendAT("AT+CREG?", "+CREG: 0,1", 1000) == 1) //Check connection
  {
    Serial.println("Sending SMS...");
    sendAT("AT+CMGF=1\r", "OK", 1000); //At command to send SMS
    sprintf(aux_str, "AT+CMGS=\"XXXXXXXXX\"", strlen(sms)); //Destinatary
    //Message text
    if (sendAT(aux_str, ">", 10000) == 1)
    {
      sendAT(sms, "OK", 10000);
    }
    Serial.println("SMS sent");
  }
  else
  {
    restart();
    start();
  }
}
void call()
{
  if (sendAT("AT+CREG?", "+CREG: 0,1", 1000) == 1) //Check connection
  {
    Serial.println("Calling...");
    sendAT("ATDXXXXXXXXX;", "OK", 1000);
    delay(20000); // Wait 20 seconds
    sendAT("ATH", "OK", 1000); // Call dangle
    Serial.println("Call finished");
  }
  else
  {
    restart();
    start();
  }
}

Program Structure

 

Once we have created the functions that we are going to need, the structure of the program does not have anything too complicated. With this program we will make a call by typing an “l” on the serial monitor and send an SMS with the letter “s”. Obviously we will also receive calls and SMS and we will show the information of both on screen, of the telephone number and the content of the message in the case that it is an SMS.

#include <SoftwareSerial.h> 

SoftwareSerial SIM900(7, 8); // 10 and 11 for Arduino MEGA

int answer;
char aux_str[50];

//SMS text. \x1A ending character
char sms[] = "Message sent from the Arduino of Prometec! \x1A \r\n";

void setup()
{
  SIM900.begin(19200); //Configure SIM900 software serial port speed
  Serial.begin(19200); //Configure serial port speed
  delay(1000);
  Serial.println("Starting...");
  power_on();
  start();
}

void loop()
{
  if (Serial.available())
    switch (Serial.read())
    {
      case 'c':
        call();
        break;
      case 's':
        sms_message();
        break;
    }
  if (SIM900.available()) {
    Serial.write(SIM900.read());
  }
}
comandos AT gprs

With this program we believe that you will be able to face your projects with greater guarantees of success, granting them a certain level of autonomy and confidence. The structure of type switch () that we have created gives us the possibility to include in a very simple way other cases in which the readings of certain sensors activate the calls or SMS, and you could even include in the latter the value of the readings within the text of the SMS in the case that is necessary.

Summary

 

 
    • To send the AT commands correctly and make sure we receive the response from the GPRS module.
    • To verify the answer when we believe it necessary.
    • Make sure that we are correctly connected to the mobile network.
    • To start and restart the module by software.
    • We have created a program to receive and send calls and SMS, which we have endowed with the ability to work autonomously with certain guarantees of success.
 
 
 

No Comments

Give a Reply