From 95fe7aafe09aede12c091d1a5c036d255f37de11 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 18 Jun 2023 08:59:37 +0200 Subject: [PATCH] overload detection code cleanup --- MotorDriver.cpp | 65 ++++++++++++++++++++++++++++--------------------- MotorDriver.h | 17 ++++++++++--- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/MotorDriver.cpp b/MotorDriver.cpp index c1f6ca4..b1a89eb 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -369,12 +369,13 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { switch (powerMode) { case POWERMODE::OFF: if (overloadNow) { + // reset overload condition as we have just turned off power + // DIAG(F("OVERLOAD POFF OFF")); overloadNow=false; lastPowerChange = micros(); - DIAG(F("OVERLOAD POFF OFF")); } - if (microsSinceLastPowerChange() > 5000000UL) { - power_sample_overload_wait = 100UL; + if (microsSinceLastPowerChange() > POWER_SAMPLE_ALL_GOOD) { + power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT; } break; case POWERMODE::ON: @@ -383,9 +384,10 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { if (lastCurrent < 0) { // We have a fault pin condition to take care of if (!overloadNow) { + // turn on overload condition as fault pin has gone active + // DIAG(F("OVERLOAD FPIN ON")); overloadNow=true; lastPowerChange = micros(); - DIAG(F("OVERLOAD FPIN ON")); } lastCurrent = -lastCurrent; if (commonFaultPin) { @@ -398,73 +400,80 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { DIAG(F("COMMON FAULT PIN ACTIVE: POWERTOGGLE TRACK %c"), trackno + 'A'); } } else { - unsigned long us; if (lastCurrent < tripValue) { - if (power_sample_overload_wait <= 1000UL && // almost virgin - (us = microsSinceLastPowerChange()) < 50000UL) { // Ignore 50ms fault pin if no current - DIAG(F("TRACK %c FAULT PIN ACTIVE - 50ms ignore %lus"), trackno + 'A', us); + if (power_sample_overload_wait <= (POWER_SAMPLE_OVERLOAD_WAIT * 10) && // almost virgin + microsSinceLastPowerChange() < POWER_SAMPLE_IGNORE_FAULT_LOW) { + // Ignore 50ms fault pin if no current + DIAG(F("TRACK %c FAULT PIN 50ms ignore"), trackno + 'A'); break; } - lastCurrent = tripValue; // exaggerate + lastCurrent = tripValue; // exaggerate so condition below (*) is true } else { - if (power_sample_overload_wait <= 100UL && // virgin - microsSinceLastPowerChange() < 5000UL) { // Ignore 5ms fault pin if we see current - DIAG(F("TRACK %c FAULT PIN ACTIVE - 5ms ignore"), trackno + 'A'); + if (power_sample_overload_wait <= POWER_SAMPLE_OVERLOAD_WAIT && // virgin + microsSinceLastPowerChange() < POWER_SAMPLE_IGNORE_FAULT_HIGH) { + // Ignore 5ms fault pin if we see current + DIAG(F("TRACK %c FAULT PIN 5ms ignore"), trackno + 'A'); break; } } - DIAG(F("TRACK %c FAULT PIN ACTIVE - for real"), trackno + 'A'); + DIAG(F("TRACK %c FAULT PIN ACTIVE"), trackno + 'A'); } } // // // - if (lastCurrent < tripValue) { + // above we looked at fault pin, below we look at current + // // // + if (lastCurrent < tripValue) { // see above (*) if (overloadNow) { + // current is below trip value, turn off overload condition + // DIAG(F("OVERLOAD PON OFF")); overloadNow=false; lastPowerChange = micros(); - DIAG(F("OVERLOAD PON OFF")); } - if (microsSinceLastPowerChange() > 5000000UL) { - power_sample_overload_wait = 100UL; + if (microsSinceLastPowerChange() > POWER_SAMPLE_ALL_GOOD) { + power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT; } } else { // too much current if (!overloadNow) { + // current is over trip value, turn on overload condition + // DIAG(F("OVERLOAD PON ON")); overloadNow=true; lastPowerChange = micros(); - DIAG(F("OVERLOAD PON ON")); } - unsigned long us = microsSinceLastPowerChange(); - if (power_sample_overload_wait > 100UL || // not virgin - us > 10000UL) { // Longer than 10ms + unsigned long uSecs = microsSinceLastPowerChange(); + if (power_sample_overload_wait > POWER_SAMPLE_OVERLOAD_WAIT || // not virgin + uSecs > POWER_SAMPLE_OFF_DELAY) { + // Overload has existed longer than delay (typ. 10ms) setPower(POWERMODE::OVERLOAD); - // the setPower just turned off, so overload is now gone if (overloadNow) { + // the setPower just turned off, so overload is now gone + // DIAG(F("OVERLOAD PON OFF")); overloadNow=false; lastPowerChange = micros(); - DIAG(F("OVERLOAD PON OFF")); } unsigned int mA=raw2mA(lastCurrent); unsigned int maxmA=raw2mA(tripValue); DIAG(F("TRACK %c POWER OVERLOAD %dmA (limit %dmA) shutdown after %lus for %lus"), - trackno + 'A', mA, maxmA, us, power_sample_overload_wait); + trackno + 'A', mA, maxmA, uSecs, power_sample_overload_wait); } } break; case POWERMODE::OVERLOAD: if (overloadNow) { + // state overload mode means power is off, turn off overload condition flag as well + // DIAG(F("OVERLOAD POVER OFF")); overloadNow=false; lastPowerChange = micros(); - DIAG(F("OVERLOAD POVER OFF")); } // Try setting it back on after the OVERLOAD_WAIT if (microsSinceLastPowerChange() > power_sample_overload_wait) { // adjust next wait time power_sample_overload_wait *= 2; - if (power_sample_overload_wait > 10000000UL) - power_sample_overload_wait = 10000000UL; + if (power_sample_overload_wait > POWER_SAMPLE_RETRY_MAX) + power_sample_overload_wait = POWER_SAMPLE_RETRY_MAX; // power on test setPower(POWERMODE::ON); - DIAG(F("TRACK %c POWER RESTORE (check %lus)"), trackno + 'A', power_sample_overload_wait); + DIAG(F("TRACK %c POWER RESTORE (was off %lus)"), trackno + 'A', power_sample_overload_wait); } break; default: diff --git a/MotorDriver.h b/MotorDriver.h index 89a2e08..fe577bd 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -237,10 +237,19 @@ class MotorDriver { int maxmA; int tripmA; - // Wait times for power management. Unit: milliseconds - static const int POWER_SAMPLE_ON_WAIT = 1; - static const int POWER_SAMPLE_OFF_WAIT = 100; - static const int POWER_SAMPLE_OVERLOAD_WAIT = 500UL; + // Times for overload management. Unit: microseconds. + // Base for wait time until power is turned on again + static const unsigned long POWER_SAMPLE_OVERLOAD_WAIT = 100UL; + // Time after we consider all faults old and forgotten + static const unsigned long POWER_SAMPLE_ALL_GOOD = 5000000UL; + // How long to ignore fault pin if current is under limit + static const unsigned long POWER_SAMPLE_IGNORE_FAULT_LOW = 50000UL; + // How long to ignore fault pin if current is higher than limit + static const unsigned long POWER_SAMPLE_IGNORE_FAULT_HIGH = 5000UL; + // How long to wait between overcurrent and turning off + static const unsigned long POWER_SAMPLE_OFF_DELAY = 10000UL; + // Upper limit for retry period + static const unsigned long POWER_SAMPLE_RETRY_MAX = 10000000UL; // Trip current for programming track, 250mA. Change only if you really // need to be non-NMRA-compliant because of decoders that are not either.