Bosch BMP3xx topic

Classes for the Bosch BMP388 and BMP390 pressure sensors.

Introduction

The BMP390 is a digital sensor with pressure and temperature measurement based on proven sensing principles. The sensor module is housed in an extremely compact 10-pin metal-lid LGA package with a footprint of only 2.0 × 2.0 mm² and max 0.8 mm package height. Its small dimensions and its low power consumption of 3.2 μA @1Hz allow the implementation in battery driven devices such as mobile phones, GPS modules or watches.

The BMP390 replaces the BMP388 and is nearly identical in specs and communication.

Although this sensor has the option of either I2C or SPI communication, this library only supports I2C. The I2C address is either 0x77 or 0x76. To connect two of these sensors to your system, you must ensure they are soldered so as to have different I2C addresses. No more than two can be attached. These sensors should be attached to a 1.7-3.6V power source and the power supply to the sensor can be stopped between measurements.

MartinL1's BMP388 library is used internally for communication with the BMP3xx. MartinL1's library was selected over the Adafruit library because it allows non-blocking operation in both normal and forced modes. It also provides many enums to help ensure correct value inputs

Bosch Recommended Oversample and Filter Settings

Recommended Pressure Oversampling

Recommended settings pressure oversampling (adapted from table 6 of the datasheet)

Oversampling settingPressure oversamplingTypical pressure resolutionRecommended temperature oversamplingMeasurement Time (typ., µsec)
Ultra low power×116 bit / 2.64 Pa×16849
Low power×217 bit / 1.32 Pa×18869
Standard resolution×418 bit / 0.66 Pa×112909
High resolution×819 bit / 0.33 Pa×120989
Ultra high resolution×1620 bit / 0.17 Pa×241189
Highest resolution×3221 bit / 0.085 Pa×273509

Recommended Temperature Oversampling

From section 3.4.2 of the datasheet:

It is recommended to base the value of osr_t [temperature oversampling] on the selected value of osrs_p [pressure oversampling] as per Table 6. Temperature oversampling above x2 is possible, but will not significantly improve the accuracy of the pressure output any further. The reason for this is that the noise of the compensated pressure value depends more on the raw pressure than on the raw temperature noise. Following the recommended setting will result in an optimal noise to power ratio.

Settings by Use Case

This is a modified version of Bosch's recommendations for pressure and temperature oversampling, IIR filter coeficients, and output data rates for various applications. This appears as table 10 in the datasheet.

Table 10: Recommended filter settings based on use cases

Use caseModeOver-sampling settingPressure over-samplingTemperature over-samplingIIR filter coefficientStandby Time (ms)Output Data Rate (ODR) [Hz]Current Consumption (IDD) [μA]RMS Noise [cm]
handheld device low-power (e.g. Android)NormalHigh resolutionx8x128012.514511
handheld device dynamic (e.g. Android)NormalStandard resolutionx4x14205031010
Weather monitoring (lowest power)ForcedUltra low powerx1x1OffN/A¹1/60455
Drop detectionNormalLow powerx2x1Off1010035836
Indoor navigationNormalUltra high resolutionx16x2440255605
DroneNormalStandard resolutionx8x12205057011
Indoor localizationNormalUltra low powerx1x146401--

¹ Standby time does not apply in forced mode

Sensor Datasheet

Documentation for the BMP390 sensor can be found at: https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp390/

Build flags

  • -D SEALEVELPRESSURE_HPA
    • use to adjust the sea level pressure used to calculate altitude from measured barometric pressure
    • if not defined, 1013.25 is used
    • The same sea level pressure flag is used for both the BMP3xx and the BME280. Whatever you select will be used for both sensors.

Sensor Constructors

BoschBMP3xx::BoschBMP3xx(int8_t powerPin, Mode mode = FORCED_MODE, Oversampling pressureOversample = OVERSAMPLING_X16, Oversampling tempOversample = OVERSAMPLING_X2, IIRFilter filterCoeff = IIR_FILTER_OFF, TimeStandby timeStandby = TIME_STANDBY_10MS, uint8_t i2cAddressHex = 0x76) explicit

Construct a new Bosch BMP3xx object using the primary hardware I2C instance.

Parameters
powerPin

The pin on the mcu controlling power to the BMP3XX Use -1 if it is continuously powered.

  • The BMP3xx requires a 1.7 - 3.6V power source
mode

Data sampling mode
Possible values are:

  • FORCED_MODE - a single measurement is made upon request and the sensor immediately returns to sleep. This mode should be used if you are stopping power to the sensor between readings. You should not use this mode if you wish to use the sensor's on-board IIR filter.
  • NORMAL_MODE - the sensor alteranates between sampling and sleeping at intervals set by the sensor output data rate, results can be read whenever needed. This mode should not be used if you will stop power to the sensor between readings. If you wish to use the sensor's on-board filtering, you should use normal mode.
pressureOversample

Pressure oversampling setting
Possible values are:

  • OVERSAMPLING_SKIP
  • OVERSAMPLING_X2
  • OVERSAMPLING_X4,
  • OVERSAMPLING_X8
  • OVERSAMPLING_X16,
  • OVERSAMPLING_X32
tempOversample Temperature oversampling setting
Possible values are the same as those for pressureOversample. Using temperature oversampling above X2 is not recommended as it does not further improve pressure data quality.
filterCoeff

Coefficient of the infinite impulse response (IIR) filter (in samples).
This is number of past samples considered in calculating the current filtered value. This setting is ignored if the sensor will not be continuously powered. This only recommended when operating in "normal" sampling mode.
Possible values are:

  • IIR_FILTER_OFF (no filtering)
  • IIR_FILTER_1,
  • IIR_FILTER_3
  • IIR_FILTER_7,
  • IIR_FILTER_15
  • IIR_FILTER_31,
  • IIR_FILTER_63
  • IIR_FILTER_127
timeStandby

Standby time between measurements when continuously powered and operating in normal mode.
This is the inverse of the output data rate (ODR).
This setting is ignored when operating in forced mode.
Possible values are:

  • TIME_STANDBY_5MS (ODR = 200 Hz)
  • TIME_STANDBY_10MS (ODR = 100 Hz)
  • TIME_STANDBY_20MS (ODR = 50 Hz)
  • TIME_STANDBY_40MS (ODR = 25 Hz)
  • TIME_STANDBY_80MS (ODR = 12.5 Hz)
  • TIME_STANDBY_160MS (ODR = 6.25 Hz)
  • TIME_STANDBY_320MS (ODR = 3.125 Hz)
  • TIME_STANDBY_640MS (ODR = 1.5 Hz)
  • TIME_STANDBY_1280MS (~1.2 seconds, ODR = 0.78 Hz)
  • TIME_STANDBY_2560MS (~2.5 seconds, ODR = 0.39 Hz)
  • TIME_STANDBY_5120MS (~5 seconds, ODR = 0.2 Hz)
  • TIME_STANDBY_10240MS (~10 seconds, ODR = 0.1 Hz)
  • TIME_STANDBY_20480MS (~20 seconds, ODR = 0.05 Hz)
  • TIME_STANDBY_40960MS (~41 seconds, ODR = 0.025 Hz)
  • TIME_STANDBY_81920MS (~82 seconds or 1.4 minutes, ODR = 0.0125 Hz)
  • TIME_STANDBY_163840MS (~164 seconds or 2.7 minutes, ODR = 0.006 Hz)
  • TIME_STANDBY_327680MS (~5.5 minutes, ODR = 0.003 Hz)
  • TIME_STANDBY_655360MS (~11 minutes, ODR = 0.0015 Hz)
i2cAddressHex The I2C address of the BMP3xx; must be either 0x76 or 0x77. The default value is 0x76.


Example Code

The BMP3xx is used in the menu a la carte example.

1#include <sensors/BoschBMP3xx.h>
2
3// NOTE: Use -1 for any pins that don't apply or aren't being used.
4const int8_t bmp3xxPower = -1; // Power pin
5Mode bmpMode = FORCED_MODE; // The operating mode of the BMP; normal or forced
6Oversampling bmpPressureOversample = OVERSAMPLING_X32;
7Oversampling bmpTempOversample = OVERSAMPLING_X2;
8IIRFilter bmpFilterCoeff = IIR_FILTER_OFF;
9TimeStandby bmpTimeStandby = TIME_STANDBY_5MS;
10uint8_t bmpI2C_addr = 0x77;
11// The BMP3xx can be addressed either as 0x77 or 0x76
12
13// Create a Bosch BMP3xx sensor object
14BoschBMP3xx bmp3xx(bmp3xxPower, bmpMode, bmpPressureOversample,
15 bmpTempOversample, bmpFilterCoeff, bmpTimeStandby,
16 bmpI2C_addr);
17
18// Create the variable pointers for the BMP3xx
19Variable* bmp3xxTemp =
20 new BoschBMP3xx_Temp(&bmp3xx, "12345678-abcd-1234-ef00-1234567890ab");
21Variable* bmp3xxPress =
22 new BoschBMP3xx_Pressure(&bmp3xx, "12345678-abcd-1234-ef00-1234567890ab");
23Variable* bmp3xxAlt =
24 new BoschBMP3xx_Altitude(&bmp3xx, "12345678-abcd-1234-ef00-1234567890ab");

Classes

class BoschBMP3xx
The Sensor sub-class for the Bosch BMP3xx.
class BoschBMP3xx_Temp
The Variable sub-class used for the temperature output from a Bosch BMP3xx.
class BoschBMP3xx_Pressure
The Variable sub-class used for the atmospheric pressure output from a Bosch BMP3xx.
class BoschBMP3xx_Altitude
The Variable sub-class used for the altitude calculated from the measurements made by a Bosch BMP3xx.

Sensor Variable Counts

The number of variables that can be returned by Bosch BMP3xx

#define BMP3XX_NUM_VARIABLES = 3
Sensor::_numReturnedValues; the BMP3xx can report 3 values.
#define BMP3XX_INC_CALC_VARIABLES = 1
Sensor::_incCalcValues; altitude is calculted within the Adafruit library.

Configuration Defines

Defines to set the calibration of the calculated base pressure used to calculate altitude by the BME3xx.

#define SEALEVELPRESSURE_HPA = (1013.25)
The atmospheric pressure at sea level.

Sensor Timing

The sensor timing for a Bosch BMP3xx

#define BMP3XX_WARM_UP_TIME_MS = 3
Sensor::_warmUpTime_ms; BMP3xx should be ready to communicate within 3ms.
#define BMP3XX_STABILIZATION_TIME_MS = 4000
Sensor::_stabilizationTime_ms; BMP3xx is stable after 4000ms.
#define BMP3XX_MEASUREMENT_TIME_MS = 80
Sensor::_measurementTime_ms; The number given in this define will be recalculated and over-written in the set-up.

Temperature

The temperature variable from a Bosch BMP388 or BMP390

  • Range is -40°C to +85°C
    • Full accuracy between 0°C and +65°C
  • Absolute accuracy is typ. ± 0.5°C at 25°C
    • ± 1.5°C over 0°C to +65°C range

BoschBMP3xx_Temp::BoschBMP3xx_Temp(BoschBMP3xx* parentSense, const char* uuid = "", const char* varCode = "BoschBMP3xxTemp") explicit

Construct a new BoschBMP3xx_Temp object.

Parameters
parentSense The parent BoschBMP3xx providing the result values.
uuid A universally unique identifier (UUID or GUID) for the variable; optional with the default value of an empty string.
varCode A short code to help identify the variable in files; optional with a default value of "BoschBMP3xxTemp".

#define BMP3XX_TEMP_RESOLUTION = 2
Decimals places in string representation; temperature should have 5 - resolution is 0.0.00015°C at the hightest oversampling. See table 7 in the sensor datasheet for resolution at all bandwidths.
#define BMP3XX_TEMP_VAR_NUM = 0
Sensor variable number; temperature is stored in sensorValues[0].
#define BMP3XX_TEMP_VAR_NAME = "temperature"
Variable name in ODM2 controlled vocabulary; "temperature".
#define BMP3XX_TEMP_UNIT_NAME = "degreeCelsius"
Variable unit name in ODM2 controlled vocabulary; "degreeCelsius" (°C)
#define BMP3XX_TEMP_DEFAULT_CODE = "BoschBMP3xxTemp"
Default variable short code; "BoschBMP3xxTemp".

Barometric Pressure

The barometric pressure variable from a Bosch BMP388 or BMP390

  • Range for both the BMP388 and BMP390 is 300‒1250 hPa
  • Absolute accuracy is typ. ± 50 Pa (±0.50 hPa)
  • Relative accuracy is typ. ± 3 Pa (±0.03 hPa), equiv. to ± 0.25 m

BoschBMP3xx_Pressure::BoschBMP3xx_Pressure(BoschBMP3xx* parentSense, const char* uuid = "", const char* varCode = "BoschBMP3xxPressure") explicit

Construct a new BoschBMP3xx_Pressure object.

Parameters
parentSense The parent BoschBMP3xx providing the result values.
uuid A universally unique identifier (UUID or GUID) for the variable; optional with the default value of an empty string.
varCode A short code to help identify the variable in files; optional with a default value of "BoschBMP3xxPressure".

#define BMP3XX_PRESSURE_RESOLUTION = 3
Decimals places in string representation; barometric pressure should have 3. Resolution of output data in highest resolution mode at lowest bandwidth is 0.016 Pa. See table 6 in the sensor datasheet for resolution at all bandwidths.
#define BMP3XX_PRESSURE_VAR_NUM = 1
Sensor variable number; pressure is stored in sensorValues[2].
#define BMP3XX_PRESSURE_VAR_NAME = "barometricPressure"
Variable name in ODM2 controlled vocabulary; "barometricPressure".
#define BMP3XX_PRESSURE_UNIT_NAME = "pascal"
Variable unit name in ODM2 controlled vocabulary; "pascal" (Pa)
#define BMP3XX_PRESSURE_DEFAULT_CODE = "BoschBMP3xxPressure"
Default variable short code; "BoschBMP3xxPressure".

Altitude

The altitude variable from a Bosch BMP388 or BMP390

BoschBMP3xx_Altitude::BoschBMP3xx_Altitude(BoschBMP3xx* parentSense, const char* uuid = "", const char* varCode = "BoschBMP3xxAltitude") explicit

Construct a new BoschBMP3xx_Altitude object.

Parameters
parentSense The parent BoschBMP3xx providing the result values.
uuid A universally unique identifier (UUID or GUID) for the variable; optional with the default value of an empty string.
varCode A short code to help identify the variable in files; optional with a default value of "BoschBMP3xxAltitude".

#define BMP3XX_ALTITUDE_RESOLUTION = 0
Decimals places in string representation; altitude should have 0 - resolution is 1m.
#define BMP3XX_ALTITUDE_VAR_NUM = 2
Sensor variable number; altitude is stored in sensorValues[3].
#define BMP3XX_ALTITUDE_VAR_NAME = "heightAboveSeaFloor"
Variable name in ODM2 controlled vocabulary; "heightAboveSeaFloor".
#define BMP3XX_ALTITUDE_UNIT_NAME = "meter"
Variable unit name in ODM2 controlled vocabulary; "meter".
#define BMP3XX_ALTITUDE_DEFAULT_CODE = "BoschBMP3xxAltitude"
Default variable short code; "BoschBMP3xxAltitude".

Define documentation

#define BMP3XX_NUM_VARIABLES = 3

Sensor::_numReturnedValues; the BMP3xx can report 3 values.


#define BMP3XX_INC_CALC_VARIABLES = 1

Sensor::_incCalcValues; altitude is calculted within the Adafruit library.


#define SEALEVELPRESSURE_HPA = (1013.25)

The atmospheric pressure at sea level.


#define BMP3XX_WARM_UP_TIME_MS = 3

Sensor::_warmUpTime_ms; BMP3xx should be ready to communicate within 3ms.

Time to first communication after both VDD > 1.8 V and VDDIO > 1.8 V is 2ms (max) for the BMP390. Power-on time from stand-by mode is 3 ms (max) for the BMP390. I don't understand why it takes longer to be ready from stand-by than from power off, but we'll use the larger number.


#define BMP3XX_STABILIZATION_TIME_MS = 4000

Sensor::_stabilizationTime_ms; BMP3xx is stable after 4000ms.

0.5 s for good numbers, but optimal at 4 s based on tests using bmp3xxtimingTest.ino


#define BMP3XX_MEASUREMENT_TIME_MS = 80

Sensor::_measurementTime_ms; The number given in this define will be recalculated and over-written in the set-up.

The BMP390 takes 78.09ms (max) to complete a measurement at 32x pressure oversampling and 2x temperature oversampling. A measurement may take up to 138ms at 32x pressure and temperature oversampling, but oversampling rates above 2x for temperature are not recommended.

Following 3.9.2 of the datasheet:

In both forced mode and normal mode the pressure and temperature measurement duration follow the equation:

\[T_{conv} = 234 \mu s + pres\_en \times (392 \mu s + 2^{osr\_p} \times 2020 \mu s) + temp\_en \times (163 \mu s + 2^{osr\_t} \times 2020 \mu s)\]

With:

  • $T_{conv}$ = total conversion time in μs
  • $pres\_en$ = "0" or "1", depending of the status of the press_en bit
  • $temp\_en$ = "0" or "1", depending of the status of the temp_en bit
  • $osr\_p$ = amount of pressure oversampling repetitions
  • $osr\_t$ = amount of temperature oversampling repetitions

Further, based on table 23 in the datasheet, there is up to a 18% difference between the "typical" measurement time (as given by the equation) and the maximum measurement time.

ModularSensors will always enable both pressure and temperature measurement and add an extra 18% wait to the calculated measurement time.


#define BMP3XX_TEMP_RESOLUTION = 2

Decimals places in string representation; temperature should have 5 - resolution is 0.0.00015°C at the hightest oversampling. See table 7 in the sensor datasheet for resolution at all bandwidths.


#define BMP3XX_TEMP_VAR_NUM = 0

Sensor variable number; temperature is stored in sensorValues[0].


#define BMP3XX_TEMP_VAR_NAME = "temperature"

Variable name in ODM2 controlled vocabulary; "temperature".


#define BMP3XX_TEMP_UNIT_NAME = "degreeCelsius"

Variable unit name in ODM2 controlled vocabulary; "degreeCelsius" (°C)


#define BMP3XX_TEMP_DEFAULT_CODE = "BoschBMP3xxTemp"

Default variable short code; "BoschBMP3xxTemp".


#define BMP3XX_PRESSURE_RESOLUTION = 3

Decimals places in string representation; barometric pressure should have 3. Resolution of output data in highest resolution mode at lowest bandwidth is 0.016 Pa. See table 6 in the sensor datasheet for resolution at all bandwidths.


#define BMP3XX_PRESSURE_VAR_NUM = 1

Sensor variable number; pressure is stored in sensorValues[2].


#define BMP3XX_PRESSURE_VAR_NAME = "barometricPressure"

Variable name in ODM2 controlled vocabulary; "barometricPressure".


#define BMP3XX_PRESSURE_UNIT_NAME = "pascal"

Variable unit name in ODM2 controlled vocabulary; "pascal" (Pa)


#define BMP3XX_PRESSURE_DEFAULT_CODE = "BoschBMP3xxPressure"

Default variable short code; "BoschBMP3xxPressure".


#define BMP3XX_ALTITUDE_RESOLUTION = 0

Decimals places in string representation; altitude should have 0 - resolution is 1m.


#define BMP3XX_ALTITUDE_VAR_NUM = 2

Sensor variable number; altitude is stored in sensorValues[3].


#define BMP3XX_ALTITUDE_VAR_NAME = "heightAboveSeaFloor"

Variable name in ODM2 controlled vocabulary; "heightAboveSeaFloor".


#define BMP3XX_ALTITUDE_DEFAULT_CODE = "BoschBMP3xxAltitude"

Default variable short code; "BoschBMP3xxAltitude".