IOT 101: From hardware to cloud — Part III

Cloud — Getting started with MQTT

Leonardo Cavagnis
7 min readJan 7, 2021

IOT is like teenage sex: everyone talks about it, nobody really knows how to do it.

In the Part II of this series, I’ve explained how to build an Android app that uses BLE (Bluetooth Low Energy) to communicate with a Smart Thermostat.

Smart Thermostat is an IOT device based on Arduino hardware platform. Read Part I for more details about it.

In this article, I will describe how to send temperature data to a Cloud system and display them in an intuitive way on a web dashboard.

This project will be finished after having integrated (within the Android app developed in part II) the server communication using MQTT protocol.

What is MQTT?

MQTT, acronym of Message Queuing Telemetry Transport, is a messaging transport protocol widely used in the Internet Of Thing (IOT) context.
Compared to its rival HTTP, MQTT is simpler, smaller and more secure.

MQTT in a nutshell

MQTT is mainly based on two architectures:

  • Publish/Subscribe architecture
    Publishers (the senders) don’t transmit messages directly to subscribers (the receivers), they classify published messages into “topics” ignoring whether there are subscribers receiving the message or not.
  • Client/Server architecture
    A client (MQTT client) connects to a server (MQTT Broker) in order to use of a service (MQTT protocol).

For further details, check out my article “Android and MQTT: A Simple guide”.

MQTT Broker: Adafruit IO

An MQTT Broker is a server which provides the MQTT service to MQTT Clients that are allowed to publish and/or subscribe on one or many topics.
There are several websites offering the MQTT broker cloud service. For this project, I chose Adafruit.IO.

Adafruit.IO is a cloud service which provides a large number of resources for Internet Of Things projects:

  • MQTT service
  • HTTP/REST service
  • Dashboard
  • Arduino library
  • and more…
Example of Adrafruit IO Dashboard

Smart Thermostat App: MQTT Integration

As described in the previous part, the Smart Thermostat app (based on BLE connectivity) is divided in two screens:

  • Scan fragment
    It shows the result of BLE Scanner by displaying all the nearby Smart Thermostat devices found.
  • Connect fragment
    It allows to interact with the connected Smart Thermostat device.

In the Connect fragment, add the MQTT Broker interaction by creating two buttons: MQTT Connect and MQTT Disconnect.
By clicking on the MQTT Connect button, the app will start to send the read temperature to the broker. To stop MQTT communication, tap on the MQTT Disconnect button.

Below, the new Connect fragment:

Android MQTT library

MQTT interaction in Android is carried out with the MQTTClient library.

MQTTClient is an Eclipse Paho Library wrapper which implements the main functionalities of the MQTT transport protocol.

Let’s start to play: Connect to the Broker

Before starting to develop the Android app, you need to create an MQTT Broker instance on Adafruit IO website.
To do this, follow below steps:

  • A window will appear displaying your Adafruit IO Key. This key is private (…don’t share it with anyone!). They are the credentials to access your private MQTT Broker.

In addition to the credentials, you also need to know the MQTT broker host link details. You can find this information in the Adafruit API Documentation.

Now that we have everything we need to connect to the Broker, let’s start the connection procedure.

When the Connect fragment is created in the Android app, an MQTTClient object will be instantiated:

const val MQTT_SERVER_URI           = "ssl://io.adafruit.com:8883"
const val MQTT_CLIENT_ID = ""

private lateinit var mqttClient : MQTTClient

// Open MQTT Broker communication
mqttClient = MQTTClient(context, MQTT_SERVER_URI, MQTT_CLIENT_ID)

by clicking on the MQTT Connect button, the connect() function will be called:

const val MQTT_USERNAME             = "Your Adafruit IO Username"
const val MQTT_PWD = "Your Adafruit IO Active Key"
// MQTT Connect button
view.findViewById<Button(R.id.button_mqtt_connect)
.setOnClickListener {
// Connect and login to MQTT Broker
mqttClient.connect(
MQTT_USERNAME,
MQTT_PWD,
object : IMqttActionListener {
override fun
onSuccess(asyncActionToken: IMqttToken?) {
//...
}

override fun
onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
//...
}
},
object : MqttCallback {
override fun
messageArrived(topic: String?, message: MqttMessage?) {
//...
}

override fun
connectionLost(cause: Throwable?) {
//...
}

override fun
deliveryComplete(token: IMqttDeliveryToken?) {
//...
}
})
}

Send temperature data to Broker

As mentioned in the previous article, by clicking on the Enable Notify button, the app will start to observe the temperature variations sent through BLE by the SmartThermostat device.
In this article, we’ll do a little step ahead: we’ll communicate temperature changes to a cloud system in order to log and plot them on a graph.

Temperature data, sent to MQTT Broker, will be collected in an MQTT Topic.
In Adafruit IO platform, you need to create a topic before using it.
Generally this is not true because an MQTT Topic, by definition, can be used without being already created.

To create a topic on Adafruit IO:

  • Login to website
  • Click on “Feeds section
  • Click on “+ New group” to create a group of topics (e.g., smarthermostat)
  • Click on “+ New Feed” to create a topic (e.g., temperature)
  • The address of new created topic is:
    <username>/feeds/<groupname>.<feedname>
    (e.g., <username>/feeds/smartthermostat.temperature)

In MQTT terms, the action of write a data in a topic is called: publishing.
Every time a new temperature data is ready on Smart Thermostat device, the app will publish the new value on topic:

const val MQTT_TEMPERATURE_TOPIC =
"<username>/feeds/smartthermostat.temperature"

by calling the publish() function:

private fun mqttPublish(temperature: Float?) {
if (mqttClient.isConnected()) {
mqttClient.publish(
MQTT_TEMPERATURE_TOPIC,
temperature.toString(),
1,
false,
object : IMqttActionListener {
override fun onSuccess
(asyncActionToken: IMqttToken?) {
//...
}
override fun onFailure
(asyncActionToken: IMqttToken?, exception: Throwable?) {
//...
}
})
}
}

Disconnect from the broker

To stop the communication with the broker, you click on MQTT Disconnect button. The disconnect() function will carry out the MQTT disconnection procedure. Below the code snippet.

// MQTT Disconnect button
view.findViewById<Button(R.id.button_mqtt_disconnect)
.setOnClickListener {
if (mqttClient.isConnected()) {
// Disconnect from MQTT Broker
mqttClient.disconnect(object : IMqttActionListener {
override fun
onSuccess(asyncActionToken: IMqttToken?) {
//...
}

override fun
onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
//...
}
})
}
}

Dashboard: Let’s show real-time data

I chose Adafruit IO mainly because of the variety of nice dashboards offered.

To create a dashboard on Adafruit IO:

  • Login to website
  • Click on “Dashboards section
  • Click on “+ New Dashboard” and type a name
    (e.g., SmartThermostat_Dashboard)
  • …your dashboard is ready to be customized!

After creating the “SmartThermostat_Dashboard” dashboard, click on it, go to the dashboard settings and click on “+ Create New Block”.

There are a lot of cool and useful elements, we’ll use the “Line Chart” block to show temperature data trend.

In the “Line Chart” block creation tutorial, choose the topic temperature inside smartthermostat group.

Now your dashboard is ready to plot temperature data!

MQTT and Arduino: Hardware-to-Cloud

MQTT is a lightweight protocol widely used for devices with limited resources.

SmartThermostat is a device that can be considered “limited resources device” because it is built with the Arduino hardware platform, therefore you can develop the entire MQTT communication on the Arduino without using a mobile phone as gateway.

In this project, we have used the Arduino Nano 33 BLE Sense.
This Arduino board is unable to directly connect to the internet because it is not equipped with a Wi-Fi or Cellular antenna. To do this, for example, you need to connect to the board an external Wi-Fi antenna (e.g., Arduino Wi-Fi shield).

For MQTT implementation on Arduino, there are several libraries available on the Arduino library manager… Check them out!

…and that’s all!

Our adventure is finished!
You can use this experiment as a starting point for your next IOT project.
If you need support or you find problems with the code, use comments or open an issue in Github.

Below, the previous articles:

Here, you can find the final version of the Smart Thermostat Android app! It includes BLE and MQTT communication described in this article.

--

--

Leonardo Cavagnis

Passionate Embedded Software Engineer, IOT Enthusiast and Open source addicted. Proudly FW Dev @ Arduino