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 @@ + + diff --git a/Cargo.toml b/Cargo.toml index d632b1d..dba02d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,19 +5,21 @@ 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" 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" , 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..1fab7fc 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,18 @@ 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 -[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..2fbb188 --- /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.rs b/examples/read-sensor-data/src/main.rs similarity index 96% rename from examples/read_sensor_data.rs rename to examples/read-sensor-data/src/main.rs index dfa9243..e79e9f6 100644 --- a/examples/read_sensor_data.rs +++ b/examples/read-sensor-data/src/main.rs @@ -1,5 +1,3 @@ -#![no_std] - use bme680::i2c::Address; use bme680::{Bme680, IIRFilterSize, OversamplingSetting, PowerMode, SettingsBuilder}; use core::time::Duration; @@ -30,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)?; @@ -51,4 +49,4 @@ fn main() -> Result<(), anyhow::Error> { info!("Humidity {}%", data.humidity_percent()); info!("Gas Resistence {}Ω", data.gas_resistance_ohm()); } -} +} \ No newline at end of file diff --git a/src/calculation.rs b/src/calculation.rs index cf698e6..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. @@ -141,13 +179,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. @@ -159,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 } diff --git a/src/lib.rs b/src/lib.rs index dd65499..ff0a5a4 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)] @@ -416,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(); } }