canbus debugging

This commit is contained in:
2026-03-15 13:43:36 +01:00
parent 32db326266
commit af27f3b820
3 changed files with 78 additions and 9 deletions

View File

@@ -18,7 +18,7 @@ pub trait BatteryInteraction {
async fn reset(&mut self) -> FatResult<()>; async fn reset(&mut self) -> FatResult<()>;
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize, Copy, Clone)]
pub struct BatteryInfo { pub struct BatteryInfo {
pub voltage_milli_volt: u32, pub voltage_milli_volt: u32,
pub average_current_milli_ampere: i32, pub average_current_milli_ampere: i32,

View File

@@ -358,6 +358,7 @@ 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();
Timer::after_millis(1000).await;
let config = self.twai_config.take().expect("twai config not set"); let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start(); let mut twai = config.into_async().start();
@@ -377,6 +378,7 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
async fn detect_sensors(&mut self, request: Detection) -> FatResult<Detection> { async fn detect_sensors(&mut self, request: Detection) -> FatResult<Detection> {
self.can_power.set_high(); self.can_power.set_high();
Timer::after_millis(1000).await;
let config = self.twai_config.take().expect("twai config not set"); let config = self.twai_config.take().expect("twai config not set");
let mut twai = config.into_async().start(); let mut twai = config.into_async().start();
@@ -409,7 +411,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(3000)) .with_timeout(Duration::from_millis(500))
.await; .await;
match resu { match resu {
Ok(_) => {} Ok(_) => {}

View File

@@ -530,13 +530,22 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
board.board_hal.get_config().night_lamp.night_lamp_hour_end, board.board_hal.get_config().night_lamp.night_lamp_hour_end,
); );
if state_of_charge < board.board_hal.get_config().night_lamp.low_soc_cutoff { match battery_state {
BatteryState::Unknown => {
light_state.battery_low = false;
},
BatteryState::Info(data) => {
if data.state_of_charge < board.board_hal.get_config().night_lamp.low_soc_cutoff {
board.board_hal.get_esp().set_low_voltage_in_cycle(); board.board_hal.get_esp().set_low_voltage_in_cycle();
info!("Set low voltage in cycle"); info!("Set low voltage in cycle");
} else if state_of_charge > board.board_hal.get_config().night_lamp.low_soc_restore { }
if data.state_of_charge > board.board_hal.get_config().night_lamp.low_soc_restore {
board.board_hal.get_esp().clear_low_voltage_in_cycle(); board.board_hal.get_esp().clear_low_voltage_in_cycle();
info!("Clear low voltage in cycle"); info!("Clear low voltage in cycle");
} }
}
}
light_state.battery_low = board.board_hal.get_esp().low_voltage_in_cycle(); light_state.battery_low = board.board_hal.get_esp().low_voltage_in_cycle();
if !light_state.out_of_work_hour { if !light_state.out_of_work_hour {
@@ -583,7 +592,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> {
let deep_sleep_duration_minutes: u32 = let deep_sleep_duration_minutes: u32 =
// if battery soc is unknown assume battery has enough change // if battery soc is unknown assume battery has enough change
if state_of_charge < 10 && !matches!(battery_state, BatteryState::Unknown) { if matches!(battery_state, BatteryState::Info(data) if data.state_of_charge < 10) {
let _ = board let _ = board
.board_hal .board_hal
.get_esp() .get_esp()
@@ -1002,7 +1011,65 @@ async fn wait_infinity(
let mut pattern_step = 0; let mut pattern_step = 0;
let serial_config_receive = AtomicBool::new(false); let serial_config_receive = AtomicBool::new(false);
let mut suppress_further_mppt_error = false; let mut suppress_further_mppt_error = false;
// Long-press exit (for webserver config modes): hold boot button for 5 seconds.
let mut exit_hold_started: Option<Instant> = None;
let exit_hold_duration = Duration::from_secs(5);
let mut exit_hold_blink = false;
loop { loop {
// While in config webserver mode, allow exiting via long-press.
if matches!(wait_type, WaitType::MissingConfig | WaitType::ConfigButton) {
let mut board = BOARD_ACCESS.get().await.lock().await;
let pressed = board.board_hal.get_esp().mode_override_pressed();
match (pressed, exit_hold_started) {
(true, None) => {
exit_hold_started = Some(Instant::now());
PROGRESS_ACTIVE.store(true, Ordering::Relaxed);
}
(false, Some(_)) => {
exit_hold_started = None;
// Clear any interim hold display.
board.board_hal.clear_progress().await;
}
_ => {}
}
if let Some(started) = exit_hold_started {
let elapsed = Instant::now() - started;
// Visible countdown: fill LEDs progressively during the hold.
// Also toggle general fault LED to match the "enter config" visibility.
exit_hold_blink = !exit_hold_blink;
let progress = core::cmp::min(elapsed, exit_hold_duration);
let lit = ((progress.as_millis() as u64 * 8) / exit_hold_duration.as_millis() as u64)
.saturating_add(1)
.min(8) as usize;
for i in 0..8 {
let _ = board.board_hal.fault(i, i < lit).await;
}
board.board_hal.general_fault(exit_hold_blink).await;
if elapsed >= exit_hold_duration {
info!("Exiting config mode due to 5s button hold");
board.board_hal.get_esp().set_restart_to_conf(false);
// ensure clean http answer / visible confirmation
Timer::after_millis(500).await;
board.board_hal
.deep_sleep(0)
.await;
}
// Short tick while holding so the pattern updates smoothly.
drop(board);
Timer::after_millis(100).await;
continue;
}
// Release lock and continue with normal wait blinking.
drop(board);
}
{ {
let mut board = BOARD_ACCESS.get().await.lock().await; let mut board = BOARD_ACCESS.get().await.lock().await;
match update_charge_indicator(&mut board).await { match update_charge_indicator(&mut board).await {