Skip to content
Buy 10+ on select items — save 10% auto-applied
Free US shipping on orders $35+
Order by 3pm ET — ships same-day from the US
Skip to main content

Raspberry Pi Pico W MQTT: Send messages anywhere | ShillehTek

October 23, 2023 173 views

Raspberry Pi Pico W MQTT: Send messages anywhere | ShillehTek
Project

Build a distributed IoT message system with Raspberry Pi Pico W and MQTT using HiveMQ Cloud in MicroPython, sending publish-subscribe data anywhere with ShillehTek.

30 min Intermediate1 parts

Video Tutorial (Optional)

Watch first if you want to follow along with the full MQTT setup and Pico W code in real time.

Project Overview

In this project, you use a Raspberry Pi Pico W with MQTT (HiveMQ broker) in MicroPython to send messages between multiple Pico W devices from anywhere over the internet. By the end, you will be able to publish and subscribe to MQTT topics to build a true distributed IoT system.

Everything used here is free to work with, and the approach scales from simple message passing to larger device fleets.

  • Time: 30 to 60 minutes
  • Skill level: Intermediate
  • What you will build: Two Pico W devices that publish and subscribe to the same MQTT topic via HiveMQ Cloud

Parts List

From ShillehTek

External

  • 2x USB cables (for power and programming)
  • Computer with Thonny installed
  • WiFi network credentials (SSID and password)
  • HiveMQ Cloud account and cluster: https://www.hivemq.com/mqtt-cloud-broker/ and console at https://console.hivemq.cloud/
  • MicroPython MQTT libraries:
    • simple.py: https://github.com/micropython/micropython-lib/blob/master/micropython/umqtt.simple/umqtt/simple.py
    • robust.py: https://github.com/micropython/micropython-lib/tree/master/micropython/umqtt.robust/umqtt

Note: The code examples use TLS (ssl=True) and expect you to provide your HiveMQ cluster hostname, username, and password via a constants module.

Step-by-Step Guide

Step 1 - Allow multiple Thonny instances

Goal: Control more than one Pico W from the same computer by running multiple Thonny windows.

What to do: In Thonny, go to Tools > Options > General and untick Allow only single Thonny instance.

Restart Thonny to activate the change.

You do not need this if each Pico W is connected to a different computer. This is only needed when you want multiple Pico W devices connected to the same computer at the same time.

Thonny IDE options showing the setting to allow multiple Thonny instances for connecting to multiple Raspberry Pi Pico W boards
Enable multiple Thonny instances if you are programming more than one Pico W from the same machine.

Once enabled, open another Thonny instance.

To open another instance on macOS, run this in Terminal:

/Applications/Thonny.app/Contents/MacOS/thonny

Expected result: You can open two Thonny windows and select a different connected Pico W in each window.

Step 2 - Set up the MQTT broker (HiveMQ Cloud)

Goal: Create a cloud MQTT broker that your Pico W devices can publish to and subscribe from over the internet.

What to do: MQTT (Message Queuing Telemetry Transport) is a lightweight publish-subscribe protocol commonly used for IoT messaging. A broker routes messages from publishers to subscribers using topics.

To get started with HiveMQ Cloud:

  • Go to https://www.hivemq.com/mqtt-cloud-broker/ and click Try out for free.
  • Navigate to https://console.hivemq.cloud/
  • Create a cluster, then create a username and password in the access management tab.
  • Save the username, password, and cluster URL. You will need these in MicroPython.

Expected result: You have a HiveMQ Cloud cluster hostname plus credentials you can use from both Pico W devices.

Step 3 - Add the MicroPython MQTT libraries to each Pico W

Goal: Install the required MQTT client code so each Pico W can connect to HiveMQ and publish or subscribe.

What to do: On all Pico W devices, add the following MicroPython library files to the filesystem:

  • simple.py: https://github.com/micropython/micropython-lib/blob/master/micropython/umqtt.simple/umqtt/simple.py
  • robust.py: https://github.com/micropython/micropython-lib/tree/master/micropython/umqtt.robust/umqtt

These libraries allow you to publish and subscribe to topics from the broker over the internet.

Expected result: Both Pico W devices have the MQTT library code available to import in your scripts.

Step 4 - Run the publisher code on Pico W #1

Goal: Connect Pico W #1 to WiFi, connect to HiveMQ, and publish a message to a topic repeatedly.

What to do: On one Pico W, run this code.

Notes from the original tutorial:

  • This publishes to a topic named Topic and sends the same message every second. Change these values for your application.
  • You must substitute your values in constants.
  • The client id does not have to be mahmood.

Code:

#Native libs
import network
import time
import random

#Third Party
from umqtt.robust import MQTTClient

# Internal libs
import constants


def connectMQTT():
    '''Connects to Broker'''
    # Client ID can be anything
    client = MQTTClient(
        client_id=b"mahmood",
        server=constants.SERVER_HOSTNAME,
        port=0,
        user=constants.USER,
        password=constants.PASSWORD,
        keepalive=7200,
        ssl=True,
        ssl_params={'server_hostname': constants.SERVER_HOSTNAME}
    )
    client.connect()
    return client


def connect_to_internet(ssid, password):
    # Pass in string arguments for ssid and password

    # Just making our internet connection
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)

    # Wait for connect or fail
    max_wait = 10
    while max_wait > 0:
      if wlan.status() < 0 or wlan.status() >= 3:
        break
      max_wait -= 1
      print('waiting for connection...')
      time.sleep(1)
    # Handle connection error
    if wlan.status() != 3:
       print(wlan.status())
       raise RuntimeError('network connection failed')
    else:
      print('connected')
      print(wlan.status())
      status = wlan.ifconfig()

def make_connections():
    # Connect to internet and set MPU to start taking readings
    connect_to_internet(constants.INTERNET_NAME, constants.INTERNET_PASSWORD)
    return connectMQTT()


def publish(topic, value, client):
    '''Sends data to the broker'''
    print(topic)
    print(value)
    client.publish(topic, value)
    print("Publish Done")



client = make_connections()

while True:

    publish('Topic', 'test _message', client)

    time.sleep(1)

Expected result: The Thonny console shows that the Pico W connects to WiFi, connects to the broker, and publishes a message every second.

Step 5 - Run the subscriber code on Pico W #2

Goal: Connect Pico W #2 to WiFi, subscribe to the same topic, and print incoming messages.

What to do: On the other Pico W, run this code.

Notes from the original tutorial:

  • This reads from the topic and uses a callback so the library can display the messages.
  • Make the client id different than the first device, or you will get an error.

Code:

#Native libs
import network
import time

#Third Party
from umqtt.simple import MQTTClient

# Internal libs
import constants


def connectMQTT():
    '''Connects to Broker'''
    # Client ID can be anything
    client = MQTTClient(
        client_id=b"other client",
        server=constants.SERVER_HOSTNAME,
        port=0,
        user=constants.USER,
        password=constants.PASSWORD,
        keepalive=7200,
        ssl=True,
        ssl_params={'server_hostname': constants.SERVER_HOSTNAME}
    )
    client.connect()
    return client


def connect_to_internet(ssid, password):
    # Pass in string arguments for ssid and password

    # Just making our internet connection
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)

    # Wait for connect or fail
    max_wait = 10
    while max_wait > 0:
      if wlan.status() < 0 or wlan.status() >= 3:
        break
      max_wait -= 1
      print('waiting for connection...')
      time.sleep(1)
    # Handle connection error
    if wlan.status() != 3:
       print(wlan.status())
       raise RuntimeError('network connection failed')
    else:
      print('connected')
      print(wlan.status())
      status = wlan.ifconfig()

def make_connections():
    # Connect to internet and set MPU to start taking readings
    connect_to_internet(constants.INTERNET_NAME, constants.INTERNET_PASSWORD)
    return connectMQTT()


def my_callback(topic, response):
    # Perform desired actions based on the subscribed topic and response
    print("Received message on topic:", topic)
    print("Response:", response)


def subscribe(topic, client):
    '''Recieves data from the broker'''
    client.subscribe(topic)
    print("Subscribe Done")

client = make_connections()
client.set_callback(my_callback)
subscribe('Topic', client)

while True:
   time.sleep(5)
   client.check_msg()

Expected result: After everything is set up correctly, you start seeing messages printed in the subscriber console at each interval.

Conclusion

You set up multiple Raspberry Pi Pico W boards to send messages anywhere over the internet using MQTT with a HiveMQ Cloud broker in MicroPython. With one device publishing and another subscribing to the same topic, you have the foundation for a distributed IoT system.

Want parts for your next IoT build? Shop components and prototyping gear at ShillehTek.com. If you want help designing a production-ready IoT system (device firmware, cloud messaging, and architecture), check out our IoT consulting services.