Getting Started with Raspberry Pi Pico W for IoT: Micropython and MQTT

Getting Started with Raspberry Pi Pico W for IoT: Micropython and MQTT

author portrait

Written by Kudzai Manditereza

Category: IoT MQTT

Published: November 15, 2022


Introduction

In this tutorial, I will show you how to build an IoT project using Raspberry Pi Pico W, MicroPython, and MQTT. By the end of this step-by-step, you’ll be able to build a system for collecting sensor data, publish it to the cloud, and visualise the information on a dashboard.

Raspberry Pi Pico W Microcontroller

Let us begin by taking a closer look at the Raspberry Pi Pico W microcontroller board. The Pico W is part of a family of microcontroller boards from Raspberry Pi that includes the Pi Pico, Pi Pico H, the Pi Pico W and the Pi Pico WH.

Image of Raspberry Pi Pico Microcontroller Boards

Image of Raspberry Pi Pico Microcontroller Boards

The main difference between the Pi Pico W and the other Pico boards is that it comes with inbuilt WiFi connectivity, hence the W. This makes it well suited for building Internet of Things (IoT) applications as I’ll demonstrate in this article.

Image of Raspberry Pi Pico W

Image of Raspberry Pi Pico W

Selecting the Sensor ( BM2480 )

To build an IoT project using the Raspberry Pi Pico W, the first thing that we need to do is to select a sensor that we are going to use to measure physical quantities such as temperature.

For our project, we will use the BME280, an environmental sensor built for indoor monitoring of temperature, pressure, and humidity. It exposes an I2C interface for reading the sensor data it generates. I2C is a serial communication protocol that uses two lines for exchanging information, a Serial Clock Line (SCL) and a Serial Data Line (SDA).

Image of BME280 Sensor

Image of BME280 Sensor

Since our Raspberry Pi Pico W has two I2C interfaces, I’m going to connect the BME280 sensor to one of the interfaces.

Raspberry Pi Pico W and BME280 Wiring and Circuit Diagram

When you buy the Raspberry Pi Pico W, you can purchase it with the pin header soldered in, or you can buy the pin header separately and solder it yourself. I purchased mine without the pins and soldered them onto the microcontroller board we will use for this demo.

Image of Raspberry Pi Pico W without pins and pin headers that can be soldered on

Image of Raspberry Pi Pico W without pins and pin headers that can be soldered on

After soldering the pins, I placed my Raspberry Pi Pico W on this breadboard and used jumper cables to connect it to the BME280 sensor.

Image of Pi Pico W on a breadboard with jumper cables to connect it to the BME280 sensor

Image of Pi Pico W on a breadboard with jumper cables to connect it to the BME280 sensor

Let’s visualize the specific connections by viewing the circuit diagram.

I have my BME280 sensor connected through the I2C interface with Serial Data Line (SDA) and Serial Clock Line (SCL) connected to pins 1 and 2 of the Raspberry Pi Pico W, respectively.

Illustrations of connections between BME280 to the Pico W

Illustrations of connections between BME280 to the Pico W

Further, the ground on the BME280 connects to pin 38 of the Pico W, which is also ground. The VCC of the BME280 sensor is connected to pin 36 of the Raspberry Pi, which provides 3,3 Volts of output.

Installing MicroPython on Raspberry Pi Pico W

While you can program your Raspberry Pi Pico W using languages like C and C++, the easiest language to use is MicroPython. MicroPython fully implements Python 3 programming language but runs directly on embedded hardware like Raspberry Pi Pico.

To program the Raspberry Pi Pico W using MicroPython, you need to begin by installing MicroPython on the device. You achieve that by connecting the Raspberry Pi Pico W to your computer and then dragging and dropping a UF2 bootloader file onto the device.

Let’s go through the process step-by-step.

First, you need to get a Micro USB Cable to connect the Pico W to a computer via USB.

Image of a Pico W connected to a computer via a USB cable

Image of a Pico W connected to a computer via a USB cable

Next, push and hold the BOOTSEL button on the microcontroller board while you plug your Pico W into the USB port of your computer. When your Pico W is connected to the computer USB port, release the BOOTSEL button.

When you do that, you’ll notice that a Mass Storage Device called RPI-RP2 will populate on your computer.

RPI-RP2 Storage Detection on the Computer

RPI-RP2 Storage Detection on the Computer

At this point, you will need a copy the UF2 bootloader file to flash your Pico W with MicroPython, which you can get by visiting the documentation section on the Raspberry Pi website.

There is a list of instructions to follow and a link for you to download the UF2 file.

Instructions to download the Raspberry Pi Pico W on Raspberry Pi documentation

Instructions to download the Raspberry Pi Pico W on Raspberry Pi documentation

I’ll click to download the Raspberry Pi Pico W version of the file.

Then I’ll copy the bootloader file into the RP1-RP2 storage that was mounted when I connected my Pico W to the computer.

Copy of bootloader file into the RP1-RP2 storage

Copy of bootloader file into the RP1-RP2 storage

The Pico will automatically detect the file and reboot. Then it will be ready to be programmed.

Downloading and Setting up Thonny IDE

Next, to program the Raspberry Pi Pico W using MicroPython, we need to use an integrated development environment (IDE) that allows us to access the Pico W from the computer and program it. The easiest MicroPython IDE to use for this case is Thonny.

You can download Thonny IDE by going to Thonny’s website and downloading a version that works with your computer’s operating system.

Homepage of the Thonny IDE website

Homepage of the Thonny IDE website

I’ll download Thonny for Windows, and install it. After installation, open Thonny, go to the bottom right corner and click to select where you need your program to be deployed.

Since your Raspberry Pi Pico W is plugged-in, it should appear on the list. Select it.

MicroPython on Thonny

MicroPython on Thonny

Now, you should see the Thonny terminal indicating you are now working on the Pico W. To test that our Raspberry Pi Pico is working, we can run a hello world command by executing:

1
print ( “hello world” )

in the terminal.

Hello World Print Command on Thonny

Hello World Print Command on Thonny

Programming Raspberry Pi Pico W Using MicroPython

Now that my development environment is set up and ready, I can begin writing the code for my IoT project.

Before I write the code, I’ll need to save the program file on the Raspberry Pi Pico W. To do that, I’ll go to File, then click on Save. Then on the Where to save file? Prompt, I’ll select Raspberry Pi Pico.

Saving the program file on the Raspberry Pi Pico W

Saving the program file on the Raspberry Pi Pico W

Now, if you want to automatically run your program each time your Raspberry Pi boots up, you must give your File the name main.py, which I’m going to do.

So I’ve got my program file saved on my Pico W, now I can start writing the code on it.

Since I’m going to read data from the BME280 sensor and publish it to the cloud using MQTT, I’ll need to install the respective MicroPython libraries on the Pico. So, I’ll go to Tools, and select Manage Packages.

On the Manage Packages Search Bar, I’ll type in bme280 and click on search.

Searching for BME280

Searching for BME280

Then I’ll proceed by selecting the MicroPython-bme280 search result, and clicking on install thereafter.

Next, to install MQTT Client library I’ll go to the terminal, and connect my Raspberry Pi Pico W to the WiFi using this set of commands.

Connecting Raspberry Pi Pico W to the WiFi

Connecting Raspberry Pi Pico W to the WiFi

Next, I’ll install MicroPython upip.

Installing MicroPython upip

Installing micropMicroPythonython upip

I’ll use pip on the terminal to install an MQTT library called micropython-umqtt.simple. However, I’ll need to start by installing micropython-umqtt.robust (as shown below).

Installing micropython-umqtt.robust

Installing micropython-umqtt.robust

Then I will go to the micropython-umqtt.simple library.

Now, it’s important to mention that the installation of the MQTT library can present some challenges, as I’ve experienced. If you come across any, here are some troubleshooting tips.

MQTT Installation Troubleshooting Tips

First, make sure you are using the latest MicroPython firmware.

If that doesn’t solve your problems, use MicroPython to navigate to your Pico W file directory and detele a folder called lib.

These steps usually solve your difficulties.

Troubleshooting MQTT Installation

Troubleshooting MQTT Installation

Programming the Raspberry Pi Pico W

Now that the required library packages for the IoT project are installed we can proceed.

Let’s go through the code that I’ve put together.

First, I’m importing the machine library to gain access to the pins of the Raspberry Pi and for I2C communication.

Next, I import network to access my WiFi network, utime for time delay, bme280 library, and lastly the MQTT library.

1
2
3
4
5
from machine import Pin, I2C
import network
import utime
import bme280
from umqtt.simple import MQTTClient

Then I initialise my WiFi connection details.

1
2
3
Configure your WiFi SSID and password
ssid = "ssid"
password = "password"

Next, I activate my WiFi connectivity on the Raspberry Pi and connect to my WiFi network. After that, I check to see the status of my WiFi connectivity.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.config(pm = 0xa11140) # Diable powersave mode
wlan.connect(ssid, password)

max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
utime.sleep(1)

#Handle connection error
if wlan.status() != 3:
raise RuntimeError('wifi connection failed')
else:
print('connected')
status = wlan.ifconfig()
print('ip = ' + status[0])

Then I initialise my Raspberry Pi’s I2C interface

1
2
#initialise I2C
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)

Next, I define a method for connecting to my MQTT Broker.

I’m using a HiveMQ Cloud MQTT broker, which I’ve already created, and I will show you how to do that shortly.

First, let’s quickly go through the connection details.

Now, it’s important to mention that these connection details are specific to a HiveMQ Cloud MQTT Broker.

Under server, you put the MQTT broker URL address. For port number you put 0 even though my broker is at port 8883. Next, I have MQTT client username and password, which I’ve set on my HiveMQ Cloud portal.

Keep Alive is set to 7200, and I’ve set SSL to True.

Then finally, under ssl_params, I’ve put the server hostname of my MQTT broker. Again these settings are specific to a HiveMQ Cloud broker, so if you use a different broker, you probably will have different settings.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def connectMQTT():
client = MQTTClient(client_id=b"kudzai_raspberrypi_picow",
server=b"8fbadaf843514ef286a2ae29e80b15a0.s1.eu.hivemq.cloud",
port=0,
user=b"mydemoclient",
password=b"passowrd",
keepalive=7200,
ssl=True,
ssl_params={'server_hostname':'8fbadaf843514ef286a2ae29e80b15a0.s1.eu.hivemq.cloud'}
)

client.connect()
return client

Then I connect to my MQTT Broker.

1
client = connectMQTT()

Creating a HiveMQ Cloud MQTT Broker

Before we proceed with the code, let me show you how I created the MQTT broker my code connects to.

On the HiveMQ website, go to Cloud, and signup for a free HiveMQ Cloud account that allows you to connect up to a hundred MQTT clients.

I’ll login to my HiveMQ Cloud portal.

When you sign up, HiveMQ automatically creates the broker cluster for you. Copy its URL by going to Manage Cluster.

HiveMQ Cloud Interface

HiveMQ Cloud Interface

And then you also need to specify the username and password for connecting to your broker under Access Management.

Connecting to your MQTT broker

Connecting to your MQTT broker

I’ve already copied these details, so let’s get back to the code.

Publishing Sensor Data to the MQTT broker

Moving on, I’ve created a method for publishing messages to my MQTT broker, and it prints publish done when the message is successfully published.

1
2
3
4
5
def publish(topic, value):
print(topic)
print(value)
client.publish(topic, value)
print("publish Done")

Finally, I have my superloop for executing the main logic.

I read the sensor data from the BME280 sensor and assigning it to temperature, pressure, and humidity variables.

Then after printing the sensor readings, I use the publish method to publish the sensor data as MQTT messages under the topics:

  • picow/temperature for temperature data
  • picow/pressure for pressure data
  • picow/humidity for humidity data

Then I delay for five seconds before reading and publishing again.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
while True:
#Read sensor data
sensor_reading = bme280.BME280(i2c=i2c)
temperature = sensor_reading.values[0]
pressure = sensor_reading.values[1]
humidity = sensor_reading.values[2]

print(sensor_reading)
#publish as MQTT payload
publish('picow/temperature', temperature)
publish('picow/pressure', pressure)
publish('picow/humidity', humidity)
#delay 5 seconds
utime.sleep(5)

Now that I’ve my code ready, I can deploy and run the code on my Raspberry Pi Pico W.

To do that, I’ll go to the Menu and click on Run. And then I’ll select Run current script.

Deploying and running the code for reading sensor data

Deploying and running the code for reading sensor data

As shown below, my code is running and publishing the bme280 sensor data to my MQTT broker.

Running and publishing the bme280 sensor data to the MQTT broker

Running and publishing the bme280 sensor data to the MQTT broker

Subscribing to and Visualising MQTT Data from Pico W

To complete our project, we need to subscribe to this MQTT data from anywhere on the internet and visualise it to know what the current temperature, pressure and humidity is in my demo room. To do that, I’m going to use Node-Red.

The Node-Red Interface

The Node-Red Interface

If you are unfamiliar with Node-Red, this is a very useful and easy-to-use-drag-and-drop tool for connecting online services.

I’m using MQTT nodes to connect to the same HiveMQ Cloud MQTT broker and subscribe to picow/temperature on the first node, picow/pressure on the second node and picow/humidity on the bottom node.

Subscribing to Sensor data on Node-Red

Subscribing to Sensor data on Node-Red

Next, I’m passing the MQTT payloads to function blocks to strip out the decimal value since the sensor reading comes as a string with units of measurement.

Passing the MQTT Payloads to Function Blocks on Node-Red

Passing the MQTT Payloads to Function Blocks on Node-Red

Then I pass the decimal values to gauge visualisation nodes from a dashboard package that I installed on Node-Red.

Gauge Nodes Interface on Node-Red

Gauge Nodes Interface on Node-Red

When we open up the dashboard page, you can see we have a nice visualisation.

I’ll breathe into my sensor to change the sensor readings. When I do that, you can see the values change instantly.

Values of sensor changing after blowing air into it

Values of sensor changing after blowing air into it

Conclusion

Now that I’ve successfully demonstrated how to build a simple IoT project using Raspberry Pi Pico W, MicroPython and MQTT, I would like you to try it out and share your experience in the comment section below. If you are in the IIoT space, you might be interested in reading this article on How to Send & Receive MQTT Sparkplug B Messages Using Raspberry Pis, Node-RED, and HiveMQ Cloud.

Sign up for a Free HiveMQ Cloud account to get started with building IoT application using MQTT.

Get HiveMQ Cloud for Free Now
Portrait of Kudzai Manditereza

About Kudzai Manditereza

Kudzai is a Developer Advocate at HiveMQ and the Founder of Industry40.tv. He is the host of an IIoT Podcast and is involved in Industry4.0 research and educational efforts.

HiveMQ 4.9.1 Maintenance Release older posts