BME280 with STM32
Few month ago I covered a tutorial on BME180 sensor, and a lot of you guys requested me to do the same for BME280. So today this tutorial covers the BME280 sensor with STM32. We will cover the temperature, pressure and humidity using the ST’s HAL library.
BME280 can operate in 3 different modes
- Sleep Mode
- Forced Mode
- Normal Mode
In Sleep mode, no measurements are performed and the power consumption is minimum. All the Registers are accessible, and we can read or modify them.
In forced mode, the sensor performs a single measurement and goes back to sleep. the measurement results can be obtained from the data registers.
For the next measurement, the Forced mode needs to be selected again.
In Normal mode, the BME280 does not go to the sleep. It perpetuates between the measurement and the standby. This mode is often used when the data is continuously required, for eg in case of gaming, or monitoring the room.
Humidity Measurement can be enabled or skipped. When enabled, several oversampling options exist.
The humidity measurement is controlled by the osrs_h[2:0] (ctrl_hum Register) setting, which is shown below. For the humidity measurement, oversampling is possible to reduce the noise. The resolution of the humidity measurement is fixed at 16 bit ADC output.
Pressure measurement can be enabled or skipped. When enabled, several oversampling options exist.
The pressure measurement is controlled by the osrs_p[2:0] (ctrl_meas Register) setting which is shown below. For the pressure measurement, oversampling is possible to reduce the noise. The resolution of the pressure data depends on the IIR filter and the oversampling setting:
• When the IIR filter is enabled, the pressure resolution is 20 bit.
• When the IIR filter is disabled, the pressure resolution is 16 + (osrs_p – 1) bit, e.g. 18 bit when osrs_p is set to ‘3’.
Similarly, the Temperature measurement Register is shown below. The resolution of the Temperature is similar to that of the Pressure measurement.
The “config” register sets the rate, filter and interface options of the device. Writes to the “config” register in normal mode may be ignored but In sleep mode writes are not ignored.
Here we set the standby time for the normal mode (Bits 7,6,5) and the IIR Filter Coefficients (Bits 4,3,2). This will be shown in the next section, where I will show the code.
Standby time combines with the Measurement time and together they are responsible for the cycle time (output data rate).
The connection is pretty simple. Connect the SCK to PB6 (SCL) and SDI to PB7 (SDA). The board is powered by 3.3V.
Note here that the SDO is connected to the ground. This is a important parameter while using the I2C for communication.
As mentioned in the datasheet, the address of the BME280 is 111011X0 and here X is determined by the SDO pin. Since I have connected it to the ground, the address in my case would be 11101100 that is 0xEC.
BME280 Config configures the oversampling, mode, standby time and filter configuration.
- First of all it will read the Trimming parameters. These values are stored in the Non Volatile Memory of the device, and they remain unchanged.
We use these values along with the RAW data to get the accurate results.
- After reading the Trimming values, it resets the device once. To do so, we write 0xB6 to the Reset Register (0xE0)
- After resetting, we write the oversampling data for the Humidity. This is done in the ctrl_hum Register (0xF2)
- Next we set the IIR Filter Coefficient and Standby Time in the config Register (0xF5). The standby time starts at the 5th bit of the config register and this is why I have shifted the data by 5. Similarly the filter coefficient is shifted by 2.
- At last we will modify the ctrl_meas Register (0xF4). Here we will set the oversampling data for the pressure and temperature along with the working mode for the device.
The pressure oversampling data has been shifted by 2 as the it starts at the 2nd bit. Similarly the temperature data is shifted by 5. The first 2 bits (1:0) of the ctrl_meas Register controls the mode.
BMEReadRaw Reads the Raw Temperature, Humidity and Pressure data from the Sensor.
- It first checks the ID of the device by reading the ID Register (0xD0).
- If the ID is 0x60, it continues reading the RAW data by reading the 8 bytes starting from PRESS_MSB_REG (0xF2)
- Out of these 8 bytes, 3 Bytes are used by Pressure (20 Bits in total), 3 Bytes by Temperature, and the last 2 bytes by Humidity.
- Here we combine these data and store them in 32 bit signed integers, pRaw, tRaw and hRaw.
In order to calculate the actual Temperature, Pressure and Humidity, we use the Compensation formulas. These formulas are defined on page number 25 of the datasheet.
The pRaw, tRaw and hRaw we calculated above is fed to these formulas, and the respective Pressure, Temperature and Humidity values are obtained.
BME280_Measure measures the three parameters.
- It first read the RAW values using the BMEReadRaw function
- If either of the parameters are skipped (oversampling is set to 0), the value returned will be 0x800000 (or 0x8000 in case of humidity)
In that case, the value will be set to 0 for the respective parameter.
- Otherwise the compensation formulas are used to calculate the accurate values of the parameters.
The main function
- Here first of all we have to define the variables as the float.
- Inside the main function call the MBE280_Config function.
- Here I am setting the oversampling for temperature to 2, pressure to 16 and humidity to 1. Also the mode is normal mode, the standby time is 0.5ms and the IIR filter coefficient is 16.
- The values I have used are from the example in the datasheet. You can see the image below
- Inside the while loop, we call the BME280_Measure function and it does the rest of the measurement and store the values in the variables that we defined earlier.
Below is the image showing the values of all three parameters.