Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Characteristic Locus
Inheritance object ObservableBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> PollingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> > Bme280
Implements IObservable<IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>> ISamplingSensor<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> ISensor<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> ITemperatureSensor ISamplingSensor<Temperature> ISensor<Temperature> IHumiditySensor ISamplingSensor<RelativeHumidity> ISensor<RelativeHumidity> IBarometricPressureSensor ISamplingSensor<Pressure> ISensor<Pressure> ISpiPeripheral II2cPeripheral IDisposable
Inherited Members PollingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.StartUpdating(TimeSpan?) PollingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.StopUpdating() SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.samplingLock SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.ReadSensor() SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.RaiseEventsAndNotify(IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>) SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.Read() SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.SamplingTokenSource SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.Conditions SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.IsSampling SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.UpdateInterval SamplingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.Updated ObservableBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.NotifyObservers(IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>) ObservableBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.Subscribe(IObserver<IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>>) ObservableBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.CreateObserver(Action<IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>>, Predicate<IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>>) ObservableBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>.observers object.Equals(object) object.Equals(object, object) object.GetHashCode() object.GetType() object.MemberwiseClone() object.ReferenceEquals(object, object) object.ToString()
Namespace Meadow.Foundation.Sensors.Atmospheric
Assembly Bme280.dll

Syntax

public class Bme280 : PollingSensorBase<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>, IObservable<IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>>, ISamplingSensor<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>, ISensor<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>, ITemperatureSensor, ISamplingSensor<Temperature>, ISensor<Temperature>, IHumiditySensor, ISamplingSensor<RelativeHumidity>, ISensor<RelativeHumidity>, IBarometricPressureSensor, ISamplingSensor<Pressure>, ISensor<Pressure>, ISpiPeripheral, II2cPeripheral, IDisposable

Constructors

Bme280(II2cBus, byte)

Initializes a new instance of the BME280 class

Declaration
public Bme280(II2cBus i2cBus, byte address = 118)

Parameters

Type Name Description
II2cBus i2cBus

I2C Bus to use for communicating with the sensor

byte address

I2C address of the sensor (default = 0x77)

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

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

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

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

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Fields

configuration

Sensor configuration

Declaration
protected Bme280.Configuration configuration

Field Value

Type Description
Bme280.Configuration

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

readBuffer

The read buffer

Declaration
protected Memory<byte> readBuffer

Field Value

Type Description
Memory<byte>

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

writeBuffer

The write buffer

Declaration
protected Memory<byte> writeBuffer

Field Value

Type Description
Memory<byte>

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Properties

DefaultI2cAddress

The default I2C address for the peripheral

Declaration
public byte DefaultI2cAddress { get; }

Property Value

Type Description
byte

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

DefaultSpiBusMode

The default SPI bus mode for the device

Declaration
public SpiClockConfiguration.Mode DefaultSpiBusMode { get; }

Property Value

Type Description
SpiClockConfiguration.Mode

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

DefaultSpiBusSpeed

The default SPI bus speed for the device

Declaration
public Frequency DefaultSpiBusSpeed { get; }

Property Value

Type Description
Frequency

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Humidity

The humidity, in percent relative humidity, from the last reading..

Declaration
public RelativeHumidity? Humidity { get; }

Property Value

Type Description
RelativeHumidity?

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

HumiditySampleCount

Humidity oversample count

Declaration
public Bme280.Oversample HumiditySampleCount { get; set; }

Property Value

Type Description
Bme280.Oversample

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

IsDisposed

Is the object disposed

Declaration
public bool IsDisposed { get; }

Property Value

Type Description
bool

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

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
Pressure?

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

PressureSampleCount

Pressure oversample count

Declaration
public Bme280.Oversample PressureSampleCount { get; set; }

Property Value

Type Description
Bme280.Oversample

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

SpiBusMode

The SPI bus mode for the device

Declaration
public SpiClockConfiguration.Mode SpiBusMode { get; set; }

Property Value

Type Description
SpiClockConfiguration.Mode

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

SpiBusSpeed

The SPI bus speed for the device

Declaration
public Frequency SpiBusSpeed { get; set; }

Property Value

Type Description
Frequency

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Temperature

The temperature from the last reading

Declaration
public Temperature? Temperature { get; }

Property Value

Type Description
Temperature?

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

TemperatureSampleCount

Temperature oversample count

Declaration
public Bme280.Oversample TemperatureSampleCount { get; set; }

Property Value

Type Description
Bme280.Oversample

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Methods

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Declaration
public void Dispose()

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Dispose(bool)

Dispose of the object

Declaration
protected virtual void Dispose(bool disposing)

Parameters

Type Name Description
bool disposing

Is disposing

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

GetChipID()

Get the chip ID

Declaration
public byte GetChipID()

Returns

Type Description
byte

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

Initialize()

Initialize the sensor

Declaration
protected void Initialize()

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

RaiseEventsAndNotify(IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>)

Raise events for subscribers and notify of value changes

Declaration
protected override void RaiseEventsAndNotify(IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> changeResult)

Parameters

Type Name Description
IChangeResult<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> changeResult

The updated sensor data

Overrides

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

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<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)> ReadSensor()

Returns

Type Description
Task<(Temperature? Temperature, RelativeHumidity? Humidity, Pressure? Pressure)>

Overrides

Meadow.Foundation.SamplingSensorBase<(Meadow.Units.Temperature? Temperature, Meadow.Units.RelativeHumidity? Humidity, Meadow.Units.Pressure? Pressure)>.ReadSensor()

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 per formant.

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(TimeSpan?)

Start updating

Declaration
public override void StartUpdating(TimeSpan? updateInterval = null)

Parameters

Type Name Description
TimeSpan? updateInterval

The update inverval

Overrides

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

UpdateConfiguration(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>>

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

PressureUpdated

Pressure changed event

Declaration
public event EventHandler<IChangeResult<Pressure>> PressureUpdated

Event Type

Type Description
EventHandler<IChangeResult<Pressure>>

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.

TemperatureUpdated

Temperature changed event

Declaration
public event EventHandler<IChangeResult<Temperature>> TemperatureUpdated

Event Type

Type Description
EventHandler<IChangeResult<Temperature>>

Remarks

Bme280
Status Status badge: working
Source code GitHub
Datasheet(s) GitHub
NuGet package NuGet Gallery for Meadow.Foundation.Sensors.Atmospheric.Bme280

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 =>
        {
            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.