In the previous tutorial , we covered the AT commands supported by a SIM900 GSM-GPRS modem. We have already discussed how to interface a SIM900A GSM-GPRS modem with Raspberry Pi, Arduino, as well as other microcontrollers and desktop computers. Now it's time to use this modem to make and receive calls and send and receive SMS.
In this tutorial, we will demonstrate voice calls and SMS messages using a SIM900A with Raspberry Pi (RPi) and a desktop computer.
Communicating with a GSM-GPRS modem using Python
We previously learned about universal asynchronous serial receiver/transmitter (UART) communication using the RPi's TTL serial port.
Simply connect the GSM modem to the RPi's TTL serial port and open a serial communication port with the modem using the serial.Serial method. Next, you can send AT commands to the modem using the serial.write method and receive a response from AT commands using the serial.read method.
The modem's response can be stored in a variable and printed to the console using the print method. You can also design a GUI Application using the TTK library and a text editor so that data is sent and received over a serial port — and displayed in a Python application.
In fact, Python is platform independent and can be used to set up serial communication on any device and any other platform (i.e. not just the RPi's Linux platform, but also others like Win32 and macOS).
On a desktop system, modem interfacing can be done using a USB serial card. To do this, first find out the name of the port where the GSM modem interfaces with the desktop, via the USB interface. We cover how to find a serial port name on a desktop here .
Typically, the modem communicates at a baud rate of 9600 bps and 8N1 UART data encoding. Modems are designed to automatically detect the transmission rate. Although the data coding scheme remains 8N1, the maximum baud rate of 115,200 bps can be used for communication with the modem.
Initializing the SIM900A GSM-GPRS modem
To begin with, we must prepare the GSM modem for cellular communication. Insert a SIM card into the SIM card holder of the SIM900A modem. The modem is similar to a cell phone and requires a SIM card to connect to a cellular network.
Most modems have SIM card holders for Mini SIM (2FF form factor). However, Micro SIM (3FF form factor) and Nano SIM (4FF form factor) can also be connected, as long as the SIM contacts correctly touch the pins on the card holder.
Then turn on the GSM modem by connecting it to a power adapter (5V-12V, 2A). The modem status LED or network LED will begin blinking. Typically flashes faster while the modem connects to the mobile network. After the modem is connected to the subscribed communication service provider (CSP), it will flash every three seconds. It may take up to a minute for the modem to initialize (just like a cell phone initialization) and connect to a subscribed mobile network.
If you call the connected SIM, the modem will start ringing through the ringer and the ring indicator LED on it will flash. This confirms that the modem is working. In fact, when you call the SIM number, the call is automatically answered by the modem after a few rings. And if you connect a speaker and microphone to the modem, you can talk and receive calls on the connected SIM. So the microphone and speaker input are actually on the modem.
SIM900A interface with RPi
The SIM900A modem is a 5V device and the Raspberry Pi is a 3.3V single board computer. We cannot directly connect the TTL serial port of the SIM900 modem with the TTL serial port of the RPi.
If you directly connect the serial ports of the modem and the RPi, it will transmit the serial data to the modem because the 5V modem can tolerate 3.3V UART voltages. But when you try to receive data from the modem on the RPi, the 5V UART signals from the modem may damage or destroy the RPi's serial receiver pin.
To be safe, we will use a 5V to 3.3V TTL Logic Shifter. A simple logic shifter from 5V to 3V3 can be designed using 1N4148 diode as shown in this circuit diagram:
Alternatively, you can use a 2-, 4-, or 8-channel level-switching I/O module. This is an 8-channel level-switching bidirectional I/O module:
Then connect the modem's Rxd, Txd, and ground pins to those on the RPi via the level switching circuit or I/O module. You are now ready to communicate with the modem via the serial port.
Making a call from Raspberry Pi
To enable serial communication with the modem on the RPi, you must import the serial, RPi.GPIO, os and time libraries. The os and time libraries are required to use the sleep function, which ensures that the RPi waits for responses from the modem.
Start by configuring the pin numbering system for the board numbers and access the RPi's TTL serial port using the serial.Serial method. The port name on the Raspberry Pi is /dev/serial0. Alternatively, the port name can be /dev/ttyS0 or /dev/ttyAMA0 — use whichever is the primary UART on the respective Raspberry Pi .
Send the AT command “AT” to the modem using the serial.write method to verify communication with it. Read the response from the modem using the serial.read method and print it to the console using the print method or to a GUI interface. The modem will respond “OK” if it is working properly and connected to the Raspberry Pi.
- To make a call, send an “ATD
” to the modem - To end the call, send an “ATH” command to the modem
The Python script shown below successfully places a call to a number and ends the call after 30 seconds. AT commands are passed as bytes to the modem and the '\r' escape sequence is used to pass command line input. You can also connect a microphone and speaker to the modem. Previously, we hacked a headset so that voice calls could be received on the GSM-GPRS modem.
import series
import operating system, time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b'ATD9166873301;\r')
print(“Calling…”)
hour.sleep(30)
port.write(b'ATH\r')
print(“Hang up call…”)
Receiving a call on the RPi
When the SIM connected to the modem is called from a phone or any mobile device, the modem automatically answers the call after a few rings. The modem transmits “RING” from its Txd pin when there is an incoming call. The number calling the SIM can be extracted using the “AT+CLIP” command.
This call is automatically answered by the modem unless rejected, which can be done using the AT “ATH” command. To manually answer the call, you can use the “ATA” command.
Configuring the SIM900 for SMS messages
The modem first needs to be configured for SMS messages from the SIM900. Start by checking if the modem is working by sending the “AT” command. Next, turn off the echo by sending the command “ATE0”. Set indicators for receiving SMS using the “AT+CNMI” command.
This is a set type command and has the following format:
AT+CNMI =
O
0: A newly received message with unsolicited result codes is buffered in the modem. If the modem buffer is full, result codes may be stored elsewhere or older indications may be replaced with new ones.
1: Result codes from received messages are discarded and rejected when the modem is online (that is, there is an active serial link between the modem and the control device). Otherwise, the result codes will be transferred directly to the control device.
2: The result codes of received messages are buffered in the modem when the modem is online (that is, there is an active serial link between the modem and the control device). Otherwise, the result codes will be transferred directly to the control device.
3: In this mode, the result codes of received messages are directly transferred to the controlling device.
O
0: dobSMS-DELIVER indications are not routed to the controlling device.
1: If SMS-DELIVER is stored in the modem, an indication of its memory location is routed to the control device using the result codes (a response to AT commands) for the “+CMTI:” command.
2: SMS-DELIVER result codes are routed directly to the control device.
3: Class 3 SMS-DELIVERs are routed to the control device using the unsolicited result codes.
O
0: CBM indications are not routed to the control device.
2: Any new CBMs are routed directly to the control device using the unsolicited result codes (a response to the AT command) — “+CMB:
O
0: SMS-STATUS-REPORTs are not routed to the controlling device.
1: SMS-STATUS-REPORTs are routed to the controlling device using the unsolicited result code (a response to the AT command) using “+CDS:
O
0: The modem buffer is flushed to the controlling device when the controlling device enters mode 1 to 3.
1: The modem buffer is cleared for the controlling device when the controlling device enters mode 1 to 3.
Remember that the controlling device is the Raspberry Pi, Arduino, microcontroller or computer that controls the GSM modem. In the SIM900A AT command reference, the modem is referred to as terminal adapter (TA) and the control device is referred to as terminal equipment (TE).
In this case, we set the SMS indications to “AT+CNMI=1, 1, 0, 0, 0”.
Then check the preferred SMS storage location using “AT+CPMS=?” command. The storage location can be set to SIM card (
There are three memories, where:
1. Messages are read and deleted
2. Message writing and sending are complete
3. Received messages are stored
We define all three memories on the SIM card using the AT command: AT+CPMS=”SM”,”SM”,”SM.” In response, the modem sends back the used and total memory for all three operations (reading, writing and storing incoming SMS).
These SMS settings will be lost if not saved to the modem. To save these settings, the command “AT+CSAS” is passed to the modem.
We delete all current SMS messages stored on the SIM card using the command AT+ CMGDA=”DEL ALL”. Finally, we check again the memory space used for SMS messages with the command AT+CPMS=”SM”,”SM”,”SM”. This time the memory locations used are 0.
import series
import operating system, time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”ATE0\r”)
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b'AT+CNMI=1,1,0,0,0\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CPMS=”SM”,”SM”,”SM”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CSAS\r')
rcv = port.read(30)
print (rcv)
hour.sleep(10)
port.write(b'AT+CMGDA=”DEL ALL”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CPMS=”SM”,”SM”,”SM”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
Sending SMS from RPi
To send the SMS, first configure the message to text mode using the command “AT+CMGF=1″. Then select a number to send the SMS using the command AT+CMGS=”XXXXXXXXXX”, where XXXXXXXXXX is a cell phone number.
The message to be sent is stored in a variable. The output buffer is flushed using the reset_output_buffer or flushoutput method, but only if the serialpy version installed on the RPI is less than 2.5.
The message is concatenated with CTRL+Z or a substitute character using the char(26) method. The message along with the replacement character is encoded using the str.encode method and sent to the modem using the serial.write method.
import series
import operating system, time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”AT+CMGF=1\r”)
print(“Text Mode Enabled…”)
sleeptime(3)
port.write(b'AT+CMGS=”9166873301″\r')
msg = “SIM900A test message…”
print(“sending message….”)
sleeptime(3)
port.reset_output_buffer
hour.sleep(1)
port.write(str.encode(msg+chr(26)))
sleeptime(3)
print(“message sent…”)
Receiving SMS on RPi
Received messages are stored on the SIM card or phone/modem. The SMS message received at a specific index can be read by passing the command AT+CMGR=
The modem will respond with the SMS instructions and a body of the received SMS.
import series
import operating system, time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”ATE0\r”)
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”AT+CMGF=1\r”)
rcv = port.read(10)
print (rcv)
hour.sleep(1)
print(“Text Mode Enabled…”)
hour.sleep(1)
port.write(b'AT+CPMS=”SM”,”SM”,”SM”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CMGR=1\r')
rcv = port.read(100)
print (rcv)
hour.sleep(1)
port.write(b'AT+CMGL=”ALL”\r')
rcv = port.read(300)
print (rcv)
hour.sleep(1)
Interfacing the SIM900A with a desktop computer
When using a desktop computer, the GSM-GPRS modem can be connected to a USB to serial card. The modem via the USB to serial card is identified as a USB slave on the desktop.
After finding out the serial port name on the desktop system (macOS, Linux or Windows), you only need to change the serial port name in the above scripts.
The modem interfaces with the desktop as follows:
Here we connect the GSM-GPRS modem to a Windows computer. On our Windows desktop, the modem through USB serial card is identified as COM22.
Making a call from a desktop computer
As mentioned earlier in the Python script, to make a call from the Raspberry Pi, first comment out or remove the following RPi-specific lines:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
Open serial communication with the COM port where the GSM modem is connected via the USB serial card. Here, it is using COM22.
Add this line:
port = serial.Serial (“COM22”, baud rate = 9600, timeout = 1)
Now we can make a call from the desktop using the SIM900 modem.
import series
import operating system, time
#import RPi.GPIO as GPIO
#GPIO.setmode(GPIO.BOARD)
#port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port = serial.Serial (“COM22”, baud rate = 9600, timeout = 1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b'ATD9166873301;\r')
print(“Calling…”)
hour.sleep(30)
port.write(b'ATH\r')
print(“Hang up call…”)
The result:
Receiving a call on a desktop computer
To receive a call on a desktop computer, the process is practically the same as on the Raspberry Pi. We can pass commands to end an incoming call or answer it manually using a serial application (like Termite or Putty) on a Windows desktop.
Configuring the SIM900 for SMS Messaging on a Desktop
Here, we also need to comment or remove RPi specific lines and add the appropriate code to open the COM serial port of a Windows desktop in the Python script – which must be written to configure the SMS settings on the Raspberry Pi.
import series
import operating system, time
#import RPi.GPIO as GPIO
#GPIO.setmode(GPIO.BOARD)
#port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port = serial.Serial (“COM22”, baud rate = 9600, timeout = 1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”ATE0\r”)
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b'AT+CNMI=1,1,0,0,0\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CPMS=”SM”,”SM”,”SM”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CSAS\r')
rcv = port.read(30)
print (rcv)
hour.sleep(10)
port.write(b'AT+CMGDA=”DEL ALL”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CPMS=”SM”,”SM”,”SM”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
The result:
Of the result codes received from the modem, a maximum of 25 messages can be stored on the SIM card. In this case, there were already two messages stored in it.
After deleting all current messages during configuration, 0 is used in the SMS memory locations.
Sending SMS from a desktop computer
Again, comment out or remove the RPi-specific lines. Add suitable code to open Windows desktop serial COM port in Python script which is written to send SMS messages from Raspberry Pi.
import series
import operating system, time
#import RPi.GPIO as GPIO
#GPIO.setmode(GPIO.BOARD)
#port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port = serial.Serial (“COM22”, baud rate = 9600, timeout = 1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”AT+CMGF=1\r”)
print(“Text Mode Enabled…”)
sleeptime(3)
port.write(b'AT+CMGS=”9166873301″\r')
msg = “SIM900A test message…”
print(“sending message….”)
sleeptime(3)
port.reset_output_buffer
hour.sleep(1)
port.write(str.encode(msg+chr(26)))
sleeptime(3)
print(“message sent…”)
The result:
Receiving SMS on a desktop computer
You also need to comment or remove RPi-specific lines here. Add code to open Windows desktop serial COM port in Python script, which is written to receive SMS on Raspberry Pi.
import series
import operating system, time
#import RPi.GPIO as GPIO
#GPIO.setmode(GPIO.BOARD)
#port = serial.Serial(“/dev/ttyS0”, baud rate=9600, timeout=1)
port = serial.Serial (“COM22”, baud rate = 9600, timeout = 1)
port.write(b'AT\r')
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”ATE0\r”)
rcv = port.read(10)
print (rcv)
hour.sleep(1)
port.write(b”AT+CMGF=1\r”)
rcv = port.read(10)
print (rcv)
hour.sleep(1)
print(“Text Mode Enabled…”)
hour.sleep(1)
port.write(b'AT+CPMS=”SM”,”SM”,”SM”\r')
rcv = port.read(30)
print (rcv)
hour.sleep(1)
port.write(b'AT+CMGR=1\r')
rcv = port.read(100)
print (rcv)
hour.sleep(1)
port.write(b'AT+CMGL=”ALL”\r')
rcv = port.read(300)
print (rcv)
hour.sleep(1)
The result :
Note: Received SMS messages are stored on SIM card, so we are passing commands to read these messages from SIM card memory locations.
Now you can connect a SIM900 GSM-GPRS modem with Raspberry Pi and any desktop system. This includes making and receiving calls and sending and receiving SMS messages.
In the next tutorial, we will learn how to interface a GPS modem with Raspberry Pi and a desktop computer.