#![no_std]
use embedded_hal as hal;
use crate::hal::blocking::delay::DelayMs;
use crate::hal::blocking::i2c::{Read, Write, WriteRead};
#[derive(Debug)]
pub enum Error<E> {
I2c(E),
}
#[derive(Copy, Clone)]
pub enum Address {
Standard = 0x18,
Alt1 = 0x08,
Alt2 = 0x28,
Alt3 = 0x38,
Alt4 = 0x48,
Alt5 = 0x58,
Alt6 = 0x68,
Alt7 = 0x78,
}
pub enum PressureUnit {
PSI,
PA,
KPA,
TORR,
INHG,
ATM,
BAR,
}
const MAXIMUM_PSI: f32 = 25.0;
const MINIMUM_PSI: f32 = 0.0;
const OUTPUT_MAX: f32 = 0xE66666 as f32;
const OUTPUT_MIN: f32 = 0x19999A as f32;
#[allow(dead_code)]
pub struct MPR<I2C, D> {
i2c: I2C,
delay: D,
address: Address,
}
impl<I2C, D, E> MPR<I2C, D>
where
I2C: Read<Error = E> + Write<Error = E> + WriteRead<Error = E>,
D: DelayMs<u8>,
{
pub fn new(i2c: I2C, delay: D, address: Address) -> Self {
MPR {
i2c,
delay,
address,
}
}
pub fn get_pressure_wait(&mut self, pu: PressureUnit) -> Result<f32, Error<E>> {
self.start_measurement();
self.delay.delay_ms(50);
self.read_pressure(pu)
}
fn start_measurement(&mut self) -> Result<(), Error<E>> {
let cmd = [0xaa, 0x00, 0x00];
self.i2c
.write(self.address as u8, &cmd)
.map_err(Error::I2c)?;
Ok(())
}
fn read_pressure(&mut self, pu: PressureUnit) -> Result<f32, Error<E>> {
let mut buffer = [0, 0, 0, 0];
self.i2c
.read(self.address as u8, &mut buffer)
.map_err(Error::I2c)?;
let reading = ((buffer[1] as u32) << 16) + ((buffer[2] as u32) << 8) + buffer[3] as u32;
let mut pressure = (reading as f32 - OUTPUT_MIN) * (MAXIMUM_PSI - MINIMUM_PSI);
pressure = (pressure / (OUTPUT_MAX - OUTPUT_MIN)) + MINIMUM_PSI;
match pu {
PressureUnit::PSI => Ok(pressure),
PressureUnit::PA => Ok(pressure * 6894.7573),
PressureUnit::KPA => Ok(pressure * 6.89476),
PressureUnit::TORR => Ok(pressure * 51.7149),
PressureUnit::INHG => Ok(pressure * 2.03602),
PressureUnit::ATM => Ok(pressure * 0.06805),
PressureUnit::BAR => Ok(pressure * 0.06895),
}
}
}