In this user guide, we will take a look at the BME280 sensor which is used to pressure, humidity, and temperature. Firstly, we will learn about BME280 and how to interface with Raspberry Pi Pico. Next, we will work on a simple example to demonstrate its working, and lastly, we will measure Temperature, Humidity, and Pressure with BME280 and display values on an OLED.
We have a similar guide with ESP32 and ESP8266 using MicroPython:
Prerequisites
Before we start this lesson 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 when we learned how to blink and chase LEDs in micro-python. If you have not followed our previous tutorial, you check here:
If you are using uPyCraft IDE, you can check this getting started guide:
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 and SPI.
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 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 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.
- VCC: connected with 3.3V
- SCL: used to generate the clock signal
- SDA: used in sending and receiving data
Raspberry Pi Pico Schematic with BME280
The connection of BME280 with the Raspberry Pi Pico 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 I2C Pins
Raspberry Pi Pico 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 Controller | GPIO Pins |
I2C0 – SDA | GP0/GP4/GP8/GP12/GP16/GP20 |
I2C0 – SCL | GP1/GP5/GP9/GP13/GP17/GP21 |
I2C1 – SDA | GP2/GP6/GP10/GP14/GP18/GP26 |
I2C1 – SCL | GP3/GP7/GP11/GP15/GP19/GP27 |
The connections between the two devices which we are using can be seen below.
BME280 | Raspberry Pi Pico |
VCC | 3.3V |
SDA | GP0 (I2C0 SDA) |
SCL | GP1 (I2C0 SCL) |
GND | GND |
We have used the same connections as specified in the table above. However you can use other combinations of SDA/SCL pins as well.
BME280 MicroPython Library
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 plugged in your system. Go to Tools > Manage Packages. This will open up the Thonny Package Manager.
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.
After a few moments this library will get successfully installed. Now we are ready to program our Raspberry Pi Pico with BME280 sensor in MicroPython.
Measuring Temperature, Pressure & Humidity with BME280
As we have already installed the BME280 library to our Raspberry Pi Pico, now we can use the functions available in the BME280 library to get sensor readings.
Let’s now look at an example to show the working of the sensor. We will connect our BME280 sensor with the Raspberry Pi Pico via the I2C protocol as shown above in the connection diagram. We will see a MicroPython script code and after uploading it to our board, we will see readings of temperature, pressure, and relative humidity printed on the MicroPython shell terminal.
BME280 MicroPython Code
Now let’s look at the MicroPython script for BME280 to get sensor readings. Copy the following code to the .py file and upload the file to Raspberry Pi Pico. This MicroPython script reads Pressure, Temperature and Humidity values from BME280 over I2C lines and prints them on MicroPython shell console.
from machine import Pin, I2C #importing relevant modules & classes
from time import sleep
import bme280 #importing BME280 library
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000) #initializing the I2C method
bme = bme280.BME280(i2c=i2c) #BME280 object created
while True:
print(bme.values)
sleep(10) #delay of 10s
How the Code Works?
Firstly, we will be importing the Pin class and I2C class from the machine module. This is because we have to specify the pin for I2C communication. We also import the sleep module so that we will be able to add a delay of 10 seconds in between our readings. Also, import the bme280 library which we previously installed.
from machine import Pin, I2C #importing relevant modules & classes
from time import sleep
import bme280 #importing BME280 library
Defining Raspberry Pi Pico GPIO Pins for BME280
Next, we will initialize the I2C GPIO pins for SCL and SDA respectively. We have used the I2C0 SCL and I2C0 SDA pins.
We have created an I2C() method which takes in four parameters. The first parameter is the I2C channel that we are using. The second parameter specifies the I2C GPIO pin of the board which is connected to the SDA line. The third parameter specifies the I2C GPIO pin of the board which is connected to the SCL line. The last parameter is the frequency connection.
We are setting the SCL on pin 1 and the SDA on pin 0.
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)
Next, we run an infinite loop inside which we create an object of BME280 named bme and access the sensor’s readings through it. We will print the values in the terminal by giving the print command. We also add a delay of 10s after each set of readings are displayed.
while True:
bme = bme280.BME280(i2c=i2c) #BME280 object created
print(bme.values)
sleep(10) #delay of 10s
Demo
After you have copied the following code onto the file click on ‘Save’ icon to save your program code on your PC. Save your file by giving it a name ending in .py and save according to your preference by giving the directory.
After you have saved the code press the Run button to upload the code to your Raspberry Pi Pico module. Before uploading code make sure the correct board is selected.
You will see Temperature(°C), Pressure (hPa) and Humidity (%) readings on shell console. Each set of readings will be updated to new ones after every 10 seconds.
Raspberry Pi Pico Display BME280 Sensor values on OLED Display
In this section, we will see how to display BME280 Pressure, Temperature, Humidity values on a 0.96 SSD1306 OLED display using MicroPython and Raspberry Pi Pico.
You may also like to read:
SSD1306 OLED Display MicroPython Library
We have already uploaded the BME280 MicroPython library to Raspberry Pi Pico. For an OLED display, we will also need to upload a library to Raspberry Pi Pico.
- To successfully do that, open your Thonny IDE with your Raspberry Pi Pico plugged in your system. Go to Tools > Manage Packages. This will open up the Thonny Package Manager.
- Search for “ssd1306” 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-ssd1306
Install this library.
After a few moments this library will get successfully installed. Now we are ready to program our Raspberry Pi Pico with OLED display.
Connecting SSD1306 OLED Display with Raspberry Pi Pico and BME280
We will need the following components to connect our Raspberry Pi Pico with the OLED Display and BME280.
- Raspberry Pi Pico
- BME280 Sensor
- SSD1306 OLED Display
- Connecting Wires
The OLED display has 4 terminals which we will connect with the Raspberry Pi Pico. As the OLED display requires an operating voltage in the range of 3.3-5V hence we will connect the VCC terminal with 3.3V which will be in common with the board and the sensor. SCL of the display will be connected with the SCL pin of the module and the SDA of the display will be connected with the SDA of the module. The ground of all three devices will be held common.
The connections between the three devices which we are using can be seen below.
SSD1306 OLED Display | Raspberry Pi Pico | BME280 |
VCC | 3.3V | VCC |
SDA | GP0 (I2C0 SDA) | SDA |
SCL | GP1 (I2C0 SCL) | SCL |
GND | GND | GND |
Schematic Raspberry Pi Pico with OLED and BME280
Follow the schematic diagram below connect them accordingly.
MicroPython Code: Displaying BME280 readings on OLED Display
from machine import Pin, I2C #importing relevant modules & classes
from time import sleep
import bme280 #importing BME280 library
from ssd1306 import SSD1306_I2C
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000) #initializing the I2C method
oled = SSD1306_I2C(128, 64, i2c)
bme = bme280.BME280(i2c=i2c) #BME280 object created
while True:
oled.fill(0)
temperature = bme.values[0] #reading the value of temperature
pressure = bme.values[1] #reading the value of pressure
humidity = bme.values[2] #reading the value of humidity
print('Temperature: ', temperature) #printing BME280 values
print('Humidity: ', humidity)
print('Pressure: ', pressure)
oled.text("Temp "+temperature, 0, 0)
oled.text("PA "+pressure, 0, 20)
oled.text("Humidity "+humidity, 0,40)
oled.show() #display
sleep(10) #delay of 10s
How does the code work?
In the section, we will explain the MicroPython code which is used to display sensor values on OLED.
Import Library
We will import the ssd1306 which is the OLED display library that we installed earlier. This will help us in accessing all the functions defined inside it.
from ssd1306 import SSD1306_I2C
Initialize OLED
The SCL and SDA pin data gets saved in the object ‘i2c’ which will connect to the I2C bus and help in the communication between the two devices
Now, we will create an object ‘oled’ of SSD1306_I2C which uses the width, height, and the i2c object as parameters.
oled = SSD1306_I2C(128, 64, i2c)
Clears the OLED display with led.fill() routine.
oled.fill(0)
Take BME280 sensor temperature, humidity, and pressure samples and print them in the shell terminal.
temperature = bme.values[0] #reading the value of temperature
pressure = bme.values[1] #reading the value of pressure
humidity = bme.values[2] #reading the value of humidity
print('Temperature: ', temperature) #printing BME280 values
print('Humidity: ', humidity)
print('Pressure: ', pressure)
Finally, display the text along with sensor readings on OLED.
oled.text("Temp "+temperature, 0, 0)
oled.text("PA "+pressure, 0, 20)
oled.text("Humidity "+humidity, 0,40)
At the end, call the show() method on oled method for changes to show on OLED. Add a delay of 10 seconds between each set of readings.
oled.show()
sleep(10)
Demonstration
Upload the above code as a .py file to Raspberry Pi Pico. Press the run button to upload the code to your Raspberry Pi Pico module. You will see BME280 temperature, pressure, and humidity values on the OLED display as follows:
Additionally, the shell console also shows the set of BME280 sensor readings:
We have other guides with popular sensors:
- HC-SR04 Ultrasonic Sensor with Raspberry Pi Pico using MicroPython
- MPU6050 with Raspberry Pi Pico (Accelerometer, Gyroscope, and Temperature)
- DHT11 DHT22 with Raspberry Pi Pico using MicroPython
- DS18B20 Temperature Sensor with Raspberry Pi Pico using MicroPython
You may also like to read other BME280 related articles:
- BME280 Data Logger with Arduino and Micro SD Card
- ESP32 MQTT Client: Subscribe and Publish BME280 sensor readings on HiveMQ
- BME280 Web Server with ESP32 (Arduino IDE)
- Telegram ESP32/ESP8266: Display BME280 sensor readings using Arduino IDE
- BME280 Web Server with ESP8266 NodeMCU (Arduino IDE)
- ESP8266 NodeMCU Send Sensor Readings to ThingSpeak using Arduino IDE (BME280)
- ESP32 Send Sensor Readings to ThingSpeak using Arduino IDE (BME280)
Works also with the adafruit BME280 (p2652)
but you need the I2C address to 0x77 in lib/bme280.py (line 41)
I ran into the same issue – OSError: [Errno 5] EIO – I can confirm this is the fix.
apparently, you need to wire it up on the same bus (using a breadboard). You cannot, as far as I have learned, use two different sets of GPIO pins. Odd.
Hi there,
when I run the above code, I always get the following error:
Traceback (most recent call last):
File “”, line 1, in
File “/lib/bme280.py”, line 75, in __init__
OSError: [Errno 5] EIO
Has somebody else encountered this issue and found a solution? I tried it with MicroPython 1.9.1 and 1.8.1
Never mind, i2c was connected at the wrong pins.
HI,
Looking for help in resolving this error. I see it come up every time I attempt to work with the BME280.
MPY: soft reboot
Traceback (most recent call last):
File “”, line 9, in
File “bme280.py”, line 74, in __init__
OSError: [Errno 5] EIO
9: bme = bme280.BME280(i2c=i2c) #BME280 object created
73 # load calibration data
74 dig_88_a1 = self.i2c.readfrom_mem(self.address, 0x88, 26)
I have the same issue.
Did you find a resolution?
Well on the webpage you create inside the loop the object bme.
The creation of the object should be outside the loop!
you need to create the object only once!
It should be
bme = bme280.BME280(i2c=i2c) #BME280 object created
while True:
print(bme.values)
sleep(10)
Even this is strange because you need to read the values somehow
I’m using this
t, p, h = bme.read_compensated_data()
to read temperature,pressure and humidity
in our case, it does not require to create object outside loop.
Well re-creating the object all the time start to partialise the stack after a while you could have a problem recreating the object. And why making a new object all the time. You made it once and get around problem with the memory stack.
Hi Daniel,
Yes you are right. Thank you for pointint out a mistake, we have just fixed it. Thanks