Using MQTT with the MKR GSM 1400
Learn how to use the MQTT protocol to send data over GSM (Global System for Mobile communication)
Introduction
In this tutorial, we will create a setup that allows a MKR GSM 1400 board to publish and subscribe to topics, using MQTT (Message Queuing Telemetry Transport). For simplicity, we will use the same device to both publish and subscribe to the same topic.
Goals
The goals of this project are:
- Connect to the GSM network.
- Connect to a broker (shiftr.io)
- Publish a topic using MQTT.
- Subscribe to the same topic.
- Print the results in the Serial Monitor.
Hardware & Software Needed
- Arduino IDE (online or offline).
- MKRGSM library installed.
- MQTT library installed.
- Arduino MKR GSM 1400.
- Antenna.
- SIM card from an operator in your country.
Message Queuing Telemetry Transport (MQTT)
The MQTT protocol was first introduced in 1999, as a light-weight publish and subscribe system. It is particularly useful for devices with low-bandwidth, where we can send commands, sensor values or messages over the Internet with little effort.
A basic explanation on how it works is that a node, for example and Arduino with a Wi-Fi module, sends a payload to a broker. A broker is a kind of "middle-point" server, that essentially stores payloads sent to it, in something called topics. A topic, is a definition of what type of data it contains, it could for example be "basement humidity" or "living room temperature". Another node can then subscribe to this information, from the broker, and voilà, data has been moved from Node A to Node B over the Internet.
There are several different ways this can be practiced, with many different layers of security depending on what type of broker and setup we use. For example, if we are dealing with non-sensitive data, such as the temperature of a specific location, we are not too concerned on who might get access to it. But there's cases where data needs to be protected, for example in Social Media messaging services.
One way to protect the data, is to for example use a token, something that is quite common when working with various IoT services. For instance, if we are publishing something to a broker, anyone who has the URL, e.g. randombroker.org/randomtopic can subscribe to it. But if we added a unique token on both sides, they wouldn't. These tokens could for example be Z6ACuLwr5T, which is not exactly something easy to guess.
MQTT is quite the interesting topic, and if you wish to read more about it, check out the links below:
- mqtt.org - all you need to know about MQTT.
- Mosquito.org - an MQTT broker.
- Inductive automation - what is MQTT?
- Randomnerdtutorials - what is MQTT and how it works.
Circuit
Creating the Program
We will now get to the programming part of this tutorial.
1. First, let's make sure we have the drivers installed. If we are using the Web Editor, we do not need to install anything. If we are using an offline editor, we need to install it manually. This can be done by navigating to Tools > Board > Board Manager.... Here we need to look for the Arduino SAMD boards (32-bits Arm® Cortex®-M0+) and install it.
2. Now, we need to install the libraries needed. If we are using the Web Editor, there is no need to install anything. If we are using an offline editor, simply go to Tools > Manage libraries.., and search for MKRGSM and install it.
3. We will also need to install the MQTT library, by Joel Gaehwiler.
Note: there are several MQTT libraries, make sure you install the right one! The image below highlights the library that needs to be installed.
4. We can now take a look at some of the core functions of this sketch:
- stores the pin number of your card.pin[]
- stores the APN of your operator.apn[]
- stores the login to your operator (typically a blank field).login[]
- stores the password to your operator (typically a blank field).password[]
- base class for all GSM based functions.GSM gsmAccess
- creates a GSM client.GSMClient net
- base class for GPRS functions, e.g. Internet, server behaviors.GPRS gprs
- creates a client that can connect to a broker, and publish/subscribe to topics and messages.MQTTClient client
- connects to the broker.client.begin(broker, net)
- publishes a topic with a message.client.publish(topic, message)
- subscribes to a topic.client.subscribe(topic)
The sketch can be found in the snippet below. Upload the sketch to the board.
1#include <MKRGSM.h>2#include <MQTT.h>3
4const char pin[] = "";5const char apn[] = "apn";6const char login[] = "login";7const char password[] = "password";8
9GSMClient net;10GPRS gprs;11GSM gsmAccess;12MQTTClient client;13
14unsigned long lastMillis = 0;15
16void connect() {17 // connection state18 bool connected = false;19
20 Serial.print("connecting to cellular network ...");21
22 // After starting the modem with gsmAccess.begin()23 // attach to the GPRS network with the APN, login and password24 while (!connected) {25 if ((gsmAccess.begin(pin) == GSM_READY) &&26 (gprs.attachGPRS(apn, login, password) == GPRS_READY)) {27 connected = true;28 } else {29 Serial.print(".");30 delay(1000);31 }32 }33
34 Serial.print("\nconnecting...");35 while (!client.connect("arduino", "try", "try")) {36 Serial.print(".");37 delay(1000);38 }39
40 Serial.println("\nconnected!");41
42 client.subscribe("/hello");43 // client.unsubscribe("/hello");44}45
46void messageReceived(String &topic, String &payload) {47 Serial.println("incoming: " + topic + " - " + payload);48
49 // Note: Do not use the client in the callback to publish, subscribe or50 // unsubscribe as it may cause deadlocks when other things arrive while51 // sending and receiving acknowledgments. Instead, change a global variable,52 // or push to a queue and handle it in the loop after calling `client.loop()`.53}54
55void setup() {56 Serial.begin(115200);57
58 // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported59 // by Arduino. You need to set the IP address directly.60 client.begin("broker.shiftr.io", net);61 client.onMessage(messageReceived);62
63 connect();64}65
66void loop() {67 client.loop();68
69 if (!client.connected()) {70 connect();71 }72
73 // publish a message roughly every second.74 if (millis() - lastMillis > 1000) {75 lastMillis = millis();76 client.publish("/hello", "world");77 }78}
Testing It Out
After you have uploaded the code to the board, open the Serial Monitor to initialize the program. If it is successful, after 10 seconds or so, it will print
connected
, followed by the message: incoming: /hello - world
. This means that we have successfully published, and subscribed to a topic, using the shiftr.io broker. Right now our message is very general, and there is a good chance that someone is using this very same topic and message, but we can actually go and see a live visualization of the messages that goes through the broker. To see this visualization, go to shiftr.io/try, and start looking for your message!
We can now start experimenting with the code, to make it a bit more interesting. Some changes we can make include:
Changing the topic (hello) and message (world). This can be done by editing the commands
andclient.subscribe("/hello")
.client.publish("/hello", "world")
Create more topics to publish and subscribe to. Just duplicate the same two commands as above, but create unique topics, such as "pinkfoxtail" or "funkybanana". This will further decrease the likelihood that someone is using the same topics!
Troubleshoot
If the code is not working, there are some common issues we can troubleshoot:
- We have not installed the MKRGSM library.
- We have not installed the MQTT library.
- We have entered the wrong pin number.
- We have entered the wrong APN (access point name, check the operator of the SIM card).
- We are out of coverage (no signal).
- SIM card may not be activated.
Conclusion
In this tutorial, we have combined the use of the GSM technology, with the MQTT communication protocol. Both are incredibly useful and popular in IoT projects, as they consume small amounts of data, are easily customizable and have great coverage all over the world.
Feel free to explore the MKRGSM library further, and try out some of the many cool functions in this library. You can also check out the MQTT repository on GitHub.
Special thanks to Joel Gaehwiler for developing the MQTT library and to everyone who contributed to this library.
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.