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,
};
use crate::log::{log, LogMessage};
use anyhow::bail;
use embedded_hal::digital::OutputPin;
use embedded_hal_bus::i2c::MutexDevice;
use esp_idf_hal::delay::Delay;
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::{
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::calibration::UnCalibrated;
use ina219::configuration::{Configuration, OperatingMode};
use ina219::errors::InitializationError;
use ina219::SyncIna219;
use measurements::{Current, Resistance, Voltage};
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>,
charge_indicator: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>,
},
ErrorInit {},
}
impl Charger<'_> {
@ -60,6 +63,7 @@ impl Charger<'_> {
);
});
}
_ => {}
}
}
fn set_charge_indicator(&mut self, charging: bool) -> anyhow::Result<()> {
@ -69,6 +73,7 @@ impl Charger<'_> {
} => {
charge_indicator.set_state(charging.into())?;
}
_ => {}
}
Ok(())
}
@ -76,6 +81,7 @@ impl Charger<'_> {
fn is_day(&self) -> bool {
match self {
Charger::SolarMpptV1 { solar_is_day, .. } => solar_is_day.get_level().into(),
_ => true,
}
}
@ -84,6 +90,9 @@ impl Charger<'_> {
Charger::SolarMpptV1 { mppt_ina, .. } => mppt_ina
.bus_voltage()
.map(|v| Voltage::from_millivolts(v.voltage_mv() as f64))?,
_ => {
bail!("hardware error during init")
}
};
Ok(voltage)
}
@ -96,6 +105,9 @@ impl Charger<'_> {
let current = shunt_voltage.as_volts() / shut_value.as_ohms();
Current::from_amperes(current)
})?,
_ => {
bail!("hardware error during init")
}
};
Ok(current)
}
@ -179,8 +191,8 @@ pub(crate) fn create_v4(
let mut charge_indicator = PinDriver::input_output(peripherals.gpio3.downgrade())?;
charge_indicator.set_pull(Pull::Floating)?;
charge_indicator.set_low()?;
let mut pump_expander = Pca9535Immediate::new(MutexDevice::new(&I2C_DRIVER), 32);
//todo error handing if init error
for pin in 0..8 {
let _ = pump_expander.pin_into_output(GPIOBank::Bank0, pin);
let _ = pump_expander.pin_into_output(GPIOBank::Bank1, pin);
@ -196,12 +208,13 @@ pub(crate) fn create_v4(
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(
MutexDevice::new(&I2C_DRIVER),
Address::from_pins(Pin::Vcc, Pin::Gnd),
)?;
);
let charger = match mppt_ina {
Ok(mut mppt_ina) => {
mppt_ina.set_configuration(Configuration {
reset: Default::default(),
bus_voltage_range: Default::default(),
@ -210,6 +223,7 @@ pub(crate) fn create_v4(
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
@ -219,10 +233,13 @@ pub(crate) fn create_v4(
.as_millis() as u32,
);
let charger = Charger::SolarMpptV1 {
Charger::SolarMpptV1 {
mppt_ina,
solar_is_day,
charge_indicator,
}
}
Err(_) => Charger::ErrorInit {},
};
let v = V4 {