Raspberry Pi Pico W Publish Sensor Readings to Node-Red Dashboard through MQTT

In this tutorial, we will learn to how to publish sensor readings to Node-Red dashboard through MQTT and Raspberry Pi Pico W. The Pico W board will as a an MQTT client and as a Publisher and Node-Red as a subscriber. We will publish BME280 sensor readings to MQTT broker with and Node-Red Dashboard will subscribe to these MQTT topics and display sensor readings on the Dashboard on charts and gauges.

In the last tutorial, we have seen how to use an MQTT client application on Raspberry Pi Pico W. You can refer this guide also:

For demonstration purpose, we will install MQTT broker and Node-Red on Raspberry pi. You can read these installation guides:

For a detailed tutorial regarding MQTT, its main components, MQTT broker and working follow the link: 

How to use Raspberry Pi Pico W with Node-Red

The following diagram shows how to use Raspberry Pi Pico W with Node-Red. For demo, we are sending BME280 sensor readings from Pic W to Node-RED via MQTT.

Raspberry Pi Pico W MQTT Publish Sensor Readings to Node-Red
  1. Raspberry Pi Pico W interfaces with BME280 sensor and publish sensor readings to the MQTT broker.
  2. MQTT broker and Node-Red both are installed on Raspberry Pi. But you can also use your Windows or Linux machine for demo by installing MQTT broker and Node-Red on them.
  3. The Raspberry Pi Pico W publishes the BME280 temperature readings on the topic: rpi_w/bme280/temperature, humidity readings on the topic: rpi_w/bme280/humidity, and pressure readings on the topic: rpi_w/bme280/pressure.
  4. Node-Red will subscribe to these three topics. Node-Red receives the sensor data on MQTT and displays these readings on dashboard using one chart and two gauges.
how to use Raspberry Pi Pico W with Node-Red through MQTT

Interfacing BME280 with Raspberry Pi Pico W

This section shows how to connect Raspberry Pi W Pico with BME280 sensor.

Raspberry Pi Pico W with BME280

We will require the following components:

  • Raspberry Pi Pico W
  • BME280 Sensor
  • Connecting Wires
  • Breadboard

The connection of BME280 with the Raspberry Pi Pico W is very simple. We have to connect the VCC terminal with 3.3V, ground with the ground (common ground), SCL of the sensor with SCL of the board, and SDA of the sensor with the SDA pin of the board.

Raspberry Pi Pico W I2C Pins

Raspberry Pi Pico W has two I2C controllers. Both I2C controllers are accessible through GPIO pins of Raspberry Pi Pico. The following table shows the connection of GPIO pins with both I2C controllers. Each connection of the controller can be configured through multiple GPIO pins as shown in the figure. But before using an I2C controller, you should configure in software which GPIO pins you want to use with a specific I2C controller. 

I2C ControllerGPIO Pins
I2C0 – SDAGP0/GP4/GP8/GP12/GP16/GP20
I2C0 – SCLGP1/GP5/GP9/GP13/GP17/GP21
I2C1 – SDAGP2/GP6/GP10/GP14/GP18/GP26
I2C1 – SCLGP3/GP7/GP11/GP15/GP19/GP27

The connections between the two devices which we are using can be seen below.

BME280Raspberry Pi Pico W
VCC3.3V
SDAGP20 (I2C0 SDA)
SCLGP21 (I2C0 SCL)
GNDGND

We have used the same connections as specified in the table above. However, you can use other combinations of SDA/SCL pins as well but remember to change them in the MicroPython script.

Connection Diagram Raspberry Pi Pico W with BME280

We have used the same connections as given in the tables above. All devices will be commonly grounded and will be powered with the same 3.3V pin of Raspberry Pi Pico W.

The diagram below shows the connection diagram of Raspberry Pi Pico W with BME280 sensor.

Raspberry Pi Pico W with BME280 sensor schematic diagram

Install MQTT and BME280 Libraries in Thonny IDE

We will have to install the BME280 library for MicroPython to continue with our project.

To successfully do that, open your Thonny IDE with your Raspberry Pi Pico W plugged in with your laptop. Go to Tools > Manage Packages. This will open up the Thonny Package Manager.

Raspberry Pi Pico Installing ssd1306 OLED library MicoPython 1

Search for “bme280” in the search bar by typing its name and clicking the button ‘Search on PyPI.’ From the following search results click on the one highlighted below: micropython-bme280. Install this library.

Installing BME280 Micropython library Thonny

After a few moments this library will get successfully installed.

The next step is to install the MQTT client library for Raspberry Pi Pico . The umqttsimple library is available for MicroPython. You can install it directly from packager manager also by typing umqttsimple in search bar but it give some issues with different versions of Thonny IDE. If you want to install through upip, you can write following commands on Thonny IDE console:

import upip
upip install("micropython-umqtt.simple")

To install MQTT client library manually, Open Thonny IDE and create a new file. Copy the code given here save it your MicroPython device.

ESP32 MQTT using Micro-Python install umqttsimple.py library

Save the new file by the name umqttsimple.py. Now we are ready to program Raspberry Pi Pico W board with Thonny IDE.

MicroPython Script to Publish Sensor Readings to Node-Red Dashboard

After installing the umqttsimple library, create new file with the name of main.py. Copy the code given below in that file and save it to Raspberry Pi Pico W device. You need to enter your network credentials and your Raspberry Pi MQTT broker address which is IP address of your raspberry Pi.

main.py

import time
from umqttsimple import MQTTClient
import ubinascii
import machine
import micropython
import network
from machine import Pin, I2C      
import bme280        #importing BME280 library
import gc
gc.collect()

ssid = 'HUAWEI-u67E'
password = '4uF77R2n'
mqtt_server = '192.168.18.8'  #Replace with your MQTT Broker IP

client_id = ubinascii.hexlify(machine.unique_id())

TOPIC_PUB_TEMP = b'rpi_w/bme280/temperature'
TOPIC_PUB_HUM = b'rpi_w/bme280/humidity'
TOPIC_PUB_PRES = b'rpi_w/bme280/pressure'

last_message = 0
message_interval = 5

i2c = I2C(0, sda=Pin(20), scl=Pin(21), freq=400000)  # initializing the I2C method

station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

print('Connection successful')
print(station.ifconfig())

def connect_mqtt():
  global client_id, mqtt_server
  client = MQTTClient(client_id, mqtt_server)

  client.connect()
  print('Connected to %s MQTT broker' % (mqtt_server))
  return client

def restart_and_reconnect():
  print('Failed to connect to MQTT broker. Reconnecting...')
  time.sleep(10)
  machine.reset()

try:
  client = connect_mqtt()
except OSError as e:
  restart_and_reconnect()

while True:
  try:
    if (time.time() - last_message) > message_interval:
      bme = bme280.BME280(i2c=i2c)         
      temperature = bme.values[0]         
      humidity = bme.values[2]                     
      pressure = bme.values[1]  
      print('Temperature: %s' %temperature, 'Humidity: %s' %humidity, 'Pressure: %s' %pressure)
      client.publish(TOPIC_PUB_TEMP, temperature)
      print('Published message %s to topic %s' %(temperature,TOPIC_PUB_TEMP))
      client.publish(TOPIC_PUB_HUM, humidity)
      print('Published message %s to topic %s' %(humidity,TOPIC_PUB_HUM))
      client.publish(TOPIC_PUB_PRES, pressure)
      print('Published message %s to topic %s' %(pressure,TOPIC_PUB_PRES))
      print()
      last_message = time.time()
  except OSError as e:
    restart_and_reconnect()

How the Code Works?

We start off by importing all the necessary libraries which would be required including time ,umqttsimple, MQTTClient, ubinascii, machine, micropython, network, bme280 and Pin and I2C classes from the machine module.

import time
from umqttsimple import MQTTClient
import ubinascii
import machine
import micropython
import network
from machine import Pin, I2C      
import bme280        #importing BME280 library
import gc

Then we activate the garbage collector and set the debug to ‘None.’

import gc
gc.collect()


Next, we will enter our network Wi-fi, its password and the IP of our MQTT broker. You will have to specify own credentials in order for the Raspberry Pi Pico W to connect with MQTT broker.

ssid = 'YOUR_SSID' #write your own wi-fi name
password = 'YOUR_PASSWORD' #write your own password
mqtt_server = 'Enter_your_broker_address'  #Replace with your MQTT Broker IP

Initialize BME280 Sensor Pins

Now, we initialize the I2C method by giving it three arguments. The first argument specifies the GPIO pin for SCL. This is given as GPIO20 for Raspberry Pi Pico W. The second parameter specifies the GPIO pin for the SDA. This is given as GPIO21 for Raspberry Pi Pico W. Keep in mind, these are the default I2C pins for SCL and SDA which we have used for the Raspberry Pi Pico W. The third parameter specifies the maximum frequency for SCL to be used.

i2c = I2C(0, sda=Pin(20), scl=Pin(21), freq=400000)  # initializing the I2C method

Then we will create a client_id variable which saves the MQTT client unique ID. This is required to make an MQTT client.

client_id = ubinascii.hexlify(machine.unique_id())

Next we will define three topics on which the Raspberry Pi Pico W will publish to. The temperature readings will be published to rpi_w/bme280/temperature. The humidity readings will be published to rpi_w/bme280/humidity. Likewise, the pressure readings will be published to rpi_w/bme280/pressure.

TOPIC_PUB_TEMP = b'rpi_w/bme280/temperature'
TOPIC_PUB_HUM = b'rpi_w/bme280/humidity'
TOPIC_PUB_PRES = b'rpi_w/bme280/pressure'

We will obtain the sensor readings after every 5 seconds. The variables below will monitor the time interval between the readings.

last_message = 0
message_interval = 5

MicroPython: Connecting to a Wi-Fi Network

Next, we will connect the Raspberry Pi Pico W board to the Wi-Fi network. The network.WLAN() is used to create a WLAN network interface object. 

Supported interfaces are:

  • network.STA_IF (station mode)
  • network.AP_IF (Soft access point mode)

After that, activate the station by passing the “True” argument to the sta_if.active() method. The connect() method is used to connect to the specified wireless network using the specified Wi-Fi name (SSID) and password. 

station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)

In station mode, isconnected() method returns “True” if Raspberry Pi Pico W successfully connects to a Wi-Fi network and a device also assigned a valid IP address. Otherwise, it returns “False”. This statement checks if the Raspberry Pi Pico W device connects to the Wi-Fi or not. The code does not move to the next step till the board is not connected to the Wi-Fi network.

while station.isconnected() == False:
  pass

After a Wi-Fi connection is established on the Raspberry Pi Pico W board, an IP address gets assigned. The ifconfig() method provides an IP address assigned to the Raspberry Pi Pico W. In this statement, we print the IP address using the ifconfig() method on the station object which we created previously.

print('Connection successful')
print(station.ifconfig())

Connect with MQTT Broker

First, we will define the connect_mqtt() function. This is used to connect the Raspberry Pi Pico W with the MQTT broker. We will initialize global variables for client_id and mqtt_server. This way we will be able to use them anywhere in the program code.

The next step is to initialize the MQTTClient() method with two parameters. The first parameter is the ID of the client named as: ‘client_id’ and the second parameter is the mqtt_server which is the IP address of the broker which are already defined above. This method will be assigned to the object ‘client.’ Then we will connecting the client with the broker. This would be done by using the connect() method on the object which we created previously: ‘client.’

def connect_mqtt():
  global client_id, mqtt_server
  client = MQTTClient(client_id, mqtt_server)
  client.connect()
  print('Connected to %s MQTT broker' % (mqtt_server))
  return client

In case of failure of connecting Raspberry Pi Pico W with MQTT broker, we create a restart_and_reconnect() function which would display a failure message on the screen. The Raspberry Pi Pico W will restart after 10 seconds.

def restart_and_reconnect():
  print('Failed to connect to MQTT broker. Reconnecting...')
  time.sleep(10)
  machine.reset()

Raspberry Pi Pico W Publish MQTT Messages

After that, we set up a while loop which acquire BME280 sensor data and publish it at the specific topics after every 5 seconds. The Raspberry Pi Pico W obtains the temperature, humidity and pressure readings and saves them in the variables ‘temperature’, ‘humidity’ and ‘pressure’ respectively. We create an object of BME280 named bme and access the temperature, humidity and pressure values through it.

bme = bme280.BME280(i2c=i2c)         
      temperature = bme.values[0]         
      humidity = bme.values[2]                     
      pressure = bme.values[1]  
      print('Temperature: %s' %temperature, 'Humidity: %s' %humidity, 'Pressure: %s' %pressure)

The temperature reading is published to the topic rpi_w/bme280/temperature. The humidity reading is published to the topic rpi_w/bme280/humidity. The pressure reading is published to the topic rpi_w/bme280/pressure.

To publish the messages we use the publish() method. This method has two arguments. The first argument is the publishing topic which we already configured in our boot.py file. The second argument is the MQTT message which is the BME280 sensor reading in our case.

In case of a failure during the process, we will call the restart_and _reconnect() function which restarts the Raspberry Pi Pico W.

while True:
  try:
    if (time.time() - last_message) > message_interval:
      bme = bme280.BME280(i2c=i2c)         
      temperature = bme.values[0]        #reading the value of temperature 
      humidity = bme.values[2]              #reading the value of humidity       
      pressure = bme.values[1]              #reading the value of pressure
      print('Temperature: %s' %temperature, 'Humidity: %s' %humidity, 'Pressure: %s' %pressure)
      client.publish(TOPIC_PUB_TEMP, temperature)
      print('Published message %s to topic %s' %(temperature,TOPIC_PUB_TEMP))
      client.publish(TOPIC_PUB_HUM, humidity)
      print('Published message %s to topic %s' %(humidity,TOPIC_PUB_HUM))
      client.publish(TOPIC_PUB_PRES, pressure)
      print('Published message %s to topic %s' %(pressure,TOPIC_PUB_PRES))
      print()
      last_message = time.time()
  except OSError as e:
    restart_and_reconnect()

Setting up Node-Red Dashboard on Raspberry Pi

Now let us build the Node-Red Dashboard to display BME280 sensor readings on graphs, charts and gauges, etc. The Pico W continuously publishes temperature, humidity, and pressure readings to MQTT broker on specified topics. Let’s use Node-Red to subscribe to those topics and view them on our laptop.

We will be using Node-Red to subscribe to the topics. However, you can use any other MQTT subscription service as well.

In order to get started with Node-Red on Raspberry Pi, refer to the guide: Install Node-RED on Raspberry Pi (32-bit and 64-bit RPI OS)

To access Node-RED, we need the IP address of Raspberry Pi and the port number on which Node-RED is accessible. By default, it starts on port 1880. Open any web browser and enter the RPI IP address followed by the port number.

192.168.18.8:1880

Creating Flow

This will open the Node-RED interface. You can start creating the flow.

access Node-RED

Make sure the dashboard is already installed. Head over to the extreme right side and find dashboard.

Node-Red Dashboard UI Overview pic1

After you click it, the Dashboard tab appears. The first step is to create the tab. Head over to the Dashboard tab and click +tab to create a new tab. Specify the name and icon and click Update for the changes to take place. Here we are using icons from Angular Material Icons.

We will create one tab named Home.

Node-Red Dashboard UI Overview pic4

Note: You can use any name according to your preference but for the icon you have to use one available at these three links found below:

Add Widgets

The next step is to add the widgets. We will add one group to the tab. Click +group in the tab and create the group. We have named it ‘BME280 Readings.’

ESP32 MQTT BME280 Publish and Subscribe Project Set up Node-Red Dashboard 1

We will display the temperature and humidity readings on gauges and the pressure readings on a line chart. Therefore we add six nodes to the flow. Head over to the Nodes section found at the far left and scroll down to view the nodes under Dashboard. Drag and drop two gauges, one chart and two mqtt in nodes to the flow as shown below:

ESP32 MQTT BME280 Publish and Subscribe Project Set up Node-Red Dashboard 2

Now double click the first mqtt node to edit its properties as shown below.

Here we have set the sever (MQTT Broker) to localhost:1883 as we are using Mosquitto Broker on our Raspberry Pi. Specify the topic to be subscribed. This node is being subscribed to the topic ‘rpi_w/bme280/temperature.’ Click the Done button.

Node-RED MQTT in subscribe to topics and select MTT broker

Similarly, double click the second mqtt node and edit its properties as shown below. Notice that this particular node is subscribed to the topic ‘rpi_w/bme280/humidity.’ Click the Done button.

Node-RED BME280 humidity MQTT in subscribe to topics and select MTT broker

Similarly, double click the third mqtt node and edit its properties as shown below. Notice that this particular node is subscribed to the topic ‘rpi_w/bme280/pressure.’ Click the Done button.

Node-RED BME280 pressure MQTT in subscribe to topics and select MTT broker

Now double click the gauges and edit their properties as well. Set the first one for temperature and the second one for humidity.

For the chart, edit the properties as shown below. The line chart will plot pressure readings.

ESP32 MQTT BME280 Publish and Subscribe Project Set up Node-Red Dashboard 4

Finally, join the nodes as shown below and click the Deploy button found at the top. The status of the MQTT nodes changes to connected.

Node-Red BME280 Dashboard with MQTT

Raspberry Pi Pico W and Node-Red Demo

First upload main.py script to Raspberry Pi Pico W. To upload MicroPython script to your Raspberry Pi Pico W device, go to Files and click on ‘Save as’ or click the Save icon. Save the file to the MicroPython device as main.py and click ok.

Now press the Run current script icon.

This would upload the code onto our Raspberry Pi Pico W board. After the code is uploaded, you will see this output of Thonny IDE terminal which shows that board has successfully connected with your Wi-Fi network and also connected to MQTT broker.

As soon as it connects with broker, it starts publishing messages on on the give topic after every two seconds.

thonny ide console output

To view the output on Node-Red UI, open a new web browser and type: http://Your_RPI_IP_address:1880/ui

The user interface will open up once you press enter.

Here you can view the dashboard consisting of the two gauges and a line chart with readings from the BME280 sensor.

Raspberry Pi Pico W MQTT Publish Sensor Readings to Node-Red Dashboard DEMO

In summary:

In this tutorial, we learned to how to use BME280 sensor to collect temperature, humidity, and pressure data, and then publish that data to an MQTT broker, how to connect Raspberry Pi Pico W to the MQTT broker, and finally Publish readings to MQTT broker and so is to Node-Red.

You can also check these tutorials where we used Node-Red:

You can also read these Raspberry Pi Pico W tutorials:

1 thought on “Raspberry Pi Pico W Publish Sensor Readings to Node-Red Dashboard through MQTT”

  1. I am trying to use a similar set up but with a ds18b20 sensor. How to I modify the main.py to use onewire instead of i2c?

    Reply

Leave a Comment