HiPi
Perl Modules for Raspberry Pi
Version 0.92 - released 28 March 2024

HiPi::Interface::BME280

This module provides an I2C interface to the BMP280/BME280 pressure, temperature and humidity (BME280) sensor.

It uses HiPi::Device::I2C as a backend.

Currently only the I2C interface is implemented

Example

Methods

Create a new instance of the class.

use HiPi qw( :bme280 );
use HiPi::Interface::BME280;

# the parameters shown are the defaults if not specified in the command

my $sen = HiPi::Interface::BME280->new(
    address    => 0x76,
    devicename => '/dev/i2c-1', 
);
            

Before use the sensor must be configured. For ease of use, 3 presets are provided

  • normal
  • oneshot
  • filter
use HiPi qw( :bme280 );
use HiPi::Interface::BME280;
my $sen = HiPi::Interface::BME280->new();
            
$sen->set_config_preset('oneshot');

These configuration presets are:

normal => {
    osrs_h => BM280_OSRS_X2,
    osrs_t => BM280_OSRS_X2,
    osrs_p => BM280_OSRS_X16,
    mode   => BM280_MODE_NORMAL,
    t_sb   => BM280_STANDBY_125,
    filter => BM280_FILTER_OFF,
},

oneshot => {
    osrs_h => BM280_OSRS_X1,
    osrs_t => BM280_OSRS_X1,
    osrs_p => BM280_OSRS_X1,
    mode   => BM280_MODE_FORCED,
    t_sb   => BM280_STANDBY_125,
    filter => BM280_FILTER_OFF,
},

filter => {
    osrs_h => BM280_OSRS_X2,
    osrs_t => BM280_OSRS_X2,
    osrs_p => BM280_OSRS_X16,
    mode   => BM280_MODE_NORMAL,
    t_sb   => BM280_STANDBY_125,
    filter => BM280_FILTER_16,
}

You can set your own customised configuration using the set_config() method.

Note that if you set mode to BM280_MODE_FORCED either using the set_config_preset oneshot preset, or using set_config, the sensor will calculate its values once for reading once. Subsequent reads will always return the same value until the mode is set again. This is useful if the sensor is read periodically ( say once per minute ) and can be set to BM280_MODE_FORCED every time before the sensor values are read.

Configure the sensor passing in hash reference $ref with the following members. Note that when using the BMP280 any settings for osrs_h ( humidity oversampling ) are ignored silently.

  • osrs_h
  • osrs_t
  • osrs_p
  • mode
  • t_sb
  • filter
my $ref = {
    osrs_h => BM280_OSRS_X2,
    osrs_t => BM280_OSRS_X2,
    osrs_p => BM280_OSRS_X16,
    mode   => BM280_MODE_NORMAL,
    t_sb   => BM280_STANDBY_125,
    filter => BM280_FILTER_16,
};

$sen->set_config( $ref );

Constants are provided for the options specified in the datasheets

osrs_h, osrs_t, osrs_p

BM280_OSRS_SKIP = 0b000
BM280_OSRS_X1   = 0b001
BM280_OSRS_X2   = 0b010
BM280_OSRS_X4   = 0b011
BM280_OSRS_X8   = 0b100
BM280_OSRS_X16  = 0b101

mode

BM280_MODE_SLEEP  = 0b00
BM280_MODE_NORMAL = 0b11
BM280_MODE_FORCED = 0b01

t_sb

BM280_STANDBY_0        = 0b000
BM280_BME_STANDBY_10   = 0b110
BM280_BME_STANDBY_20   = 0b111
BM280_STANDBY_62       = 0b001
BM280_STANDBY_125      = 0b010
BM280_STANDBY_250      = 0b011
BM280_STANDBY_500      = 0b100
BM280_STANDBY_1000     = 0b101
BM280_BMP_STANDBY_1000 = 0b110
BM280_BMP_STANDBY_2000 = 0b111
            
Note: Values 0b110 and 0b111 have different meaning for BMP280 and BME280 sensors

filter

BM280_FILTER_OFF = 0b000
BM280_FILTER_2   = 0b001
BM280_FILTER_4   = 0b010
BM280_FILTER_8   = 0b011
BM280_FILTER_16  = 0b100

Returns a hash reference with keys for the current configuration values read from the sensor:

  • osrs_h
  • osrs_t
  • osrs_p
  • mode
  • t_sb
  • filter

When using the BMP280 there will be no 'osrs_h' value.

See method set_config for the possible values for each key.

This method may be used in combination wuth get_config to retrieve the configuration and set a single key to a new value.

my $ref = $sen->get_config();
$ref->{mode} = BM280_MODE_SLEEP;
$sen->set_config( $ref );

Note that if you set mode to BM280_MODE_FORCED either using the set_config_preset oneshot preset, or using set_config, the sensor will calculate its values once for reading once. Subsequent reads will always return the same value until the mode is set again. This is useful if the sensor is read periodically ( say once per minute ) and can be set to BM280_MODE_FORCED every time before the sensor values are read.

Read the temperature, pressure and humidity from the sensor. Note that for the BMP280 humidity will be undefined

my( $temperature, $pressure, $humidity ) = $sen->get_values();
print qq(Temperature : $temperature *C\n);
print qq(Pressure :    $pressure Pa\n);
print qq(Humidity :    $humidity %\n) if defined( $humidity );

Get values from the sensor as a hash reference with the keys

  • t
  • p
  • h
  • raw_t
  • raw_p
  • raw_h

t, p and h are the compensated values for temperature, pressure and humidity derived by the method described in the sensor data sheets. The raw_ values are the uncompensated values directly from the sensor registers obtained with a call to method get_raw_value_hash. For the BMP280 'h' and 'raw_h' are not present.

my $ref = $sen->get_value_hash();
print qq(Temperature : $ref->{t} *C\n);
print qq(Pressure :    $ref->{p} Pa\n);
print qq(Humidity :    $ref->{h} %\n) if $ref->{h};

Method used internally to get the raw values for temperature, pressure and humidity from the sensor registers. These values must be converted using the conpensation values from the sensor. This is done for you when you call get_value_hash or get_values. Use this method if you want to see the raw values from the sensor registers. You can get the compensation factors from the compensation method.

my $ref = $sen->get_raw_value_hash();

Write a reset instruction to the sensor reset register

$sen->reset();

Return the value from the ID register.

The value returned should be

  • BMP280 0x58 ( 88 )
  • BME280 0x60 ( 96 )

The BMP280 datasheet says that some pre sale and sample sensors may have id 0x56 or 0x57

my $id = $sen->sensor_id();

Return a hash containing the two boolean values from the status register.

The hash keys are

  • measuring
  • im_update
# wait till the sensor is not busy
            
my $status = $sen->get_status();
while ( $status->{measuring} || $status->{im_update} ) {
    $sen->sleep_milliseconds(1);
    $status = $sen->get_status;
}

Returns the content of the compensation registers as a reference to array. The values are used internally to compensate the raw values and calculate readings. If you wish the raw values are available from the method get_raw_value_hash

my $comp = $sen->compensation;
my $dig_T1 = $comp->[BM280_COMP_DIG_T1];

Constants are provided for the array indexes of the compensation values.

BM280_COMP_DIG_T1 = 0
BM280_COMP_DIG_T2 = 1
BM280_COMP_DIG_T3 = 2

BM280_COMP_DIG_P1 = 3
BM280_COMP_DIG_P2 = 4
BM280_COMP_DIG_P3 = 5
BM280_COMP_DIG_P4 = 6
BM280_COMP_DIG_P5 = 7
BM280_COMP_DIG_P6 = 8
BM280_COMP_DIG_P7 = 9
BM280_COMP_DIG_P8 = 10
BM280_COMP_DIG_P9 = 11

BM280_COMP_DIG_H1 = 12
BM280_COMP_DIG_H2 = 13
BM280_COMP_DIG_H3 = 14
BM280_COMP_DIG_H4 = 15
BM280_COMP_DIG_H5 = 16
BM280_COMP_DIG_H6 = 17

There are no _DIG_H* values on the BMP280

If we know the elevation of the sensor in meters , we can find the sea level pressure using the results of the call to get_values.

my ( $temperature, $pressure ) = $sen->get_values();

my $elevation = 38;'  # meters
my $sealevelpress = $sen->sea_level_pressure( $pressure, $elevation, $temperature )

Example

use HiPi qw( :bme280 );
use HiPi::Interface::BME280;

my $mpl = HiPi::Interface::BME280->new();
$mpl->set_config_preset('oneshot');

my( $temperature, $pressure, $humidity ) = $mpl->get_values();
print qq(Temperature  : $temperature *C\n);
print qq(Pressure  :    $pressure Pa\n);
print qq(Humidity  :    $humidity %\n) if defined( $humidity );

# Google tells me my elevation

my $elevation = 38.0;
my $msl = $mpl->sea_level_pressure( $pressure, $elevation, $temperature );
print qq(Sea Level :   $msl\n);