extract rtc module, extract tank module, fix backupview refresh, switch to embedded storage for eeprom
This commit is contained in:
124
rust/src/hal/water.rs
Normal file
124
rust/src/hal/water.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
use crate::hal::TANK_MULTI_SAMPLE;
|
||||
use anyhow::{anyhow, bail};
|
||||
use ds18b20::Ds18b20;
|
||||
use esp_idf_hal::adc::oneshot::config::AdcChannelConfig;
|
||||
use esp_idf_hal::adc::oneshot::{AdcChannelDriver, AdcDriver};
|
||||
use esp_idf_hal::adc::{attenuation, Resolution, ADC1};
|
||||
use esp_idf_hal::delay::Delay;
|
||||
use esp_idf_hal::gpio::{AnyIOPin, Gpio5, InputOutput, PinDriver, Pull};
|
||||
use esp_idf_sys::EspError;
|
||||
use one_wire_bus::OneWire;
|
||||
|
||||
pub struct TankSensor<'a> {
|
||||
one_wire_bus: OneWire<PinDriver<'a, AnyIOPin, InputOutput>>,
|
||||
tank_channel: AdcChannelDriver<'a, Gpio5, AdcDriver<'a, ADC1>>,
|
||||
tank_power: PinDriver<'a, AnyIOPin, InputOutput>,
|
||||
delay: Delay,
|
||||
}
|
||||
|
||||
impl<'a> TankSensor<'a> {
|
||||
pub(crate) fn create(
|
||||
one_wire_pin: AnyIOPin,
|
||||
adc1: ADC1,
|
||||
gpio5: Gpio5,
|
||||
tank_power_pin: AnyIOPin,
|
||||
) -> TankSensor<'a> {
|
||||
let mut one_wire_pin =
|
||||
PinDriver::input_output_od(one_wire_pin).expect("Failed to configure pin");
|
||||
one_wire_pin
|
||||
.set_pull(Pull::Floating)
|
||||
.expect("Failed to set pull");
|
||||
|
||||
let adc_config = AdcChannelConfig {
|
||||
attenuation: attenuation::DB_11,
|
||||
resolution: Resolution::Resolution12Bit,
|
||||
calibration: esp_idf_hal::adc::oneshot::config::Calibration::Curve,
|
||||
};
|
||||
let tank_driver = AdcDriver::new(adc1).expect("Failed to configure ADC");
|
||||
let tank_channel = AdcChannelDriver::new(tank_driver, gpio5, &adc_config)
|
||||
.expect("Failed to configure ADC channel");
|
||||
|
||||
let mut tank_power =
|
||||
PinDriver::input_output(tank_power_pin).expect("Failed to configure pin");
|
||||
tank_power
|
||||
.set_pull(Pull::Floating)
|
||||
.expect("Failed to set pull");
|
||||
|
||||
let one_wire_bus =
|
||||
OneWire::new(one_wire_pin).expect("OneWire bus did not pull up after release");
|
||||
|
||||
TankSensor {
|
||||
one_wire_bus,
|
||||
tank_channel,
|
||||
tank_power,
|
||||
delay: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn water_temperature_c(&mut self) -> anyhow::Result<f32> {
|
||||
//multisample should be moved to water_temperature_c
|
||||
let mut attempt = 1;
|
||||
let water_temp: Result<f32, anyhow::Error> = loop {
|
||||
let temp = self.single_temperature_c();
|
||||
match &temp {
|
||||
Ok(res) => {
|
||||
println!("Water temp is {}", res);
|
||||
break temp;
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Could not get water temp {} attempt {}", err, attempt)
|
||||
}
|
||||
}
|
||||
if attempt == 5 {
|
||||
break temp;
|
||||
}
|
||||
attempt += 1;
|
||||
};
|
||||
water_temp
|
||||
}
|
||||
|
||||
fn single_temperature_c(&mut self) -> anyhow::Result<f32> {
|
||||
self.one_wire_bus
|
||||
.reset(&mut self.delay)
|
||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||
let first = self.one_wire_bus.devices(false, &mut self.delay).next();
|
||||
if first.is_none() {
|
||||
bail!("Not found any one wire Ds18b20");
|
||||
}
|
||||
let device_address = first
|
||||
.unwrap()
|
||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||
|
||||
let water_temp_sensor = Ds18b20::new::<EspError>(device_address)
|
||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||
|
||||
water_temp_sensor
|
||||
.start_temp_measurement(&mut self.one_wire_bus, &mut self.delay)
|
||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||
ds18b20::Resolution::Bits12.delay_for_measurement_time(&mut self.delay);
|
||||
let sensor_data = water_temp_sensor
|
||||
.read_data(&mut self.one_wire_bus, &mut self.delay)
|
||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||
if sensor_data.temperature == 85_f32 {
|
||||
bail!("Ds18b20 dummy temperature returned");
|
||||
}
|
||||
anyhow::Ok(sensor_data.temperature / 10_f32)
|
||||
}
|
||||
|
||||
pub fn tank_sensor_voltage(&mut self) -> anyhow::Result<f32> {
|
||||
self.tank_power.set_high()?;
|
||||
//let stabilize
|
||||
self.delay.delay_ms(100);
|
||||
|
||||
let mut store = [0_u16; TANK_MULTI_SAMPLE];
|
||||
for multisample in 0..TANK_MULTI_SAMPLE {
|
||||
let value = self.tank_channel.read()?;
|
||||
store[multisample] = value;
|
||||
}
|
||||
self.tank_power.set_low()?;
|
||||
|
||||
store.sort();
|
||||
let median_mv = store[6] as f32 / 1000_f32;
|
||||
anyhow::Ok(median_mv)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user