# BME280 module

This module provides a simple interface to [BME280/BMP280 temperature/air presssure/humidity sensors](http://www.bosch-sensortec.com/bst/products/all_products/bme280) (Bosch Sensortec).

Note that you must call [`init()`](#bme280init) before you can start reading values!

## 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 temperature 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 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.init()

Initializes module. Initialization is mandatory before read values.

#### Syntax

`bme280.init(sda, scl, [temp_oss, press_oss, humi_oss, power_mode, inactive_duration, IIR_filter])`

#### Parameters
- `sda` - SDA pin  
- `scl` - SCL pin
- (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 fitler coefficient is 16.

|`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
```lua
alt=320 -- altitude of the measurement place

bme280.init(3, 4)

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()
print(string.format("T=%d.%02d", T/100, T%100))
print(string.format("humidity=%d.%03d%%", H/1000, H%1000))
D = bme280.dewpoint(H, T)
print(string.format("dew_point=%d.%02d", 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)
print(string.format("altitude=%d.%02d", curAlt/100, curAlt%100))
```
Use `bme280.init(sda, scl, 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)
```lua
bme280.init(3, 4, nil, nil, nil, 0) -- initialize to sleep mode
bme280.startreadout(0, function ()
  T = bme280.temp()
  print(string.format("T=%d.%02d", T/100, T%100))
end)
```

## 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.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](http://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf#page=51).
- `callback` if provided it will be invoked after given `delay`. The sensor reading should be finalized by then so.

#### Returns  
`nil`

## 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)