fix: restore PI reference on final ramp tick (iteration O regression)

The iteration O 3-tick ramp ended with dcCurController.SetRef(0) before
transitioning to STOP. Param::Change only fires when idcspnt or idclim
parameter values change — a normal STOP → OFF → WAITSTART → ENABLE →
ACTIVATE → RUN → EVSEACTIVATE restart cycle never touches those, so
nothing restored the PI reference. On the next entry to EVSEACTIVATE
the controller targeted 0 A and the charger sipped ~0.1 kW.

Bench-confirmed 2026-05-21 on iteration O firmware: after lowering the
ChargeLimit_pct to drop into COMPLETE and then raising it back, charging
restarted at 0.1 kW instead of ramping to 9 kW.

Fix: on the final ramp tick, restore SetRef to MIN(idcspnt, idclim)
instead of zeroing it. The GPIO clears (acpres_out, evseact_out) still
cut AC enable so the output current decays through the filter caps;
the reference value is irrelevant during STOP but matters for the next
EVSEACTIVATE entry.

The ramp-restore block in the vcucmd != Complete branch (charger.cpp:431
in iteration O) only handles the mid-ramp reversal case (counter ≠ 0);
it didn't help when the ramp completed cleanly. This commit closes that
gap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bastian de Byl
2026-05-21 16:23:47 -04:00
parent 0514940877
commit a30cded074
+9 -1
View File
@@ -414,9 +414,17 @@ void ChargerStateMachine()
}
else
{
dcCurController.SetRef(0);
// Final ramp tick: clear GPIOs (cuts AC enable; output decays
// through filter caps) and restore the PI reference to the
// current idcspnt/idclim so the NEXT EVSEACTIVATE entry
// doesn't sip at 0 A. Param::Change only fires on parameter
// changes; a normal restart cycle never touches idcspnt or
// idclim, so without this restore the PI controller stays
// pinned at 0 across the cycle. Iteration O bug — bench-
// confirmed 0.1 kW sip on limit-raise from COMPLETE.
DigIo::acpres_out.Clear();
DigIo::evseact_out.Clear();
dcCurController.SetRef(MIN(Param::Get(Param::idcspnt), Param::Get(Param::idclim)));
completeRampTicks = 0;
completeRampOriginalRef = 0;
state = STOP;