Tinkering with Raspberry (and other things)

Short message texting (SMS) with Huawei E220


Finally I got a second Raspberry for tinkering as the old one is now operating as my own calendar and address server (which is pretty useless if the “agencies” really can monitor and decrypt HTTPS, SSL, VPN and every other means of communication). And I have been to my “evidence vault” and found an old UMTS-modem, a Huawei E220. So the most obvious thing to do was to send and receive short message texts (SMS) via my Raspberry Pi. There are some frameworks out there that do this from scratch, but I wanted to dig a little deeper and do it by myself. So read on and I will reference some of the available tools and show you my proof of concept.

UMTS/HSDPA/3G modems

There are numerous USB-modems out there. I first tried to use an Huawei E167 with my Pi but that didn’t work out. The modem, connected via USB, got disconnected from the Pi every 5 minutes or so, leaving it unusable. With the Huawei E220 (which despite its higher number I bought one year earlier than the E167) I didn’t have that problem. And, surprisingly, because the older modem is much bigger it has a bigger antenna, thus having better reception even when hidden behind some furniture!

So the first thing was to check if the modem gets recognized. UMTS-modems do consume a lot of power, so I used a Y-cable that uses two USB ports, one for power and signals, the second plug for additional power. I recommend using a powered USB-hub. When I connected the cable directly to the Pi, it stopped working. Now here is a picture of the modem I am using:


Of course you will need a SIM-card to use the modem. I bought a very cheap one from (Germans only here) “Tchibo” as a pre-paid card that is valid for one year. It came with 5 Euros credit to spend so I was able to start right away.

Huawei modems do have a special partition in their firmware that announces a CD-ROM drive to the operating system when connected. In this partition the drivers and a software for operating the modem are located. As this is generally a good idea as you have everything you need to operate the modem within the modem, this is exactly what we do not need with the Pi. So the first step would be to check if the modem gets recognized and then get rid of the CD partition.

Connecting the modem

The following steps can be done without any SIM card in the modem. I prefer this method as it prevents me from doing something stupid that may cause horrendous costs or render the SIM card unusable…

With the Pi running just plug in the modem. Wait a few seconds, then run the command

sudo lsusb

to check if the modem gets recognized at all. You should get something like this:


Clearly, the Huawei modem is recognized by the system. Excellent. Although I have no idea why my E220 modem gets recognized as an E169/E620/E800 type. If you happen to see an additional CD-drive, this is OK, I will cover that in a second.

Now it is time to check if the Pi created any devices for the modem (which it should do automatically). Type

sudo dmesg | grep usb

This should display all connected USB devices, including the modem. The modem entries look like this:


Don’t worry about the three entries for the GSM modem, the first one is the one we are going to use. In human understandable terms the first “GSM modem” line reads: A GSM modem was detected, the hardware is numbered as “1-” and a device “ttyUSB0” has been created. You can check this with “ls -al /dev/ttyUSB0”, which should give an output like this:

crw-rw---T 1 root dialout 188, 0 Sep 12 16:57 /dev/ttyUSB0

Getting rid of the CD drive and other useful configurations

If you happen to see an additional CD drive, the following steps will disable that feature on the modem. Why is there a CD partition, anyway? Simple answer: in this partition the Huawei people did save driver and software for the modem so that it can be used without downloading anything. Pretty clever. Plug the modem in, install the needed bits from its internal CD partition and you are ready to go.
Using it with the Pi means problems. At least I made the experience that with the CD partition enabled, things didn’t work out.

The Huawei modems recognize a number of system commands that we can use to configure the internals of the modem. To do this we need access to the modem via its serial interface. So we need a terminal program. I chose “picocom” which can be downloaded using the apt package manager:

sudo apt-get install picocom

A short manual is included as a manpage (type “man picocom” in the shell, or look here).

So what do we need to configure next? During my tinkering I discovered a set of obstacles that I needed to get rid of:

  • The modem announcing a CD partition to the operating system
  • The need to manually input the SIM’s PIN number at every start
  • Frequent disconnects when changing from GSM to UMTS networks

So we are using the AT-system commands to remove all these things once and for all… To connect to the modem using picocom type (the last letter is a small “L” (not a “one”:

picocom /dev/ttyUSB0 -b 115200 -l

You should get a screen like this:

Bildschirmfoto 2013-09-12 um 17.38.40

Now, if you type “AT”, followed by “Enter” (the key) it should display “OK”. If all goes as expected, you are now connected to the modem.

To remove the CD partition we use the “AT^U2DIAG” command. The “^” needs to be displayed on screen, on my Mac I need to type “^” followed by the space-key. Type:


The U2DIAG-command is very versatile. It can be used to activate different operating modes of the modem:

  • AT^U2DIAG=0 – the device is only modem
  • AT^U2DIAG=1 – device is in modem mode + CD ROM
  • AT^U2DIAG=255 – the device in modem mode + CD ROM + card reader
  • AT^U2DIAG=256 – the device in modem mode + card reader

To check if everything worked well, exit picocom by typing


that is: press the CTRL-key (and hold it pressed), then type “a” and then (CTRL still pressed) “x”.

Next, we configure the modem to NOT ask for the SIM PIN any more. Replace xxxx with your PIN! Of course this step needs a SIM card inserted in the modem.


You can re-enable the PIN constraint with “AT+CLCK=”SC”,1,”xxxx”.

Now exit picocom, unplug the modem and replug it to let the changes take effect. If you do a “dmesg | grep usb” now, it should not display an additional CD-rom drive.

I encountered frequent disconnects/connects with my modem at first. A little bit of poking around and (luckily) looking at the modem at the exact moment it got disconnected brought the solution: whenever the modem changes the network type, that is going from GPRS to UMTS (3G) and vice versa, it did disconnect (and that was visible by the LED changing its color). As I only wanted to send and receive text messages I decided to configure the modem to use GPRS only. I do not need UMTS (3G) functionality with that modem ever. So lets get this done.

Connect to the modem with picocom (as above) and type:


You should get something like


There are 4 modes that can be selected for operation:

  • Only GPRS/EDGE: 13,1,3FFFFFFF,2,4
  • Only 3G: 14,2,3FFFFFFF,2,4
  • Preferred GPRS/EDGE: 2,1,3FFFFFFF,2,4
  • Preferred 3G: 2,2,3FFFFFFF,2,4

All we need to do is activate the mode we need: “Only GPRS/EGDE” in this case. In picocom type:


Pay attention that there are no spaces after the commas and type in the correct number of “F”s.

Sending and receiving SMS

I did quite a lot of research on this and found numerous valuable resources online. One of the most complete frameworks for controlling a phone/modem from Unix/Linux is Gammu. It seems a little complicated at first, but once one has read most of the excellent documentation things get clear. Again, I wanted to do things by myself to get e deeper understanding of things, so I did not use Gammu. Another great source of information is the SMS Tutorial at

Let’s have a look at the basics by interfacing with the modem directly with picocom. Modems support two types of SMS handling: text mode and PDU mode. Text mode is easier and I will use it throughout this post. In PDU-mode the SMS is binary encoded which adds some complexity. Again, I wanted a “proof of concept” and decided to go with textmode.

One word about AT-commands before we begin:

  • AT+CMD? outputs the current configuration for CMD in the form “+CMD=xxx”
  • AT+CMD=xxx sets the parameters for CMD

The command for SMS mode is “CMGF”:

AT+CMGF?      displays current mode
AT+CMGF=1     sets text mode
AT+CMGF=0     sets PDU mode

So set the modem to text mode first. It should respond with “OK”. Next we use the command “CMGL” to read all messages. This command takes one parameter that is used to configure if we want to get all messages, only new messages etc. Here is a list:

  • ALL. List all messages
  • REC UNREAD. List “received unread” messages
  • REC READ. List “received and already read” messages
  • STO UNSENT. The messages that are stored but not sent
  • STO SENT. Messages stored and sent

So to read all messages from the card you would type


and get an output like this:

+CMGL: 0,"REC READ","+4911234567890",,"13/07/11,19:03:45+08"
this is message number one
+CMGL: 1,"REC READ","+4911234567890",,"13/07/11,19:48:31+08"
Second message, 45 minutes later


The format of this output is straightforward. The command (CMGL) is repeated, followed by the index of the SMS. Then follows the status and the phone number from the sender and a timestamp. The following lines (until the next line starts with “+CMGL”) are the message.

Messages can be deleted using the “CMGD” command. It takes the index and an (optional) flag as parameters:


The flag value can be one of the following:

  • 0 – Only delete SMS at index given
  • 1 – Ignore index and delete all “received read” SMS
  • 2 – Ignore index and delete all “received read” or “stored sent” SMS
  • 3 – Ignore index and delete all “received read” or “stored sent” or “stored unsent” SMS
  • 4 – Ignore index and delete all SMS

Lastly, we are going to send an SMS. This is done with the command “CMGS”. The syntax is:

AT+CMGS="phonenumber"<CR>the message to send<Ctrl+z>

If you are doing this in picocom you need to press the return-key after the number, type the message and finalize it by pressing CTRL+z. If you encounter the message “+CMS ERROR: 330” the message center service number is not set. You can check the configured service center number with the command “AT+CSCA?”. It should return something like “+CSCA: “xxxxxxxxxxxx”,145.

Beware: I just spent one hour debugging, because I did get the “ERROR: 330” message despite the fact that “CSCA” did return the correct number. In the end I decided to just write the number again to the modem and give it a try. And it worked. I just have no idea why… Here’s a screenshot:


So that’s pretty much it. The Raspberry Pi can receive and send SMS texts. This gives us a lot of new tinkering possibilities. Send the Pi a SMS, get it parsed and let it send you an SMS back or do something with the home automation system. Wonderful 🙂

And just in the process of writing this, trying to remember all the websites I visited and testing the whole stuff again, I found a webpage with a python library for encoding/decoding SMS messages. With python’s serial library this makes things really easy. Connect to the device, send AT commands and do whatever you want to do with it.


16 thoughts on “Short message texting (SMS) with Huawei E220

  1. Hi

    First thanks for your tutorial. Till python everything works fine. I installed python-messaging-0.5.12 but i get this error and i don t know what could be the reason

    “>>> import messaging
    >>> import serial
    Traceback (most recent call last):
    File “”, line 1, in
    ImportError: No module named serial

    Can you help me somehow?

    Thanks in advance

    • It seems you haven’t installed the python-serial module. Try:
      sudo apt-get install python-serial

      Tip: To get a list of the python modules you have installed do this (assuming you are using a text shell):

      This takes a while and then gives you a list of all python modules installed.

      Hope that helps,

      • wow, that was very quick

        thanks a lot . that fixed my issue but now i have this..

        “>>> from messaging import PDU
        Traceback (most recent call last):
        File “”, line 1, in
        ImportError: cannot import name PDU

        but i can t find something like pdu in python..

        thanks a lot again for your help

      • Hi again.

        I have never worked with the python messaging module, but a quick search on the internet and a short look at the documentation of the module ( shows me that you need to import as:
        from messaging.sms import pdu

        I strongly encourage you to read the documentation and tutorials to the packages you intend to use!

        (Sidenote: I will now be offline for a while, so I won’t be as quick as the last two times 😉

  2. Hi,
    Thank you for this useful tutorial. I have also a Huawei E220 and tried everything in this post, but I was not able to run it correctly. If I try to run the AT-command AT+CMGF? it send an error message “+CME ERROR: SIM busy”. What can I do?

  3. Hello what OS do you use for your pi?

  4. what if i wanted to insert the text from a .txt file i already have in the raspberry pi

    • Well, then you need to write some script/program that inserts that text into the SMS message before sending it to the device.

  5. Hello Mr. Pi 🙂
    What if I want to send MMS via RPi? Any idea about that? or can u provide me with some useful links? I have googled about that but haven’t got any relevant thing.

    • Hi!
      I know there are some python MMS packages out there (just google mms python). I have never worked with MMS myself so I can’t give you a hint on the more useful libraries, sorry. Be careful though, lots of solutions out there, especially in the raspberry pi forums, will just send an e-mail to a mail-mms-gateway and that’s not what you want (I suppose).

      If you find something useful, please return to here and put it into a comment!

  6. When sending a text message, the recipient receives the message from the number of the SIM card. Is there any way to have it just as a name?

  7. Hi,
    I am receiving “COMMAND NOT SUPPORTED” if I send AT^U2DIAG=0 to modem. AT gives OK.
    What should the problem be?

    • I solved my own problem. It was due to character ^. I think modem echoes back every caharcter. To write this ^ you have to press 2 times but in putty console it shows only one time. I think in modem it is like so: AT^^U2DIAG, therefore I get error. I found ALT code for that char and tried it, it workd so far. Simply press ALT 94 on console for this char.