allow mppt module to fail during startup without aborting

This commit is contained in:
Empire Phoenix 2025-06-25 01:38:54 +02:00
parent 6b711e29fc
commit 577c38d026

View File

@ -8,11 +8,12 @@ use crate::hal::{
REPEAT_MOIST_MEASURE, REPEAT_MOIST_MEASURE,
}; };
use crate::log::{log, LogMessage}; use crate::log::{log, LogMessage};
use anyhow::bail;
use embedded_hal::digital::OutputPin; use embedded_hal::digital::OutputPin;
use embedded_hal_bus::i2c::MutexDevice; use embedded_hal_bus::i2c::MutexDevice;
use esp_idf_hal::delay::Delay; use esp_idf_hal::delay::Delay;
use esp_idf_hal::gpio::{AnyInputPin, IOPin, InputOutput, Output, PinDriver, Pull}; use esp_idf_hal::gpio::{AnyInputPin, IOPin, InputOutput, Output, PinDriver, Pull};
use esp_idf_hal::i2c::I2cDriver; use esp_idf_hal::i2c::{I2cDriver, I2cError};
use esp_idf_hal::pcnt::{ use esp_idf_hal::pcnt::{
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex,
}; };
@ -20,6 +21,7 @@ use esp_idf_sys::{gpio_hold_dis, gpio_hold_en};
use ina219::address::{Address, Pin}; use ina219::address::{Address, Pin};
use ina219::calibration::UnCalibrated; use ina219::calibration::UnCalibrated;
use ina219::configuration::{Configuration, OperatingMode}; use ina219::configuration::{Configuration, OperatingMode};
use ina219::errors::InitializationError;
use ina219::SyncIna219; use ina219::SyncIna219;
use measurements::{Current, Resistance, Voltage}; use measurements::{Current, Resistance, Voltage};
use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface}; use pca9535::{GPIOBank, Pca9535Immediate, StandardExpanderInterface};
@ -38,6 +40,7 @@ pub enum Charger<'a> {
solar_is_day: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>, solar_is_day: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>,
charge_indicator: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>, charge_indicator: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>,
}, },
ErrorInit {},
} }
impl Charger<'_> { impl Charger<'_> {
@ -60,6 +63,7 @@ impl Charger<'_> {
); );
}); });
} }
_ => {}
} }
} }
fn set_charge_indicator(&mut self, charging: bool) -> anyhow::Result<()> { fn set_charge_indicator(&mut self, charging: bool) -> anyhow::Result<()> {
@ -69,6 +73,7 @@ impl Charger<'_> {
} => { } => {
charge_indicator.set_state(charging.into())?; charge_indicator.set_state(charging.into())?;
} }
_ => {}
} }
Ok(()) Ok(())
} }
@ -76,6 +81,7 @@ impl Charger<'_> {
fn is_day(&self) -> bool { fn is_day(&self) -> bool {
match self { match self {
Charger::SolarMpptV1 { solar_is_day, .. } => solar_is_day.get_level().into(), Charger::SolarMpptV1 { solar_is_day, .. } => solar_is_day.get_level().into(),
_ => true,
} }
} }
@ -84,6 +90,9 @@ impl Charger<'_> {
Charger::SolarMpptV1 { mppt_ina, .. } => mppt_ina Charger::SolarMpptV1 { mppt_ina, .. } => mppt_ina
.bus_voltage() .bus_voltage()
.map(|v| Voltage::from_millivolts(v.voltage_mv() as f64))?, .map(|v| Voltage::from_millivolts(v.voltage_mv() as f64))?,
_ => {
bail!("hardware error during init")
}
}; };
Ok(voltage) Ok(voltage)
} }
@ -96,6 +105,9 @@ impl Charger<'_> {
let current = shunt_voltage.as_volts() / shut_value.as_ohms(); let current = shunt_voltage.as_volts() / shut_value.as_ohms();
Current::from_amperes(current) Current::from_amperes(current)
})?, })?,
_ => {
bail!("hardware error during init")
}
}; };
Ok(current) Ok(current)
} }
@ -179,8 +191,8 @@ pub(crate) fn create_v4(
let mut charge_indicator = PinDriver::input_output(peripherals.gpio3.downgrade())?; let mut charge_indicator = PinDriver::input_output(peripherals.gpio3.downgrade())?;
charge_indicator.set_pull(Pull::Floating)?; charge_indicator.set_pull(Pull::Floating)?;
charge_indicator.set_low()?; charge_indicator.set_low()?;
let mut pump_expander = Pca9535Immediate::new(MutexDevice::new(&I2C_DRIVER), 32); let mut pump_expander = Pca9535Immediate::new(MutexDevice::new(&I2C_DRIVER), 32);
//todo error handing if init error
for pin in 0..8 { for pin in 0..8 {
let _ = pump_expander.pin_into_output(GPIOBank::Bank0, pin); let _ = pump_expander.pin_into_output(GPIOBank::Bank0, pin);
let _ = pump_expander.pin_into_output(GPIOBank::Bank1, pin); let _ = pump_expander.pin_into_output(GPIOBank::Bank1, pin);
@ -196,33 +208,38 @@ pub(crate) fn create_v4(
let _ = sensor_expander.pin_set_low(GPIOBank::Bank1, pin); let _ = sensor_expander.pin_set_low(GPIOBank::Bank1, pin);
} }
//TODO error handling is not done nicely here, should not break if ina is not responsive
let mut mppt_ina = SyncIna219::new( let mut mppt_ina = SyncIna219::new(
MutexDevice::new(&I2C_DRIVER), MutexDevice::new(&I2C_DRIVER),
Address::from_pins(Pin::Vcc, Pin::Gnd), Address::from_pins(Pin::Vcc, Pin::Gnd),
)?;
mppt_ina.set_configuration(Configuration {
reset: Default::default(),
bus_voltage_range: Default::default(),
shunt_voltage_range: Default::default(),
bus_resolution: Default::default(),
shunt_resolution: ina219::configuration::Resolution::Avg128,
operating_mode: Default::default(),
})?;
//TODO this is probably already done until we are ready first time?, maybe add startup time comparison on access?
esp.delay.delay_ms(
mppt_ina
.configuration()?
.conversion_time()
.unwrap()
.as_millis() as u32,
); );
let charger = Charger::SolarMpptV1 { let charger = match mppt_ina {
mppt_ina, Ok(mut mppt_ina) => {
solar_is_day, mppt_ina.set_configuration(Configuration {
charge_indicator, reset: Default::default(),
bus_voltage_range: Default::default(),
shunt_voltage_range: Default::default(),
bus_resolution: Default::default(),
shunt_resolution: ina219::configuration::Resolution::Avg128,
operating_mode: Default::default(),
})?;
//TODO this is probably already done until we are ready first time?, maybe add startup time comparison on access?
esp.delay.delay_ms(
mppt_ina
.configuration()?
.conversion_time()
.unwrap()
.as_millis() as u32,
);
Charger::SolarMpptV1 {
mppt_ina,
solar_is_day,
charge_indicator,
}
}
Err(_) => Charger::ErrorInit {},
}; };
let v = V4 { let v = V4 {