Sending data over MQTT#
MQTT (Message Queuing Telemetry Transport) is a protocol that is widely used to send messages from sensors to be logged. We will demonstrate how to connect a Pico to a MQTT broker.
Requirements
A Pico
A Wifi adapator (we are using a Pico W which has built in Wifi)
Set-up#
Since the Wifi module is built in - we don’t need to worry about wiring anything to the Pico W.
The only step we need to first take is to create a settings.toml
file in the CIRCUITPY drive. This is a type of text file which will hold all our sensitive network information separate to the main code.py
file.
The information that we will hold here is your WiFi’s SSID (its name) and password, as well as your Raspberry Pi’s IP address.
WIFI_SSID = "___" # Fill in with your WiFi network's name
WIFI_PASSWORD = "___" # Fill in with your WiFi network's password
IP_ADDRESS = "___" # Fill in with your Raspberry Pi's password
MQTT_PORT = ___ # Fill in the port you are connecting over
MQTT_USERNAME = "" # User name for connecting to MQTT Broker
MQTT_KEY = "" # Password to connect to MQTT Broker
BROKER = "" # URL to connect to MQTT Broker
Warning
Remember this information is stored in plain text and so can be read by anyone with access to the Pico
There may be other information you want to include here like the port or other URL extensions.
Note
Make sure to keep the speech marks when putting your own network details into the settings.toml
. This ensures that CircuitPython recognises the variables as strings.
The port number is best left as an integer
Code set-up#
Now we can program our Pico to connect to WiFi and send data to a MQTT broker
Below is an example for sending temperature and time data to a broker.
Importing libraries#
Several libraries are required
adafruit_requests
adafruit_connection_manager
adafruit_minimqtt
adafruit_ticks
all four are in the circuitpython library package
a fifth useful library is adafruit_logging which can be helpful to diagnose connection problems
import os
import microcontroller
import adafruit_connection_manager
import wifi
import adafruit_requests
import time
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import adafruit_logging as logging
import json
#Retrieve variables from settings.toml
inatorname = os.getenv("INATORNAME")
ssid = os.getenv("WIFI_SSID")
password = os.getenv("WIFI_PASSWORD")
ip = os.getenv('IP_ADDRESS')
#port=os.getenv('PORT')
wifi_con = False
# Initalize Wifi, Socket Pool, Request Session
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
requests = adafruit_requests.Session(pool, ssl_context)
# Connect to the Wi-Fi network
print(f"\nConnecting to {ssid} network...")
try:
wifi.radio.connect(ssid, password)
wifi_con = True
except OSError as e:
print(f"❌ OSError: {e}")
wifi_con = False
if wifi_con:
print("✅ Wifi!\n")
print("IP-Adress is", wifi.radio.ipv4_address)
# MQTT Topic to publish data from Pico to HiveMQ Cloud
mqtt_topic = "/datalog/TEM1"
# Define callback methods which are called when events occur
def connect(mqtt_client, userdata, flags, rc):
# This function will be called when the mqtt_client is connected
# successfully to the broker.
print("Connected to MQTT Broker!")
print(f"Flags: {flags}\n RC: {rc}")
def disconnect(mqtt_client, userdata, rc):
# This method is called when the mqtt_client disconnects
# from the broker.
print("Disconnected from MQTT Broker!")
def subscribe(mqtt_client, userdata, topic, granted_qos):
# This method is called when the mqtt_client subscribes to a new feed.
print(f"Subscribed to {topic} with QOS level {granted_qos}")
def unsubscribe(mqtt_client, userdata, topic, pid):
# This method is called when the mqtt_client unsubscribes from a feed.
print(f"Unsubscribed from {topic} with PID {pid}")
def publish(mqtt_client, userdata, topic, pid):
# This method is called when the mqtt_client publishes data to a feed.
print(f"Published to {topic} with PID {pid}")
def message(client, topic, message):
print(f"New message on topic {topic}: {message}")
#Set up the MQTT client
mqtt_client = MQTT.MQTT(
broker=os.getenv('BROKER'),
port=os.getenv('PORT'),
username=os.getenv('MQTT_USERNAME'),
password=os.getenv('MQTT_KEY'),
socket_pool=pool,
is_ssl = True,
keep_alive = 3600,
ssl_context = ssl_context
)
#Set up logging if having connection difficulties
#mqtt_client.logger = logging.getLogger('test')
#mqtt_client.logger.setLevel(logging.DEBUG)
# Connect callback handlers to mqtt_client
mqtt_client.on_connect = connect
mqtt_client.on_disconnect = disconnect
mqtt_client.on_subscribe = subscribe
mqtt_client.on_unsubscribe = unsubscribe
mqtt_client.on_publish = publish
mqtt_client.on_message = message
print(f"Attempting to connect to {mqtt_client.broker}:{mqtt_client.port}")
mqtt_client.connect()
while True:
temp = microcontroller.cpu.temperature
timetrial = time.monotonic()
#Create dictionary
json_dict = {"inator":inatorname,"cpu_temp":temp,"time":timetrial} # Send data with JSON syntax
json_data = json.dumps(json_dict)
json_byte = ("{"+f"inator:{inatorname},cpu_temp:{temp},time:{timetrial}"+"}")
print(f" | ✅ Sending JSON ('key':'value'): {json_data}")
mqtt_client.publish(mqtt_topic,str(json_data))
print(f"| ✅ Sent")
time.sleep(60)