From ffa9bf9b5bb3b342ff0bdc844e3f398c4330f1a2 Mon Sep 17 00:00:00 2001 From: Denis-Cosmin NUTIU Date: Sat, 16 Nov 2024 14:44:51 +0200 Subject: [PATCH 01/11] prepare v0.9.0 --- Cargo.toml | 11 +++++++---- README.md | 2 +- src/lib.rs | 56 ------------------------------------------------------ 3 files changed, 8 insertions(+), 61 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d632b1d..7bcf6d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,19 +5,22 @@ documentation = "https://github.com/dnutiu/bme680-rust" license = "MIT" name = "bme680" repository = "https://github.com/dnutiu/bme680-rust" -version = "0.8.0" +version = "0.9.0" edition = "2021" [badges] maintenance = { status = "passively-maintained" } [dependencies] -bitflags = "1.2" +bitflags = "2.6.0" embedded-hal = "=1.0.0" log = "0.4" serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] } linux-embedded-hal = "0.4.0" -anyhow = "1.0.80" +anyhow = { version = "1.0.80" , default-features = false} [dev-dependencies] -env_logger = "0.9" \ No newline at end of file +env_logger = "0.11.5" + +[target.'cfg(target_os = "linux")'.dependencies] +linux-embedded-hal = "0.4.0" \ No newline at end of file diff --git a/README.md b/README.md index 461a878..262fd9c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ To use this library, create a new project and add it as a dependency: ```toml [dependencies] -bme680 = {git = "https://github.com/dnutiu/bme680-rust.git", version = "0.8.0"} +bme680 = {git = "https://github.com/dnutiu/bme680-rust.git", version = "0.9.0"} ``` # Alternative diff --git a/src/lib.rs b/src/lib.rs index dd65499..c5f0ffa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,62 +3,6 @@ //! //! The library uses the embedded-hal crate to abstract reading and writing via I²C. //! In the examples you can find a demo how to use the library in Linux using the linux-embedded-hal crate (e.g. on a RPI). -//! ```no_run - -//! use bme680::{Bme680, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder}; -//! use core::time::Duration; -//! use embedded_hal::delay::DelayNs; -//! use linux_embedded_hal as hal; -//! use linux_embedded_hal::Delay; -//! use log::info; -//! use bme680::i2c::Address; -//! -//! // Please export RUST_LOG=info in order to see logs in the console. -//! fn main() -> Result<(), anyhow::Error> -//! { -//! env_logger::init(); -//! -//! let i2c = hal::I2cdev::new("/dev/i2c-1").unwrap(); -//! let mut delayer = Delay {}; -//! -//! let mut dev = Bme680::init(i2c, &mut delayer, Address::Primary)?; -//! let mut delay = Delay {}; -//! -//! let settings = SettingsBuilder::new() -//! .with_humidity_oversampling(OversamplingSetting::OS2x) -//! .with_pressure_oversampling(OversamplingSetting::OS4x) -//! .with_temperature_oversampling(OversamplingSetting::OS8x) -//! .with_temperature_filter(IIRFilterSize::Size3) -//! .with_gas_measurement(Duration::from_millis(1500), 320, 25) -//! .with_temperature_offset(-2.2) -//! .with_run_gas(true) -//! .build(); -//! -//! let profile_dur = dev.get_profile_duration(&settings.0)?; -//! info!("Profile duration {:?}", profile_dur); -//! info!("Setting sensor settings"); -//! dev.set_sensor_settings(&mut delayer, settings)?; -//! info!("Setting forced power modes"); -//! dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; -//! -//! let sensor_settings = dev.get_sensor_settings(settings.1); -//! info!("Sensor settings: {:?}", sensor_settings); -//! -//! loop { -//! let _ = delay.delay_ms(5000u32); -//! let power_mode = dev.get_sensor_mode(); -//! info!("Sensor power mode: {:?}", power_mode); -//! info!("Setting forced power modes"); -//! dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; -//! info!("Retrieving sensor data"); -//! let (data, _state) = dev.get_measurement(&mut delayer)?; -//! info!("Sensor Data {:?}", data); -//! info!("Temperature {}°C", data.temperature_celsius()); -//! info!("Pressure {}hPa", data.pressure_hpa()); -//! info!("Humidity {}%", data.humidity_percent()); -//! info!("Gas Resistence {}Ω", data.gas_resistance_ohm()); -//! } -//! } #![no_std] #![forbid(unsafe_code)] From 877c8bb6bc32dd5322c04814a83a03b3ca3c2c7e Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 15:23:30 +0200 Subject: [PATCH 02/11] Downgrade bitflags back to version 1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7bcf6d1..c0a29c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" maintenance = { status = "passively-maintained" } [dependencies] -bitflags = "2.6.0" +bitflags = "1.3.2" embedded-hal = "=1.0.0" log = "0.4" serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] } From 46c0c67c67b0f5516aeaefcf853a7eb2bfe8d0c8 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 16:05:40 +0200 Subject: [PATCH 03/11] Add complete example for reading sensor data --- README.md | 27 +++++++++++--- examples/read-sensor-data/Cargo.toml | 12 +++++++ examples/read-sensor-data/src/main.rs | 52 +++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 examples/read-sensor-data/Cargo.toml create mode 100644 examples/read-sensor-data/src/main.rs diff --git a/README.md b/README.md index 262fd9c..1fab7fc 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,15 @@ To use this library, create a new project and add it as a dependency: bme680 = {git = "https://github.com/dnutiu/bme680-rust.git", version = "0.9.0"} ``` -# Alternative -[drogue-bme680](https://github.com/drogue-iot/drogue-bme680) +# Getting started on Raspberry Pi -# Example getting started Linux +Assuming that you have connected the sensor to the Raspberry PI's GPIO ports. + +Install required libraries for developing I2C. + +```bash +sudo apt-get install build-essential libi2c-dev i2c-tools python-dev libffi-dev +``` Determine the I2C device path @@ -39,4 +44,18 @@ pi@raspberrypi:~ $ i2cdetect -y 1 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 -``` \ No newline at end of file +``` + +The read-sensor-data from the examples folder is configured to use the I2C device `/dev/i2c-1` and the `0x76` address. + +To run the example, clone the repository and go to the examples' folder: + +```bash +git clone https://github.com/dnutiu/bme680-rust.git && cd bme680-rust/examples/read-sensor-data +``` +Then run the example: + +```bash +export RUST_LOG=info +cargo run +``` diff --git a/examples/read-sensor-data/Cargo.toml b/examples/read-sensor-data/Cargo.toml new file mode 100644 index 0000000..a93b21a --- /dev/null +++ b/examples/read-sensor-data/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "read-sensor-data" +version = "0.1.0" +edition = "2021" + +[dependencies] +bme680 = {path = "../"} +env_logger = "0.11.5" +linux-embedded-hal = "0.4.0" +anyhow = { version = "1.0.80" } +log = "0.4" +embedded-hal = "=1.0.0" \ No newline at end of file diff --git a/examples/read-sensor-data/src/main.rs b/examples/read-sensor-data/src/main.rs new file mode 100644 index 0000000..bfbcf3e --- /dev/null +++ b/examples/read-sensor-data/src/main.rs @@ -0,0 +1,52 @@ +use bme680::i2c::Address; +use bme680::{Bme680, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder}; +use core::time::Duration; +use embedded_hal::delay::DelayNs; +use linux_embedded_hal as hal; +use linux_embedded_hal::Delay; +use log::info; + +// Please export RUST_LOG=info in order to see logs in the console. +fn main() -> Result<(), anyhow::Error> { + env_logger::init(); + + let i2c = hal::I2cdev::new("/dev/i2c-1").unwrap(); + let mut delayer = Delay {}; + + let mut dev = Bme680::init(i2c, &mut delayer, Address::Primary)?; + let mut delay = Delay {}; + + let settings = SettingsBuilder::new() + .with_humidity_oversampling(OversamplingSetting::OS2x) + .with_pressure_oversampling(OversamplingSetting::OS4x) + .with_temperature_oversampling(OversamplingSetting::OS8x) + .with_temperature_filter(IIRFilterSize::Size3) + .with_gas_measurement(Duration::from_millis(1500), 320, 23) + .with_run_gas(true) + .build(); + + let profile_dur = dev.get_profile_duration(&settings.0)?; + info!("Profile duration {:?}", profile_dur); + info!("Setting sensor settings"); + dev.set_sensor_settings(&mut delayer, settings)?; + info!("Setting forced power modes"); + dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; + + let sensor_settings = dev.get_sensor_settings(settings.1); + info!("Sensor settings: {:?}", sensor_settings); + + loop { + let _ = delay.delay_ms(5000u32); + let power_mode = dev.get_sensor_mode(); + info!("Sensor power mode: {:?}", power_mode); + info!("Setting forced power modes"); + dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; + info!("Retrieving sensor data"); + let (data, _state) = dev.get_measurement(&mut delayer)?; + info!("Sensor Data {:?}", data); + info!("Temperature {}°C", data.temperature_celsius()); + info!("Pressure {}hPa", data.pressure_hpa()); + info!("Humidity {}%", data.humidity_percent()); + info!("Gas Resistence {}Ω", data.gas_resistance_ohm()); + } +} \ No newline at end of file From c3b200bae933a10ca9a1c696938e946c45ae36cc Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 16:26:16 +0200 Subject: [PATCH 04/11] Fix example path --- examples/read-sensor-data/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/read-sensor-data/Cargo.toml b/examples/read-sensor-data/Cargo.toml index a93b21a..2fbb188 100644 --- a/examples/read-sensor-data/Cargo.toml +++ b/examples/read-sensor-data/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -bme680 = {path = "../"} +bme680 = {path = "../../"} env_logger = "0.11.5" linux-embedded-hal = "0.4.0" anyhow = { version = "1.0.80" } From 3e09c525483a9fdeef1599c3fd2d27e93fe22ff9 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 16:41:00 +0200 Subject: [PATCH 05/11] Update bitflags to 2.6 --- Cargo.toml | 4 ++-- examples/read_sensor_data.rs | 2 +- src/lib.rs | 2 +- src/settings.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0a29c8..3b6e3dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,12 +12,12 @@ edition = "2021" maintenance = { status = "passively-maintained" } [dependencies] -bitflags = "1.3.2" +bitflags = "2.6" embedded-hal = "=1.0.0" log = "0.4" serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] } linux-embedded-hal = "0.4.0" -anyhow = { version = "1.0.80" , default-features = false} +anyhow = { version = "1.0" , default-features = false} [dev-dependencies] env_logger = "0.11.5" diff --git a/examples/read_sensor_data.rs b/examples/read_sensor_data.rs index dfa9243..4c6097b 100644 --- a/examples/read_sensor_data.rs +++ b/examples/read_sensor_data.rs @@ -30,7 +30,7 @@ fn main() -> Result<(), anyhow::Error> { let profile_dur = dev.get_profile_duration(&settings.0)?; info!("Profile duration {:?}", profile_dur); info!("Setting sensor settings"); - dev.set_sensor_settings(&mut delayer, settings)?; + dev.set_sensor_settings(&mut delayer, &settings)?; info!("Setting forced power modes"); dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; diff --git a/src/lib.rs b/src/lib.rs index c5f0ffa..ff0a5a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -360,7 +360,7 @@ where pub fn set_sensor_settings( &mut self, delay: &mut D, - settings: Settings, + settings: &Settings, ) -> Result<(), anyhow::Error> { let (sensor_settings, desired_settings) = settings; let tph_sett = sensor_settings.temperature_settings; diff --git a/src/settings.rs b/src/settings.rs index 56cff0d..0bfa31f 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -140,7 +140,7 @@ bitflags! { /// To set NB conversion setting. const NBCONV_SEL = 128; /// To set all gas sensor related settings - const GAS_SENSOR_SEL = Self::GAS_MEAS_SEL.bits | Self::RUN_GAS_SEL.bits | Self::NBCONV_SEL.bits; + const GAS_SENSOR_SEL = Self::GAS_MEAS_SEL.bits() | Self::RUN_GAS_SEL.bits() | Self::NBCONV_SEL.bits(); } } From cd6f7a34cd2b9cd96e27d26c8c2a63e9b109e06f Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 16:42:20 +0200 Subject: [PATCH 06/11] delete old example file --- examples/read_sensor_data.rs | 54 ------------------------------------ 1 file changed, 54 deletions(-) delete mode 100644 examples/read_sensor_data.rs diff --git a/examples/read_sensor_data.rs b/examples/read_sensor_data.rs deleted file mode 100644 index 4c6097b..0000000 --- a/examples/read_sensor_data.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![no_std] - -use bme680::i2c::Address; -use bme680::{Bme680, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder}; -use core::time::Duration; -use embedded_hal::delay::DelayNs; -use linux_embedded_hal as hal; -use linux_embedded_hal::Delay; -use log::info; - -// Please export RUST_LOG=info in order to see logs in the console. -fn main() -> Result<(), anyhow::Error> { - env_logger::init(); - - let i2c = hal::I2cdev::new("/dev/i2c-1").unwrap(); - let mut delayer = Delay {}; - - let mut dev = Bme680::init(i2c, &mut delayer, Address::Primary)?; - let mut delay = Delay {}; - - let settings = SettingsBuilder::new() - .with_humidity_oversampling(OversamplingSetting::OS2x) - .with_pressure_oversampling(OversamplingSetting::OS4x) - .with_temperature_oversampling(OversamplingSetting::OS8x) - .with_temperature_filter(IIRFilterSize::Size3) - .with_gas_measurement(Duration::from_millis(1500), 320, 23) - .with_run_gas(true) - .build(); - - let profile_dur = dev.get_profile_duration(&settings.0)?; - info!("Profile duration {:?}", profile_dur); - info!("Setting sensor settings"); - dev.set_sensor_settings(&mut delayer, &settings)?; - info!("Setting forced power modes"); - dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; - - let sensor_settings = dev.get_sensor_settings(settings.1); - info!("Sensor settings: {:?}", sensor_settings); - - loop { - let _ = delay.delay_ms(5000u32); - let power_mode = dev.get_sensor_mode(); - info!("Sensor power mode: {:?}", power_mode); - info!("Setting forced power modes"); - dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; - info!("Retrieving sensor data"); - let (data, _state) = dev.get_measurement(&mut delayer)?; - info!("Sensor Data {:?}", data); - info!("Temperature {}°C", data.temperature_celsius()); - info!("Pressure {}hPa", data.pressure_hpa()); - info!("Humidity {}%", data.humidity_percent()); - info!("Gas Resistence {}Ω", data.gas_resistance_ohm()); - } -} From 6a26ba4397b3fc37b57609dde6a14c8f9be81a1b Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 16:43:18 +0200 Subject: [PATCH 07/11] fix read sensor data example --- examples/read-sensor-data/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/read-sensor-data/src/main.rs b/examples/read-sensor-data/src/main.rs index bfbcf3e..e79e9f6 100644 --- a/examples/read-sensor-data/src/main.rs +++ b/examples/read-sensor-data/src/main.rs @@ -28,7 +28,7 @@ fn main() -> Result<(), anyhow::Error> { let profile_dur = dev.get_profile_duration(&settings.0)?; info!("Profile duration {:?}", profile_dur); info!("Setting sensor settings"); - dev.set_sensor_settings(&mut delayer, settings)?; + dev.set_sensor_settings(&mut delayer, &settings)?; info!("Setting forced power modes"); dev.set_sensor_mode(&mut delayer, PowerMode::ForcedMode)?; From 56d9b7a58a28235e1d93e71135474d8ec4e2ef0a Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 16:43:32 +0200 Subject: [PATCH 08/11] add example to module --- .idea/bme680-rust.iml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.idea/bme680-rust.iml b/.idea/bme680-rust.iml index 7c12fe5..29b11b5 100644 --- a/.idea/bme680-rust.iml +++ b/.idea/bme680-rust.iml @@ -4,6 +4,8 @@ + + From bd54956320f43089f0ca928a9f179b2d8f54e365 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 17:10:23 +0200 Subject: [PATCH 09/11] use clamp instead of computing min-max --- src/calculation.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/calculation.rs b/src/calculation.rs index cf698e6..93b8d07 100644 --- a/src/calculation.rs +++ b/src/calculation.rs @@ -141,13 +141,8 @@ impl Calculation { let var4: i32 = (var4 + temp_scaled * calibration_data.par_h7 as i32 / 100i32) >> 4i32; let var5: i32 = ((var3 >> 14i32) * (var3 >> 14i32)) >> 10i32; let var6: i32 = (var4 * var5) >> 1i32; - let mut calc_hum: i32 = (((var3 + var6) >> 10i32) * 1000i32) >> 12i32; - if calc_hum > 100000i32 { - calc_hum = 100000i32; - } else if calc_hum < 0i32 { - calc_hum = 0i32; - } - calc_hum as u32 + let calc_hum: i32 = (((var3 + var6) >> 10i32) * 1000i32) >> 12i32; + calc_hum.clamp(0, 100000) as u32 } /// Calculates and returns the gas resistance. From 300bd90f8ef212e7a2c56bc953bbc6d58b219176 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 17:13:50 +0200 Subject: [PATCH 10/11] make look-up table static --- src/calculation.rs | 78 ++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/calculation.rs b/src/calculation.rs index 93b8d07..45bcce5 100644 --- a/src/calculation.rs +++ b/src/calculation.rs @@ -4,6 +4,44 @@ use core::time::Duration; /// Calculates values needed or returned by the BME80 Sensor. pub struct Calculation {} +static GAS_LOOKUP_TABLE_1: [u32; 16] = [ + 2147483647u32, + 2147483647u32, + 2147483647u32, + 2147483647u32, + 2147483647u32, + 2126008810u32, + 2147483647u32, + 2130303777u32, + 2147483647u32, + 2147483647u32, + 2143188679u32, + 2136746228u32, + 2147483647u32, + 2126008810u32, + 2147483647u32, + 2147483647u32, +]; + +static GAS_LOOKUP_TABLE_2: [u32; 16] = [ + 4096000000u32, + 2048000000u32, + 1024000000u32, + 512000000u32, + 255744255u32, + 127110228u32, + 64000000u32, + 32258064u32, + 16016016u32, + 8000000u32, + 4000000u32, + 2000000u32, + 1, + 500000u32, + 250000u32, + 125000u32, +]; + impl Calculation { /// Calculates and returns the sensor's heater resistance. /// * `calibration_data` - The calibration data of the sensor. @@ -154,47 +192,11 @@ impl Calculation { gas_resistance_adc: u16, gas_range: u8, ) -> u32 { - let lookup_table1: [u32; 16] = [ - 2147483647u32, - 2147483647u32, - 2147483647u32, - 2147483647u32, - 2147483647u32, - 2126008810u32, - 2147483647u32, - 2130303777u32, - 2147483647u32, - 2147483647u32, - 2143188679u32, - 2136746228u32, - 2147483647u32, - 2126008810u32, - 2147483647u32, - 2147483647u32, - ]; - let lookup_table2: [u32; 16] = [ - 4096000000u32, - 2048000000u32, - 1024000000u32, - 512000000u32, - 255744255u32, - 127110228u32, - 64000000u32, - 32258064u32, - 16016016u32, - 8000000u32, - 4000000u32, - 2000000u32, - 1, - 500000u32, - 250000u32, - 125000u32, - ]; let var1: i64 = ((1340 + 5 * calibration_data.range_sw_err as i64) - * lookup_table1[gas_range as usize] as i64) + * GAS_LOOKUP_TABLE_1[gas_range as usize] as i64) >> 16; let var2: u64 = (((gas_resistance_adc as i64) << 15) - 16777216 + var1) as u64; - let var3: i64 = (lookup_table2[gas_range as usize] as i64 * var1) >> 9; + let var3: i64 = (GAS_LOOKUP_TABLE_2[gas_range as usize] as i64 * var1) >> 9; let calc_gas_res: u32 = ((var3 + ((var2 as i64) >> 1i64)) / var2 as i64) as u32; calc_gas_res } From eede29b24bd8fc5a1adffde460bdea6b29f298e6 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Sat, 16 Nov 2024 17:17:26 +0200 Subject: [PATCH 11/11] remove linux embedded hal --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3b6e3dd..dba02d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,6 @@ bitflags = "2.6" embedded-hal = "=1.0.0" log = "0.4" serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] } -linux-embedded-hal = "0.4.0" anyhow = { version = "1.0" , default-features = false} [dev-dependencies]