Connecting to a MQTT Broker

You can connect your CircuitPython device to any MQTT broker of your choice. MQTT brokers generally fall in three categories: Commercial hosted (Paid), Free hosted (Adafruit IO's MQTT broker lives on servers owned by Adafruit - we have a free tier), or Free and self-hosted (bring your own server!).

Commercial Brokers

These large-scale commercial (paid) brokers come with a higher data-rate speed and usually include device management features. 

These brokers can also connect to CircuitPython devices running MiniMQTT. The primary advantage of using one of these services over your own broker or Adafruit IO is integration with a larger suite of cloud-hosted tools. For example, if you are sending data to an Azure IoT Hub via MQTT, you could visualize sensor data using PowerBI or run machine learning models on it from Azure. 

Self-Hosted Brokers

There are plenty of tools out there to host your own MQTT broker. We like Eclipse's Mosquitto - it's an open-source broker which implements the MQTT protocol. There are images for Mac, Linux, Windows and Raspberry Pi.

Secrets File Setup

While you created a secrets file and connected to the Internet in the previous step, you'll need to edit the secrets.py file to include information about your MQTT broker.

Add the following code to your secrets.py file, replacing _your_broker_url_or_ip with the URL or IP Address of the MQTT broker you'd like to connect to.

If your MQTT broker requires authentication, replace _your_mqtt_broker_username_ with the username you use to log into the broker.

Then, replace _your_mqtt_broker_password_ with the password you use to authenticate your username with the broker.

If your MQTT broker does not require authentication, you may remove  these fields.

Download: file
secrets = {
    'ssid' : '_your_wifi_ssid_',
    'password' : '_your_wifi_password_',
    'broker' : '_your_mqtt_broker_url_or_ip',
    'user' : '_your_mqtt_broker_username_',
    'pass' : '_your_mqtt_broker_password_'
    }

Code

Copy the following code to your code.py file on your microcontroller:

import board
import busio
from digitalio import DigitalInOut
import neopixel
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket

from adafruit_minimqtt import MQTT

### WiFi ###

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)

# If you have an externally connected ESP32:
# esp32_cs = DigitalInOut(board.D9)
# esp32_ready = DigitalInOut(board.D10)
# esp32_reset = DigitalInOut(board.D5)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
"""Use below for Most Boards"""
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards
"""Uncomment below for ItsyBitsy M4"""
# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
# Uncomment below for an externally defined RGB LED
# import adafruit_rgbled
# from adafruit_esp32spi import PWMOut
# RED_LED = PWMOut.PWMOut(esp, 26)
# GREEN_LED = PWMOut.PWMOut(esp, 27)
# BLUE_LED = PWMOut.PWMOut(esp, 25)
# status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)

### Topic Setup ###

# MQTT Topic
# Use this topic if you'd like to connect to a standard MQTT broker
mqtt_topic = 'test/topic'

# Adafruit IO-style Topic
# Use this topic if you'd like to connect to io.adafruit.com
# mqtt_topic = 'aio_user/feeds/temperature'

### Code ###

# Define callback methods which are called when events occur
# pylint: disable=unused-argument, redefined-outer-name
def connect(client, userdata, flags, rc):
    # This function will be called when the client is connected
    # successfully to the broker.
    print('Connected to MQTT Broker!')
    print('Flags: {0}\n RC: {1}'.format(flags, rc))

def disconnect(client, userdata, rc):
    # This method is called when the client disconnects
    # from the broker.
    print('Disconnected from MQTT Broker!')

def subscribe(client, userdata, topic, granted_qos):
    # This method is called when the client subscribes to a new feed.
    print('Subscribed to {0} with QOS level {1}'.format(topic, granted_qos))

def unsubscribe(client, userdata, topic, pid):
    # This method is called when the client unsubscribes from a feed.
    print('Unsubscribed from {0} with PID {1}'.format(topic, pid))

def publish(client, userdata, topic, pid):
    # This method is called when the client publishes data to a feed.
    print('Published to {0} with PID {1}'.format(topic, pid))

# Connect to WiFi
wifi.connect()

# Set up a MiniMQTT Client
client =  MQTT(socket,
               broker = secrets['broker'],
               username = secrets['user'],
               password = secrets['pass'],
               network_manager = wifi)

# Connect callback handlers to client
client.on_connect = connect
client.on_disconnect = disconnect
client.on_subscribe = subscribe
client.on_unsubscribe = unsubscribe
client.on_publish = publish

print('Attempting to connect to %s'%client.broker)
client.connect()

print('Subscribing to %s'%mqtt_topic)
client.subscribe(mqtt_topic)

print('Publishing to %s'%mqtt_topic)
client.publish(mqtt_topic, 'Hello Broker!')

print('Unsubscribing from %s'%mqtt_topic)
client.unsubscribe(mqtt_topic)

print('Disconnecting from %s'%client.broker)
client.disconnect()

Before running your code, you'll need to make a few small changes for your configuration.

First, replace mqtt_topic with the mqtt topic you'd like to subscribe to. For example, if you are building a weather station and want to subscribe to its temperature.

Change the mqtt_topic from

mqtt_topic = 'test/topic'

to

mqtt_topic= 'weatherstation/temperature'

MiniMQTT Port Configuration

By default, MiniMQTT connects to port 8883 (Secure/SSL). If you'd like to connect to a different port on the broker, use the following code to initialize the client.

client =  MQTT(socket,
               broker = secrets['broker'],
port = 1234, username = secrets['user'], password = secrets['pass'], network_manager = wifi)

You can toggle between an insecure (port 1883) and secure (port 8883) connection by setting the is_ssl parameter to True or False

client =  MQTT(socket,
               broker = secrets['broker'],
               username = secrets['user'],
               password = secrets['pass'],
is_ssl = False, network_manager = wifi)

Code Usage

After setting up your topic and broker configuration, it's time to connect. Save the code.py file and open the serial monitor.

The client attempts to connect to the MQTT broker you specified.

Download: file
Attempting to connect to io.adafruit.com
Connected to MQTT Broker!
Flags: 0
RC: 0

The client subscribes to the mqtt_topic you specified.

Download: file
Subscribed to user/topic with QOS level 1

And notifies you that it subscribed to mqtt_topic with a quality of service level of 1. You can set the quality of service level by modifying the call to subscribe (read the docs about this method here).

The client publishes the string Hello Broker to the mqtt_topic.

Download: file
Published to user/topic with PID 11

The client unsubscribes from the mqtt_topic.

Download: file
Unsubscribed from user/topic with PID 22

Finally, the client disconnects from the MQTT broker

Download: file
Disconnected from MQTT Broker!

The code tests all the primary methods of the MiniMQTT client. We'll walk through the code to understand how this example works.

This guide was first published on Jul 23, 2019. It was last updated on Jul 23, 2019. This page (Connecting to a MQTT Broker) was last updated on Dec 05, 2019.