From f5d4dcb97c73cc8693bf557233a278c5925873e4 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Wed, 14 Jun 2023 00:58:02 +0200 Subject: [PATCH 1/8] new overload detection --- GITHUB_SHA.h | 2 +- MotorDriver.cpp | 112 ++++++++++++++++++++++++++++-------------------- MotorDriver.h | 19 +++++--- 3 files changed, 81 insertions(+), 52 deletions(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 7ef8904..4ac112c 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202306031954Z" +#define GITHUB_SHA "devel-202306132257Z" diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 678a28a..3bfaaea 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -154,11 +154,7 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i // senseFactorInternal, raw2mA(1000),mA2raw(1000)); } - // prepare values for current detection - sampleDelay = 0; - lastSampleTaken = millis(); progTripValue = mA2raw(TRIP_CURRENT_PROG); - } bool MotorDriver::isPWMCapable() { @@ -167,6 +163,7 @@ bool MotorDriver::isPWMCapable() { void MotorDriver::setPower(POWERMODE mode) { + if (powerMode == mode) return; bool on=mode==POWERMODE::ON; if (on) { // when switching a track On, we need to check the crrentOffset with the pin OFF @@ -367,63 +364,86 @@ void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & res } void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { - if (millis() - lastSampleTaken < sampleDelay) return; - lastSampleTaken = millis(); + //if (millis() - lastSampleTaken < sampleDelay) return; + //lastSampleTaken = millis(); int tripValue= useProgLimit?progTripValue:getRawCurrentTripValue(); + + // check if there was a change from last time + if (powerMode != oldPowerMode) { + lastPowerChange = micros(); + oldPowerMode = powerMode; + } - // Trackname for diag messages later switch (powerMode) { case POWERMODE::OFF: - sampleDelay = POWER_SAMPLE_OFF_WAIT; + if (microsSinceLastPowerChange() > 5000000UL) { + power_sample_overload_wait = 100UL; + } break; case POWERMODE::ON: // Check current lastCurrent=getCurrentRaw(); if (lastCurrent < 0) { - // We have a fault pin condition to take care of - lastCurrent = -lastCurrent; - setPower(POWERMODE::OVERLOAD); // Turn off, decide later how fast to turn on again - if (commonFaultPin) { - if (lastCurrent < tripValue) { - setPower(POWERMODE::ON); // maybe other track - } - // Write this after the fact as we want to turn on as fast as possible - // because we don't know which output actually triggered the fault pin - DIAG(F("COMMON FAULT PIN ACTIVE: POWERTOGGLE TRACK %c"), trackno + 'A'); - } else { - DIAG(F("TRACK %c FAULT PIN ACTIVE - OVERLOAD"), trackno + 'A'); - if (lastCurrent < tripValue) { - lastCurrent = tripValue; // exaggerate - } + // We have a fault pin condition to take care of + lastCurrent = -lastCurrent; + if (commonFaultPin) { + if (lastCurrent < tripValue) { + // probably other track, do a fast toggle. + setPower(POWERMODE::OVERLOAD); // Turn off, decide later how fast to turn on again + setPower(POWERMODE::ON); // maybe other track + // Write this after the fact as we want to turn on as fast as possible + // because we don't know which output actually triggered the fault pin + 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); + break; + } + lastCurrent = tripValue; // exaggerate + } 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'); + break; + } + } + DIAG(F("TRACK %c FAULT PIN ACTIVE - for real"), trackno + 'A'); + } } + // // // if (lastCurrent < tripValue) { - sampleDelay = POWER_SAMPLE_ON_WAIT; - if(power_good_counter<100) - power_good_counter++; - else - if (power_sample_overload_wait>POWER_SAMPLE_OVERLOAD_WAIT) power_sample_overload_wait=POWER_SAMPLE_OVERLOAD_WAIT; + if (microsSinceLastPowerChange() > 5000000UL) { + power_sample_overload_wait = 100UL; + } } else { - setPower(POWERMODE::OVERLOAD); - unsigned int mA=raw2mA(lastCurrent); - unsigned int maxmA=raw2mA(tripValue); - power_good_counter=0; - sampleDelay = power_sample_overload_wait; - DIAG(F("TRACK %c POWER OVERLOAD %dmA (limit %dmA) shutdown for %dms"), trackno + 'A', mA, maxmA, sampleDelay); - if (power_sample_overload_wait >= 10000) - power_sample_overload_wait = 10000; - else - power_sample_overload_wait *= 2; + // too much current + if (power_sample_overload_wait > 100UL || // not virgin + microsSinceLastPowerChange() > 10000UL) { // Longer than 10ms + setPower(POWERMODE::OVERLOAD); + unsigned int mA=raw2mA(lastCurrent); + unsigned int maxmA=raw2mA(tripValue); + DIAG(F("TRACK %c POWER OVERLOAD %dmA (limit %dmA) shutdown for %lus"), + trackno + 'A', mA, maxmA, power_sample_overload_wait); + } } break; - case POWERMODE::OVERLOAD: - // Try setting it back on after the OVERLOAD_WAIT + case POWERMODE::OVERLOAD: + // 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; + // power on test setPower(POWERMODE::ON); - sampleDelay = POWER_SAMPLE_ON_WAIT; - // Debug code.... - DIAG(F("TRACK %c POWER RESTORE (check %dms)"), trackno + 'A', sampleDelay); - break; - default: - sampleDelay = 999; // cant get here..meaningless statement to avoid compiler warning. + DIAG(F("TRACK %c POWER RESTORE (check %lus)"), trackno + 'A', power_sample_overload_wait); + } + break; + default: + break; } } diff --git a/MotorDriver.h b/MotorDriver.h index be77d2d..a6e0aa7 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -186,6 +186,15 @@ class MotorDriver { inline void setTrackLetter(char c) { trackLetter = c; }; + // this returns how much time has passed since the last power change. If it + // was really long ago (approx > 52min) advance counter approx 35 min so that + // we are at 18 minutes again. Times for 32 bit unsigned long. + inline unsigned long microsSinceLastPowerChange() { + unsigned long diff = micros() - lastPowerChange; + if (diff > (1UL << (6 *sizeof(unsigned long)))) + lastPowerChange += 1UL << (4 * sizeof(unsigned long)); + return diff; + }; #ifdef ANALOG_READ_INTERRUPT bool sampleCurrentFromHW(); void startCurrentFromHW(); @@ -217,8 +226,8 @@ class MotorDriver { int rawCurrentTripValue; // current sampling POWERMODE powerMode; - unsigned long lastSampleTaken; - unsigned int sampleDelay; + POWERMODE oldPowerMode; + unsigned long lastPowerChange; // timestamp in microseconds int progTripValue; int lastCurrent; #ifdef ANALOG_READ_INTERRUPT @@ -229,9 +238,9 @@ class MotorDriver { int tripmA; // Wait times for power management. Unit: milliseconds - static const int POWER_SAMPLE_ON_WAIT = 100; - static const int POWER_SAMPLE_OFF_WAIT = 1000; - static const int POWER_SAMPLE_OVERLOAD_WAIT = 20; + static const int POWER_SAMPLE_ON_WAIT = 1; + static const int POWER_SAMPLE_OFF_WAIT = 100; + static const int POWER_SAMPLE_OVERLOAD_WAIT = 500UL; // Trip current for programming track, 250mA. Change only if you really // need to be non-NMRA-compliant because of decoders that are not either. From f99deb4276e5059382e3f6d96accaeb7cde2ace6 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Wed, 14 Jun 2023 22:57:28 +0200 Subject: [PATCH 2/8] overload detection different timestamps and verbose diag --- GITHUB_SHA.h | 2 +- MotorDriver.cpp | 46 +++++++++++++++++++++++++++++++++++----------- MotorDriver.h | 2 +- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 4ac112c..22bb009 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202306132257Z" +#define GITHUB_SHA "devel-202306142056Z" diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 3bfaaea..c1f6ca4 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -364,18 +364,15 @@ void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & res } void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { - //if (millis() - lastSampleTaken < sampleDelay) return; - //lastSampleTaken = millis(); int tripValue= useProgLimit?progTripValue:getRawCurrentTripValue(); - // check if there was a change from last time - if (powerMode != oldPowerMode) { - lastPowerChange = micros(); - oldPowerMode = powerMode; - } - switch (powerMode) { case POWERMODE::OFF: + if (overloadNow) { + overloadNow=false; + lastPowerChange = micros(); + DIAG(F("OVERLOAD POFF OFF")); + } if (microsSinceLastPowerChange() > 5000000UL) { power_sample_overload_wait = 100UL; } @@ -385,6 +382,11 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { lastCurrent=getCurrentRaw(); if (lastCurrent < 0) { // We have a fault pin condition to take care of + if (!overloadNow) { + overloadNow=true; + lastPowerChange = micros(); + DIAG(F("OVERLOAD FPIN ON")); + } lastCurrent = -lastCurrent; if (commonFaultPin) { if (lastCurrent < tripValue) { @@ -416,22 +418,44 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { } // // // if (lastCurrent < tripValue) { + if (overloadNow) { + overloadNow=false; + lastPowerChange = micros(); + DIAG(F("OVERLOAD PON OFF")); + } if (microsSinceLastPowerChange() > 5000000UL) { power_sample_overload_wait = 100UL; } } else { // too much current + if (!overloadNow) { + overloadNow=true; + lastPowerChange = micros(); + DIAG(F("OVERLOAD PON ON")); + } + unsigned long us = microsSinceLastPowerChange(); if (power_sample_overload_wait > 100UL || // not virgin - microsSinceLastPowerChange() > 10000UL) { // Longer than 10ms + us > 10000UL) { // Longer than 10ms setPower(POWERMODE::OVERLOAD); + // the setPower just turned off, so overload is now gone + if (overloadNow) { + 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 for %lus"), - trackno + 'A', mA, maxmA, power_sample_overload_wait); + DIAG(F("TRACK %c POWER OVERLOAD %dmA (limit %dmA) shutdown after %lus for %lus"), + trackno + 'A', mA, maxmA, us, power_sample_overload_wait); } } break; case POWERMODE::OVERLOAD: + if (overloadNow) { + 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 diff --git a/MotorDriver.h b/MotorDriver.h index a6e0aa7..89a2e08 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -226,7 +226,7 @@ class MotorDriver { int rawCurrentTripValue; // current sampling POWERMODE powerMode; - POWERMODE oldPowerMode; + bool overloadNow = false; unsigned long lastPowerChange; // timestamp in microseconds int progTripValue; int lastCurrent; From 95fe7aafe09aede12c091d1a5c036d255f37de11 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 18 Jun 2023 08:59:37 +0200 Subject: [PATCH 3/8] 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. From 277825c5305fcd2c40c24839705537230559d302 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 18 Jun 2023 09:01:32 +0200 Subject: [PATCH 4/8] versiontag --- GITHUB_SHA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 22bb009..37d7d5f 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202306142056Z" +#define GITHUB_SHA "devel-202306180700Z" From cade89ba1692f12b610368c4f67897a2d4fe7fa8 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 18 Jun 2023 09:48:15 +0200 Subject: [PATCH 5/8] check ADCee::init() return value --- MotorDriver.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MotorDriver.cpp b/MotorDriver.cpp index b1a89eb..5ed8684 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -108,8 +108,13 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i } currentPin=current_pin; - if (currentPin!=UNUSED_PIN) - ADCee::init(currentPin); + if (currentPin!=UNUSED_PIN) { + int ret = ADCee::init(currentPin); + if (ret < -1010) { // XXX give value a name later + DIAG(F("ADCee::init error %d, disable current pin %d"), ret, currentPin); + currentPin = UNUSED_PIN; + } + } senseOffset=0; // value can not be obtained until waveform is activated if (fault_pin != UNUSED_PIN) { From f83be0522034d3ad9c9cdefd473095eb431b6a89 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 18 Jun 2023 19:26:38 +0200 Subject: [PATCH 6/8] STM32: Use mask as loop variable --- DCCTimerSTM32.cpp | 28 +++++++++++++++++++--------- GITHUB_SHA.h | 2 +- TrackManager.h | 12 +++++++++--- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/DCCTimerSTM32.cpp b/DCCTimerSTM32.cpp index a45c4d4..7ed2b95 100644 --- a/DCCTimerSTM32.cpp +++ b/DCCTimerSTM32.cpp @@ -30,6 +30,10 @@ #ifdef ARDUINO_ARCH_STM32 #include "DCCTimer.h" +#ifdef DEBUG_ADC +#include "TrackManager.h" +#endif +#include "DIAG.h" #if defined(ARDUINO_NUCLEO_F411RE) // Nucleo-64 boards don't have Serial1 defined by default @@ -307,6 +311,8 @@ int ADCee::init(uint8_t pin) { analogchans[id] = adcchan; // Keep track of which ADC channel is used for reading this pin usedpins |= (1 << id); // This pin is now ready + DIAG(F("ADCee::init(): value=%d, channel=%d, id=%d"), value, adcchan, id); + return value; } @@ -340,11 +346,13 @@ void ADCee::scan() { // found value analogvals[id] = ADC1->DR; // advance at least one track - // for scope debug TrackManager::track[1]->setBrake(0); +#ifdef DEBUG_ADC + if (id == 1) TrackManager::track[1]->setBrake(0); +#endif waiting = false; id++; mask = mask << 1; - if (id == NUM_ADC_INPUTS+1) { + if (mask == 0) { // the 1 has been shifted out id = 0; mask = 1; } @@ -355,18 +363,20 @@ void ADCee::scan() { // look for a valid track to sample or until we are around while (true) { if (mask & usedpins) { - // start new ADC aquire on id + // start new ADC aquire on id ADC1->SQR3 = analogchans[id]; //1st conversion in regular sequence ADC1->CR2 |= (1 << 30); //Start 1st conversion SWSTART - // for scope debug TrackManager::track[1]->setBrake(1); - waiting = true; - return; +#ifdef DEBUG_ADC + if (id == 1) TrackManager::track[1]->setBrake(1); +#endif + waiting = true; + return; } id++; mask = mask << 1; - if (id == NUM_ADC_INPUTS+1) { - id = 0; - mask = 1; + if (mask == 0) { // the 1 has been shifted out + id = 0; + mask = 1; } } } diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 37d7d5f..8bd3812 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202306180700Z" +#define GITHUB_SHA "devel-202306181725Z" diff --git a/TrackManager.h b/TrackManager.h index ef4a47c..19e756d 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -84,8 +84,15 @@ class TrackManager { static int16_t joinRelay; static bool progTrackSyncMain; // true when prog track is a siding switched to main - static bool progTrackBoosted; // true when prog track is not current limited - + static bool progTrackBoosted; // true when prog track is not current limited + +#ifdef DEBUG_ADC + public: +#else + private: +#endif + static MotorDriver* track[MAX_TRACKS]; + private: static void addTrack(byte t, MotorDriver* driver); static byte lastTrack; @@ -93,7 +100,6 @@ class TrackManager { static POWERMODE mainPowerGuess; static void applyDCSpeed(byte t); - static MotorDriver* track[MAX_TRACKS]; static TRACK_MODE trackMode[MAX_TRACKS]; static int16_t trackDCAddr[MAX_TRACKS]; // dc address if TRACK_MODE_DC or TRACK_MODE_DCX #ifdef ARDUINO_ARCH_ESP32 From 6dd175f63bddeb361942df0c2725f7974f1c6e7a Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 19 Jun 2023 00:33:53 +0200 Subject: [PATCH 7/8] fix power change timer micros overflow --- GITHUB_SHA.h | 2 +- MotorDriver.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 8bd3812..41f732d 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202306181725Z" +#define GITHUB_SHA "devel-202306182233Z" diff --git a/MotorDriver.h b/MotorDriver.h index fe577bd..1eb4e95 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -190,9 +190,10 @@ class MotorDriver { // was really long ago (approx > 52min) advance counter approx 35 min so that // we are at 18 minutes again. Times for 32 bit unsigned long. inline unsigned long microsSinceLastPowerChange() { - unsigned long diff = micros() - lastPowerChange; - if (diff > (1UL << (6 *sizeof(unsigned long)))) - lastPowerChange += 1UL << (4 * sizeof(unsigned long)); + unsigned long now = micros(); + unsigned long diff = now - lastPowerChange; + if (diff > (1UL << (7 *sizeof(unsigned long)))) // 2^(4*7)us = 268.4 seconds + lastPowerChange = now - 30000000UL; // 30 seconds ago return diff; }; #ifdef ANALOG_READ_INTERRUPT From 1888073dc230aa18794490c44a94bd1c05620d59 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 19 Jun 2023 08:43:50 +0200 Subject: [PATCH 8/8] set lastPowerChange we doing the power on retry after overload --- GITHUB_SHA.h | 2 +- MotorDriver.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 41f732d..8b6faac 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202306182233Z" +#define GITHUB_SHA "devel-202306190642Z" diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 5ed8684..0eed19a 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -478,6 +478,10 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) { power_sample_overload_wait = POWER_SAMPLE_RETRY_MAX; // power on test setPower(POWERMODE::ON); + // here we change power but not the overloadNow as that was + // already changed to false when we entered POWERMODE::OVERLOAD + // so we need to set the lastPowerChange anyway. + lastPowerChange = micros(); DIAG(F("TRACK %c POWER RESTORE (was off %lus)"), trackno + 'A', power_sample_overload_wait); } break;