It's rather ridiculous to think how cheap you can get GSM/GPRS modems nowadays. Take the SIM800L, you'll get those from China for a couple of Euros. Sure, that's not the fanciest choice, and the breakout module has some serious shortcomings that limit your application options vastly (more on that later), but at least you do have this choice. I remember well how adding a GSM modem to an electronics projects has seemed like an unaccomplishable dream due to their prices.
I was lucky enough some years back and I had to actually work with some modules for work, and well, not much has changed in actually handling them - mostly some standardized and generally well documented Hayes commands.
Getting started
Well naturally, you're going to need a SIM card and activate it to fully use the module. Sure, you can use it without one as well, but that's obviously going to limit your options what to do with it.
Depending on where in the world you're living, you can just walk into any store, get a prepaid SIM card and are all set. The "activate the SIM card" part is nothing more than having it register to its home network for the first time - which means putting the SIM card the right way around into the module's slot and power it up.
However, for the very first time, I'd recommend to use a normal mobile phone for that, might be just easier. Plus, you can make sure the SIM card is okay, can make and receive calls etc., so if anything won't work with the SIM800L module, at least you'll know it's not the card.
Powering up the SIM800L module
For the start, you're going to need a power source and a serial port. You can get USB to serial converters that double as power supply for breadboard use (for example from Olimex), but keep two things in mind:
1. Power supply voltage
SIM800L itself requires an input voltage between 3.4 and 4.4 volts, some breakout boards come with integrated power regulators that require 5.0 volts. The USB to serial converter mentioned supplies either 3.3 or 5.0 volts, so make sure you match that.
2. Power supply current
The module can be a bit power hungry, especially during mobile network activity If your power source can't keep up, the module will shut down / reset in the middle of the action. Powering from your computer's USB port might not be sufficient for all operations! You might have luck placing a capacitor (1000uF and more) parallel to the voltage supply, but an external power supply (USB charger, wall wart, lab power supply) might be a better choice in the end. YMMV of course.
Serial port
As for the serial port, anything goes. If you manage to power the SIM800L module from your USB to serial converter, you're all set. If you end up using a separate power supply, make sure of those two things:
- serial port and SIM800L share the same ground connection
- do not connect any power outputs from the USB to serial connector to anywhere
Connecting the rest
Well, there's nothing else to connect to the module. I mentioned in the beginning some serious shortcomings of the SIM800L module, and while the SIM800L itself has an audio interface, the cheap breakout boards won't have the connectors routed out. Not being able to connect a microphone or headphone/loudspeaker makes it pretty much unsuitable for usual telephony applications.
But for SMS, GRPS and just having fun with a GSM module, this is still a good choice in my opinion.
First steps with the SIM800L
Open up your favorite serial communication program and set it up to use the correct serial device, e.g. /dev/TTYUSB0
at 115200 baud with 8N1 (8 data bits, No parity check, 1 stop bit)
With everything else set up, SIM card inserted, powering up the SIM800L module should show something like this:
RDY
+CFUN: 1
+CPIN: SIM PIN
If nothing shows up, check if the communication itself is up by typing "AT
" and wait for an "OK
" response. If just garbage show up while typing, your baud rate is is most likely wrong. If nothing happens at all, check your wiring (note that RX connects to TX and the other way around).
> AT
< OK
Note, I'll add ">
" for output you type and "<
" for output the SIM800L responses in the next examples to make it all a bit more clear.
Some words up front
The rest of this post will go through the basic commands and usage of the SIM800L module. Most of it might also apply to other GSM/GRRS modules. For a complete list of commands, please check for the SIM800 Series AT Command Manual.
Entering the PIN code
If your SIM card requires a PIN to unlock it, the module will ask for it by displaying a "+CPIN: SIM PIN
" as seen above. Enter it with a AT+CPIN=<pin>
command.
< +CPIN: SIM PIN
> AT+CPIN=1234
< OK
<
< +CPIN: READY
<
< Call Ready
<
< SMS Ready
If you enter an incorrect PIN, you'll get an "ERROR
" response. If you end up getting a "+CPIN: SIM PUK
", you probably done that three times and better have your PUK ready.
Check the network
Usually the SIM card is registered automatically to the home network. You can check this with the "AT+COPS?
" request
> AT+COPS?
< +COPS: 0,0,"Elisa Corporation"
<
< OK
And you can also check a list of all available operators:
> AT+COPS=?
< +COPS: (2,"Elisa Corporation","elisa","24405"),(3,"SONERA","SONERA","24491"),(3,"FINNET","FINNET","24412"),,(0-4),(0-2)
<
< OK
It might take a few seconds before the response is displayed - and obviously your responses for both commands is most likely going to be different.
Before making the first phone call, let's check the signal strength
> AT+CSQ
< +CSQ: 15,0
<
< OK
That's an RSSI of -84dBm and error rate of zero percent, good enough. In general, the higher the first number the better. The second one is preferably always zero.
Phone calls
Time to do some phone calls, send some DTMF tones and check our prepaid balance afterwards.
Place a phone call
Easiest test is of course to call ourselves Let's call to a very fake but theoretically valid local Finnish mobile phone number, 050 123 4567
> ATD0501234567;
< OK
After sending the command, nothing else will happen on the serial line, and a few seconds later the phone should start to ring.
If that's the case, hoorray, everything works. Let's hang up
> ATH
< OK
Receive a phone call
Latest now you should have your SIM card's phone number, so call it back with your phone and have an eye on the serial console. Eventually, it will show this:
<
< RING
Also, if your breakout module has a RING LED, it will indicate an incoming call. The longer you let it ring, the more "RING
" messages appear. Until you hang up on your phone, which is indicated by a "NO CARRIER
" message.
...
<
< RING
<
< RING
<
< NO CARRIER
So far so good. Except we have no clue who's actually calling there. If you're not interested in that, that's okay, but otherwise, it's a good idea to enable Caller Line Identifier Presentation
> AT+CLIP=1
< OK
And now we call again.
<
< RING
<
< +CLIP: "+358501234567",145,"",0,"",0
<
< RING
<
< +CLIP: "+358501234567",145,"",0,"",0
...
Nice, now we know. In this case the number is in international format (indicated by the 145 in the second parameter). Once more, check the SIM800 Series AT Command Manual for all the details and more information.
Play DTMF tones
Dual-tone multi-frequency signaling or DTMF, touch-tone or anything alike are the tones played when pressing dial keys during a phone call. The Wikipedia article will tell you all about it and what it can be used for, but in this case, we'll just use it as an alternative to a real phone call, since our audio options are non-existing with the SIM800L module.
Basic format of DTMF signal command is "AT+CLDTMF=<length>,<key>
", with length being values from 1-100 for each 100ms (so 0.1s to 10s) to generate the tone, and key being the dialpad keys 0-9, A-F, * and #.
So, let's call the module again, this time answering the call with "ATA
" and simulating pressing the following keys
- 5 for 500ms
- C for 800ms
- # for 2 seconds
and then we hang up.
<
< RING
<
< +CLIP: "+358501234567",145,"",0,"",0
> ATA
< OK
> AT+CLDTMF=5,"5"
< OK
> AT+CLDTMF=8,"C"
< OK
> AT+CLDTMF=20,"#"
< OK
> ATH
< OK
Yay, music.
Sending USSD
Unstructured Supplementary Service Data (USSD) is, in short, what you're sending when you are "dialing" a number enclosed in * and # characters. In case of prepaid SIM cards, you can use these to top up and check your balance. The actual USSD message might differ from your network operator, but in my case, "dialing" the number "*100#" will show me the balance.
> AT+CUSD=1,"*100#"
< OK
<
< +CUSD: 0, "Saldo 6.00e, Prepaid vanhenee 23.01.2017.", 15
Sending and receiving SMS
Although SMS is sort of obsolete nowadays in human communication, it might still offer some use for things like remote automation, and to learn as much as possible about a GSM module.
Unless you want to learn the hard way about PDU message formats, it's best to set the SMS message format to text mode
> AT+CMGF=1
< OK
Now SMS can be sent and read in plain text instead of a low level binary protocol. I of course encourage you to set the mode back to PDU via "AT+CMGF=0
" at some point just to have a look at it.
Receiving SMS
Let's start this way around. Take your phone and send a SMS to your module. When you look back in your serial console, you should see something like this:
<
< +CMTI: "SM",13
Message stored in "SIM Message storage" memory index 13 has been received. The index most likely differs in your case, I still have lots of network messages from the registration stored. Well, let's read it.
> AT+CMGR=13
< +CMGR: "REC READ","+358501234567","","16/10/22,22:36:42+12"
< Hello module
<
< OK
Obviously the parameter is the same index number. To list all the SMSs, you can use "AT+CMGL="ALL"
"
Well, just for shits and giggles, let's show the same in PDU mode:
> AT+CMGF=0
< OK
> AT+CMGR=13
< +CMGR: 1,"",31
< 0791534850020280040C915358103254760000610122226324210DC8329BFD06B5DFE43ABB0C02
<
< OK
Yes.. now imagine writing a message that way. Although writing a converter might be an interesting project. Still, let's stay in text mode for that.
Sending message
> AT+CMGS="0501234567"
> > Fuck off.^Z
< +CMGS: 0
<
< OK
It's straight forward, but some notes:
It's not a typo or wrong formatted. You send the "AT+CMGS
" command with the number, after which a prompt appears. Here is where you write your message. When you're done writing and ready to send, you press CTRL+Z to end the input mode. This allows you to also add line breaks to the message.
Mobile data via GPRS
The final subject in this post will be an introduction to data communication via GRPS. SIM800L can be set up to use either single connection or multi connection, i.e. keep more than one connection alive at the same time. The main difference is usually that GPRS related commands take an additional parameter in multi connection mode to set the connection ID.
To make matters easier in the beginning, we stick to one single connection at a time:
> AT+CIPMUX=0
< OK
Also, let's check the current GPRS connection status
> AT+CIPSTATUS
< OK
<
< STATE: IP INITIAL
Initial state, i.e. nothing is going on.
Setting up GPRS communication
You're going to need some mobile internet configuration information from your operator for this step. I don't know how common it is that they publish this information, in my case, they have it all on their customer service website. You'll basically need the access point name and maybe username and password information.
For me, it's simply access point "Internet" without any identification. So setting it up, and checking the connection status afterwards.
> AT+CSTT="Internet","",""
< OK
> AT+CIPSTATUS
< OK
<
< STATE: IP START
State has changed, good. Bringing up the module's wireless connector next.
> AT+CIICR
< OK
> AT+CIPSTATUS
< OK
<
< STATE: IP GPRSACT
We can now check our module's IP address
> AT+CIFSR
< 10.158.41.180
And for fun, let's just look up some DNS as well
> AT+CDNSGIP="google.fi"
< OK
<
< +CDNSGIP: 1,"google.fi","172.217.22.163"
Excellent.
Connecting to somewhere
As last example, we're going to receive something via HTTP from a Hollywood movie IP address 350.123.55.218.
> AT+CIPSTART="TCP","350.123.55.218","80"
< OK
<
< CONNECT OK
> AT+CIPSEND
> > GET /~sven/test.xxx HTTP/1.0^J^M
> ^J^M
> ^Z
< SEND OK
HTTP/1.1 200 OK
Date: Sat, 22 Oct 2016 21:09:50 GMT
Server: Apache
Last-Modified: Sat, 22 Oct 2016 21:07:38 GMT
ETag: "d-53f7a8c72025b"
Accept-Ranges: bytes
Content-Length: 13
Connection: close
yeah, works.
< CLOSED
Sending data is similar to sending a SMS in terms that you just say "I send now" and then a prompt appears to actually send the message, and finish it with CONTROL+Z. Where the two differ is in new line handling. You'll have to manually add a carriage return \r
with CONTROL+M and line feed \n
with CONTROL+J.
It's possible that this actually depends on the serial communication program you're using, but in case of minicom it looks like there's no way around this
Moving on from here
Well, that was that then. Hopefully the basic functionality and way of operation is clear now, and together with the AT command reference, the rest of the SIM800L's features can be discovered and explored. There's still things like phone book, clock, alarms and a whole bunch of higher level GRPS communication to look into.
Adding it to a microcontroller
While it is fun to play around with the module via serial console, and calling people you cannot hear is strangely satisfying, there's room for more. So naturally, connecting it to a microcontroller is a next step. I have already a project for that in the queue and it will eventually show up here.