remove: delete initial_hal implementation, update moisture sensor logic to handle optional raw values, optimize TWAI management, and improve CAN data handling
This commit is contained in:
@@ -315,7 +315,7 @@ async fn worker(
|
|||||||
|
|
||||||
probe_gnd.set_as_output(Speed::Low);
|
probe_gnd.set_as_output(Speed::Low);
|
||||||
probe_gnd.set_low();
|
probe_gnd.set_low();
|
||||||
let probe_duration = Duration::from_millis(1000);
|
let probe_duration = Duration::from_millis(100);
|
||||||
while Instant::now()
|
while Instant::now()
|
||||||
.checked_duration_since(start)
|
.checked_duration_since(start)
|
||||||
.unwrap_or(Duration::from_millis(0))
|
.unwrap_or(Duration::from_millis(0))
|
||||||
@@ -352,8 +352,7 @@ async fn worker(
|
|||||||
}
|
}
|
||||||
probe_gnd.set_as_input(Pull::None);
|
probe_gnd.set_as_input(Pull::None);
|
||||||
|
|
||||||
// Compute frequency from 100 ms window
|
let freq_hz: u32 = pulses * (1000/probe_duration.as_millis()).into(); // pulses per 0.1s => Hz
|
||||||
let freq_hz = pulses; // pulses per 0.1s => Hz
|
|
||||||
|
|
||||||
let mut msg: heapless::String<128> = heapless::String::new();
|
let mut msg: heapless::String<128> = heapless::String::new();
|
||||||
let _ = write!(
|
let _ = write!(
|
||||||
@@ -365,7 +364,7 @@ async fn worker(
|
|||||||
);
|
);
|
||||||
log(msg);
|
log(msg);
|
||||||
|
|
||||||
let mut moisture = CanFrame::new(moisture_id, &(freq_hz as u16).to_be_bytes()).unwrap();
|
let mut moisture = CanFrame::new(moisture_id, &(freq_hz as u32).to_be_bytes()).unwrap();
|
||||||
match can.transmit(&mut moisture) {
|
match can.transmit(&mut moisture) {
|
||||||
Ok(..) => {
|
Ok(..) => {
|
||||||
let mut msg: heapless::String<128> = heapless::String::new();
|
let mut msg: heapless::String<128> = heapless::String::new();
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ impl Esp<'_> {
|
|||||||
loop {
|
loop {
|
||||||
match self.uart0.read_buffered(&mut buf) {
|
match self.uart0.read_buffered(&mut buf) {
|
||||||
Ok(read) => {
|
Ok(read) => {
|
||||||
if (read == 0) {
|
if read == 0 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let c = buf[0] as char;
|
let c = buf[0] as char;
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
use crate::alloc::boxed::Box;
|
|
||||||
use crate::fat_error::{FatError, FatResult};
|
|
||||||
use crate::hal::esp::Esp;
|
|
||||||
use crate::hal::rtc::{BackupHeader, RTCModuleInteraction};
|
|
||||||
use crate::hal::water::TankSensor;
|
|
||||||
use crate::hal::{BoardInteraction, FreePeripherals, Moistures, TIME_ACCESS};
|
|
||||||
use crate::{
|
|
||||||
bail,
|
|
||||||
config::PlantControllerConfig,
|
|
||||||
hal::battery::{BatteryInteraction, NoBatteryMonitor},
|
|
||||||
};
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use esp_hal::gpio::{Level, Output, OutputConfig};
|
|
||||||
use measurements::{Current, Voltage};
|
|
||||||
|
|
||||||
pub struct Initial<'a> {
|
|
||||||
pub(crate) general_fault: Output<'a>,
|
|
||||||
pub(crate) esp: Esp<'a>,
|
|
||||||
pub(crate) config: PlantControllerConfig,
|
|
||||||
pub(crate) battery: Box<dyn BatteryInteraction + Send>,
|
|
||||||
pub rtc: Box<dyn RTCModuleInteraction + Send>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct NoRTC {}
|
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
|
||||||
impl RTCModuleInteraction for NoRTC {
|
|
||||||
async fn get_backup_info(&mut self) -> Result<BackupHeader, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_backup_config(&mut self, _chunk: usize) -> FatResult<([u8; 32], usize, u16)> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn backup_config(&mut self, _offset: usize, _bytes: &[u8]) -> FatResult<()> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn backup_config_finalize(&mut self, _crc: u16, _length: usize) -> FatResult<()> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_rtc_time(&mut self) -> Result<DateTime<Utc>, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn set_rtc_time(&mut self, _time: &DateTime<Utc>) -> Result<(), FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn create_initial_board(
|
|
||||||
free_pins: FreePeripherals<'static>,
|
|
||||||
config: PlantControllerConfig,
|
|
||||||
esp: Esp<'static>,
|
|
||||||
) -> Result<Box<dyn BoardInteraction<'static> + Send>, FatError> {
|
|
||||||
log::info!("Start initial");
|
|
||||||
let general_fault = Output::new(free_pins.gpio23, Level::Low, OutputConfig::default());
|
|
||||||
let v = Initial {
|
|
||||||
general_fault,
|
|
||||||
config,
|
|
||||||
esp,
|
|
||||||
battery: Box::new(NoBatteryMonitor {}),
|
|
||||||
rtc: Box::new(NoRTC {}),
|
|
||||||
};
|
|
||||||
Ok(Box::new(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
|
||||||
impl<'a> BoardInteraction<'a> for Initial<'a> {
|
|
||||||
fn get_tank_sensor(&mut self) -> Result<&mut TankSensor<'a>, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_esp(&mut self) -> &mut Esp<'a> {
|
|
||||||
&mut self.esp
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_config(&mut self) -> &PlantControllerConfig {
|
|
||||||
&self.config
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send> {
|
|
||||||
&mut self.battery
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send> {
|
|
||||||
&mut self.rtc
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn set_charge_indicator(&mut self, _charging: bool) -> Result<(), FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
|
||||||
let rtc = TIME_ACCESS.get().await.lock().await;
|
|
||||||
self.esp.deep_sleep(duration_in_ms, rtc);
|
|
||||||
}
|
|
||||||
fn is_day(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
async fn light(&mut self, _enable: bool) -> Result<(), FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn pump(&mut self, _plant: usize, _enable: bool) -> Result<(), FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn pump_current(&mut self, _plant: usize) -> Result<Current, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn fault(&mut self, _plant: usize, _enable: bool) -> Result<(), FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn measure_moisture_hz(&mut self) -> Result<Moistures, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn general_fault(&mut self, enable: bool) {
|
|
||||||
self.general_fault.set_level(enable.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn test(&mut self) -> Result<(), FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_config(&mut self, config: PlantControllerConfig) {
|
|
||||||
self.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_mptt_voltage(&mut self) -> Result<Voltage, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_mptt_current(&mut self) -> Result<Current, FatError> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn can_power(&mut self, state: bool) -> FatResult<()> {
|
|
||||||
bail!("Please configure board revision")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ use esp_hal::uart::{Config as UartConfig};
|
|||||||
pub(crate) mod battery;
|
pub(crate) mod battery;
|
||||||
// mod can_api; // replaced by external canapi crate
|
// mod can_api; // replaced by external canapi crate
|
||||||
pub mod esp;
|
pub mod esp;
|
||||||
mod initial_hal;
|
|
||||||
mod little_fs2storage_adapter;
|
mod little_fs2storage_adapter;
|
||||||
pub(crate) mod rtc;
|
pub(crate) mod rtc;
|
||||||
mod shared_flash;
|
mod shared_flash;
|
||||||
@@ -40,7 +39,7 @@ use esp_hal::peripherals::TWAI0;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bail,
|
bail,
|
||||||
config::{BatteryBoardVersion, BoardVersion, PlantControllerConfig},
|
config::{BatteryBoardVersion, PlantControllerConfig},
|
||||||
hal::{
|
hal::{
|
||||||
battery::{BatteryInteraction, NoBatteryMonitor},
|
battery::{BatteryInteraction, NoBatteryMonitor},
|
||||||
esp::Esp,
|
esp::Esp,
|
||||||
@@ -50,7 +49,6 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
use alloc::string::String;
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bincode::{Decode, Encode};
|
use bincode::{Decode, Encode};
|
||||||
@@ -682,8 +680,8 @@ pub async fn esp_set_time(time: DateTime<FixedOffset>) -> FatResult<()> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize)]
|
||||||
pub struct Moistures {
|
pub struct Moistures {
|
||||||
pub sensor_a_hz: [f32; PLANT_COUNT],
|
pub sensor_a_hz: [Option<f32>; PLANT_COUNT],
|
||||||
pub sensor_b_hz: [f32; PLANT_COUNT],
|
pub sensor_b_hz: [Option<f32>; PLANT_COUNT],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize)]
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ use crate::hal::{
|
|||||||
};
|
};
|
||||||
use crate::log::{LogMessage, LOG_ACCESS};
|
use crate::log::{LogMessage, LOG_ACCESS};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{ToString};
|
||||||
use alloc::vec;
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
|
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
|
||||||
use canapi::SensorSlot;
|
use canapi::SensorSlot;
|
||||||
@@ -22,7 +21,6 @@ use embassy_time::{Duration, Timer, WithTimeout};
|
|||||||
use embedded_can::{Frame, Id};
|
use embedded_can::{Frame, Id};
|
||||||
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
|
||||||
use esp_hal::i2c::master::I2c;
|
use esp_hal::i2c::master::I2c;
|
||||||
use esp_hal::peripherals;
|
|
||||||
use esp_hal::twai::{EspTwaiError, EspTwaiFrame, StandardId, Twai, TwaiConfiguration, TwaiMode};
|
use esp_hal::twai::{EspTwaiError, EspTwaiFrame, StandardId, Twai, TwaiConfiguration, TwaiMode};
|
||||||
use esp_hal::{twai, Async, Blocking};
|
use esp_hal::{twai, Async, Blocking};
|
||||||
use ina219::address::{Address, Pin};
|
use ina219::address::{Address, Pin};
|
||||||
@@ -134,7 +132,7 @@ pub struct V4<'a> {
|
|||||||
|
|
||||||
extra1: Output<'a>,
|
extra1: Output<'a>,
|
||||||
extra2: Output<'a>,
|
extra2: Output<'a>,
|
||||||
can_mutex: embassy_sync::mutex::Mutex<CriticalSectionRawMutex, ()>,
|
twai_config: Option<TwaiConfiguration<'static, Blocking>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,11 +150,13 @@ pub(crate) async fn create_v4(
|
|||||||
let mut general_fault = Output::new(peripherals.gpio23, Level::Low, OutputConfig::default());
|
let mut general_fault = Output::new(peripherals.gpio23, Level::Low, OutputConfig::default());
|
||||||
general_fault.set_low();
|
general_fault.set_low();
|
||||||
|
|
||||||
let twai_peripheral = Some(peripherals.twai);
|
let twai_config = Some(TwaiConfiguration::new(
|
||||||
|
peripherals.twai,
|
||||||
|
peripherals.gpio0,
|
||||||
let twai_rx_pin = Some(peripherals.gpio2);
|
peripherals.gpio2,
|
||||||
let twai_tx_pin = Some(peripherals.gpio0);
|
TWAI_BAUDRATE,
|
||||||
|
TwaiMode::Normal,
|
||||||
|
));
|
||||||
|
|
||||||
let extra1 = Output::new(peripherals.gpio6, Level::Low, OutputConfig::default());
|
let extra1 = Output::new(peripherals.gpio6, Level::Low, OutputConfig::default());
|
||||||
let extra2 = Output::new(peripherals.gpio15, Level::Low, OutputConfig::default());
|
let extra2 = Output::new(peripherals.gpio15, Level::Low, OutputConfig::default());
|
||||||
@@ -260,38 +260,11 @@ pub(crate) async fn create_v4(
|
|||||||
extra1,
|
extra1,
|
||||||
extra2,
|
extra2,
|
||||||
can_power,
|
can_power,
|
||||||
can_mutex: embassy_sync::mutex::Mutex::new(()),
|
twai_config
|
||||||
};
|
};
|
||||||
Ok(Box::new(v))
|
Ok(Box::new(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn teardown_twai(old: Twai<Async>) {
|
|
||||||
let config = old.stop();
|
|
||||||
drop(config);
|
|
||||||
// Re-acquire the peripheral and pins
|
|
||||||
let rx_pin = unsafe { peripherals::GPIO2::steal() };
|
|
||||||
let tx_pin = unsafe { peripherals::GPIO0::steal() };
|
|
||||||
|
|
||||||
// Set pins to low to avoid parasitic powering
|
|
||||||
let _ = Input::new(rx_pin, InputConfig::default().with_pull(Pull::None));
|
|
||||||
let _ = Input::new(tx_pin, InputConfig::default().with_pull(Pull::None));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_twai<'a>() -> Twai<'a, Async> {
|
|
||||||
// Release the pins from Output back to raw pins and store everything
|
|
||||||
let twai = unsafe { peripherals::TWAI0::steal() };
|
|
||||||
let twai_rx_pin = unsafe { peripherals::GPIO2::steal() };
|
|
||||||
let twai_tx_pin = unsafe { peripherals::GPIO0::steal() };
|
|
||||||
|
|
||||||
let twai_config = TwaiConfiguration::new(
|
|
||||||
twai,
|
|
||||||
twai_rx_pin,
|
|
||||||
twai_tx_pin,
|
|
||||||
TWAI_BAUDRATE,
|
|
||||||
TwaiMode::Normal,
|
|
||||||
);
|
|
||||||
twai_config.into_async().start()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
impl<'a> BoardInteraction<'a> for V4<'a> {
|
impl<'a> BoardInteraction<'a> for V4<'a> {
|
||||||
@@ -384,10 +357,8 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
}
|
}
|
||||||
async fn measure_moisture_hz(&mut self) -> FatResult<Moistures> {
|
async fn measure_moisture_hz(&mut self) -> FatResult<Moistures> {
|
||||||
self.can_power.set_high();
|
self.can_power.set_high();
|
||||||
let mut twai = create_twai();
|
let config = self.twai_config.take().expect("twai config not set");
|
||||||
|
let mut twai = config.into_async().start();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Timer::after_millis(10).await;
|
Timer::after_millis(10).await;
|
||||||
|
|
||||||
@@ -395,17 +366,20 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
|
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
|
||||||
.with_timeout(Duration::from_millis(5000))
|
.with_timeout(Duration::from_millis(5000))
|
||||||
.await;
|
.await;
|
||||||
teardown_twai(twai);
|
|
||||||
|
let config = twai.stop().into_blocking();
|
||||||
|
self.twai_config.replace(config);
|
||||||
|
|
||||||
self.can_power.set_low();
|
self.can_power.set_low();
|
||||||
Ok(moistures)
|
Ok(moistures)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn detect_sensors(&mut self) -> FatResult<DetectionResult> {
|
async fn detect_sensors(&mut self) -> FatResult<DetectionResult> {
|
||||||
self.can_power.set_high();
|
self.can_power.set_high();
|
||||||
let mut twai = create_twai();
|
let config = self.twai_config.take().expect("twai config not set");
|
||||||
// Give CAN some time to stabilize
|
let mut twai = config.into_async().start();
|
||||||
Timer::after_millis(3000).await;
|
|
||||||
|
|
||||||
|
Timer::after_millis(1000).await;
|
||||||
info!("Sending info messages now");
|
info!("Sending info messages now");
|
||||||
// Send a few test messages per potential sensor node
|
// Send a few test messages per potential sensor node
|
||||||
for plant in 0..PLANT_COUNT {
|
for plant in 0..PLANT_COUNT {
|
||||||
@@ -418,7 +392,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
// Try a few times; we intentionally ignore rx here and rely on stub logic
|
// Try a few times; we intentionally ignore rx here and rely on stub logic
|
||||||
let resu = twai
|
let resu = twai
|
||||||
.transmit_async(&frame)
|
.transmit_async(&frame)
|
||||||
.with_timeout(Duration::from_millis(1000))
|
.with_timeout(Duration::from_millis(3000))
|
||||||
.await;
|
.await;
|
||||||
match resu {
|
match resu {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@@ -438,11 +412,13 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
|
|
||||||
let mut moistures = Moistures::default();
|
let mut moistures = Moistures::default();
|
||||||
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
|
let _ = wait_for_can_measurements(&mut twai, &mut moistures)
|
||||||
.with_timeout(Duration::from_millis(1000))
|
.with_timeout(Duration::from_millis(3000))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|
||||||
teardown_twai(twai);
|
let config = twai.stop().into_blocking();
|
||||||
|
self.twai_config.replace(config);
|
||||||
|
|
||||||
self.can_power.set_low();
|
self.can_power.set_low();
|
||||||
|
|
||||||
|
|
||||||
@@ -490,8 +466,8 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
}
|
}
|
||||||
let moisture = self.measure_moisture_hz().await?;
|
let moisture = self.measure_moisture_hz().await?;
|
||||||
for plant in 0..PLANT_COUNT {
|
for plant in 0..PLANT_COUNT {
|
||||||
let a = moisture.sensor_a_hz[plant] as u32;
|
let a = moisture.sensor_a_hz[plant].unwrap_or(0.0) as u32;
|
||||||
let b = moisture.sensor_b_hz[plant] as u32;
|
let b = moisture.sensor_b_hz[plant].unwrap_or(0.0) as u32;
|
||||||
LOG_ACCESS
|
LOG_ACCESS
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
@@ -515,11 +491,9 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn can_power(&mut self, state: bool) -> FatResult<()> {
|
async fn can_power(&mut self, state: bool) -> FatResult<()> {
|
||||||
if state && self.can_power.is_set_low(){
|
if state && self.can_power.is_set_low() {
|
||||||
self.can_power.set_high();
|
self.can_power.set_high();
|
||||||
create_twai();
|
|
||||||
} else {
|
} else {
|
||||||
teardown_twai(create_twai());
|
|
||||||
self.can_power.set_low();
|
self.can_power.set_low();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -552,10 +526,10 @@ async fn wait_for_can_measurements(
|
|||||||
let frequency = u16::from_be_bytes([data[0], data[1]]);
|
let frequency = u16::from_be_bytes([data[0], data[1]]);
|
||||||
match sensor {
|
match sensor {
|
||||||
SensorSlot::A => {
|
SensorSlot::A => {
|
||||||
moistures.sensor_a_hz[plant] = frequency as f32;
|
moistures.sensor_a_hz[plant] = Some(frequency as f32);
|
||||||
}
|
}
|
||||||
SensorSlot::B => {
|
SensorSlot::B => {
|
||||||
moistures.sensor_b_hz[plant] = frequency as f32;
|
moistures.sensor_b_hz[plant] = Some(frequency as f32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -585,10 +559,10 @@ impl From<Moistures> for DetectionResult {
|
|||||||
fn from(value: Moistures) -> Self {
|
fn from(value: Moistures) -> Self {
|
||||||
let mut result = DetectionResult::default();
|
let mut result = DetectionResult::default();
|
||||||
for (plant, sensor) in value.sensor_a_hz.iter().enumerate() {
|
for (plant, sensor) in value.sensor_a_hz.iter().enumerate() {
|
||||||
result.plant[plant].sensor_a = *sensor > 1.0_f32;
|
result.plant[plant].sensor_a = sensor.is_some();
|
||||||
}
|
}
|
||||||
for (plant, sensor) in value.sensor_b_hz.iter().enumerate() {
|
for (plant, sensor) in value.sensor_b_hz.iter().enumerate() {
|
||||||
result.plant[plant].sensor_b = *sensor > 1.0_f32;
|
result.plant[plant].sensor_b = sensor.is_some();
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const MOIST_SENSOR_MIN_FREQUENCY: f32 = 150.; // this is really, really dry, thi
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize)]
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
pub enum MoistureSensorError {
|
pub enum MoistureSensorError {
|
||||||
|
NoMessage,
|
||||||
ShortCircuit { hz: f32, max: f32 },
|
ShortCircuit { hz: f32, max: f32 },
|
||||||
OpenLoop { hz: f32, min: f32 },
|
OpenLoop { hz: f32, min: f32 },
|
||||||
}
|
}
|
||||||
@@ -118,6 +119,11 @@ impl PlantState {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let sensor_a = if board.board_hal.get_config().plants[plant_id].sensor_a {
|
let sensor_a = if board.board_hal.get_config().plants[plant_id].sensor_a {
|
||||||
let raw = moistures.sensor_a_hz[plant_id];
|
let raw = moistures.sensor_a_hz[plant_id];
|
||||||
|
match raw {
|
||||||
|
None => {
|
||||||
|
MoistureSensorState::SensorError(MoistureSensorError::NoMessage)
|
||||||
|
}
|
||||||
|
Some(raw) => {
|
||||||
match map_range_moisture(
|
match map_range_moisture(
|
||||||
raw,
|
raw,
|
||||||
board.board_hal.get_config().plants[plant_id]
|
board.board_hal.get_config().plants[plant_id]
|
||||||
@@ -133,12 +139,20 @@ impl PlantState {
|
|||||||
},
|
},
|
||||||
Err(err) => MoistureSensorState::SensorError(err),
|
Err(err) => MoistureSensorState::SensorError(err),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
MoistureSensorState::Disabled
|
MoistureSensorState::Disabled
|
||||||
};
|
};
|
||||||
|
|
||||||
let sensor_b = if board.board_hal.get_config().plants[plant_id].sensor_b {
|
let sensor_b = if board.board_hal.get_config().plants[plant_id].sensor_b {
|
||||||
let raw = moistures.sensor_b_hz[plant_id];
|
let raw = moistures.sensor_b_hz[plant_id];
|
||||||
|
match raw {
|
||||||
|
None => {
|
||||||
|
MoistureSensorState::SensorError(MoistureSensorError::NoMessage)
|
||||||
|
}
|
||||||
|
Some(raw) => {
|
||||||
match map_range_moisture(
|
match map_range_moisture(
|
||||||
raw,
|
raw,
|
||||||
board.board_hal.get_config().plants[plant_id]
|
board.board_hal.get_config().plants[plant_id]
|
||||||
@@ -154,6 +168,8 @@ impl PlantState {
|
|||||||
},
|
},
|
||||||
Err(err) => MoistureSensorState::SensorError(err),
|
Err(err) => MoistureSensorState::SensorError(err),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
MoistureSensorState::Disabled
|
MoistureSensorState::Disabled
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -130,11 +130,11 @@ where
|
|||||||
T: Read + Write,
|
T: Read + Write,
|
||||||
{
|
{
|
||||||
let actual_data = read_up_to_bytes_from_request(request, None).await?;
|
let actual_data = read_up_to_bytes_from_request(request, None).await?;
|
||||||
let pump_test: CanPower = serde_json::from_slice(&actual_data)?;
|
let can_power_request: CanPower = serde_json::from_slice(&actual_data)?;
|
||||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||||
|
|
||||||
let config = &board.board_hal.can_power(pump_test.state).await?;
|
board.board_hal.can_power(can_power_request.state).await?;
|
||||||
let enable = pump_test.state;
|
let enable = can_power_request.state;
|
||||||
info!(
|
info!(
|
||||||
"set can power to {enable}"
|
"set can power to {enable}"
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user