Raspberry Pi GSM Phone Modem Setup

Recently, I bought a GSM module for my Raspberry Pi to tinker around with GSM and learn more about how phones work on a lower level: https://www.amazon.com/Raspberry-Bluetooth-Expansion-Compatible-DataTransfer/dp/B076CPX4NN

Here are some notes to help fellow tinkerers as I found very little helpful information out there regarding how to interact with GSM modem using a Raspberry Pi.

Helpful Resources:

GSM/GPRS/GNSS Hat WaveShare Wiki


Prior to installation, make sure your SIM card is activated and installed on the bottom side of the module.

Place the module on top of the Pi using the corresponding connector that goes with the pins similar to what is shown in the above photo.

That will be sufficient to supply a serial connection and power to the module from the Raspberry Pi.

If you'd like to connect another host to the module, use the USB TO UART connection using the USB cable that was included with the module (the USB cable only has one possible connection it can plug into on the module).

Connect the Modem to the Network and Connect Directly to the Modem:

I used a Ting GSM SIM card. In order to prep the SIM card, I merely needed to make sure it was activated prior to installing the module.

Per the wiki article, the CP2102 driver must be installed on the host that will connect to the SIM. Fortunately, this driver has been included in the Linux kernel since 2.6 and can be enabled with sudo modprobe cp210x. Check that the module has been enabled with lsmod | grep 'cp210x'.

After this, press the PWRKEY button on the module for one second (it hangs off the side and literally says "PWRKEY" on the module's board so it should be relatively easy to find). The NET indicator should start blinking about 1 time per second meaning that the module has not logged in to the GSM network. After it logs in successfully, the NET indicator should start blinking once every 3 seconds.

The modem on my external host connected via the USB to UART cable (running Arch Linux) was assigned the file /dev/ttyUSB1 which I found by running dmesg | grep tty. I verified it was using the correct driver because the output stated usb 1-11: cp210x converter now attached to ttyUSB1.

Again, the device file that came using the USB cable was /dev/ttyUSB1.

On the Pi that the SIM is connected to, the device file was /dev/ttyAMA0 but I could not figure out how to serial into it or if I could. If you'd like to connect via Serial to the SIM, I would recommend just plugging in the USB cable from the Pi into the USB to UART connection on the module.

Retrieve the serial settings of the device using stty:

sudo stty -F /dev/ttyUSB1

According to the Waveshare wiki the baud rate is 115200. Connect to the device using screen:

sudo screen /dev/ttyUSB1 115200

Note, the PWRKEY button must be pressed after each reboot of the pi or module in order to connect to it. Just make sure the PWR light is solid red, the STA light is solid and the NET light flashes every three seconds.\

Once connected to the GSM modem, you can check the status of the SIM using the AT command which should return OK if it is connected to a network. My SIM connected once I pressed the PWRKEY for one second so I did not need to troubleshoot connection issues.

Assuming all went well, the GSM modem should be suitable to send/receive texts, calls and data.

Send and receive texts/calls:

I wrote some Python utilities to make this much simpler: https://github.com/heywoodlh/pygsm.

Download pygsm:

git clone https://github.com/heywoodlh/pygsm

Install dependencies:

cd pygsm sudo pip3 install -r requirements.txt

Usage of text.py:

text.py has two main modes, send or read. send is for sending texts and read is for reading texts. send requires that the -i flag be pointing to the serial device (in this case as stated above, it is /dev/ttyUSB1), that the -r flag be pointing to the recipient's phone number (+1xxxxxxxxxx), and that the -m flag supplies the message that will be received (preferably in single or double quotes)..

General help message:

❯ ./text.py --help
usage: text.py [-h] {send,read} ...

Utility for dealing with texts over GSM via serial connection

positional arguments:
  {send,read}  send or read messages
    send       send text messages
    read       read text messages

optional arguments:
  -h, --help   show this help message and exit

send help message:

❯ ./text.py send --help
usage: text.py send [-h] -i TTY -r NUM [-m MES]

optional arguments:
  -h, --help            show this help message and exit
  -i TTY, --interface TTY
                        serial interface
  -r NUM, --recipient NUM
                        phone number to send to
  -m MES, --message MES
                        message contents

send example:

sudo ./text.py send -i /dev/ttyUSB1 -r +1xxxxxxxxxx -m 'Hey, what is up?'

read only takes a single parameter: -i flag for the serial interface (/dev/ttyUSB1). At this time read only reads all text messages, it does not do anything more.

read help message:

❯ ./text.py read --help
usage: text.py read [-h] -i TTY

optional arguments:
  -h, --help            show this help message and exit
  -i TTY, --interface TTY
                        serial interface

read example command:

❯ sudo ./text.py read -i /dev/ttyUSB0
+CMGL: 1,"REC READ","+1xxxxxxxxxx","","18/09/12,10:50:11-24"

This is my awesome text message!

Usage of call.py:

call.py is for making and receiving phone calls. A headphone should be plugged into the Raspberry Pi module in order to actually use this. call.py has two modes: make (for making calls) and receive (for answering calls).

call.py help message:

❯ ./call.py --help
usage: call.py [-h] {make,receive} ...

Utility for dealing with calls over GSM via serial connection

positional arguments:
  {make,receive}  make or receive calls
    make          make phone call
    receive       answer incoming phone calls

optional arguments:
  -h, --help      show this help message and exit

make requires two arguments: -i for the serial interface (/dev/ttyUSB1), -r for the number that will be called (+1xxxxxxxxxx).

make help message:

❯ ./call.py make --help
usage: call.py make [-h] -i TTY -r NUM

optional arguments:
  -h, --help            show this help message and exit
  -i TTY, --interface TTY
                        serial interface
  -r NUM, --recipient NUM
                        phone number to call

make example command:

❯ sudo ./call.py make -i /dev/ttyUSB0 -r +1xxxxxxxxxx

As prompted on the screen, type 'end' (without quotes) to hang up the call.

Before going into the receive mode of call.py, enable calls to come through by running enableCall.py:

sudo ./enableCall.py -i /dev/ttyUSB1

receive allows you to answer incoming phone calls. It takes a single argument: -i for the serial interface (/dev/ttyUSB1). Obviously, it requires a phone call to be incoming in order to answer.

receive help message:

❯ sudo ./call.py receive --help
usage: call.py receive [-h] -i TTY

optional arguments:
  -h, --help            show this help message and exit
  -i TTY, --interface TTY
                        serial interface

receive example command:

sudo ./call.py receive -i /dev/ttyUSB1


This Raspberry Pi GSM module is really fun. I enjoyed learning more about how GSM works throughout this project. I would definitely recommend others do the same. You really could turn your Raspberry Pi into a full-featured phone if you worked on it hard enough!