/// <summary>
        /// Read coefficient data from device.
        /// </summary>
        /// <param name="bme680">The <see cref="Bme680"/> to read coefficient data from.</param>
        internal void ReadFromDevice(Bme680 bme680)
        {
            // Temperature.
            TCal1 = (ushort)bme680.Read16Bits(Register.temp_cal_1);
            TCal2 = bme680.Read16Bits(Register.temp_cal_2);
            TCal3 = bme680.Read8Bits(Register.temp_cal_3);

            // Humidity.
            HCal1 = (ushort)((bme680.Read8Bits(Register.hum_cal_1_msb) << 4) | (bme680.Read8Bits(Register.hum_cal_1_lsb) & 0b_0000_1111));
            HCal2 = (ushort)((bme680.Read8Bits(Register.hum_cal_2_msb) << 4) | (bme680.Read8Bits(Register.hum_cal_2_lsb) >> 4));
            HCal3 = (sbyte)bme680.Read8Bits(Register.hum_cal_3);
            HCal4 = (sbyte)bme680.Read8Bits(Register.hum_cal_4);
            HCal5 = (sbyte)bme680.Read8Bits(Register.hum_cal_5);
            HCal6 = bme680.Read8Bits(Register.hum_cal_6);
            HCal7 = (sbyte)(bme680.Read8Bits(Register.hum_cal_7));

            // Pressure.
            PCal1  = (ushort)bme680.Read16Bits(Register.pres_cal_1_lsb);
            PCal2  = bme680.Read16Bits(Register.pres_cal_2_lsb);
            PCal3  = bme680.Read8Bits(Register.pres_cal_3);
            PCal4  = bme680.Read16Bits(Register.pres_cal_4_lsb);
            PCal5  = bme680.Read16Bits(Register.pres_cal_5_lsb);
            PCal6  = bme680.Read8Bits(Register.pres_cal_6);
            PCal7  = bme680.Read8Bits(Register.pres_cal_7);
            PCal8  = bme680.Read16Bits(Register.pres_cal_8_lsb);
            PCal9  = bme680.Read16Bits(Register.pres_cal_9_lsb);
            PCal10 = bme680.Read8Bits(Register.pres_cal_10);
        }
        public override bool Configure(string jsonDeviceConfiguration)
        {
            var config      = DeserializeDeviceConfig <Bme680Configuration>(jsonDeviceConfiguration);
            var i2CSettings = new I2cConnectionSettings(1, config.I2CAddress);
            var i2CDevice   = I2cDevice.Create(i2CSettings);

            // TODO: probably requires try catch?! Check device availability
            _bme680 = new Bme680(i2CDevice);

            SetDefaultConfiguration();
            SetPropertiesFromConfig(config);
            SetHeaterProfilesFromConfig(config);

            _measurementDuration = _bme680.GetMeasurementDuration(_bme680.HeaterProfile);
            return(true);
        }
Example #3
0
        internal void ReadFromDevice(Bme680 bme680)
        {
            // load humidity calibration data
            ParH1 = (ushort)((bme680.Read8BitsFromRegister((byte)Register.PAR_H1_MSB) << 4) |
                             (bme680.Read8BitsFromRegister((byte)Register.PAR_H1_LSB) & (byte)Mask.BIT_H1_DATA_MSK));
            ParH2 = (ushort)((bme680.Read8BitsFromRegister((byte)Register.PAR_H2_MSB) << 4) |
                             (bme680.Read8BitsFromRegister((byte)Register.PAR_H2_LSB) >> 4));
            ParH3 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_H3);
            ParH4 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_H4);
            ParH5 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_H5);
            ParH6 = bme680.Read8BitsFromRegister((byte)Register.PAR_H6);
            ParH7 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_H7);

            // load gas calibration data
            ParGh1 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_GH1);
            ParGh2 = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_GH2);
            ParGh3 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_GH3);

            // load temperature calibration data
            ParT1 = bme680.Read16BitsFromRegister((byte)Register.PAR_T1);
            ParT2 = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_T2);
            ParT3 = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_T3);

            // load pressure calibration data
            ParP1  = bme680.Read16BitsFromRegister((byte)Register.PAR_P1);
            ParP2  = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_P2);
            ParP3  = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_P3);
            ParP4  = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_P4);
            ParP5  = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_P5);
            ParP6  = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_P6);
            ParP7  = (sbyte)bme680.Read8BitsFromRegister((byte)Register.PAR_P7);
            ParP8  = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_P8);
            ParP9  = (short)bme680.Read16BitsFromRegister((byte)Register.PAR_P9);
            ParP10 = bme680.Read8BitsFromRegister((byte)Register.PAR_P10);

            // load heater calibration data
            var rangeReg = bme680.Read8BitsFromRegister((byte)Register.RES_HEAT_RANGE);

            ResHeatRange = (byte)((rangeReg & (byte)Mask.RH_RANGE) >> 4);

            var rangeSwReg = bme680.Read8BitsFromRegister((byte)Register.RANGE_SW_ERR);

            RangeSwErr = (sbyte)((rangeSwReg & (byte)Mask.RS_ERROR) >> 4);

            ResHeatVal = (sbyte)bme680.Read8BitsFromRegister((byte)Register.RES_HEAT_VAL);
        }
Example #4
0
        static async Task Main(string[] args)
        {
            // The BME680 uses either 0x76 or 0x77 as I2C address, the address has to be specified here
            var settings  = new I2cConnectionSettings(1, Bme680.SecondaryI2cAddress);
            var i2CDevice = I2cDevice.Create(settings);

            using var bme680 = new Bme680(i2CDevice);

            // set custom device settings (A higher sampling also increases the time a measurement will take)
            // A sampling rate of X4 will take roughly 4 times longer than a sampling rate of X1
            // You can find out how long a measurement will take by using the method GetProfileDuration()
            bme680.HumiditySampling    = Sampling.X4;
            bme680.TemperatureSampling = Sampling.X1;
            bme680.PressureSampling    = Sampling.Skipped;
            bme680.FilterCoefficient   = FilterCoefficient.C31;

            // set custom settings for gas conversion
            bme680.GasConversionIsEnabled = true;
            bme680.HeaterIsEnabled        = true;

            // The BME680 sensor can save up to 10 heater profiles for use
            // this profile will set the target temperature of the heating plate to 330°C
            // with a heating duration of 120ms and an ambient temperature of 24.0°C
            bme680.SaveHeaterProfileToDevice(HeaterProfile.Profile3, 330, 120, 24.0);
            bme680.CurrentHeaterProfile = HeaterProfile.Profile3;

            Console.WriteLine("Performing measurements with custom configuration:\n");
            while (true)
            {
                // perform the measurement
                var measurement = await bme680.PerformMeasurementAsync();

                // print results
                Console.WriteLine($"Temperature: {measurement.Temperature:0.##}°C");
                Console.WriteLine($"Humidity: {measurement.Humidity:0.##}%");
                Console.WriteLine($"Pressure: {measurement.Pressure:0.##} Pa");
                Console.WriteLine($"Gas Resistance: {measurement.GasResistance:0.##} Ohm");
                Console.WriteLine();

                // it can make sense to update the heater profile continually since the ambient temperature
                // is taken into account when the heater profile is set
                bme680.SaveHeaterProfileToDevice(HeaterProfile.Profile3, 330, 120, measurement.Temperature);

                Task.Delay(1000).Wait();
            }
        }
Example #5
0
        public MeadowApp()
        {
            Console.WriteLine("Initializing...");

            // configure our BME280 on the I2C Bus
            var i2c = Device.CreateI2cBus();

            bme680 = new Bme680(
                i2c
                //Bme680.I2cAddress.Adddress0x77 //Might need this enum
                );

            //// Example that uses an IObersvable subscription to only be notified
            //// when the temperature changes by at least a degree, and humidty by 5%.
            //// (blowing hot breath on the sensor should trigger)
            //bme680.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:
            //bme680.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}%");
            //};


            //// just for funsies.
            //Console.WriteLine($"ChipID: {bme680.GetChipID():X2}");
            ////Thread.Sleep(1000);

            // get an initial reading
            ReadConditions().Wait();

            //// start updating continuously
            //bme680.StartUpdating();
        }
Example #6
0
        /// <summary>
        /// Main entry point for the program.
        /// </summary>
        static async Task Main()
        {
            Console.WriteLine("Hello BME680!");

            // The I2C bus ID on the Raspberry Pi 3.
            const int busId = 1;

            var i2cSettings   = new I2cConnectionSettings(busId, Bme680.DefaultI2cAddress);
            var unixI2cDevice = I2cDevice.Create(i2cSettings);

            using (var bme680 = new Bme680(unixI2cDevice))
            {
                // Prevents reading old data from the sensor's registers.
                bme680.Reset();

                bme680.SetHumiditySampling(Sampling.UltraLowPower);
                bme680.SetTemperatureSampling(Sampling.LowPower);
                bme680.SetPressureSampling(Sampling.UltraHighResolution);

                while (true)
                {
                    // Once a reading has been taken, the sensor goes back to sleep mode.
                    if (bme680.ReadPowerMode() == Bme680PowerMode.Sleep)
                    {
                        // This instructs the sensor to take a measurement.
                        bme680.SetPowerMode(Bme680PowerMode.Forced);
                    }

                    // This prevent us from reading old data from the sensor.
                    if (bme680.ReadHasNewData())
                    {
                        var temperature = Math.Round((await bme680.ReadTemperatureAsync()).Celsius, 2).ToString("N2");
                        var pressure    = Math.Round(await bme680.ReadPressureAsync() / 100, 2).ToString("N2");
                        var humidity    = Math.Round(await bme680.ReadHumidityAsync(), 2).ToString("N2");

                        Console.WriteLine($"{temperature} °c | {pressure} hPa | {humidity} %rH");

                        Thread.Sleep(1000);
                    }
                }
            }
        }
Example #7
0
        static async Task Main(string[] args)
        {
            // The BME680 uses either 0x76 or 0x77 as I2C address, the address has to be specified here
            var settings  = new I2cConnectionSettings(1, Bme680.DefaultI2cAddress);
            var i2CDevice = I2cDevice.Create(settings);

            using var bme680 = new Bme680(i2CDevice);

            while (true)
            {
                var measurement = await bme680.PerformMeasurementAsync();

                Console.WriteLine($"Temperature: {measurement.Temperature:0.##}°C");
                Console.WriteLine($"Humidity: {measurement.Humidity:0.##}%");
                Console.WriteLine($"Pressure: {measurement.Pressure:0.##} Pa");
                Console.WriteLine($"Gas Resistance: {measurement.GasResistance:0.##} Ohm");
                Console.WriteLine();

                await Task.Delay(1000);
            }
        }
Example #8
0
        /// <summary>
        /// Main entry point for the program.
        /// </summary>
        public static void Main()
        {
            Console.WriteLine("Hello BME680!");

            // The I2C bus ID on the Raspberry Pi 3.
            const int busId = 1;
            // set this to the current sea level pressure in the area for correct altitude readings
            var defaultSeaLevelPressure = WeatherHelper.MeanSeaLevel;

            var i2cSettings = new I2cConnectionSettings(busId, Bme680.DefaultI2cAddress);
            var i2cDevice   = I2cDevice.Create(i2cSettings);

            using (var bme680 = new Bme680(i2cDevice))
            {
                while (true)
                {
                    // get the time a measurement will take with the current settings
                    var measurementDuration = bme680.GetMeasurementDuration(bme680.HeaterProfile);

                    // 10 consecutive measurement with default settings
                    for (var i = 0; i < 10; i++)
                    {
                        // This instructs the sensor to take a measurement.
                        bme680.SetPowerMode(Bme680PowerMode.Forced);

                        // wait while measurement is being taken
                        Thread.Sleep(measurementDuration);

                        // Print out the measured data
                        bme680.TryReadTemperature(out var tempValue);
                        bme680.TryReadPressure(out var preValue);
                        bme680.TryReadHumidity(out var humValue);
                        bme680.TryReadGasResistance(out var gasResistance);
                        var altValue = WeatherHelper.CalculateAltitude(preValue, defaultSeaLevelPressure, tempValue);

                        Console.WriteLine($"Gas resistance: {gasResistance:0.##}Ohm");
                        Console.WriteLine($"Temperature: {tempValue.DegreesCelsius:0.#}\u00B0C");
                        Console.WriteLine($"Pressure: {preValue.Hectopascals:0.##}hPa");
                        Console.WriteLine($"Altitude: {altValue:0.##}m");
                        Console.WriteLine($"Relative humidity: {humValue:0.#}%");

                        // WeatherHelper supports more calculations, such as saturated vapor pressure, actual vapor pressure and absolute humidity.
                        Console.WriteLine($"Heat index: {WeatherHelper.CalculateHeatIndex(tempValue, humValue).DegreesCelsius:0.#}\u00B0C");
                        Console.WriteLine($"Dew point: {WeatherHelper.CalculateDewPoint(tempValue, humValue).DegreesCelsius:0.#}\u00B0C");

                        // when measuring the gas resistance on each cycle it is important to wait a certain interval
                        // because a heating plate is activated which will heat up the sensor without sleep, this can
                        // falsify all readings coming from the sensor
                        Thread.Sleep(1000);
                    }

                    // change the settings
                    bme680.TemperatureSampling = Sampling.HighResolution;
                    bme680.HumiditySampling    = Sampling.UltraHighResolution;
                    bme680.PressureSampling    = Sampling.Skipped;

                    bme680.ConfigureHeatingProfile(Bme680HeaterProfile.Profile2, 280, 80, 24);
                    bme680.HeaterProfile = Bme680HeaterProfile.Profile2;

                    measurementDuration = bme680.GetMeasurementDuration(bme680.HeaterProfile);

                    // 10 consecutive measurements with custom settings
                    for (int i = 0; i < 10; i++)
                    {
                        // perform the measurement
                        bme680.SetPowerMode(Bme680PowerMode.Forced);
                        Thread.Sleep(measurementDuration);

                        // Print out the measured data
                        bme680.TryReadTemperature(out var tempValue);
                        bme680.TryReadPressure(out var preValue);
                        bme680.TryReadHumidity(out var humValue);
                        bme680.TryReadGasResistance(out var gasResistance);
                        var altValue = WeatherHelper.CalculateAltitude(preValue, defaultSeaLevelPressure, tempValue);

                        Console.WriteLine($"Gas resistance: {gasResistance:0.##}Ohm");
                        Console.WriteLine($"Temperature: {tempValue.DegreesCelsius:0.#}\u00B0C");
                        Console.WriteLine($"Pressure: {preValue.Hectopascals:0.##}hPa");
                        Console.WriteLine($"Altitude: {altValue:0.##}m");
                        Console.WriteLine($"Relative humidity: {humValue:0.#}%");

                        // WeatherHelper supports more calculations, such as saturated vapor pressure, actual vapor pressure and absolute humidity.
                        Console.WriteLine($"Heat index: {WeatherHelper.CalculateHeatIndex(tempValue, humValue).DegreesCelsius:0.#}\u00B0C");
                        Console.WriteLine($"Dew point: {WeatherHelper.CalculateDewPoint(tempValue, humValue).DegreesCelsius:0.#}\u00B0C");
                        Thread.Sleep(1000);
                    }

                    // reset will change settings back to default
                    bme680.Reset();
                }
            }
        }
Example #9
0
        /// <summary>
        /// Main entry point for the program.
        /// </summary>
        static void Main()
        {
            Console.WriteLine("Hello BME680!");

            // The I2C bus ID on the Raspberry Pi 3.
            const int busId = 1;

            var i2cSettings = new I2cConnectionSettings(busId, Bme680.DefaultI2cAddress);
            var i2cDevice   = I2cDevice.Create(i2cSettings);

            using (var bme680 = new Bme680(i2cDevice))
            {
                while (true)
                {
                    // get the time a measurement will take with the current settings
                    var measurementDuration = bme680.GetMeasurementDuration(bme680.HeaterProfile);

                    // 10 consecutive measurement with default settings
                    for (var i = 0; i < 10; i++)
                    {
                        // This instructs the sensor to take a measurement.
                        bme680.SetPowerMode(Bme680PowerMode.Forced);

                        // wait while measurement is being taken
                        Thread.Sleep(measurementDuration);

                        // Print out the measured data
                        bme680.TryReadTemperature(out var temperature);
                        bme680.TryReadPressure(out var pressure);
                        bme680.TryReadHumidity(out var humidity);
                        bme680.TryReadGasResistance(out var gasResistance);

                        Console.WriteLine($"{temperature.Celsius:N2} \u00B0C | {pressure.Hectopascal:N2} hPa | {humidity:N2} %rH | {gasResistance:N2} Ohm");

                        // when measuring the gas resistance on each cycle it is important to wait a certain interval
                        // because a heating plate is activated which will heat up the sensor without sleep, this can
                        // falsify all readings coming from the sensor
                        Thread.Sleep(1000);
                    }

                    // change the settings
                    bme680.TemperatureSampling = Sampling.HighResolution;
                    bme680.HumiditySampling    = Sampling.UltraHighResolution;
                    bme680.PressureSampling    = Sampling.Skipped;

                    bme680.ConfigureHeatingProfile(Bme680HeaterProfile.Profile2, 280, 80, 24);
                    bme680.HeaterProfile = Bme680HeaterProfile.Profile2;

                    measurementDuration = bme680.GetMeasurementDuration(bme680.HeaterProfile);

                    // 10 consecutive measurements with custom settings
                    for (int i = 0; i < 10; i++)
                    {
                        // perform the measurement
                        bme680.SetPowerMode(Bme680PowerMode.Forced);
                        Thread.Sleep(measurementDuration);

                        // Print out the measured data
                        bme680.TryReadTemperature(out var temperature);
                        bme680.TryReadPressure(out var pressure);
                        bme680.TryReadHumidity(out var humidity);
                        bme680.TryReadGasResistance(out var gasResistance);

                        Console.WriteLine($"{temperature.Celsius:N2} \u00B0C | {pressure.Hectopascal:N2} hPa | {humidity:N2} %rH | {gasResistance:N2} Ohm");
                        Thread.Sleep(1000);
                    }

                    // reset will change settings back to default
                    bme680.Reset();
                }
            }
        }
 public void Dispose()
 {
     _bme680?.Dispose();
     _bme680 = null;
 }
Example #11
0
        /// <summary>
        /// Main entry point for the program.
        /// </summary>
        static int Main(string[] args)
        {
            // Parse options passed from the command line.
            var parseResult = Parser.Default.ParseArguments <Options>(args).WithParsed(options => _options = options);

            if (parseResult is NotParsed <Options> )
            {
                // Invalid options passed to program, exit with non-ok status code.
                return(-1);
            }

            if (_options.Quiet == false)
            {
                Console.WriteLine("Hello BME680!");
            }

            // The I2C bus ID on the Raspberry Pi 3.
            const int busId = 1;

            var i2cConnectionSettings = new I2cConnectionSettings(busId, Bme680.DefaultI2cAddress);
            var unixI2cDevice         = new UnixI2cDevice(i2cConnectionSettings);

            using (var bme680 = new Bme680(unixI2cDevice))
            {
                bme680.Reset();
                bme680.SetHumidityOversampling(Oversampling.x1);
                bme680.SetTemperatureOversampling(Oversampling.x2);
                bme680.SetPressureOversampling(Oversampling.x16);

                while (true)
                {
                    // Once a reading has been taken, the sensor goes back to sleep mode.
                    if (bme680.PowerMode == PowerMode.Sleep)
                    {
                        // This instructs the sensor to take a measurement.
                        bme680.SetPowerMode(PowerMode.Forced);
                    }

                    // This prevent us from reading old data from the sensor.
                    if (bme680.HasNewData)
                    {
                        var reading = new
                        {
                            Temperature = Math.Round(bme680.Temperature.Celsius, 2).ToString("N2"),
                            Pressure    = Math.Round(bme680.Pressure / 100, 2).ToString("N2"),
                            Humidity    = Math.Round(bme680.Humidity, 2).ToString("N2")
                        };

                        if (_options.JsonOutput)
                        {
                            Console.WriteLine(JsonConvert.SerializeObject(reading));
                        }
                        else
                        {
                            Console.WriteLine($"{reading.Temperature} °c | {reading.Pressure} hPa | {reading.Humidity} %rH");
                        }

                        Thread.Sleep(1000);
                    }
                }
            }
        }