Remarks
Bme280 | |
---|---|
Status | |
Source code | GitHub |
Datasheet(s) | GitHub |
NuGet package |
The BME280 is a combined temperature, pressure and humidity sensor controlled via I2C.
Purchasing
The BME280 sensor is available as a breakout board from the following suppliers:
The BME280 can operating in polling and interrupt mode. By default, this sensor operates in interrupt mode.
Code Example
Bme280 sensor;
public override Task Initialize()
{
Resolver.Log.Info("Initializing...");
//CreateSpiSensor();
CreateI2CSensor();
var consumer = Bme280.CreateObserver(
handler: result =>
{
Resolver.Log.Info($"Observer: Temp changed by threshold; new temp: {result.New.Temperature?.Celsius:N2}C, old: {result.Old?.Temperature?.Celsius:N2}C");
},
filter: result =>
{
//c# 8 pattern match syntax. checks for !null and assigns var.
if (result.Old is { } old)
{
return (
(result.New.Temperature.Value - old.Temperature.Value).Abs().Celsius > 0.5
&&
(result.New.Humidity.Value - old.Humidity.Value).Percent > 0.05
);
}
return false;
}
);
sensor.Subscribe(consumer);
sensor.Updated += (sender, result) =>
{
Resolver.Log.Info($" Temperature: {result.New.Temperature?.Celsius:N2}C");
Resolver.Log.Info($" Relative Humidity: {result.New.Humidity:N2}%");
Resolver.Log.Info($" Pressure: {result.New.Pressure?.Millibar:N2}mbar ({result.New.Pressure?.Pascal:N2}Pa)");
};
return Task.CompletedTask;
}
public override async Task Run()
{
var conditions = await sensor.Read();
Resolver.Log.Info("Initial Readings:");
Resolver.Log.Info($" Temperature: {conditions.Temperature?.Celsius:N2}C");
Resolver.Log.Info($" Pressure: {conditions.Pressure?.Bar:N2}hPa");
Resolver.Log.Info($" Relative Humidity: {conditions.Humidity?.Percent:N2}%");
sensor.StartUpdating(TimeSpan.FromSeconds(1));
}
void CreateSpiSensor()
{
Resolver.Log.Info("Create BME280 sensor with SPI...");
var spi = Device.CreateSpiBus();
sensor = new Bme280(spi, Device.Pins.D00.CreateDigitalOutputPort());
}
void CreateI2CSensor()
{
Resolver.Log.Info("Create BME280 sensor with I2C...");
var i2c = Device.CreateI2cBus();
sensor = new Bme280(i2c, (byte)Bme280.Addresses.Default); // SDA pulled up
}
Sample project(s) available on GitHub
Interrupt Mode
When the driver is operating in interrupt mode, the driver will periodically check the sensor reading. An interrupt will be generated if the difference between the last reported reading and the current reading is greater than a threshold value.
The sensor operates in interrupt mode by default.
The following application will generate interrupts when changes to any one of the temperature, humidity or pressure readings exceed their threshold values:
public class MeadowApp : App<F7Micro, MeadowApp>
{
Bme280 bme280;
public MeadowApp()
{
Console.WriteLine("Initializing...");
// configure our BME280 on the I2C Bus
var i2c = Device.CreateI2cBus();
bme280 = new Bme280 (
i2c,
Bme280.I2cAddress.Adddress0x77 //default
);
bme280.Subscribe(new FilterableObserver<AtmosphericConditionChangeResult, AtmosphericConditions>(
h => {
Console.WriteLine($"Temp and pressure changed by threshold; new temp: {h.New.Temperature}, old: {h.Old.Temperature}");
},
e => {
return (
(Math.Abs(e.Delta.Temperature) > 1)
&&
(Math.Abs(e.Delta.Pressure) > 5)
);
}
));
// classical .NET events can also be used:
bme280.Updated += (object sender, AtmosphericConditionChangeResult e) =>
{
Console.WriteLine($" Temperature: {e.New.Temperature}ºC");
Console.WriteLine($" Pressure: {e.New.Pressure}hPa");
Console.WriteLine($" Relative Humidity: {e.New.Humidity}%");
};
// get chip id
Console.WriteLine($"ChipID: {bme280.GetChipID():X2}");
// get an initial reading
ReadConditions().Wait();
// start updating continuously
bme280.StartUpdating();
}
protected async Task ReadConditions()
{
var conditions = await bme280.Read();
Console.WriteLine("Initial Readings:");
Console.WriteLine($" Temperature: {conditions.Temperature}ºC");
Console.WriteLine($" Pressure: {conditions.Pressure}hPa");
Console.WriteLine($" Relative Humidity: {conditions.Humidity}%");
}
}
Sample projects available on GitHub
Polling Mode
In polling mode, it is the responsibility of the main application to check the sensor readings ona periodic basis. The following application creates an instance of the BME280
class using the I2C interface. The temperature, pressure and humidity are read every second and the readings displayed using the debugger.
The sensor is put into polling mode by setting the updateInterval
to 0
in the constructor.
public class MeadowApp : App<F7Micro, MeadowApp>
{
public MeadowApp()
{
// Create a new BME280 object and put the sensor into polling
// mode (update interval set to 0ms).
Bme280 sensor = new Bme280(updateInterval: 0);
string message;
while (true)
{
// Make the sensor take new readings.
sensor.Update();
// Prepare a message for the user and output to the debug console.
message = "Temperature: " + sensor.Temperature.ToString("F1") + " C\n";
message += "Humidity: " + sensor.Humidity.ToString("F1") + " %\n";
message += "Pressure: " + (sensor.Pressure / 100).ToString("F0") + " hPa\n\n";
Console.WriteLine(message);
// Sleep for 1000ms before repeating the process.
Thread.Sleep(1000);
}
}
}
Wiring Example
The BME280 can be connected using I2C or SPI. Only 4 wires are required when using I2C:
- 3.3V
- Ground
- SDA
- SCL
It should be noted that the Sparkfun board is supplied with pull-up resistors enabled by default. The Adafruit board does not have any pull-up resistors onboard. It is therefore necessary to add two pull-up resistors (4.7 K
should be adequate for a single device) between 3.3V and SDA and 3.3V and SCL.
Syntax
public class Bme280 : PollingSensorBase<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>, ISamplingSensor<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>, ISamplingSensor<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>, ITemperatureSensor, IHumiditySensor, IBarometricPressureSensor
Constructors
Bme280(II2cBus, Byte)
Initializes a new instance of the BME280 class
Declaration
public Bme280(II2cBus i2cBus, byte address = null)
Parameters
Type | Name | Description |
---|---|---|
II2cBus | i2cBus | I2C Bus to use for communicating with the sensor |
System.Byte | address | I2C address of the sensor (default = 0x77) |
Bme280(ISpiBus, IDigitalOutputPort)
Initializes a new instance of the BME280 class
Declaration
public Bme280(ISpiBus spiBus, IDigitalOutputPort chipSelectPort)
Parameters
Type | Name | Description |
---|---|---|
ISpiBus | spiBus | The SPI bus connected to the BME280 |
IDigitalOutputPort | chipSelectPort | The port for the chip select pin |
Bme280(ISpiBus, IPin)
Initializes a new instance of the BME280 class
Declaration
public Bme280(ISpiBus spiBus, IPin chipSelectPin)
Parameters
Type | Name | Description |
---|---|---|
ISpiBus | spiBus | The SPI bus connected to the BME280 |
IPin | chipSelectPin | The chip select pin |
Fields
configuration
Sensor configuration
Declaration
protected Bme280.Configuration configuration
Field Value
Type | Description |
---|---|
Bme280.Configuration |
readBuffer
The read buffer
Declaration
protected Memory<byte> readBuffer
Field Value
Type | Description |
---|---|
Memory<System.Byte> |
writeBuffer
The write buffer
Declaration
protected Memory<byte> writeBuffer
Field Value
Type | Description |
---|---|
Memory<System.Byte> |
Properties
Humidity
The humidity, in percent relative humidity, from the last reading..
Declaration
public RelativeHumidity? Humidity { get; }
Property Value
Type | Description |
---|---|
System.Nullable<RelativeHumidity> |
HumiditySampleCount
Humidity oversample count
Declaration
public Bme280.Oversample HumiditySampleCount { get; set; }
Property Value
Type | Description |
---|---|
Bme280.Oversample |
Pressure
The pressure, in hectopascals (hPa), from the last reading. 1 hPa is equal to one millibar, or 1/10th of a kilopascal (kPa)/centibar.
Declaration
public Pressure? Pressure { get; }
Property Value
Type | Description |
---|---|
System.Nullable<Pressure> |
PressureSampleCount
Pressure oversample count
Declaration
public Bme280.Oversample PressureSampleCount { get; set; }
Property Value
Type | Description |
---|---|
Bme280.Oversample |
Temperature
The temperature from the last reading
Declaration
public Units.Temperature? Temperature { get; }
Property Value
Type | Description |
---|---|
System.Nullable<Units.Temperature> |
TemperatureSampleCount
Temperature oversample count
Declaration
public Bme280.Oversample TemperatureSampleCount { get; set; }
Property Value
Type | Description |
---|---|
Bme280.Oversample |
Methods
GetChipID()
Get the chip ID
Declaration
public byte GetChipID()
Returns
Type | Description |
---|---|
System.Byte |
Initialize()
Initialize the sensor
Declaration
protected void Initialize()
RaiseEventsAndNotify(IChangeResult<(Nullable<Units.Temperature> Temperature, Nullable<RelativeHumidity> Humidity, Nullable<Pressure> Pressure)>)
Raise events for subcribers and notify of value changes
Declaration
protected override void RaiseEventsAndNotify(IChangeResult<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> changeResult)
Parameters
Type | Name | Description |
---|---|---|
IChangeResult<System.ValueTuple<System.Nullable<Units.Temperature>, System.Nullable<RelativeHumidity>, System.Nullable<Pressure>>> | changeResult | The updated sensor data |
ReadCompensationData()
Reads the compensation data.
Declaration
protected void ReadCompensationData()
Remarks
The compensation data is written to the chip at the time of manufacture and cannot be changed. This information is used to convert the readings from the sensor into actual temperature, pressure and humidity readings. From the data sheet, the register addresses and length are: Temperature and pressure: start address 0x88, end address 0x9F (length = 24) Humidity 1: 0xa1, length = 1 Humidity 2 and 3: start address 0xe1, end address 0xe7, (length = 8)
ReadSensor()
Update the sensor information from the BME280.
Declaration
protected override Task<(Units.Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> ReadSensor()
Returns
Type | Description |
---|---|
Task<System.ValueTuple<System.Nullable<Units.Temperature>, System.Nullable<RelativeHumidity>, System.Nullable<Pressure>>> |
Overrides
Remarks
Reads the raw temperature, pressure and humidity data from the BME280 and applies the compensation data to get the actual readings. These are made available through the Temperature, Pressure and Humidity properties. All three readings are taken at once to ensure that the three readings are consistent. Register locations and formulas taken from the Bosch BME280 datasheet revision 1.1, May 2015. Register locations - section 5.3 Memory Map Formulas - section 4.2.3 Compensation Formulas The integer formulas have been used to try and keep the calculations performant.
Reset()
Reset the sensor.
Declaration
public void Reset()
Remarks
Perform a full power-on-reset of the sensor and reset the configuration of the sensor.
StartUpdating(Nullable<TimeSpan>)
Start updating
Declaration
public override void StartUpdating(TimeSpan? updateInterval = null)
Parameters
Type | Name | Description |
---|---|---|
System.Nullable<TimeSpan> | updateInterval | The update inveral |
UpdateConfiguration(Bme280.Configuration)
Update the configuration for the BME280.
Declaration
protected void UpdateConfiguration(Bme280.Configuration configuration)
Parameters
Type | Name | Description |
---|---|---|
Bme280.Configuration | configuration |
Remarks
This method uses the data in the configuration properties in order to set up the BME280. Ensure that the following are set correctly before calling this method:
- Standby
- Filter
- HumidityOverSampling
- TemperatureOverSampling
- PressureOverSampling
- Mode
Events
HumidityUpdated
Humidity changed event
Declaration
public event EventHandler<IChangeResult<RelativeHumidity>> HumidityUpdated
Event Type
Type | Description |
---|---|
EventHandler<IChangeResult<RelativeHumidity>> |
PressureUpdated
Pressure changed event
Declaration
public event EventHandler<IChangeResult<Pressure>> PressureUpdated
Event Type
Type | Description |
---|---|
EventHandler<IChangeResult<Pressure>> |
TemperatureUpdated
Temperature changed event
Declaration
public event EventHandler<IChangeResult<Units.Temperature>> TemperatureUpdated
Event Type
Type | Description |
---|---|
EventHandler<IChangeResult<Units.Temperature>> |