GSM Answer Call + Get Text... Help me!

Hey guys! I have a SIM900 GSM module. So far, I have got it to call, and text. However, now I want it to receive texts and calls. When I call the GSM phone number, I hear it do a ring from the audio output speaker. But, how do I pick UP the call? (Answer the call) Also, I can't find any online code for getting text messages! Help!

Any help would be super! Thanks!

NOTE: I am not using any GSM/GPRS libraries. I’m only using Software Serial. Is that OK?

That's all ok and that's a good exercice.

Read the AT command guide for the sim900. You'll find in there all what you need such as ATA to pick up or ATH to hang up the phone If I remember correctly

http://wiki.amperka.ru/_media/продукты:gprs_shield:gprs-shield_sim900_at_commands.pdf

(Try to find the most recent)

J-M-L:
That's all ok and that's a good exercice.

Read the AT command guide for the sim900. You'll find in there all what you need such as ATA to pick up or ATH to hang up the phone If I remember correctly

http://wiki.amperka.ru/_media/продукты:gprs_shield:gprs-shield_sim900_at_commands.pdf

(Try to find the most recent)

Thanks so much! Do you know how to detect if there IS an incoming call at all? (So if there is an incoming call, it gives the user option to accept or decline) That PDF did not say. Thank you so much, you've been quite helpful!

Listen to the serial line you should see RING

J-M-L:
Listen to the serial line you should see RING

So I could say

if (SIM900.read() == "RING") 
{//Blah blah blah}
else { //Blah Blah Blah}

[/code]

Conceptually yes - of course read() does not return a string you can compare that way

Read Robin's excellent tutorial on Serial Basics

J-M-L:
Conceptually yes - of course read() does not return a string you can compare that way

Right, of course. So, how should I do read this? Just to be clear the GSM module IS returning a string, right?

The modules put out a string proactively on incoming call [RING], or incoming text (starts with “+CMTI”). I havent checked for incoming email, but i suspect there they do too.

If you have an FTDI board you can plug directly into the tx/rx of the module and see for yourself exactly whats being output.

stupid-questions:
Just to be clear the GSM module IS returning a string, right?

no, it is not if you don’t use a library. it is sending bits on the Serial line which you read into a char and put in an array. Once you’ve got a number of bytes with a terminator, usually a Carriage Return (CR) and/or a Line Feed (LF) , then you have a string in a char buffer that you can compare to whatever you expect using strcmp() for example.

if you want to know how to do this, as mentioned above, read read and understand Robin’s Serial Input Basics

scrumfled:
The modules put out a string proactively on incoming call [RING], or incoming text (starts with “+CMTI”). I havent checked for incoming email, but i suspect there they do too.

If you have an FTDI board you can plug directly into the tx/rx of the module and see for yourself exactly whats being output.

So, uh… will this Arduino code work?

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8); // configure software serial port
SoftwareSerial Master(12, 13); // RX, TX

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
      pinMode(9, OUTPUT);
pinMode(9, OUTPUT); 
 digitalWrite(9,LOW);
 delay(1000);
 digitalWrite(9,HIGH);
 delay(2000);
 digitalWrite(9,LOW);
 delay(3000);
}


void setup() {
    SIM900power();
      SIM900.begin(19200);
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (SIM900.available() > 0 && newData == false) {
        rc = SIM900.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

That's kinda the idea

  • Are you sure of your end markers? (I don't think so)
  • you are setting 9 twice as an output in your power function
  • you seem to have 2 software serial ports - what is Master? (It is a bit touchy to use 2 software serials at the same time)

With the right markets this code will let you see what your sim900 generates upon an incoming call. That's a very good first step to understand what you need to parse

J-M-L:
That's kinda the idea

  • Are you sure of your end markers? (I don't think so)
  • you are setting 9 twice as an output in your power function
  • you seem to have 2 software serial ports - what is Master? (It is a bit touchy to use 2 software serials at the same time)

With the right markets this code will let you see what your sim900 generates upon an incoming call. That's a very good first step to understand what you need to parse

-What should the endmarker be?
-Oops I shall fix that :slight_smile:
-I do have two ports. Why is this touchy? Ya see, I have the GSM module plugged into an Arduino uno. The uno sends/gets data from another arduino, an arduino mega. The Arduino mega has a screen, a keyboard, a clock, and some other stuff plugged into it. The stuff takes up too much pins to be put on all ONE board with the GSM module, so I had to have two. One with the GSM and the other with all the other stuff. Why is that bad?

Thanks for the help so far!

-What should the endmarker be?

it depends what are you receiving?

    char startMarker = '<';
    char endMarker = '>';

are all the communication you get starting with < and ending with >?

Why is that bad?

I did not say bad - I said “It is a bit touchy:slight_smile:

That’s because the library has a known limitations: if using multiple software serial ports, only one can receive data at a time → so you need to handle that carefully

see TwoPortReceive example

Note that your Mega has multiple hardware Serial Ports so on that side you should not use Software Serial and I would recommend you connect the UNO to the MEGA using the UNO pin 0 and 1 (so you can’t connect at the same time to your computer for debugging) and the SIM900 to the Software Serial. This way you have only one Software Serial. (or you can also envision connecting the Mega and Uno using I2C for example if you want to keep your hardware Serial for the GSM or for connecting to your computer.

J-M-L:
That's because the library has a known limitations: if using multiple software serial ports, only one can receive data at a time --> so you need to handle that carefully

Oh, well I already am NOT using both at the same time so it is fine in that case.

J-M-L:
it depends what are you receiving?

I am receiving the word "RING" from the GSM module, right? So would I have to make the endmarker G? (That is a stupid question, I know, but I am new-ish to this) I mean, the GSM module does output RING, right? That is what I heard previously in this thread. It outputs RING, but NOT in the String form. Right?

I think the module will send a CR/LF or LF or CR to mark the end of a line. that's what I would listen for.

what you should do is a small piece of code that just prints in both ASCII and Hexadecimal (i.e. the character code, not it's keyboard representation) to see what's coming from the module. Once you understand that and with the knowledge you gained from understanding how to parse incoming data from the Serial line, you'll be the king of the world :slight_smile:

J-M-L:
I think the module will send a CR/LF or LF or CR to mark the end of a line. that’s what I would listen for.

what you should do is a small piece of code that just prints in both ASCII and Hexadecimal (i.e. the character code, not it’s keyboard representation) to see what’s coming from the module. Once you understand that and with the knowledge you gained from understanding how to parse incoming data from the Serial line, you’ll be the king of the world :slight_smile:

Oooohhhh… King of the world?! Tempting…

So I could just hook up the GSM module to the UNO, then initialize it, then have code that reads and prints what is coming from it. (With NO end maker thing) Then, call the module and see what the Serial Monitor does. Like this?

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8); // configure software serial port

char c;

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
      pinMode(9, OUTPUT);
pinMode(9, OUTPUT); 
 digitalWrite(9,LOW);
 delay(1000);
 digitalWrite(9,HIGH);
 delay(2000);
 digitalWrite(9,LOW);
 delay(3000);
}


void setup() {
    SIM900power();
      SIM900.begin(19200);
    Serial.begin(9600);
    Serial.println("<System ready>");
}

void loop() {
c = SIM900.read();
Serial.print(c);
}

Or should it be done WITH the end marker thing? Wait but I don’t know the end marker… Unless it is “LF” or something…

Thank you thank you thank you!

I just ran the code as mentioned above.
On my UNO, I saw "System Ready" then a bunch of question marks.

I tried calling my Arduino. Through the audio output of the GSM module, I could hear a cute little familiar ringtone. However, on the Serial Monitor all I saw was the question marks. Yes, the Serial Monitor IS set to the right baud rate.

And with this code, it was just the UNO. The Mega was off and doing nothing.

What does this mean?????????????

well, you see garbage because you ask to print garbage :slight_smile:

You need to test if there is something to read first

Try this code (set your arduino Serial console to
**[/u] [u]**115200**[/u] [u]**
and of course I assume your GSM is set up indeed at 19200 bauds)

#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8); // configure software serial port

void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);
  delay(1000);
  digitalWrite(9, HIGH);
  delay(2000);
  digitalWrite(9, LOW);
  delay(3000);
}


void setup() {
  SIM900power();
  SIM900.begin(19200); // make sure your GSM is set up at 19200 and not 9600
  Serial.begin(115200); // no need to go slow, set your console to 115200
  Serial.println("<System ready>\n");
}

void loop() {
  int c;

  while (SIM900.available()) {
    // we have pending communication, read what's coming
    c = SIM900.read(); // returns -1 if error
    if (c != -1) { // if this is not an error print what we've got
      if (c == '\n') Serial.println("[LF]"); // code 0x0A
      else if (c == '\r') Serial.println("[CR]"); // code 0x0D
      else Serial.print(c); // normal character
    }
  }
}

J-M-L:
well, you see garbage because you ask to print garbage :slight_smile:

You need to test if there is something to read first

Try this code (set your arduino Serial console to
**[/u] [u]**115200**[/u] [u]**
and of course I assume your GSM is set up indeed at 19200 bauds)

#include <SoftwareSerial.h>

SoftwareSerial SIM900(7, 8); // configure software serial port

void SIM900power()
// software equivalent of pressing the GSM shield “power” button
{
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);
  delay(1000);
  digitalWrite(9, HIGH);
  delay(2000);
  digitalWrite(9, LOW);
  delay(3000);
}

void setup() {
  SIM900power();
  SIM900.begin(19200); // make sure your GSM is set up at 19200 and not 9600
  Serial.begin(115200); // no need to go slow, set your console to 115200
  Serial.println("\n");
}

void loop() {
  int c;

while (SIM900.available()) {
    // we have pending communication, read what’s coming
    c = SIM900.read(); // returns -1 if error
    if (c != -1) { // if this is not an error print what we’ve got
      if (c == ‘\n’) Serial.println("[LF]"); // code 0x0A
      else if (c == ‘\r’) Serial.println("[CR]"); // code 0x0D
      else Serial.print(c); // normal character
    }
  }
}

Hi! I ran your code, and set the Serial Monitor to the proper Baud Rate.
Now NOTHING appeared on the Serial Monitor. When I tried calling the Arduino, nothing happened!
What am I doing wrong?
Could it be that my GSM module is not at the proper rate?

Thanks!
SQ