BME280 module

Since Origin / Contributor Maintainer Source
2016-02-21 vsky279 vsky279 bme280.c

This module provides a simple interface to BME280/BMP280 temperature/air presssure/humidity sensors (Bosch Sensortec).

Caution

Note that you must call setup() before you can start reading values! Furthermore, there has to be a variable delay between some tens to hundreds of milliseconds between setup() and reading measurements. Instead of using a fixed delay you might also poll the sensor until data is delivered e.g. humi() not returning nil anymore.

bme280.altitude()

For given air pressure and sea level air pressure returns the altitude in meters as an integer multiplied with 100, i.e. altimeter function.

Syntax

bme280.altitude(P, QNH)

Parameters

  • P measured pressure
  • QNH current sea level pressure

Returns

altitude in meters of measurement point

bme280.baro()

Reads the sensor and returns the air pressure in hectopascals as an integer multiplied with 1000 or nil when readout is not successful. Current temperature is needed to calculate the air pressure so temperature reading is performed prior reading pressure data. Second returned variable is therefore current air temperature.

Syntax

bme280.baro()

Parameters

none

Returns

  • P air pressure in hectopascals multiplied by 1000
  • T temperature in celsius as an integer multiplied with 100

bme280.dewpoint()

For given temperature and relative humidity returns the dew point in celsius as an integer multiplied with 100.

Syntax

bme280.dewpoint(H, T)

Parameters

  • H relative humidity in percent multiplied by 1000.
  • T temperate in celsius multiplied by 100.

Returns

dew point in celsisus

bme280.humi()

Reads the sensor and returns the air relative humidity in percents as an integer multiplied with 100 or nil when readout is not successful. Current temperature is needed to calculate the relative humidity so temperature reading is performed prior reading pressure data. Second returned variable is therefore current temperature.

Syntax

bme280.humi()

Parameters

none

Returns

  • H last relative humidity reading in % times 1000
  • T temperature in celsius as an integer multiplied with 100

bme280.qfe2qnh()

For given altitude converts the air pressure to sea level air pressure.

Syntax

bme280.qfe2qnh(P, altitude)

Parameters

  • P measured pressure
  • altitude altitude in meters of measurement point

Returns

sea level pressure

bme280.read()

Reads the sensor and returns the temperature, the air pressure, the air relative humidity and

Syntax

bme280.read([altitude])

Parameters

  • (optional) altitude- altitude in meters of measurement point. If provided also the air pressure converted to sea level air pressure is returned.

Returns

  • T temperature in celsius as an integer multiplied with 100
  • P air pressure in hectopascals multiplied by 1000
  • H relative humidity in percent multiplied by 1000
  • QNH air pressure in hectopascals multiplied by 1000 converted to sea level

Any of these variables is nil if the readout of given measure was not successful.

bme280.startreadout()

Starts readout (turns the sensor into forced mode). After the readout the sensor turns to sleep mode.

Syntax

bme280.startreadout(delay, callback)

Parameters

  • delay sets sensor to forced mode and calls the callback (if provided) after given number of milliseconds. For 0 the default delay is set to 113ms (sufficient time to perform reading for oversampling settings 16x). For different oversampling setting please refer to BME280 Final Datasheet - Appendix B: Measurement time and current calculation.
  • callback if provided it will be invoked after given delay. The sensor reading should be finalized by then so.

Returns

nil

bme280.setup()

Initializes module. Initialization is mandatory before read values.

Syntax

bme280.setup([temp_oss, press_oss, humi_oss, power_mode, inactive_duration, IIR_filter])

Parameters

  • (optional) temp_oss - Controls oversampling of temperature data. Default oversampling is 16x.
  • (optional) press_oss - Controls oversampling of pressure data. Default oversampling is 16x.
  • (optional) humi_oss - Controls oversampling of humidity data. Default oversampling is 16x
  • (optional) sensor_mode - Controls the sensor mode of the device. Default sensor more is normal.
  • (optional) inactive_duration - Controls inactive duration in normal mode. Default inactive duration is 20ms.
  • (optional) IIR_filter - Controls the time constant of the IIR filter. Default filter coefficient is 16.
  • (optional) cold_start - If 0 then the BME280 chip is not initialised. Useful in a battery operated setup when the ESP deep sleeps and on wakeup needs to initialise the driver (the module) but not the chip itself. The chip was kept powered (sleeping too) and is holding the latest reading that should be fetched quickly before another reading starts (bme280.startreadout()). By default the chip is initialised.
temp_oss, press_oss, humi_oss Data oversampling
0 Skipped (output set to 0x80000)
1 oversampling ×1
2 oversampling ×2
3 oversampling ×4
4 oversampling ×8
5 oversampling ×16
sensor_mode Sensor mode
0 Sleep mode
1 and 2 Forced mode
3 Normal mode

Using forced mode is recommended for applications which require low sampling rate or hostbased synchronization. The sensor enters into sleep mode after a forced readout. Please refer to BME280 Final Datasheet for more details.

inactive_duration t standby (ms)
0 0.5
1 62.5
2 125
3 250
4 500
5 1000
6 10
7 20
IIR_filter Filter coefficient
0 Filter off
1 2
2 4
3 8
4 16

Returns

nil if initialization has failed (no sensor connected?), 2 if sensor is BME280, 1 if sensor is BMP280

Example

alt=320 -- altitude of the measurement place

sda, scl = 3, 4
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
bme280.setup()

P, T = bme280.baro()
print(string.format("QFE=%d.%03d", P/1000, P%1000))

-- convert measure air pressure to sea level pressure
QNH = bme280.qfe2qnh(P, alt)
print(string.format("QNH=%d.%03d", QNH/1000, QNH%1000))

H, T = bme280.humi()

local Tsgn = (T < 0 and -1 or 1); T = Tsgn*T
print(string.format("T=%s%d.%02d", Tsgn<0 and "-" or "", T/100, T%100))
print(string.format("humidity=%d.%03d%%", H/1000, H%1000))

D = bme280.dewpoint(H, T)
local Dsgn = (D < 0 and -1 or 1); D = Dsgn*D
print(string.format("dew_point=%s%d.%02d", Dsgn<0 and "-" or "", D/100, D%100))

-- altimeter function - calculate altitude based on current sea level pressure (QNH) and measure pressure
P = bme280.baro()
curAlt = bme280.altitude(P, QNH)
local curAltsgn = (curAlt < 0 and -1 or 1); curAlt = curAltsgn*curAlt
print(string.format("altitude=%s%d.%02d", curAltsgn<0 and "-" or "", curAlt/100, curAlt%100))

Or simpler and more efficient

alt=320 -- altitude of the measurement place

sda, scl = 3, 4
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
bme280.setup()

T, P, H, QNH = bme280.read(alt)
local Tsgn = (T < 0 and -1 or 1); T = Tsgn*T
print(string.format("T=%s%d.%02d", Tsgn<0 and "-" or "", T/100, T%100))
print(string.format("QFE=%d.%03d", P/1000, P%1000))
print(string.format("QNH=%d.%03d", QNH/1000, QNH%1000))
print(string.format("humidity=%d.%03d%%", H/1000, H%1000))
D = bme280.dewpoint(H, T)
local Dsgn = (D < 0 and -1 or 1); D = Dsgn*D
print(string.format("dew_point=%s%d.%02d", Dsgn<0 and "-" or "", D/100, D%100))

-- altimeter function - calculate altitude based on current sea level pressure (QNH) and measure pressure
P = bme280.baro()
curAlt = bme280.altitude(P, QNH)
local curAltsgn = (curAlt < 0 and -1 or 1); curAlt = curAltsgn*curAlt
print(string.format("altitude=%s%d.%02d", curAltsgn<0 and "-" or "", curAlt/100, curAlt%100))

Use bme280.setup(1, 3, 0, 3, 0, 4) for "game mode" - Oversampling settings pressure ×4, temperature ×1, humidity ×0, sensor mode: normal mode, inactive duration = 0.5 ms, IIR filter settings filter coefficient 16.

Example of readout in forced mode (asynchronous)

sda, scl = 3, 4
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
bme280.setup(nil, nil, nil, 0) -- initialize to sleep mode
bme280.startreadout(0, function ()
  T, P = bme280.read()
  local Tsgn = (T < 0 and -1 or 1); T = Tsgn*T
  print(string.format("T=%s%d.%02d", Tsgn<0 and "-" or "", T/100, T%100))
end)

bme280.temp()

Reads the sensor and returns the temperature in celsius as an integer multiplied with 100.

Syntax

bme280.temp()

Parameters

none

Returns

  • T temperature in celsius as an integer multiplied with 100 or nil when readout is not successful
  • t_fine temperature measure used in pressure and humidity compensation formulas (generally no need to use this value)