1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

overload detection code cleanup

This commit is contained in:
Harald Barth 2023-06-18 08:59:37 +02:00
parent f99deb4276
commit 95fe7aafe0
2 changed files with 50 additions and 32 deletions

View File

@ -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:

View File

@ -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.