RPi Pico B.Tech/Diploma Beginner

Interface BME280 with Raspberry Pi Pico using MicroPython

Interface BME280 with Raspberry Pi Pico using MicroPython Code to read temperature, humidity, pressure & display on Python Shell & OLED

  • Suitable forB.Tech/Diploma RPi Pico students
  • Build time1-2 weeks
  • LevelBeginner
  • Available atAjvika Labs, Kakinada

About this project

Overview
In this tutorial, we will learn how to Interface BME280 with Raspberry Pi Pico using MicroPython. The BME280 is a popular environmental sensor from BOSCH that can measure temperature, humidity, pressure & altitude. BME280 can be used to make Weather Station projects as well as Altimeter.
Using the BME280 library, we can develop a MicroPython Code in Thonny IDE to read data using Raspberry Pi Pico. The tutorial contains circuits, connections, and Code to communicate BME280 via the I2C protocol. In the first example, we will display the BME280 Sensor reading on Shell. In the 2nd example, we will use a 0.96″ I2C OLED Display to display BME280 parameters.
Bill of Materials
We need the following components for this tutorial:
Raspberry Pi Pico – 1
BME280 Sensor – 1
0.96″ OLED Display – 1
Jumper Wires – 10
Breadbaord – 1
Micro-USB Cable – 1
BME280 Barometric Pressure Sensor
The
BME280
is
Barometric Pressure Sensor
that can measure temperature, Humidity & Atmospheric Pressure. The Sensor has an
I2C Bus
and operates on
3.3V
Power Supply. The unit combines high linearity and high accuracy sensors and is perfectly feasible for
low current consumption
, long-term stability, and high EMC robustness.
The sensor is best for measuring
humidity
with
±3%
accuracy,
barometric pressure
with
±1
hPa absolute accuracy, and
temperature
with
±1.0°C
accuracy. Because pressure changes with
altitude
and the pressure measurements are so good, you can also use it as an altimeter with
±1
meter or better accuracy.
Interfacing BME280 Sensor with Raspberry Pi Pico
Let us connect BME280 Sensor with Raspberry Pi Pico via I2C pins. The connection is fairly simple.
Connect the VCC, GND, SCL & SDA pin of BME280 Sensor to 3.3V, GND, GP21 & GP20 of Raspberry Pi Pico respectively.
You can use a breadboard for assembly & testing.
MicroPython Code: BME280 & Pi Pico Interfacing
The code for interfacing the BME280 Sensor with Raspberry Pi Pico is divided into two parts:
bme280.py
main.py
First, the main code requires a library for BME280. The library has all the required modules and registers details to extract the data from the Sensor.
bme280.py
Open your Thonny IDE and paste the following code to the Thonny Editor. Save the file inside the Raspberry Pi Pico and name it as bme280.py.

# Authors: Paul Cunnane 2016, Peter Dahlebrg 2016
#
# This module borrows from the Adafruit BME280 Python library. Original
# Copyright notices are reproduced below.
#
# Those libraries were written for the Raspberry Pi. This modification is
# intended for the MicroPython and esp8266 boards.
#
# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# Based on the BMP280 driver with BME280 changes provided by
# David J Taylor, Edinburgh (www.satsignal.eu)
#
# Based on Adafruit_I2C.py created by Kevin Townsend.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import
time
from
ustruct
import
unpack
unpack_from
from
array
import
array
# BME280 default address.
BME280_I2CADDR
=
0x76
# Operating Modes
BME280_OSAMPLE_1
=

BME280_OSAMPLE_2
=

BME280_OSAMPLE_4
=

BME280_OSAMPLE_8
=

BME280_OSAMPLE_16
=

BME280_REGISTER_CONTROL_HUM
=
0xF2
BME280_REGISTER_CONTROL
=
0xF4
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
self
address
=
address
if
i2c
is
None
:
raise
ValueError
(
'An I2C object is required.'
)
self
i2c
=
i2c
# load calibration data
dig_88_a1
=
self
i2c
readfrom_mem
(
self
address
0x88

)
dig_e1_e7
=
self
i2c
readfrom_mem
(
self
address
0xE1

)
self
dig_T1
self
dig_T2
self
dig_T3
self
dig_P1
\
self
dig_P2
self
dig_P3
self
dig_P4
self
dig_P5
\
self
dig_P6
self
dig_P7
self
dig_P8
self
dig_P9
\
_
self
dig_H1
=
unpack
(
"<HhhHhhhhhhhhBB"
dig_88_a1
)
self
dig_H2
self
dig_H3
=
unpack
(
"<hB"
dig_e1_e7
)
e4_sign
=
unpack_from
(
"<b"
dig_e1_e7

)
[

]
self
dig_H4
=
(
e4_sign
<<

)
(
dig_e1_e7
[

]
&
0xF
)
e6_sign
=
unpack_from
(
"<b"
dig_e1_e7

)
[

]
self
dig_H5
=
(
e6_sign
<<

)
(
dig_e1_e7
[

]
>>

)
self
dig_H6
=
unpack_from
(
"<b"
dig_e1_e7

)
[

]
self
i2c
writeto_mem
(
self
address
BME280_REGISTER_CONTROL
bytearray
(
[
0x3F
]
)
)
self
t_fine
=

# temporary data holders which stay allocated
self
_l1_barray
=
bytearray
(

)
self
_l8_barray
=
bytearray
(

)
self
_l3_resultarray
=
array
(
"i"
[

]
)
def
read_raw_data
(
self
result
)
:
""
" Reads the raw (uncompensated) data from the sensor.
Args:
result: array of length 3 or alike where the result will be
stored, in temperature, pressure, humidity order
Returns:
None
"
""
self
_l1_barray
[

]
=
self
_mode
self
i2c
writeto_mem
(
self
address
BME280_REGISTER_CONTROL_HUM
self
_l1_barray
)
self
_l1_barray
[

]
=
self
_mode
<<

self
_mode
<<

self
i2c
writeto_mem
(
self
address
BME280_REGISTER_CONTROL
self
_l1_barray
)
sleep_time
=
1250
+
2300
*
(

<<
self
_mode
)
sleep_time
=
sleep_time
+
2300
*
(

<<
self
_mode
)
+

sleep_time
=
sleep_time
+
2300
*
(

<<
self
_mode
)
+

time
sleep_us
(
sleep_time
)
# Wait the required time
# burst readout from 0xF7 to 0xFE, recommended by datasheet
self
i2c
readfrom_mem_into
(
self
address
0xF7
self
_l8_barray
)
readout
=
self
_l8
_
barray
# pressure(0xF7): ((msb << 16) | (lsb << 8) | xlsb) >> 4
raw_press
=
(
(
readout
[

]
<<

)
(
readout
[

]
<<

)
readout
[

]
)
>>

# temperature(0xFA): ((msb << 16) | (lsb << 8) | xlsb) >> 4
raw_temp
=
(
(
readout
[

]
<<

)
(
readout
[

]
<<

)
readout
[

]
)
>>

# humidity(0xFD): (msb << 8) | lsb
raw_hum
=
(
readout
[

]
<<

)
readout
[

]
result
[

]
=
raw_temp
result
[

]
=
raw_press
result
[

]
=
raw_hum
def
read_compensated_data
(
self
result
=
None
)
:
"

Technologies used

ESP8266Raspberry PiBLEBME280OLEDPythonI2CMicroPython

Hardware components

  • ESP8266
  • Raspberry Pi
  • BME280
  • OLED

Software & tools

  • Thonny
  • MicroPython

What you get

  • Working project / hardware kit, tested before delivery
  • Complete source code with explanation
  • Project demo and guidance for your viva
  • Project report, PPT and IEEE paper support (on request)
Delivery & Payment
Delivery takes a minimum of two weeks from the date your inquiry is confirmed. Payment is in two parts: • 50% advance to start the project • Remaining 50% before delivery Note: • Documentation and PPT are not included by default • If you need documentation/PPT, it can be arranged for extra time and cost We'll confirm the exact timeline and cost with you after reviewing your requirements.