SMS with the Wavecom WMOi3 GSM Modem and Arduino

I didn't say it was pretty.
I didn’t say it was pretty.

These little GSM modules and similar models pop up very cheaply on eBay, usually removed from old equipment (commonly found on the “BT Redcare GSM STU” which can be had for under a tenner) and they are a great way to add text message (SMS) functionality to a project for very little money. I actually got this one for free and it doesn’t get much better than that.

They can do a lot more than just text messaging too, including GPRS data, phone calls, fax and supports phone books stored on the SIM and additional hardware such as a speaker, microphone, keypad and status LEDs, it even has a couple of GPIO pins. You could easily create your own Arduino based mobile phone with one of these if you were so inclined. I’m just going to be using it for SMS for the moment.

Other than the WMOi3 and an Arduino of some sort you will also need a 50 pin connector and an antenna with an MMCX connector, I’m using this one.

The data connector is a 50 way male header with a fine 1.27 pitch, mine came with a short female to female ribbon cable so I got one of these 50pin male headers and soldered wires for power and rx/tx to that, fiddly but doable and then liberally covered it in hot glue. I also brought out wires for CTS and RTS but they aren’t being used here.

The WMOi3 needs a 5V supply of at least 1A according to the datasheet (at risk of “serious dysfunctions” otherwise) so you can’t connect it to your Arduino 5V output. In practice it can use as little as 9mA when idle but during TX bursts at 2W it can apparently use anything from 810mA to as much as 1A.

Connecting it up

WavecomWMOi3_connectorThe WMOi3 is controlled with an extended set of AT commands over serial (default at 9600, 8, N, 1) or SPI, I’m using serial and as the TX and RX pins are TTL it can be connected straight to an Arduino as follows:

Pins 3, 4 & 15: +5V 1A supply
Pins 1,2,6 & 21: to supply ground and Arduino ground
Pin 25 (TX): to pin 3 on the Arduino
Pin 28 (RX): to pin 2 on the Arduino

The communications with the WMOi3 will be using SoftwareSerial so the hardware serial can be used for communication between the Arduino and a PC.

Quick test setup


Interactive control

Now we need to load a simple sketch onto the Arduino so we can communicate with the WMOi3 and check it is all set up correctly and working.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);

void setup()

void loop()
if (mySerial.available())
if (Serial.available())

This just forwards everything from the GSM module to the Arduino hardware serial and vice versa so we can type AT commands in on the connected PC and receive the response. For this we will need to use a proper terminal program such as minicom as the Arduino serial monitor doesn’t send all the AT commands through properly.

Using the terminal program connect to the port the Arduino is connected on at 57600, 8, N, 1 and then reset the Arduino to make sure you get the Ready message in the terminal so you know it is working.

Power up the WMOi3 and as it boots you should see several +WIND indicators slowly appear such as:

+WIND: 3
+WIND: 1
+WIND: 4

3 indicates it is ready to accept AT commands (except phonebooks, AOC, SMS)
1 indicates the SIM has been detected
4 indicates it is ready to accept all AT commands

Now we can send ATI (just type ATI followed by enter) to check what type of module you have, it will give a response like:


Which tells us this unit can work on the 900MHz extended band and 1800MHz band.

To check the hardware version you can send AT+WHWV which will respond with something like:

Hardware Version 5.0

Next, check if full functionality is enabled by sending AT+CFUN? if it responds with +CFUN: 1 then all is good and we can have some fun(!), if it came back with +CFUN: 0 then issue an AT+CFUN=1 to enable full functionality.

Doing a AT+CFUN=1 any point will cause it to restart the phone functionality a register on the network and you will see the +WIND indicators again.

Before we proceed it is useful to enable error codes by issuing AT+CMEE=1 which will allow us to see why a call failed later on.

You can just jump to trying to make a call or send a message now and come back to this if it doesn’t work but here are some checks to see if it is registered on the network and which network.

To check if it is registered on the network issue AT+CREG? which will give a response like +CREG: 0,1 where the second digit indicates on of the following:

0: not registered & not currently searching for a new operator.
1: registered on home network.
2: not registered & currently searching for a new operator to register to.
3: registration denied.
4: unknown.
5: registered, roaming.

To see which network it is registered on do an AT+COPS?

You will get a response like: +COPS: 0,2,23410

where the 0 indicates it is set for automatic registration on the network, 2 indicates the operator is reported in numeric format and 23410 is the operator code (O2 in the UK in this case). You can get a list of the operator codes here.

Doing AT+COPS=3,0 will change it from the numerical code to an alphanumeric string, in this case AT+COPS? now returns +COPS: 0,0,”BTCELLNET” so obviously this one was made before BT Cellnet became O2. In fact we can check when it was made with AT+WDOP which on this one returns

Production Date (W/Y): 47/2001

If the first digit returned by AT+COPS? is not a 0 do an AT+COPS=0 to set automatic registration and then do a AT+CFUN=1

You can check if the network is available at any time with AT+WSTR=2 which will respond with +WSTR: 2,1 for network available or +WSTR: 2,0 for not available.

You can also check the status of the device with AT+CPAS which will return a result like +CPAS: 0 where the number indicates:

0: ready (allow commands)
1: unavailable (does not allow commands)
2: unknown
3: ringing (ringer is active)
4: call in progress
5: asleep (low functionality)


Making a test call

So lets make a quick call just to check it is all working, to dial a number, eg 0123456789 you do ATD followed by the number and a semicolon at the end, eg.


The device will respond with OK if the call succeeds, BUSY if the called number is engaged, NO ANSWER if there is no answer after networks preset time out, or NO CARRIER.

To hang up the call send ATH

If the call fails with NO CARRIER you can do AT+CEER to get the eror code (because we set AT+CMEE=1 earlier) and you can find a list of all the error codes starting on Page 189 (section 18.4 Failure Cause) of the AT commands reference here.


Sending a text message

OK so that verifies it is working but what we are really interested in is text messages (SMS).

To send a text message eg, to 0123456789 we start with:


the device will respond with a prompt:


Now type your message and end with a Ctrl-Z or send the hex representation (0x1A) and the device will send the text message and respond with +CMGS: x where x is a number incremented by one for each message sent, resetting to 0 once it reaches 255.


Reading a received message

By default when a message comes in the device will send +CMTI: “SM”,x where x is the number of the message.

To read a received message first set text mode with AT+CMGF=1

Then to list all stored messages AT+CMGL=”ALL” which will respond with something like this:

+CMGL: 1,"REC READ","+44123456789",,"13/06/01,20:48:58+04"
Testing testing 123
+CMGL: 2,"REC UNREAD","+44123456789",,"13/06/02,17:05:59+04"
Text of another message

or to read only unread messages use AT+CMGL=”REC UNREAD” or for only read messages AT+CMGL=”REC READ”. You can also request a specific message with AT+CMGR=x where x is the message number.

We can change it so an incoming message is automatically output when it is received by setting AT+CNMI=2,2,0,0,0
An incoming messages will now look like:

+CMT: "+44123456789",,"13/06/02,18:18:12+04"
This is a test message.

To delete a specific message use AT+CMGD=x,0 wher x is the message number or youc an use AT+CMGD=1,1 to delete all read messages or AT+CMGD=1,4 to delete all messages.


Automating it

So far everything has been interactive by manually issuing AT commands, to automate it we just need to build the correct sequence of commands in a sketch and send them over the serial connection, so to send a message when a button is pressed we could do something like:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

void setup() {
pinMode(7, INPUT_PULLUP); // Button across pin 7 and ground
mySerial.println("AT+CMGF=1"); // Set WMOi3 to text mode

void loop() {
int buttonState = digitalRead(7); // Read state of button
if (buttonState == LOW) { // Button was pressed
Serial.println("Button pressed, sending message... ");
mySerial.println("AT+CMGS=0123456789"); // Set the number to send to
mySerial.println("The button was pressed"); // Set the message
mySerial.println(char(26)); // Ctrl-Z to send
Serial.println("Message sent");

Just remember to allow a delay after each command for the device to return its OK and by ready for the next one. In the real world you would want to add some code to debounce the button input as well.

To make things even easier there is a handy SerialGSM library here with some examples to show how easy it is to use.

Although for receiving with this module you will need to edit SerialGSM.cpp and change AT+CNMI=3,3,0,0 near the top to AT+CNMI=2,2,0,0,0

From there it is trivial to create something to take actions based on a text message, like this quick example to turn an LED on and off by sending a text message of on or off.

#include <SerialGSM.h>
#include <SoftwareSerial.h>
SerialGSM cell(2,3);

boolean sendonce=true;
void setup(){
pinMode(13, OUTPUT);

void loop(){
if (cell.ReceiveSMS()){
String sender = cell.Sender();
String message = cell.Message();

if (sender=="+44123456789") {
Serial.println("Authorised user");
if (message=="on") {
Serial.println("Turning LED on");
digitalWrite(13, HIGH);
} else if (message=="off") {
Serial.println("Turning LED off");
digitalWrite(13, LOW);
} else {
Serial.println("Invalid command");
} else {
Serial.println("Not an authorised user");

What now?

I’m probably going to hook this up to one of my OSWIN boards or a Nanode to make a 2 way network SMS gateway although I’m also tempted to hook it up to my GPS module to make a vehicle tracker and that Arduino mobile phone is also tempting, I like the idea of building one into one of those huge 80s handsets. I think I need another one.


Useful links

WMOi3 User guide
AT commands reference

29 thoughts on “SMS with the Wavecom WMOi3 GSM Modem and Arduino

  1. Hello there!Very nice project and well done!i ma trying to make something with SMS control.I “speak: with my modem via Heper Terminal but when i send SMS “on” nothing happend.Any idea?please reply asap.
    Really thanks

  2. Sir. iam trying to send SMS through WAVECOM GSM modem. But mine +CREG is always showing searching for network. Its not getting registered. I tried AT+COPS. Still its not working. Can you please tell a solution for this


  3. Great news, its good that you didn’t need to send it back, it’s always a worry buying stuff from China but I’ve not really had any big problems and the support is usually OK.

    I’ve got a wavecom module on my watch list, just waiting now.

  4. yes i tried AT+COPS=0 followed by AT+CFUN=1. But no diff. its showing +CREG 0,2. Also tried AT+COPS=1,2,”network id”.:( Still not working.

  5. Antenna is OK?

    Is the SIM on a network supported by your module? eg. doing an ATI tells me mine does 900 and 1800 MHz networks (MULTIBAND 900E 1800).

    You could try a factory reset with AT&F

    Other than that I’m at a bit of a loss at the moment.

  6. The wavecom I ordered off ebay was still connected to the main PCB and had an antenna plugged in. I used a hot air gun to sweat off the 2×25 way connector and I’m attempting to solder some wires on the very small pins now, what a flippin job!!!

    If I get it working I plan to add SMS control to my central heating, tired of walking upstairs to put it on for an hour, I might even do an android app to allow me to hide the sms sending behind a nice user interface.

  7. They are fine pitch aren’t they, I found it easiest to temporarily bend adjacent pins out of the way slightly and keep the connector plugged into the ribbon cable while soldering to stop the pins moving under heat.

    I did an Android app like that for a GPS tracker that worked over SMS, worked really well and you can even get confirmation texts back from the device and pass them straight through to your app hiding them from the usual SMS app.

  8. Yep, I’ve plugged mine into the connector as well.

    It’s a really good buy, I’ll have to keep my eyes open on ebay for another one I fancy adding one to the burglar alarm.

    I might even add one to monitor the aquarium temperature and alert me if the pump or heater fails …. there’s loads to do with them.

  9. Yeah it’s great value. Using one for my alarm system was why I got another one, one for that and one to play with. Already have a landline dialler on my alarm but belt and braces… it will also replace my current SMS door bell system.

    There is also the option of using an incoming voice call to fire an event, just check the caller ID matches an approved list and then reject the call so the caller isn’t charged. Our electric gate system at work works like that.

  10. Nathan,
    Finally got around to getting the modem wired up and slowly getting somewhere but the switching on/off the LED doesn’t seem to work.

    I updated the SerialGSM.cpp file as you requested.

    Firstly the Sender number shows as “21” not the phone number, could this be a memory location in the SIM instead of the phone no.? (the SIM is out of my son’s old phone)

    Secondly the message appears as”0791449737709399040C91445709968642000031219211427500026F37″ instead of “on” ??

    Any thoughts?

  11. Just having a quick flick through the command reference and it looks like it isn’t getting set to text mode and is in PDU mode (a binary string in hex) instead. The SerialGSM library should be setting it to text though, the AT+CMGF=1 command is in there for the FwdSMS2Serial function.

    Try manually sending an AT+CMGF=1 to it over serial and you should get an OK back.

    Then do a AT+CSAS which will save it as the default setting in EEPROM.

  12. Thanks,
    I suspected it was something to do with the way the data was being reported add the manual method of reading messages worked ok.

    Had to go out but will do some more when I get back in.


  13. OK, something strange.
    If I setup the AT+CMGF=1 and AT+CNMI=2,2,0,0,0 manually and then load the LED skecth everything works fine.

    If I power down and up the modem, the AT+CMGF=1 is lost and returns to 0.

    Also I’m not convinced the writing of the configuration are actually written to the modem.

    More investigating required.

  14. Yep, confirmed that I can get it working fine, even with an android app to send the text messages but as soon as I power down the modem it loses the settings and the SerialGSM library doesn’t seem to set them.

    I’m not an expert in C so I’m not sure how this code snippet from the SerialGSM.cpp code works;
    “this->println(“AT+CMGF=1″); // set SMS mode to text”
    I suspect this is the culprit, what does “this->” do?


  15. It is used to remove ambiguity between members with the same name, eg. between Serial.println and the println inherited from SoftwareSerial, sometimes just for code clarity. Nothing jumps out as wrong there for me though.

    I’ll have a look at mine tomorrow and see if the default setting is getting saved on that and if I can change it, might help narrow it down.

  16. Getting a bit closer to the issue I think, I think it is something to do with the timing, I enabled the verbose mode in the CPP file and now I get 2 “+CME ERROR: 515” results from the modem after booting, I’m going to to play around with the timing.

  17. OK, not got to the root cause yet but if I comment out the cell.deleteAllSMS command then it all works fine, I even increased the delay in the command to 1 second but it still stops it from working ???? strange.

  18. Wondering if you managed to get the GPRS working on this modem? I cant seem to get it working!

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.