Calculate corrected temp, pressure at sea level, and add cli

This commit is contained in:
Klemens Schölhorn 2019-03-31 16:57:32 +02:00
parent 170c598216
commit 5346f864f2
2 changed files with 75 additions and 18 deletions

View File

@ -2,6 +2,7 @@
name = "rust-sensor"
version = "0.1.0"
authors = ["Klemens Schölhorn <klemens@schoelhorn.eu>"]
edition = "2018"
[dependencies]
i2csensors = "0.1"

View File

@ -3,38 +3,94 @@ extern crate i2cdev_bmp280;
extern crate i2csensors;
extern crate si7021;
use i2cdev::linux::LinuxI2CDevice;
use i2cdev::linux::{LinuxI2CDevice, LinuxI2CError};
use i2cdev_bmp280::*;
use si7021::*;
use i2csensors::{Barometer, Hygrometer, Thermometer};
use si7021::{Si7021, SI7021_I2C_ADDRESS};
use std::env;
fn main() {
let i2c_path = env::args().skip(1).next().expect("i2c bus path (eg. /dev/i2c-1)");
static BMP280_I2C_ADDRESS: u16 = 0x76;
i2c_sensors(&i2c_path);
fn main() -> Result<(), LinuxI2CError> {
let mut verbose = false;
let mut args = env::args().skip(1).peekable();
if let None = args.peek() {
eprintln!("Usage: tiny-wetter [-v] <i2c device> <altitude>");
return Ok(());
}
if let Some(arg) = args.peek() {
if arg == "-v" {
verbose = true;
args.next();
}
}
let i2c_path = args.next().expect("missing i2c device");
let altitude = args.next().expect("missing altitude").parse().expect("invalid altitude");
let weather = read_tiny_wetter(&i2c_path)?;
if verbose {
println!("temperature (bmp280): {:6.1} °C", weather.temperature_bmp280);
println!("temperature (si7021): {:6.1} °C", weather.temperature_si7021);
println!("corrected temperature: {:6.1} °C", weather.temperature());
println!("relative humidity: {:6.1} %", weather.relative_humidity);
println!("real pressure: {:6.1} hPa", weather.pressure / 100.);
println!("pressure at sea level: {:6.1} hPa", weather.sea_level_preassure(altitude) / 100.);
} else {
println!("{:.1} {:.1} {:.1}",
weather.temperature(),
weather.relative_humidity,
weather.sea_level_preassure(altitude) / 100.,
);
}
Ok(())
}
fn i2c_sensors(path: &str) {
let i2c_device = LinuxI2CDevice::new(path, 0b1110110).unwrap();
struct TinyWetterReading {
temperature_bmp280: f32,
temperature_si7021: f32,
pressure: f32,
relative_humidity: f32,
}
let settings = BMP280Settings {
impl TinyWetterReading {
fn temperature(&self) -> f32 {
(self.temperature_bmp280 + self.temperature_si7021) / 2. - 1.
}
fn sea_level_preassure(&self, altitude: f32) -> f32 {
let coef = 13f32 / 2000.;
let divisor = self.temperature() + coef * altitude + 273.15;
self.pressure * (1f32 - coef * altitude / divisor).powf(-5.257)
}
}
fn read_tiny_wetter(path: &str) -> Result<TinyWetterReading, LinuxI2CError> {
let bmp280_settings = BMP280Settings {
compensation: BMP280CompensationAlgorithm::Float,
t_sb: BMP280Timing::ms4000,
iir_filter_coeff: BMP280FilterCoefficient::UltraHigh,
osrs_t: BMP280TemperatureOversampling::x2,
osrs_t: BMP280TemperatureOversampling::x16,
osrs_p: BMP280PressureOversampling::UltraHighResolution,
power_mode: BMP280PowerMode::NormalMode,
power_mode: BMP280PowerMode::ForcedMode,
};
let mut bmp280 = BMP280::new(i2c_device, settings).unwrap();
let i2c_device = LinuxI2CDevice::new(path, BMP280_I2C_ADDRESS)?;
let mut bmp280 = BMP280::new(i2c_device, bmp280_settings)?;
println!("pressure: {:6.2} kPa", bmp280.pressure_kpa().unwrap());
println!("temp1: {:6.2} °C", bmp280.temperature_celsius().unwrap());
let i2c_device = LinuxI2CDevice::new(path, SI7021_I2C_ADDRESS)?;
let mut si7021 = Si7021::new(i2c_device);
let device = LinuxI2CDevice::new(path, SI7021_I2C_ADDRESS).unwrap();
let mut si7021 = Si7021::new(device);
println!("humidity: {:6.2} %", si7021.relative_humidity().unwrap());
println!("temp2: {:6.2} °C", si7021.temperature_celsius().unwrap());
Ok(TinyWetterReading {
temperature_bmp280: bmp280.temperature_celsius()?,
temperature_si7021: si7021.temperature_celsius()?,
pressure: bmp280.pressure_kpa()? * 1000.,
relative_humidity: si7021.relative_humidity()?,
})
}