Introduction to MQTT and How to Transmit Data via MQTT

I. Introduction

MQTT is short for Message Queuing Telemetry Transport. It is a lightweight IoT communication protocol based on the publish/subscribe pattern. It has the following characteristics:

  • Easy to Use: The MQTT protocol specification is simple, making it easy to learn and use.
  • High Reliability: MQTT uses the TCP protocol for transmission, ensuring high reliability.
  • Low Latency: The publish/subscribe pattern employed by MQTT reduces message delivery latency.

In robot applications, MQTT can be used in the following scenarios:

  • Sensor Data Upload: MQTT can be used to upload sensor data to the cloud or other robot systems.
  • Robot Control: MQTT enables remote control of robots.
  • Robot Collaboration: MQTT facilitates collaboration among multiple robots.

The MQTT protocol consists of three main components:

  • Client: An MQTT client is an application that sends and receives messages.
  • Server: The MQTT server is an application that processes messages.
  • Topic: A topic is the message path used to distinguish different types of messages.

The MQTT protocol communicates using the publish/subscribe pattern. Publishers post messages to topics, and subscribers subscribe to topics and receive the messages published by publishers.
This is very similar to topics in ROS2.

1. MQTT Client

An MQTT client can be any type of application, including embedded devices, PC applications, and web applications. An MQTT client needs to implement three main functions of the MQTT protocol:

  • Connect: The client connects to the MQTT server.
  • Publish: The client publishes messages to a topic.
  • Subscribe: The client subscribes to a topic and receives messages published by publishers.

2. MQTT Server

The MQTT server is an application running the MQTT protocol. The MQTT server needs to implement three main functions of the MQTT protocol:

  • Connect: The server accepts connection requests from clients.
  • Publish: The server delivers messages published by publishers to subscribers.
  • Subscribe: The server stores subscribers’ subscription information.

3. MQTT Topic

An MQTT topic is the message path used to distinguish different types of messages. The format of a topic is:

1
/topic/[topic_name]

where topic_name is the topic name. The topic name can contain letters, numbers, underscores, and dots.

4. MQTT Message

An MQTT message consists of two parts:

  • Header: The header contains information such as the message identifier, topic, and QoS.
  • Data: The data is the content of the message.

QoS is the Quality of Service level, which controls the reliability of the message. There are three QoS levels:

  • 0: At most once delivery.
  • 1: At least once delivery.
  • 2: Exactly once delivery.

II. How to Deploy an MQTT Service

1. Which MQTT Implementation to Choose

From the previous introduction, we know that to use MQTT, a server is required. This server can either be self - deployed or use the services provided by public clouds.

For now, I choose to deploy a local service. However, for stability and network considerations, I may choose to use Alibaba Cloud’s MQTT service in the future.

As mentioned earlier, MQTT is a protocol, and there are many specific implementations. I choose to use Mosquitto, which is maintained by the Eclipse Foundation and implements MQTT protocol versions 5, 3.1, and 3.1.1.

Here are some advantages of using Mosquitto:

  1. Lightweight: Mosquitto is very compact and has low system resource requirements, allowing it to run on various devices, including embedded devices.
  2. Cross - platform: Whether it’s Linux, Windows, MacOS, or even more operating systems, Mosquitto is well - supported.
  3. High Stability: Mosquitto has been around for a long time and is widely used in many production environments, and its stability has been proven.
  4. Active Community: Mosquitto is maintained by the Eclipse Foundation and has an active developer and user community. This means that when you encounter problems, many people may be able to offer help.
  5. Optimized for IoT: The MQTT protocol itself is designed for low - power and unreliable networks. As an MQTT implementation, Mosquitto also performs well in IoT solutions.
  6. Powerful Security Mechanisms: Mosquitto supports SSL/TLS and has an ACL (Access Control Lists) function to help you manage who can publish or subscribe to specific topics.

Surprisingly, RabbitMQ also supports the MQTT protocol, and the configuration is simple. It’s just that this function is not enabled by default. I may give it a try in the future. Developers in the Internet industry should be more familiar with RabbitMQ.

2. Deployment and Configuration Process

  1. Installation
1
sudo apt install mosquitto
  1. Configuration
1
2
3
4
5
6
7
# Create a configuration file
vim /etc/mosquitto/mosquitto.conf
# Fill in the following content
# Port
listener 1883
# Username and password
allow_anonymous true

Note: For local testing convenience, I allow anonymous access here. However, this should not be done in actual development applications.

  1. Start
1
sudo systemctl start mosquitto

So far, a simple MQTT server has been set up.

Using MQTT for Data Transmission

In ROS, there are dedicated tools to help with this step. However, in ROS2, there aren’t any yet. But from what I’ve seen on the forum, people recommend using code for data transmission.

I use the Python paho package. First, it needs to be installed.

1
pip install paho

Here, I’ll post two pieces of code, one for the publisher and the other for the subscriber.

1. publisher

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import time
import paho.mqtt.client as mqtt


class Publisher:
def __init__(self, host="127.0.0.1", port=1883, topic="test_channel"):
self.host = host
self.port = port
self.topic = topic
self.client = mqtt.Client()

self.client.on_connect = self.on_connect
self.client.on_publish = self.on_publish

def on_connect(self, client, userdata, flags, rc):
print("Connected with result code "+str(rc))

def on_publish(self, client, userdata, mid):
print("Message Published ...")

def start(self, msg="Hello MQTT", times=10, delay=1):
self.client.connect(self.host, self.port, 60)
self.client.loop_start()

for i in range(times):
time.sleep(delay)
self.client.publish(self.topic, f"{msg} {i}")


if __name__ == "__main__":
publisher = Publisher()
publisher.start()

2. subscriber

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import paho.mqtt.client as mqtt


class Subscriber:
def __init__(self, host="127.0.0.1", port=1883, topic="test_channel"):
self.host = host
self.port = port
self.topic = topic
self.msg_count = 0
self.client = mqtt.Client()

self.client.on_connect = self.on_connect
self.client.on_message = self.on_message

def on_connect(self, client, userdata, flags, rc):
print("Connected with result code "+str(rc))
self.client.subscribe(self.topic)

def on_message(self, client, userdata, msg):
self.msg_count += 1
print(f"Message {self.msg_count}: {msg.topic} {str(msg.payload)}")

def start(self):
self.client.connect(self.host, self.port, 60)
self.client.loop_forever()


if __name__ == "__main__":
subscriber = Subscriber()
subscriber.start()

These two scripts can be run on the same machine as Mosquitto. Otherwise, you need to modify the host in the code to the actual IP address of Mosquitto and ensure that there are no network restrictions.

When testing, run the subscriber first, and then the publisher. Otherwise, the subscriber may not receive data.