MQTT is a lightweight messaging protocol for IoT in publish/subscribe model, offering reliable real-time communication with minimal code and bandwidth. It is especially beneficial for devices with limited resources and low-bandwidth networks, making it widely adopted in IoT, mobile internet, IoV, and power industries.
Raspberry Pi is a small single-board computer based on ARM and developed by the Raspberry Pi Foundation in the United Kingdom. This board provides USB interfaces and Ethernet interfaces can connect the keyboard, mouse, and networking cable. This board has the basic functions of PC and Raspberry Pi integrates Wi-Fi, Bluetooth, and a large number of GPIO, and is widely used in teaching, family entertainment, IoT, etc.
In this project, we will use Python to write a simple MQTT client on Raspberry Pi and implement connection, subscription, messaging, and other functions between this client and MQTT Broker.
Raspberry Pi is a versatile mini-computer that can run different operating systems, including Raspberry Pi OS, Ubuntu, and Kodi. Each operating system has its own unique set of features, advantages, and recommended applications.
Raspberry Pi OS in particular, is highly recommended for beginners due to its compatibility with Raspberry Pi hardware and the pre-installed optimized software and tools. It is based on Debian Linux and customized specifically for Raspberry Pi, providing a user-friendly platform for programming, multimedia, and electronics projects.
To install Raspberry Pi OS, we advise following the official documentation's installation guide. This article uses a Raspberry Pi 4 with the Raspberry Pi OS with desktop (Debian version: 11) installed.
We will use Python as the development language for MQTT on the Raspberry Pi. With an easy-to-learn syntax and a vast range of libraries and tutorials available online, Python is an excellent choice for working with MQTT.
This project is developed using Python 3.6. Typically, Raspberry Pi already comes with Python 3 pre-installed. However, if you are unsure whether Python 3 is installed, you can verify it by using the following command:
$ python3 --version
Python 3.6.7
If the command line returns "Python 3.x.x" (where "x" indicates the version number), it means that Python 3 is already installed on your Raspberry Pi. In case it is not installed, you can use the "apt" command to install it, or you can follow the Python3 installation guidelines.
sudo apt install python3
We will use the Paho Python Client library, which offers a client class that supports MQTT v5.0, v3.1.1, and v3.1 in Python 2.7 and 3.x. In addition, it includes convenient helper functions that make publishing one-off messages to an MQTT server very simple.
Use the source code to install
git clone --depth 1 -b v1.6.1 https://github.com/eclipse/paho.mqtt.python
cd paho.mqtt.python
python3 setup.py install
Use pip3 to install
pip3 install paho-mqtt==1.6.1
Before proceeding, please ensure you have an MQTT broker to communicate and test with. There are several options for obtaining an MQTT broker:
-
Private deployment
EMQX is the most scalable open-source MQTT broker for IoT, IIoT, and connected vehicles. You can run the following Docker command to install EMQX.
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx
-
Fully managed cloud service
The fully managed cloud service is the easiest way to start an MQTT service. With EMQX Cloud, you can get started in just a few minutes and run your MQTT service in 20+ regions across AWS, Google Cloud, and Microsoft Azure, ensuring global availability and fast connectivity.
The latest edition, EMQX Cloud Serverless, provides a forever free 1M session minutes/month complimentary offering for developers to easily start their MQTT deployment within seconds.
-
Free public MQTT broker
The Free public MQTT broker is exclusively available for those who wish to learn and test the MQTT protocol. It is important to avoid using it in production environments as it may pose security risks and downtime concerns.
For this blog post, we will use the free public MQTT broker at broker.emqx.io
.
MQTT Broker Info
Server:
broker.emqx.io
TCP Port:
1883
WebSocket Port:
8083
SSL/TLS Port:
8883
Secure WebSocket Port:
8084
For more information, please check out: Free Public MQTT Broker.
Connection code
# test_connect.py
import paho.mqtt.client as mqtt
# The callback function. It will be triggered when trying to connect to the MQTT broker
# client is the client instance connected this time
# userdata is users' information, usually empty. If it is needed, you can set it through user_data_set function.
# flags save the dictionary of broker response flag.
# rc is the response code.
# Generally, we only need to pay attention to whether the response code is 0.
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected success")
else:
print(f"Connected fail with code {rc}")
client = mqtt.Client()
client.on_connect = on_connect
client.connect("broker.emqx.io", 1883, 60)
client.loop_forever()
You can save the code above as a file named "test_connect.py". To run the file, open a terminal on your Raspberry Pi and navigate to the directory where the file is located. Then enter the command below to execute the script. This will start the MQTT client and connect to the MQTT broker.
python3 test_connect.py
In the on_connect
function, we check the response code returned by the MQTT broker. If the response code is 0
, we print "Connected success" to indicate the successful connection. However, if the response code is not 0
, we need to check its meaning based on the following response code table.
0: connection succeeded
1: connection failed - incorrect protocol version
2: connection failed - invalid client identifier
3: connection failed - the broker is not available
4: connection failed - wrong username or password
5: connection failed - unauthorized
6-255: undefined
If it is other issues, you can check the network situation, or check whether `paho-mqtt` has been installed.
The MQTT protocol routes messages based on topics. Subscribers can subscribe to the topics they are interested in with the broker. When a publisher sends a message to a specific topic, the broker forwards that message to all subscribers who have subscribed to that topic.
Open any text editor and input the following code. Save the file as "subscriber.py".
# subscriber.py
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
# Subscribe, which need to put into on_connect
# If reconnect after losing the connection with the broker, it will continue to subscribe to the raspberry/topic topic
client.subscribe("raspberry/topic")
# The callback function, it will be triggered when receiving messages
def on_message(client, userdata, msg):
print(f"{msg.topic} {msg.payload}")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
# Set the will message, when the Raspberry Pi is powered off, or the network is interrupted abnormally, it will send the will message to other clients
client.will_set('raspberry/status', b'{"status": "Off"}')
# Create connection, the three parameters are broker address, broker port number, and keep-alive time respectively
client.connect("broker.emqx.io", 1883, 60)
# Set the network loop blocking, it will not actively end the program before calling disconnect() or the program crash
client.loop_forever()
The subscribe()
function enables Raspberry Pi to subscribe to a particular topic. In the code above, we use this function to subscribe to the topic raspberry/topic
and monitor any incoming messages.
Additionally, we utilize the will_set()
function to set up a will message. This feature of MQTT allows the device to send messages to a specified topic in case it is unintentionally powered off. Using this feature, we can determine whether the Raspberry Pi has been powered off or has network connectivity problems.
Open any text editor and input the following code. Save the file as "publisher.py".
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
# Send a message to the raspberry/topic every 1 second, 5 times in a row
for i in range(5):
# The four parameters are topic, sending content, QoS and whether retaining the message respectively
client.publish('raspberry/topic', payload=i, qos=0, retain=False)
print(f"send {i} to raspberry/topic")
client = mqtt.Client()
client.on_connect = on_connect
client.connect("broker.emqx.io", 1883, 60)
client.loop_forever()
The publish()
function allows for sending messages to a specific topic. In the code example above, we use this function to send messages to the topic raspberry/topic
. The QoS parameter is another feature of MQTT that defines the quality of service level for message delivery. To learn more about the QoS level, please refer to Introduction to MQTT QoS 0, 1, 2.
For more information about using Paho Client, please check out the blog How to Use MQTT in Python with Paho Client.
For conducting the following tests, we will use MQTTX. MQTTX is an elegant cross-platform MQTT 5.0 desktop client that runs on macOS, Linux, and Windows. Its user-friendly chat-style interface enables users to easily create multiple MQTT/MQTTS connections and subscribe/publish MQTT messages.
-
Running the MQTT subscription script
subscriber.py
, we will see the client successfully connected and started waiting for the publisher to publish messages.python3 subscriber.py
-
Publish a message to the "raspberry/topic" using MQTTX as the publisher.
-
You will see the messages published by MQTTX.
-
Subscribe to the
raspberry/topic
within the MQTTX client. -
Run
publish.py
in the terminal. -
In the MQTTX client, you can view the messages that have been published by the Raspberry Pi.
Next, we will test whether the will message has been set successfully.
-
Subscribe to
raspberry/status
in the MQTTX client. -
Interrupt the program or disconnect the network of the Raspberry Pi.
-
View the messages that
raspberry/status
received, in the MQTTX client.
The provided code establishes a serial connection with a Raspberry Pi, reads data from the serial port, and publishes it to an MQTT broker. It uses the serial
library to configure the serial port settings and read data, while the paho.mqtt.client
library is used to connect to the MQTT broker and publish the data. The code reads serial data in a loop, publishes it to the specified MQTT topic, and repeats this process for a defined number of iterations. Finally, it disconnects from the MQTT broker and closes the serial connection.
import time
import paho.mqtt.client as mqtt
import serial
# Establishing the connection with the serial port
ser = serial.Serial(
# Serial Port to read the data from
port='/dev/ttyAMA0', # Use `dmesg | grep tty` to find the port
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
broker_address = "broker.emqx.io"
broker_port = 1883
topic = "emqx/serial/read"
client = mqtt.Client()
client.connect(broker_address, broker_port)
# Read data from serial port and publish it to MQTT broker
for i in range(10):
data = ser.readline().decode()
client.publish(topic, data)
print("Read data {data} from serial port and publish it to MQTT broker".format(data=data))
time.sleep(1)
client.disconnect()
ser.close()
The provided code establishes a serial connection with a Raspberry Pi and listens for MQTT messages. When a message is received, it is written to the serial port. The code uses the serial
library to configure the serial port settings and write data, while the paho.mqtt.client
library is used to connect to the MQTT broker, handle MQTT message reception, and publish data to the serial port. The MQTT client is set up with the necessary callbacks, including on_connect
to subscribe to a specific MQTT topic and on_message
to handle incoming messages. Once connected, the code enters an infinite loop to continuously listen for MQTT messages and write them to the serial port.
import paho.mqtt.client as mqtt
import serial
# Establishing the connection with the serial port
ser = serial.Serial(
# Serial Port to read the data from
port='/dev/ttyAMA0', # Use `dmesg | grep tty` to find the port
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
broker_address = "broker.emqx.io"
broker_port = 1883
topic = "emqx/serial/write"
def on_connect(client, userdata, flags, rc):
print("Connected to MQTT broker")
client.subscribe(topic)
def on_message(client, userdata, msg):
payload = msg.payload.decode()
print("Received message: {payload} on topic {topic}".format(payload=payload, topic=msg.topic))
# Write data to serial port
ser.write(payload.encode())
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(broker_address, broker_port)
client.loop_forever()
In this blog, we use the Python MQTT client library paho-mqtt
to write and test the client on the Raspberry Pi. We have implemented the connection, subscription, messaging, and other functions between the client and the MQTT broker.
Great progress so far! You have learned the basics of building many exciting applications with the MQTT. For example:
- You can remotely control the Raspberry Pi from your mobile phone using MQTT messages.
- By regularly sending device data from the Raspberry Pi to the MQTT broker, you can continuously monitor and receive messages on your mobile phone.
- With Raspberry Pi accessing the MQTT broker and employing various sensors and ESP modules, you can create numerous interesting IoT applications.
Next, you can check out the MQTT Guide: Beginner to Advanced series provided by EMQ to learn about MQTT protocol features, explore more advanced applications of MQTT, and get started with MQTT application and service development.
- MQTT on ESP32: A Beginner's Guide
- A Developer's Journey with ESP32 and MQTT Broker
- A Guide on Collecting and Reporting Soil Moisture with ESP32 and Sensor through MQTT
- Using MQTT on ESP8266: A Quick Start Guide
- Remote control LED with ESP8266 and MQTT
- MicroPython MQTT Tutorial Based on Raspberry Pi
- How to Deploy an MQTT Broker on Raspberry Pi