Raspberry Pi Pico W Send Sensor Readings to ThingSpeak (BME280)

In this tutorial, we will learn how to publish sensor readings to ThingSpeak using Raspberry Pi Pico W with MicroPython. ThingSpeak provides an API to send data to their analytics and we can make an HTTP POST request from Pico W to send data. Hence, we will also learn how to perform HTTP requests from Raspberry Pi Pico W.

For demonstration, we will transmit BME280 sensor readings to ThingSpeak easily and interactively show them on graphs. Any suitable sensor can be used such as DS18B20, BME680, LM35, and MPU6050 but for this article, we will use a BME280 sensor which is used to gauge temperature, pressure, and humidity.

Raspberry Pi Pico W Send Sensor Readings to ThingSpeak (BME280)

We will cover the subsequent content in this article:

  1. Introduction to BME280 sensor
  2. Connecting BME280 sensor with the Raspberry Pi Pico W development board
  3. Getting ThingSpeak API Ready
  4. Publish multiple fields of sensor readings to ThingSpeak (Temperature, humidity, and pressure)

Prerequisites

Before we start this tutorial, make sure you are familiar with and have the latest version Python 3 in your system, have set up MicoPython in Raspberry Pi Pico, and have a running Integrated Development Environment(IDE) in which we will be doing the programming. We will be using the same Thonny IDE as we have done previously in the getting started guide. If you have not followed our previous tutorial, you check here:

BME280 Introduction

The BME280 sensor is used to measure readings regarding ambient temperature, barometric pressure, and relative humidity. It is mostly used in web and mobile applications where low power consumption is key. This sensor uses I2C or SPI to communicate data with the micro-controllers. Although there are several different versions of BME280 available in the market, the one we will be studying uses I2C communication protocol.

I2C means Inter-Integrated Circuit and works on the principle of the synchronous, multi-master multi-slave system. With BME280 and the microcontroller, the Raspberry Pi Pico W acts as a master, and the BME280 sensor as a slave because it is an external device, acts as a slave. The Raspberry Pi Pico W communicates with the BME280 sensor through the I2C protocol to give temperature, barometric pressure, and relative humidity readings.

Pinout Diagram

The figure below shows the BME280 sensor and its pinout.

BME280 Pinout Diagram
BME280 Pinout
  • VCC: connected with 3.3V
  • SCL: used to generate the clock signal
  • SDA: used in sending and receiving data

Interfacing Raspberry Pi Pico W with BME280

Raspberry Pi Pico W with BME280 sensor

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

We will require the following components:

  • Raspberry Pi Pico
  • 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

BME280 MicroPython Library

Create a file with name of BME280.py in Thonny IDE and copy following code to that file. This is a MicroPython library to get temperature, pressure and humidity readings from BME280.

from machine import I2C
import time

# BME280 default address.
BME280_I2CADDR = 0x76

# Operating Modes
BME280_OSAMPLE_1 = 1
BME280_OSAMPLE_2 = 2
BME280_OSAMPLE_4 = 3
BME280_OSAMPLE_8 = 4
BME280_OSAMPLE_16 = 5

# BME280 Registers

BME280_REGISTER_DIG_T1 = 0x88  # Trimming parameter registers
BME280_REGISTER_DIG_T2 = 0x8A
BME280_REGISTER_DIG_T3 = 0x8C

BME280_REGISTER_DIG_P1 = 0x8E
BME280_REGISTER_DIG_P2 = 0x90
BME280_REGISTER_DIG_P3 = 0x92
BME280_REGISTER_DIG_P4 = 0x94
BME280_REGISTER_DIG_P5 = 0x96
BME280_REGISTER_DIG_P6 = 0x98
BME280_REGISTER_DIG_P7 = 0x9A
BME280_REGISTER_DIG_P8 = 0x9C
BME280_REGISTER_DIG_P9 = 0x9E

BME280_REGISTER_DIG_H1 = 0xA1
BME280_REGISTER_DIG_H2 = 0xE1
BME280_REGISTER_DIG_H3 = 0xE3
BME280_REGISTER_DIG_H4 = 0xE4
BME280_REGISTER_DIG_H5 = 0xE5
BME280_REGISTER_DIG_H6 = 0xE6
BME280_REGISTER_DIG_H7 = 0xE7

BME280_REGISTER_CHIPID = 0xD0
BME280_REGISTER_VERSION = 0xD1
BME280_REGISTER_SOFTRESET = 0xE0

BME280_REGISTER_CONTROL_HUM = 0xF2
BME280_REGISTER_CONTROL = 0xF4
BME280_REGISTER_CONFIG = 0xF5
BME280_REGISTER_PRESSURE_DATA = 0xF7
BME280_REGISTER_TEMP_DATA = 0xFA
BME280_REGISTER_HUMIDITY_DATA = 0xFD


class Device:
  """Class for communicating with an I2C device.

  Allows reading and writing 8-bit, 16-bit, and byte array values to
  registers on the device."""

  def __init__(self, address, i2c):
    """Create an instance of the I2C device at the specified address using
    the specified I2C interface object."""
    self._address = address
    self._i2c = i2c

  def writeRaw8(self, value):
    """Write an 8-bit value on the bus (without register)."""
    value = value & 0xFF
    self._i2c.writeto(self._address, value)

  def write8(self, register, value):
    """Write an 8-bit value to the specified register."""
    b=bytearray(1)
    b[0]=value & 0xFF
    self._i2c.writeto_mem(self._address, register, b)

  def write16(self, register, value):
    """Write a 16-bit value to the specified register."""
    value = value & 0xFFFF
    b=bytearray(2)
    b[0]= value & 0xFF
    b[1]= (value>>8) & 0xFF
    self.i2c.writeto_mem(self._address, register, value)

  def readRaw8(self):
    """Read an 8-bit value on the bus (without register)."""
    return int.from_bytes(self._i2c.readfrom(self._address, 1),'little') & 0xFF

  def readU8(self, register):
    """Read an unsigned byte from the specified register."""
    return int.from_bytes(
        self._i2c.readfrom_mem(self._address, register, 1),'little') & 0xFF

  def readS8(self, register):
    """Read a signed byte from the specified register."""
    result = self.readU8(register)
    if result > 127:
      result -= 256
    return result

  def readU16(self, register, little_endian=True):
    """Read an unsigned 16-bit value from the specified register, with the
    specified endianness (default little endian, or least significant byte
    first)."""
    result = int.from_bytes(
        self._i2c.readfrom_mem(self._address, register, 2),'little') & 0xFFFF
    if not little_endian:
      result = ((result << 8) & 0xFF00) + (result >> 8)
    return result

  def readS16(self, register, little_endian=True):
    """Read a signed 16-bit value from the specified register, with the
    specified endianness (default little endian, or least significant byte
    first)."""
    result = self.readU16(register, little_endian)
    if result > 32767:
      result -= 65536
    return result

  def readU16LE(self, register):
    """Read an unsigned 16-bit value from the specified register, in little
    endian byte order."""
    return self.readU16(register, little_endian=True)

  def readU16BE(self, register):
    """Read an unsigned 16-bit value from the specified register, in big
    endian byte order."""
    return self.readU16(register, little_endian=False)

  def readS16LE(self, register):
    """Read a signed 16-bit value from the specified register, in little
    endian byte order."""
    return self.readS16(register, little_endian=True)

  def readS16BE(self, register):
    """Read a signed 16-bit value from the specified register, in big
    endian byte order."""
    return self.readS16(register, little_endian=False)


class BME280:
  def __init__(self, mode=BME280_OSAMPLE_1, address=BME280_I2CADDR, i2c=None,
               **kwargs):
    # Check that mode is valid.
    if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,
                    BME280_OSAMPLE_8, BME280_OSAMPLE_16]:
        raise ValueError(
            'Unexpected mode value {0}. Set mode to one of '
            'BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or '
            'BME280_ULTRAHIGHRES'.format(mode))
    self._mode = mode
    # Create I2C device.
    if i2c is None:
      raise ValueError('An I2C object is required.')
    self._device = Device(address, i2c)
    # Load calibration values.
    self._load_calibration()
    self._device.write8(BME280_REGISTER_CONTROL, 0x3F)
    self.t_fine = 0

  def _load_calibration(self):

    self.dig_T1 = self._device.readU16LE(BME280_REGISTER_DIG_T1)
    self.dig_T2 = self._device.readS16LE(BME280_REGISTER_DIG_T2)
    self.dig_T3 = self._device.readS16LE(BME280_REGISTER_DIG_T3)

    self.dig_P1 = self._device.readU16LE(BME280_REGISTER_DIG_P1)
    self.dig_P2 = self._device.readS16LE(BME280_REGISTER_DIG_P2)
    self.dig_P3 = self._device.readS16LE(BME280_REGISTER_DIG_P3)
    self.dig_P4 = self._device.readS16LE(BME280_REGISTER_DIG_P4)
    self.dig_P5 = self._device.readS16LE(BME280_REGISTER_DIG_P5)
    self.dig_P6 = self._device.readS16LE(BME280_REGISTER_DIG_P6)
    self.dig_P7 = self._device.readS16LE(BME280_REGISTER_DIG_P7)
    self.dig_P8 = self._device.readS16LE(BME280_REGISTER_DIG_P8)
    self.dig_P9 = self._device.readS16LE(BME280_REGISTER_DIG_P9)

    self.dig_H1 = self._device.readU8(BME280_REGISTER_DIG_H1)
    self.dig_H2 = self._device.readS16LE(BME280_REGISTER_DIG_H2)
    self.dig_H3 = self._device.readU8(BME280_REGISTER_DIG_H3)
    self.dig_H6 = self._device.readS8(BME280_REGISTER_DIG_H7)

    h4 = self._device.readS8(BME280_REGISTER_DIG_H4)
    h4 = (h4 << 24) >> 20
    self.dig_H4 = h4 | (self._device.readU8(BME280_REGISTER_DIG_H5) & 0x0F)

    h5 = self._device.readS8(BME280_REGISTER_DIG_H6)
    h5 = (h5 << 24) >> 20
    self.dig_H5 = h5 | (
        self._device.readU8(BME280_REGISTER_DIG_H5) >> 4 & 0x0F)

  def read_raw_temp(self):
    """Reads the raw (uncompensated) temperature from the sensor."""
    meas = self._mode
    self._device.write8(BME280_REGISTER_CONTROL_HUM, meas)
    meas = self._mode << 5 | self._mode << 2 | 1
    self._device.write8(BME280_REGISTER_CONTROL, meas)
    sleep_time = 1250 + 2300 * (1 << self._mode)

    sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
    sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
    time.sleep_us(sleep_time)  # Wait the required time
    msb = self._device.readU8(BME280_REGISTER_TEMP_DATA)
    lsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 1)
    xlsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 2)
    raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
    return raw

  def read_raw_pressure(self):
    """Reads the raw (uncompensated) pressure level from the sensor."""
    """Assumes that the temperature has already been read """
    """i.e. that enough delay has been provided"""
    msb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA)
    lsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 1)
    xlsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 2)
    raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
    return raw

  def read_raw_humidity(self):
    """Assumes that the temperature has already been read """
    """i.e. that enough delay has been provided"""
    msb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA)
    lsb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA + 1)
    raw = (msb << 8) | lsb
    return raw

  def read_temperature(self):
    """Get the compensated temperature in 0.01 of a degree celsius."""
    adc = self.read_raw_temp()
    var1 = ((adc >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11)
    var2 = ((
        (((adc >> 4) - self.dig_T1) * ((adc >> 4) - self.dig_T1)) >> 12) *
        self.dig_T3) >> 14
    self.t_fine = var1 + var2
    return (self.t_fine * 5 + 128) >> 8

  def read_pressure(self):
    """Gets the compensated pressure in Pascals."""
    adc = self.read_raw_pressure()
    var1 = self.t_fine - 128000
    var2 = var1 * var1 * self.dig_P6
    var2 = var2 + ((var1 * self.dig_P5) << 17)
    var2 = var2 + (self.dig_P4 << 35)
    var1 = (((var1 * var1 * self.dig_P3) >> 8) +
            ((var1 * self.dig_P2) >> 12))
    var1 = (((1 << 47) + var1) * self.dig_P1) >> 33
    if var1 == 0:
      return 0
    p = 1048576 - adc
    p = (((p << 31) - var2) * 3125) // var1
    var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
    var2 = (self.dig_P8 * p) >> 19
    return ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)

  def read_humidity(self):
    adc = self.read_raw_humidity()
    # print 'Raw humidity = {0:d}'.format (adc)
    h = self.t_fine - 76800
    h = (((((adc << 14) - (self.dig_H4 << 20) - (self.dig_H5 * h)) +
         16384) >> 15) * (((((((h * self.dig_H6) >> 10) * (((h *
                          self.dig_H3) >> 11) + 32768)) >> 10) + 2097152) *
                          self.dig_H2 + 8192) >> 14))
    h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4)
    h = 0 if h < 0 else h
    h = 419430400 if h > 419430400 else h
    return h >> 12

  @property
  def temperature(self):
    "Return the temperature in degrees."
    t = self.read_temperature()
    ti = t // 100
    td = t - ti * 100
    return "{}.{:02d}C".format(ti, td)

  @property
  def pressure(self):
    "Return the temperature in hPa."
    p = self.read_pressure() // 256
    pi = p // 100
    pd = p - pi * 100
    return "{}.{:02d}hPa".format(pi, pd)

  @property
  def humidity(self):
    "Return the humidity in percent."
    h = self.read_humidity()
    hi = h // 1024
    hd = h * 100 // 1024 - hi * 100
    return "{}.{:02d}%".format(hi, hd)

Getting ThingSpeak API Ready

ThingSpeak is an open-source API that is used to store or retrieve data using HTTP or MQTT protocol. This takes place over the Internet or through the LAN. We will use this API to publish sensor readings from BME280 with Raspberry Pi Pico W . In ThingSpeak you can access your data from anywhere in the world. You can display your data in plots and graphs.

For more information about ThingSpeak API, you can have a look at our tutorials given below:

Creating Account

ThingSpeak API is free to use but we will have to create a MathWorks Account.
First go to the following website: https://thingspeak.com/
The following window will appear. Click on the ‘Get Started for Free’ button.

ESP32 HTTP ThingSpeak get started

Now you will be redirected to the account window. If you already have an existing MathWorks account you can use that to log in. Otherwise, you will have to create a new one. Click ‘Create One!’ to make a new MathWorks account.

ESP32 HTTP ThingSpeak account

When you have successfully signed in you will receive the following notification:
Click ‘OK’.

ESP32 HTTP ThingSpeak account successful

Publish to multiple fields of sensor readings to ThingSpeak (Temperature, Humidity and Pressure)

We will start by creating a new channel for our project. Go to Channels > My Channels. Then click ‘New Channel’.

raspberry pi pico w thingspeak account

You will be prompted to give a name to your channel. We will give a name, some description and mark the first field. In this section, we will show you how to publish multiple data. You can use any name, description, and field according to your preference. There are a total of eight fields that we can add to our channel at the same time. We will tick the first three fields and add the names. Click ‘Save Channel’ to proceed.

thingspeak create new channel multiple fields1

Your channel will now be created.

thingspeak create new channel multiple fields2

Go to private view and click the pencil icon on top of each Field Chart. This will let us customize the graphs according to our preference. You can add details accordingly. After you press the Save button, the chart will get updated to the settings you just set.

thingspeak create new channel multiple fields3

After that go to the API key tab and click it. You will now be able to access your unique API key. Save it and keep it secure as you will need it later in the program code.

thingspeak create new channel multiple fields4

Raspberry Pi Pico W ThingSpeak MicroPython Script

Open your Thonny IDE and go to File > New to open a new file. Copy the code given below in that file. This code will work with your Raspberry Pi Pico W. You just have to replace the network credentials and your API key.

import machine
import urequests
from machine import Pin, I2C
import network, time
import BME280

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

HTTP_HEADERS = {"Content-Type": "application/json"}
THINGSPEAK_WRITE_API_KEY = "Enter_Your_Write_API_KEY"

UPDATE_TIME_INTERVAL = 5000  # in ms
last_update = time.ticks_ms()

ssid = "Replace_with_wifi_ssid"
password = "Replace_with_wifi_pswd"

# Configure Raspberry Pi Pico W as Station
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)

if not sta_if.isconnected():
    print("connecting to network...")
    sta_if.connect(ssid, password)
    while not sta_if.isconnected():
        pass
print("network config:", sta_if.ifconfig())

while True:
    if time.ticks_ms() - last_update >= UPDATE_TIME_INTERVAL:
        bme = BME280.BME280(i2c=i2c)  # BME280 object created
        temperature = bme.temperature  # reading the value of temperature
        humidity = bme.humidity  # reading the value of humidity
        pressure = bme.pressure  # reading the value of pressure

        bme_readings = {"field1": temperature, "field2": pressure, "field3": humidity}
        request = urequests.post(
            "http://api.thingspeak.com/update?api_key=" + THINGSPEAK_WRITE_API_KEY,
            json=bme_readings,
            headers=HTTP_HEADERS,
        )
        request.close()
        print(bme_readings)

How does the Code Works?

Firstly, we will be importing all the necessary libraries required for this project. This includes the Pin class and SoftI2C class from the machine module. This is because we have to specify the pin for I2C communication. We also import the time module so that we will be able to add a delay in between our readings. Also, import the BME280 library which we have previously uploaded to Raspberry Pi Pico W. Moreover, we will require urequests and network modules as well.

import machine
import urequests 
from machine import Pin, I2C
import network, time
import BME280 

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

We will specify our ThingSpeak write API key in the ‘THINGSPEAK_WRITE_API_KEY’ variable that will hold our unique API key. This is the key that we saved previously when creating a new channel in ThingSpeak. Moreover, we will create another variable ‘HTTP_HEADERS’ that will be used later on while connecting with the API.

HTTP_HEADERS = {'Content-Type': 'application/json'} 
THINGSPEAK_WRITE_API_KEY = '****************' 

We will update the sensor readings after every 5 seconds. Moreover the ‘last_update’ variable will keep track of the time.

UPDATE_TIME_INTERVAL = 5000  # in ms 
last_update = time.ticks_ms() 

Connect Raspberry Pi Pico W to Local Network

Next, we will create two variables to save the SSID and the password values. You have to replace both of them with your network credentials to successfully connect with your router.

ssid='YOUR_SSID'
password='YOUR_PASSWORD'

The following lines of code will configure the Raspberry Pi Pico W board as station. The Raspberry Pi Pico W will connect with the local network and the IP address will get printed in the Thonny Shell. This is necessary as we want to send sensor readings to ThingSpeak.

sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)

if not sta_if.isconnected():
    print('connecting to network...')
    sta_if.connect(ssid, password)
    while not sta_if.isconnected():
     pass
print('network config:', sta_if.ifconfig()) 

Get Sensor Readings and Publish to ThingSpeak

Inside the while loop we will first check if it time to update the sensor readings. Then we will create an object of BME280 named bme and access the temperature, humidity and pressure through it. These sensor readings will be saved in their respective variables: temperature, humidity, and pressure.

while True: 
    if time.ticks_ms() - last_update >= UPDATE_TIME_INTERVAL: 
         bme = BME280.BME280(i2c=i2c)          #BME280 object created
         temperature = bme.temperature         #reading the value of temperature
         humidity = bme.humidity               #reading the value of humidity
         pressure = bme.pressure               #reading the value of pressure

         bme_readings = {'field1':temperature, 'field2':pressure, 'field3':humidity} 
         request = urequests.post( 'http://api.thingspeak.com/update?api_key=' + THINGSPEAK_WRITE_API_KEY, json = bme_readings, headers = HTTP_HEADERS )  
         request.close() 
         print(bme_readings) 

Next, we will create a variable ‘bme_readings’ to hold the readings that will get published to their respective fields. In our case, we had set Field 1 for temperature readings, Field 2 for pressure readings and Field 3 for humidity readings respectively.

After that we will post these three sensor readings to their respective fields by using urequests.post() method and specifying the ThingSpeak Credentials that we defined previously. After that close the request.

Additionally, all these three readings will get printed on the shell terminal after a delay of 5 seconds.

bme_readings = {'field1':temperature, 'field2':pressure, 'field3':humidity} 
         request = urequests.post( 'http://api.thingspeak.com/update?api_key=' + THINGSPEAK_WRITE_API_KEY, json = bme_readings, headers = HTTP_HEADERS )  
         request.close() 
         print(bme_readings)

Demonstration

After you have copied the above codes onto a BME280.py and main.py files, click the ‘Save’ icon to save your program code on your PC. Firstly save BME280.py and then save main.py. After that click on run button.

Raspberry Pi Pico W Web Server MicoPython code-min

After you have saved the code, press the Run button to upload the code to your board. Before uploading code make sure the correct board is selected.

In the Thonny shell terminal you will be able to view the Raspberry Pi Pico W board get connected. After every 5 seconds, new sensor readings will keep appearing as they get published to their respective fields.

BME280 readings thingspeak Raspberry Pi Pico wireless

Next, open the ThingSpeak API and you will be able to see temperature, pressure and humidity readings updating after 5 seconds in your charts.

Raspberry Pi Pico W Send Sensor Readings to ThingSpeak (BME280)
ThingSpeak Dashboard

Video demo:

Conclusion

In conclusion, we were able to learn how to publish sensor readings to ThingSpeak using MicroPython and Raspberry Pi Pico W in a fairly easy way. Likewise, you can publish single or multiple data to ThingSpeak API which you will be able to access from anywhere around the world.

If you find this Raspberry Pi Pico W project useful, you may also like to read:

Leave a Comment