MQTT is a communication protocol widely used in Home Automation and IoT applications to connect multiple devices. In this tutorial, you’ll learn how to choose and set up an MQTT broker and how to publish and subscribe to MQTT messages with the Raspberry Pi Pico.
Installing MQTT MicroPython Modules #
To write code in MicroPython to use the MQTT communication protocol, we’ll use two MQTT modules: umqtt.simply.py, and umqtt.robust.py.
You can download the files from the repository:
https://github.com/micropython/micropython-lib/blob/master/micropython/umqtt.simple/umqtt/simple.py
https://github.com/micropython/micropython-lib/blob/master/micropython/umqtt.robust/umqtt/robust.py
micropython library – umqtt (2024-09-13).zip #
Follow the next steps to upload the modules to your Raspberry Pi Pico.
With the Raspberry Pi Pico connected to your computer and with a connection established with Thonny IDE, go to View > Files.
create a folder and upload the files into it, you should have the umqtt folder with the simple.py and robust.py files inside:
Creating a Configuration File #
We’ll create a configuration file to save the SSID, password, and your MQTT broker details: URL, username, and password.
Create a new file called config.py on Thonny IDE and copy the following code:
wifi_ssid = 'REPLACE_WITH_YOUR_SSID'
wifi_password = 'REPLACE_WITH_YOUR_PASSWORD'
mqtt_server = b'MQTT_BROKER_URL'
mqtt_username = b'BROKER_USERNAME'
mqtt_password = b'BROKER_PASSWORD'
Replace the variables with your own details.
If you’re using a local Mosquitto MQTT broker, you should pass the broker IP address without the port. For example:
mqtt_server = b'192.168.1.79'
Publishing MQTT Messages #
The following code creates a counter and will publish it on a MQTT broker with the topic: pico/counter
import machine
import time
import network
import ubinascii
from umqtt.simple import MQTTClient
import config
# MQTT Parameters
MQTT_SERVER = config.mqtt_server
MQTT_PORT = 0
MQTT_USER = config.mqtt_username
MQTT_PASSWORD = config.mqtt_password
MQTT_CLIENT_ID = b"raspberrypi_picow"
MQTT_KEEPALIVE = 7200
MQTT_SSL = False # set to False if using local Mosquitto MQTT broker
onboard_led = machine.Pin("LED", machine.Pin.OUT)
onboard_led.value(0) # LED off
def initialize_wifi(ssid, password):
# Connect to WiFi
print('Connecting to WiFi Network Name:', ssid)
wlan = network.WLAN(network.STA_IF)
wlan.config(hostname="RPI_PICOW")
wlan.active(True) # power up the WiFi chip
print('Waiting for wifi chip to power up...')
time.sleep(3) # wait three seconds for the chip to power up and initialize
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
time.sleep(1)
onboard_led.value(1)
print("Success! We have connected to your access point!")
print("Try to ping the device at", wlan.ifconfig()[0])
print("- subnetmask:", wlan.ifconfig()[1])
print("- gateway:", wlan.ifconfig()[2])
mac = ubinascii.hexlify(wlan.config('mac'),':').decode()
print("- MAC address:", mac)
return True
def connect_mqtt():
try:
client = MQTTClient(client_id=MQTT_CLIENT_ID,
server=MQTT_SERVER,
port=MQTT_PORT,
user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=MQTT_KEEPALIVE,
ssl=MQTT_SSL)
client.connect()
return client
except Exception as e:
print('Error connecting to MQTT:', e)
raise # Re-raise the exception to see the full traceback
try:
if not initialize_wifi(config.wifi_ssid, config.wifi_password):
print('Error connecting to the network... exiting program!')
else:
# Connect to MQTT broker, start MQTT client
client = connect_mqtt()
counter = 0
while True:
# Publish as MQTT payload
client.publish("pico/counter", str(counter))
print("MQTT Publish Done, pico/counter:", counter)
counter += 1 # Incrment counter
time.sleep(2) # Delay 2 seconds
except Exception as e:
print('Error:', e)
Output:
Example in node-Red:
Recieving MQTT Messages #
You can also subscribe to a topic with this example you can post ON of OFF to pico/led to toggle the onboard LED
import machine
import time
import network
import ubinascii
from umqtt.simple import MQTTClient
import config
# MQTT Parameters
MQTT_SERVER = config.mqtt_server
MQTT_PORT = 1883
MQTT_USER = config.mqtt_username
MQTT_PASSWORD = config.mqtt_password
MQTT_CLIENT_ID = b"raspberrypi_picow"
MQTT_KEEPALIVE = 7200
MQTT_SSL = False # set to False if using local Mosquitto MQTT broker
onboard_led = machine.Pin("LED", machine.Pin.OUT)
onboard_led.value(0) # LED off
def initialize_wifi(ssid, password):
# Connect to WiFi
print('Connecting to WiFi Network Name:', ssid)
wlan = network.WLAN(network.STA_IF)
wlan.config(hostname="RPI_PICOW")
wlan.active(True) # power up the WiFi chip
print('Waiting for wifi chip to power up...')
time.sleep(3) # wait three seconds for the chip to power up and initialize
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
time.sleep(1)
onboard_led.value(1)
print("Success! We have connected to your access point!")
print("Try to ping the device at", wlan.ifconfig()[0])
print("- subnetmask:", wlan.ifconfig()[1])
print("- gateway:", wlan.ifconfig()[2])
mac = ubinascii.hexlify(wlan.config('mac'),':').decode()
print("- MAC address:", mac)
return True
# Callback function that runs when you receive a message on subscribed topic
def mqtt_subscription_callback(topic, message):
# Perform desired actions based on the subscribed topic and response
print('Received message on topic:', topic)
# Check the content of the received message
if topic == b'pico/led':
print('Response:', message)
if message == b'ON':
print('Turning LED ON')
onboard_led.value(1) # Turn LED ON
elif message == b'OFF':
print('Turning LED OFF')
onboard_led.value(0) # Turn LED OFF
else:
print('Unknown command')
else:
print('MQTT Topic does not exist!')
def connect_mqtt():
try:
mqtt_client = MQTTClient(client_id=MQTT_CLIENT_ID,
server=MQTT_SERVER,
port=MQTT_PORT,
user=MQTT_USER,
password=MQTT_PASSWORD,
keepalive=MQTT_KEEPALIVE,
ssl=MQTT_SSL)
mqtt_client.set_callback(mqtt_subscription_callback) # Callback function for subscribed topics
mqtt_client.connect()
return mqtt_client
except Exception as e:
print('Error connecting to MQTT:', e)
raise # Re-raise the exception to see the full traceback
try:
if not initialize_wifi(config.wifi_ssid, config.wifi_password):
print('Error connecting to the network... exiting program!')
else:
# Connect to MQTT broker, start MQTT client
mqtt_client = connect_mqtt()
mqtt_client.subscribe("pico/led") # Subscription topic
counter = 0
while True:
# Publish as MQTT payload
mqtt_client.publish("pico/counter", str(counter))
print("MQTT Publish Done, pico/counter:", counter)
counter += 1 # Incrment counter
mqtt_client.check_msg()
time.sleep(.5) # Delay 2 seconds
except Exception as e:
print('Error:', e)
Output
Node-red example
Node-Red JSON
[
{
"id": "d5151a6c44cb22da",
"type": "mqtt in",
"z": "662968eb7c1fe279",
"name": "",
"topic": "pico/counter",
"qos": "2",
"datatype": "auto-detect",
"broker": "c24b706d2522fd62",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 390,
"y": 300,
"wires": [
[
"15a850a8fe47803b"
]
]
},
{
"id": "15a850a8fe47803b",
"type": "debug",
"z": "662968eb7c1fe279",
"name": "debug 1",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "payload",
"statusType": "auto",
"x": 560,
"y": 300,
"wires": []
},
{
"id": "ddb7b82df4d93566",
"type": "mqtt out",
"z": "662968eb7c1fe279",
"name": "pico/led",
"topic": "pico/led",
"qos": "0",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "d9b89792031d1673",
"x": 560,
"y": 420,
"wires": []
},
{
"id": "cac9a0e2f8a31361",
"type": "inject",
"z": "662968eb7c1fe279",
"name": "LED ON",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "ON",
"payloadType": "str",
"x": 400,
"y": 380,
"wires": [
[
"ddb7b82df4d93566"
]
]
},
{
"id": "e92b26d7f46b4554",
"type": "inject",
"z": "662968eb7c1fe279",
"name": "LED OFF",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "OFF",
"payloadType": "str",
"x": 400,
"y": 440,
"wires": [
[
"ddb7b82df4d93566"
]
]
},
{
"id": "c24b706d2522fd62",
"type": "mqtt-broker",
"name": "",
"broker": "localhost",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "d9b89792031d1673",
"type": "mqtt-broker",
"name": "",
"broker": "192.168.2.30",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
}
]