Although there are a few vendors of mobile phone network hardware for Arduino, Raspberry Pi, etc there are plenty of other options, but a lack of good documentation and a handful of practical issues. This article comprises some notes on getting a SimCom Y7080 working over the LTE CAT-NB network in the UK, but should generalise fairly well.
I have two use cases in mind which underpin the direction which this article takes. Both require only low bandwidth (low data transfer rates) but should ideally have good coverage (fortunately, these two things go together). These are: a) static sensors reporting readings, and b) tracker reporting GPS location.
Choosing Hardware
There are plenty of people selling mobile network modules, including “trackers” on AliExpress and similar sites. The variety of options is rather baffling. Broadly speaking these are in one of three categories:
- Obsolete hardware designed for GSM (2G), GPRS. I’ll include 3G here too. These networks are being (or have been) taken down in most developed countries. The hardware is cheap for a reason!
- Hardware which works on the same network services as normal 4G/5G mobile phones. This might be right for you, but the higher bandwidth required for voice means poor coverage in rural areas or indoors.
- Hardware supporting either LTE CAT-NB or LTE CAT-M1 (LTE = 4G). The former is also known as “NB-IoT” (but this term is used very loosely!) and is the lower-bandwidth (but better coverage) of the two, although both are relatively lower bandwidth than “normal” 4G. LTE CAT-M1 is better for devices which are likely to move between towers/cells and LTE CAT-NB is better for static devices (especially if they are likely to be in difficult terrain). This is where I am focussing this article. NB: LTE CAT1 is different to CAT-M1; it is a medium-bandwidth LTE standard.
A second consideration is the geographical region because different regions use different frequencies. These are usually given as a “band” number, e.g. “band 20” or B20. Hardware suppliers should list the bands they support and seem to segment their products into “global”, “Europe”, “Japan” etc. Check the bands that your local network providers use for LTE CAT-NB/M1.
I ended up drilling down to “breakout” boards based on SIMCom modules, as these seem to have a good compromise between price and available documentation, as well as having GNSS (i.e. GPS) as an option. AND Global make a selection of SIMCom-based boards and sell on AliExpress; I have a preference for choosing a supplier who seems to be more than just a reseller of random modules they do not understand! The SIM7000 module supports both CAT-NB and CAT-M1, while the Y7080 module supports only CAT-NB. As I’m getting the board to play/experiment, I opted for the cheaper Y7080E (E = European bands) board with the GPS option at a little over £12 + tax + shipping. The AND boards also have helpful power supply specifications, allowing 2.2V-4.2V for NB only, or 3.0V-4.2V with GNSS, perfect for operation from a LiPo cell (I like my 18650!), while working with 3.3V logic. Note that AND also list a SIMCom A7670 board in their “nb-iot breakout board” category, but it uses LTE CAT1. However: before you go and buy one, see the end of this post!
Getting a SIM Card
This was MUCH harder than I expected. There are two significant issues: a) making sure the SIM card, and the mobile network operators which are accessible with it in your area, supports one or both of CAT-NB or CAT-M1 according to your hardware and use case, and b) finding a supplier who will deal with a non-business customer. For (a), its often just difficult to find out the specific detail among the supposedly multi-country and multi-network offers. Additionally, many suppliers are peddling their cloud platforms and I just want a SIM! And, much to my irritation, it seems like almost everyone wants to charge >£8 for delivery; dudes, its just a SIM card!
I ended up using getting a Vodafone SIM card from AllioT. Their specific focus on Vodafone in the UK, which I had identified as the nework with good coverage for me, was an important deciding factor. This does work, although they do charge a lot for delivery (the terrible DPD, who took 4 attempts to deliver it).
Other options I tried first, and failed with:
- Soracom were very quick to send out a card (without stupid postage costs), and the charging rate seems quite good. Unfortunately, it only supports CAT-M1, and not CAT-NB, and the Y7080 is CAT-NB only.
- Onomondo dish out 5 free SIM cards (30 day limit). Sounds good for some DIY testing but they come pre-activated so you really only get 30 days. The cards also took a while to arrive. It also turned out that they didn’t have a CAT-NB/M1 service in the UK, on the free trial plan at least. That took a while to work out.
Options for the future:
- Olivia Wireless looked quite reasonable and explicitly mentioned NB-IoT on Vodafone in the UK. First off, I only found their 5 year package, so I thought I’d look at them for a long term deployment. Since then I found their sensible PAYG. They also offer “pooled data” allowances. Worth a look.
- m2m data connect also mention Vodafone in the UK and have CAT-NB and CAT-M1. The rates look OK but I’d already made contact with AllioT.
Discarded options:
- 1NCE won’t sell to private individuals
- Hologram didn’t look like they had the right network coverage for the UK.
- Wherever SIM looked promising until “we do not sell individual M2M SIM cards and our offers are not aimed at private individuals”.
- Things Mobile have too many extra charges in the small print, and have some bad reviews.
- Lots of others which either look unsuitable (or suitability isn’t clear) for my region, seem pricey, or other issues, such as InfiniSIM, KeySIM, EMnify.
Getting it Working #1 – Just Connect!
So… my Vodafone SIM finally arrived but the Vodafone portal didn’t work properly (no SIM listed, lots of 500 errors). After failed attempts to get my module to connect, I contacted Alliot and got a different URL for the portal [the one at iotportal.vodafone.com is pure shit, while m2mportal.vodafone.com works] and was able to activate the SIM. Yay! I set the status to “active.test” and it seems not to be counting the data used against my 1M/month quota; it looks like there is a 100k test allowance.
Using the datasheet from SIMCom (Y70XX Series AT Command Manual) and an onomondo blog post + discovering the APN is “lpwan” from the Vodafone portal got me started. Here is the summary. I assume readers are familiar with making a serial connection and using a terminal to issue AT commands. FWIW, I use a USB serial adapter and Termite for interactive exploration. Consult the AT Command Manual to understand the parameters and responses.
If you’ve been messing about, or even with a newly-delivered module, it makes sense to factory reset:
AT+RESET
Check the type of hardware:
ATI
The factory settings of the modem may be to use power saving mode (PSM). This is great for real use but having it shut down when you are reading the manual or thinking is a nuisance. Check the PSM with:
AT+CPSMS?
My response shows +CPSMS:1,,,01001000,00100001 , so PSM is active and causes a shut down after 1 minute (see the manual), so I’ll turn it off (this preserves the periods) with:
AT+CPSMS=0
Tell the modem to issue Unsolicited Response Codes (URCs) when the network state changes. This avoids the need to keep polling for status.
AT+CEREG=1
Check whether the modem is set to auto-connect:
AT+COPS?
That should return +COPS:0 . If not (another onomondo post is quite helpful concerning good practices for connecting/disconnecting), send the command:
AT+COPS=0
Specify a PDN for connection, in this case with id=1, and save it:
AT+CGDCONT=1,"IP","lpwan"
AT+NV=SAVE
That should trigger a reboot ending in the message ^SIMST:1 to tell you the SIM card is successfully initialied.
A nice extra is to ask the modem to report its IP address when connecting. You can see if this is enabled with:
AT+NIPINFO?
And if that returns +NIPINFO:0 (i.e. it is turned off), turn reporting on with:
AT+NIPINFO=1
Connect to the network with id=1:
AT+CGACT=1,1
Give it a while to connect. This can take a seriously long time for the first connection: minutes! You should eventually see two messages which confirm connection. The first declares that the PDN is active: +CGEV:ME PDN ACT 1 . The second shows the date/time, e.g. +CTZEU:+04,0,2024/01/10,13:44:05 . You will probably also see +CEREG:5 (connected and roaming) and if you followed the suggestion above, a line starting +NIPINFO:1,”IP” .
Now check which network/operator is connected:
AT+COPS?
In my case this gave +COPS:0,2,”23415″,9 , showing I had indeed connected (the value of the stat is 2) to Vodafone UK CAT-NB network. The “24315” decodes to 243 = UK and 15 = Vodafone (these country and network codes appear in the Vodafone portal under devices > details, if you dig about a bit!). The final 9 means the modem is using the NB access technology (it would be 7 for CAT-M1).
You can also see which networks are available with:
AT+COPS=?
In my case, this returned +COPS:(2,,,”23415″,9),,(0-4),(2) , showing only one network is available and that it is connected. The “,,(0-4),(2)” at the end is just boiler-plate; see the manual.
As an extra, maybe look at the signal strength.
AT+CESQ
If you’ve finished, rather than just switching off, try using the following, which will preserve settings for a faster re-connection next time, then remove power off when the modem responds with +POWERDOWN:0,-1 .
AT+FASTOFF
Next time you turn the module on (and have the serial port connected), you should find it connects without intervention and reports the same kind of things which were obtained using the manual approach above, e.g.:
+POWERON:0
^SIMST:1
+CEREG:2
+CGEV:ME PDN ACT 1
+NIPINFO:1,”IP”,”10.198.71.109″
+CEREG:5
+CTZEU:+04,0,2024/01/11,21:59:41
Getting Started #2 – Ping and NTP
The important preparation is to make sure that the destination servers are not blocked by a firewall. In my case, the vodafone access control list (ACL) was initially set to only allow one IP address through (which I had provided to AllIot when getting set up) and only one ACL is associated with each APN. I bet there is something similar on other operators. I found the ACL settings under Administration > APN Access Lists. It works with either a numeric IP address or a host name (FQDN). If you don’t do this, you will get time-out errors.
Once that is done, the basic process is straight-forward. Note that the modem initially returns an “OK”, then does the ping (etc), and then returns the result. Check the documentation for the meaning of all the parameters. This example only does one ping, of the 8.8.8.8 Google DNS server, and has a 10s timeout.
AT+NPING="8.8.8.8",32,1,10,1
Getting date and time from an NTP server is also straight-forwards. Here I query one of the usual UK NTP servers.
AT+CMNTP=131.111.8.171
This is also an asynchronous command which will respond immediately with “OK” then give something like: +CMNTP:0,”24/01/10,17:14:57+4″ . If you get +CNMP:2 then the request timed out.
Time-outs can happen if the signal strength is too low, even if you have an established connection.
Next Steps #1 – HTTP Requests
Set the APN access list (aka ACL) if required!
This is just a simple example to show how to make a HTTP GET request. The Y7080 is quite nice for this, whereas some other modules require several more commands. Remember that you are working with a low bandwidth channel and that the response will come through as the raw text or bytes; use a URL pointing to something simple. I put up a simple test page on this site.
The first step is to prepare the modem to communicate with a particular host (in this case, my website, for which the “www” part is not needed):
AT+HTTPCREATE=http://hilltop-cottage.info
This returns a “handle” for use in what follows by replying with +HTTPCREATE:0. For the Y7080, you can only have one handle open at a time (see the close command below), so it will be 0.
How use the handle to make a request for my test page, providing the path to the “page”. See the documentation for the parameters (spoiler: the first is the handle and the second means GET).
AT+HTTPSEND=0,0,"/test.txt"
As for ping and NTP, the process is asynchronous, with the modem first replying “OK” then going off to try the request. I found that it then replies +REQUESTSUCCESS in some error conditions. The one I discovered was that a poor network signal can lead to +REQUESTSUCCESS being followed by +HTTPDICONN:0,-1 , which means some kind of network error. In this case, you can try the HTTPSEND again, without needing to repeat the HTTPCREATE. You might get +BADREQUEST if the handle is not currently in use and this sometimes happens even with everything done correctly (just repeating the HTTPSEND might be enough).
If it really is a successful fetch then prepare for several messages to come through the serial port.
First will be the HTTP headers, which are introduced by something like +HTTPNMIH:0,0,304 (the values are handle, a continuation flag, and the length of the header string). Each header is followed by newline characters, and the first line should be HTTP/1.1 200 OK . Then comes the content. Since this is a minimal page, there will only be one chunk of content. For my test page it should be introduced by +HTTPNMIC:0,0,23,23 (the values are as for NMIH but there are now two lengths, the first is the total length, and the second is the length of this chunk). Then you should see the content of test.txt, “A plain text test file”. Receipt of larger content, which needs more than 1 chunk makes use the continuation flag; it is set to 1 until the last chunk. Finally, the modem will signal that the connection to the HTTP server was closed by sending +HTTPDICONN:0,-2 .
Free up the HTTP connection handle by providing the handle to HTTPCLOSE:
AT+HTTPCLOSE=0
Complications come in when dealing with HTTPS, and there is a SIMCom application note (see the link to the AT commands reference, above) dealing with this, but there may be bandwidth issues with all the overhead of encrypted HTTP using CAT-NB. If you need to HTTP POST, then HTTPS is essential so HTTP is probably not the way to go for sending data vs lower overhead protocols.
That said, here is the experience in POSTing simple messages. I used the httpbin.org service, specifically its /post endpoint, which responds with some JSON containing your payload and headers etc IF the request is a POST, otherwise returning a HTTP status code of 405.
Getting HTTP POST to work was not quite as simple as the documentation led me to believe. It turned out to be necessary to set the Content-Length header, rather then relying on the modem to do this. Failing to do this causes some very strange responses when attempting requests against httpbin.org. Oddly, issuing a request using Postman from my PC and suppressing the Content-Length header does not cause any problems, so I suspect some proxying in the Vodafone platform is at fault. Also, with the module and antenna in exactly the same position (admittedly with a fairly low -92dBm received signal strength), attempts at POST seem more prone to failure with +HTTPDICONN:0,-1. Anyway, here is the transcript of a simple interaction (omitting “OK”) using the same formatting convention as above:
AT+HTTPCREATE="http://httpbin.org"
+HTTPCREATE:0
AT+HTTPHEADER=0,Content-Length:5\r\n
AT+HTTPCONTENT=0,flood
AT+HTTPSEND=0,1,"/post"
+REQUESTSUCCESS
+HTTPNMIH:0,0,230
HTTP/1.1 200 OK
Date: Fri, 12 Jan 2024 16:54:44 GMT
Content-Type: application/json
Content-Length: 294
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
+HTTPNMIC:0,0,294,294
{
“args”: {},
“data”: “flood”,
“files”: {},
“form”: {},
“headers”: {
“Content-Length”: “5”,
“Host”: “httpbin.org”,
“X-Amzn-Trace-Id”: “Root=1-65a16ed4-2094703473d8153049b1d240”
},
“json”: null,
“origin”: “46.108.136.9”,
“url”: “http://httpbin.org/post”
}
AT+HTTPCLOSE=0
Notice that the header must end with “\r\n” (i.e. carriage return and line feed control characters to signify the end of the header), and also that the second parameter of HTTPSEND is 1. Also, in spite of the documentation indictating it is required, there is no “\r\n” on the HTTPCONTENT. No explicit Content-Type was set, so httpbin has returned the payload as “data”; it is just a string of bytes. If the HTTP service expects JSON, or treats it differently, as httpbin does, then the incantation is a bit different. Also, while the documentation suggests you can use commands like AT+HTTPCONTENT=0,{“RPM”:22}, I found that this did not work in practice; the double-quote marks are clearly causing a problem as httpbin says it things the data is “RPMPOST /p”. I resorted to using the hex encoded approach. Here is an edited-down transcript:
AT+HTTPCREATE=http://httpbin.org
AT+HTTPHEADER=0,Content-Type:application/json\r\n
AT+HTTPHEADER=0,Content-Length:10\r\n
AT+HTTPCONTENT=0,7b2252504d223a32327d,1
AT+HTTPSEND=0,1,"/post"
AT+HTTPCLOSE=0
Giving:
+HTTPNMIC:0,0,359,359
{
“args”: {},
“data”: “{\”RPM\”:22}”,
“files”: {},
“form”: {},
“headers”: {
“Content-Length”: “10”,
“Content-Type”: “application/json”,
“Host”: “httpbin.org”,
“X-Amzn-Trace-Id”: “Root=1-65a28db6-4775b6bd41c402ac1f9ac7dd”
},
“json”: {
“RPM”: 22
},
“origin”: “46.190.188.99”,
“url”: “http://httpbin.org/post”
}
Note that the Content-Length was still required (see earlier notes about this potentially being a Vodafone platform issue) and that I found the \r\n termination of the content (0a0d in hex) is not required (and these characters are not counted in the Content-Length).
Then, after a bit of persistence, the solution to the HTTPCONTENT quotes problem was discovered to be surrounding the content in double quote and escaping the inner double-quotes, like so:
AT+HTTPCONTENT=0,"{\"RPP\":23}"
Next Steps #2 – MQTT Misadventures
The SIMCom application note for Y70XX MQTT(S) which I found appears to be wrong (misadventure #1 but see the end of this article!), but the module I have recognises the commands in the AT commands manual.
My use cases are data source applications, so I’ll look at PUBLISH first.
For real use, with a broker on the public internet, MQTTS and authentication is a must, but a basic test on an open testing broker is a good place to start and mqtt://public.mqtthq.com:1883 should fit the bill, but there is also test.mosquitto.org.
Misadventure #2 coming up!
AT+MQNEW=public.mqtthq.com,1883,5000,200
A reply of +MQNEW:0 is good but if you get +CME ERROR:8002, check the APN ACL in the Vodafone portal! Guess who spent several minutes being baffled.
Try to make a connection (use a sensibly unique client id!):
AT+MQCON=0,4,"client_id",1000,1,0
The broker just disconnects at almost every attempt, responding with:
OK
+MQDISCON:0
I found no way around this. Initially, I thought it was because of the version 4 required by the AT command; there is no MQTT version 4! However, this might be a different interpretation of “protocol version” as outlined in this blog post explaining why there is no version 4 of MQTT (i.e. version 3.1.1 = 4!).Persisting with multiple attempts, each beginning MQNEW, eventually did work; a connection was established, shown by +MQCONNACK:0,0 and I was able to publish (note that the payload is a set of hex bytes) to a topic “aardvark” and see it in another client.
AT+MQPUB=0,"aardvark",0,0,0,4,61626364
I surmise that these open public brokers have quite aggressive connection controls, and that the low bandwidth makes the connection dialogue too slow. Maybe it is load dependent because trying again on UK Saturday lunch time seems much more likely to connect OK, and my PC client is just quietly re-trying the background. Once connected (CONNACK), at least the connection seems durable.
Disconnection with AT+MQDISCONN=0 is not the exact counterpart of AT+MQCON; after disconnection a new AT+MQNEW is required.
Although it is out of my core use cases, there may be utility in MQTT SUBSCRIBE. Sending a “retained” message to the broker from another device/service, the modem can come online and subscribe as a way of asynchronous messaging to the device (which will only poll occasionally to conserve battery power). Assuming I’ve published a message of “World” to topic aardwolf from somewhere else, the AT commands and reply looks like this (responses edited down):
AT+MQNEW=test.mosquitto.org,1883,5000,200
AT+MQCON=0,4,"client_911",1000,1,0
AT+MQSUB=0,aardwolf
+MQSUBACK:0,aardwolf,0
+MQPUB:0,aardwolf,0,1,0,5,576F726C64
OK, so now for the final episode of the misadventure. When I spotted that the MQTT(S) application note had different commands to the AT Commands document, I just got on using the commands from the latter. Only later did I notice that it did not mention encrypted/TLS/MQTTS. I tried providing the connection info for my Azure IoT Hub, hoping that it would auto-negotiate. It did not; I got +CME ERROR:8002.
I surmise that the hardware version I have (I get Y7080E R2212 in response to ATI) has firmware which predates MQTTS support. Version 1.00 of the MQTT(S) application note is dated 2022-11-30. It clearly states “This document applies to SIMCom Y7025 Series, Y7026 Series, Y7028 Series ,Y7012 Series, Y7080E Series”. So much for that. It looks like buying a Y7080 rather than a SIM7080 was a false economy. The trouble is the SSL config for SIM7080 looks rather complicated and doesn’t appear to have a simple “just encrypt” option without having to install certificates etc. I also have concerns about firmware version, so I don’t think just ordering a SIM7080 is the smart move either. Back to the drawing board. First idea = try to get the firmware updated. There is an application note for firmware updating and firmware release notes for Y7028… wish me luck!
Updating Firmware
The SimCom website says you need to contact technical support for a patch, which looks like it is a small “diff” and they need your current and desired firmware versions. The full version of the module, including firmware is found using:
AT+NV=GET,PRODUCTVER
I got 2212B03V01Y7080E . SimCom tech support wanted to know where I got the module from and my country, but seemed happy with my answers and eventually got back to me with what I think is a full firmware update file, for 2212B07V01Y7080E, not just a “diff”, and the comment:
Y7080E comes with GPS, and FOTA has only a few tens of K of available space. For example, B03->B05 is not enough space, so only minor upgrades can be made, such as frequency flips with minimal changes. So is there a way to upgrade B03 to B07? Yes, we provide firmware upgrade tool for upgrading. [links to download tool and firmware]
Stumbling through the documentation it looked like I needed to hold BOOT to VDD_EXT then use their tool to upload the new firmware. A close inspection of the PCB alongside the SimCom module pin-out suggested two test points, “T3” and “EXT” were what I needed, so two short “Du Pont” connecters were soldered in. Unfortunately, the tool was only partly in English, with the “download” pop-up (yes the firmware upload process is called “download”) in Chinese. Google translating the word “upgrade” showed me the correct Chinese characters to allow selection of the correct drop-down. So, I connected my usual USB-Serial adapter and … it failed. It turned out that it is NOT necessary to play about with pulling BOOT to VDD_EXT. Just connect the serial adapter and run the SimCom tool. It worked.
My firmware is now updated! And now the missing MQTT commands are available (see misadventure #1, above).
A return to MQTT looking for glory appears in another article; this one is quite long enough.