PIC MCU with BME280 Pressure, Temperature & Humidity Sensor

This post shows how to interface Microchip PIC16F887 microcontroller with BME280 barometric pressure, temperature and humidity sensor. Values of temperature, humidity and pressure are displayed on 20×4 LCD screen connected to the microcontroller.
In this project the BME280 sensor is used in I2C mode and the compiler used is mikroC PRO for PIC.

The BME280 sensor from Bosch Sensortec is a low cost digital pressure, temperature and humidity sensor with good accuracy. Because pressure changes with altitude we can use it as an altimeter with ±1 meter accuracy (pressure accuracy = ±1 hPa). Some parameters of the sensor are listed below:

Pressure range: 300 … 1100 hPa (equivalent to +9000…-500m above/below sea level)
Pressure resolution: 0.01 hPa ( < 10 cm)
Temperature range: -40 … 85 °C
Temperature resolution: 0.01 °C
Humidity range: 0 … 100 %
Interface: I2C and SPI
Supply voltage range: 1.71 … 3.6 V

The BME280 chip works with maximum voltage of 3.6V (supply voltage range is from 1.71 to 3.6V) which means we’ve to use a 3V3 voltage regulator to supply it from a 5V source.
Also, if we’re working with a 5V system (development board, microcontroller …) like the PIC16F887 microcontroller we’ve to use a voltage level shifter (level converter) which converts the 3.3V (comes from the BME280 chip) into 5V (goes to the PIC16F887) and vice versa. This level shifter is for the I2C bus lines (clock and data).

Some BME280 modules come with 3V3 voltage regulator and level shifter like the one provided by Adafruit Industries which is shown below.
A module like this can be used with 3.3V or 5V system without any problem.

Ardafruit BME280 sensor breakout board

In this example I’m going to use a Chinese BME280 module came with 3.3V regulator and level shifter, this means connection will be more easier.

BME280 Library (driver) for mikroC PRO for PIC compiler:
To simplify the C code, I wrote a simple library (driver) for the BME280 sensor. With this library the interfacing is more easier.

Library Functions:
uint8_t BME280_begin(mode, T_sampling, H_sampling, P_sampling, filter, standby): this function initializes the BME280 sensor with the 6 configurations (mode, T_sampling, H_sampling, P_sampling, filter and standby), returns 1 if OK and 0 if error, where:

mode is sensor mode which can be: MODE_SLEEP, MODE_FORCED or MODE_NORMAL.

T_sampling is temperature oversampling, H_sampling is humidity oversampling and P_sampling is pressure oversampling, each one of them can be one from the following list:
SAMPLING_SKIPPED    —>  skipped, output set to 0x80000
SAMPLING_X1           —>  oversampling x1
SAMPLING_X2           —>  oversampling x2
SAMPLING_X4           —>  oversampling x4
SAMPLING_X8           —>  oversampling x8
SAMPLING_X16         —>  oversampling x16

filter sets BME280 sensor IIR filter configuration, it could be:
FILTER_OFF  —>  filter off
FILTER_2     —>  filter coefficient = 2
FILTER_4     —>  filter coefficient = 4
FILTER_8     —>  filter coefficient = 8
FILTER_16    —>  filter coefficient = 16

standby is BME280 sensor standby time:
STANDBY_0_5    —>  standby time = 0.5 ms
STANDBY_62_5   —>  standby time = 62.5 ms
STANDBY_125    —>  standby time = 125 ms
STANDBY_250    —>  standby time = 250 ms
STANDBY_500    —>  standby time = 500 ms
STANDBY_1000   —>  standby time = 1000 ms
STANDBY_10     —>  standby time = 10 ms
STANDBY_20     —>  standby time = 20 ms

Example:
The following line initializes the BME280 sensor in normal mode, temperature oversampling = X2, humidity oversampling = X1, pressure oversampling = X16, IIR filter coefficient = 16 and standby time = 0.5 ms:
BME280_begin(MODE_NORMAL, SAMPLING_X2, SAMPLING_X1, SAMPLING_X16, FILTER_16, STANDBY_0_5);

uint8_t BME280_ForcedMeasurement(): this function is used to start a new measurement conversion, used in forced mode only. Returns 1 if ok and 0 if error (sensor is not in sleep mode).

uint8_t BME280_readTemperature(int32_t temp): reads temperature from the BME280 sensor.
Temperature is stored in hundredths °C (output value of “5123” equals 51.23 °C). Temperature value is saved to the pointer
temp, returns 1 if OK and 0 if error.

uint8_t BME280_readHumidity(uint32_t humi): reads humidity from the BME280 sensor.
Humidity is stored in relative humidity percent in 1024 steps (output value of “47445” represents 47445/1024 = 46.333 %RH). Humidity value is saved to the pointer
humi, returns 1 if OK and 0 if error.

uint8_t BME280_readPressure(uint32_t pres): reads pressure from the BME280 sensor.
Pressure is stored in Pa (output value of “96386” equals 96386 Pa = 963.86 hPa). Pressure value is saved to the pointer
pres, returns 1 if OK and 0 if error.

BME280 sensor driver for mikroC PRO for PIC compiler download:
Driver source file download link is below, installation of this driver is easy, just add it to project folder.
Driver full name (with extension) is: BME280.C.
BME280 mikroC PRO for PIC driver

Interfacing PIC16F887 microcontroller with BME280 sensor:
This is an example that shows how to interface the BME280 sensor with PIC MCU and shows how to use the device driver.

Hardware Required:

  • PIC16F887 microcontroller   —> datasheet
  • BME280 sensor module with 3.3V regulator and level shifter   —->  BME280 datasheet
  • 20×4 LCD screen
  • 10k ohm variable resistor (or potentiometer)
  • 330 ohm resistor
  • 5V source
  • Breadboard
  • Jumper wires
  • PIC microcontroller programmer (PICkit 3, PICkit 4…)

Example circuit schematic diagram is shown below.
Note that the BME280 module shown in the circuit diagram has a 3.3V regulator and level shifter.

PIC16F887 BME280 I2C sensor and 20x4 LCD interfacing circuit

All the grounded terminals are connected together.

Generally, the BME280 module has at least 4 pins because it can work in SPI mode or I2C mode. For the I2C mode we need 4 pins: VCC, GND, SCL and SDA, where:
GND (ground) is connected to circuit ground (0V)
VCC is the supply pin, it is connected to +5V
SCL is I2C bus serial clock line, connected to PIC16F887 RC3 pin (#18)
SDA is I2C bus serial data line, connected to PIC16F887 RC4 pin (#23).

The 2004 LCD screen is used to display temperature and pressure values where:
RS —> pin RD0
E   —> pin RD1
D4 —> pin RD2
D5 —> pin RD3
D6 —> pin RD4
D7 —> pin RD5

VSS, RW, D0, D1, D2, D3 and K are connected to circuit ground.
VEE to the variable resistor (or potentiometer) output
VDD to +5V and A to +5V through 330 ohm resistor.

VEE pin is used to control the contrast of the LCD. A (anode) and K (cathode) are the back light LED pins.

In this project the PIC16F887 microcontroller runs with its internal oscillator @ 8 MHz and MCLR pin is configured as an input pin.

Interfacing PIC16F887 with BME280 sensor C code:
The C code below is for mikroC PRO for PIC compiler, it was tested with version 7.2.0.

To be able to compile project C code, a driver for the BME280 sensor is required, download link is above. After you download driver file which named BME280.c, add it to your project folder.

As any other I2C device, the BME280 sensor has an I2C slave address which is 0xEC or 0xEE. This address depends on the connection of the SDO pin (used for SPI mode as serial data out or MISO), if the SDO pin is connected (directly or through resistor) to VCC (3.3V) the address will be 0xEE, and if it’s connected to GND the address will be 0xEC. The default I2C address of the library is defined as 0xEE and my device I2C address is 0xEC.

In the code the definition of the I2C slave address is as shown below:

The initialization of the BME280 sensor is done using the function:
BME280_begin(MODE_NORMAL, SAMPLING_X1, SAMPLING_X1, SAMPLING_X1, FILTER_OFF, STANDBY_0_5);
which returns 1 if OK and 0 if error. In the code the initialization of the sensor is as shown below:

The LCD displays “connection error!” if there was an error with the initialization of the device.

Reading the values of temperature, humidity and pressure is done as shown below.
Note that the library returns the temperature in hundredths °C which means we’ve to divide it by 100, it returns the humidity in relative humidity percent (RH%) in 1024 steps which means we’ve to divide it by 1024 and it returns the pressure in Pa, to get the pressure in hPa we’ve to divide it by 100.

Temperature, humidity and pressure values are displayed on 20×4 LCD screen.

1 bar = 10000 Pa = 100 hPa. ( 1 hPa = 100 Pa)
Pa: Pascal
hPa: hectoPascal

Full mikroC code:
Configuration words (for PIC16F887 microcontroller):
CONFIG1 = 0x2CD4
CONFIG2 = 0x0700

The following image shows a protoboard circuit of the project:

PIC16F887 with BME280 sensor (I2C mode) and LCD

Related Project:
PIC MCU with BMP280 temperature and pressure sensor | mikroC Projects

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top