From 9368a69e30760a5bdde48b5e314a134a365de331 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 15 Feb 2021 00:31:36 +0100 Subject: [PATCH 1/8] Handle shields with common fault pins (Pololu) --- DCCEXParser.cpp | 3 ++- DCCWaveform.cpp | 20 +++++++++++++++++--- MotorDriver.cpp | 8 +++++++- MotorDriver.h | 4 ++++ MotorDrivers.h | 8 ++++---- WiThrottle.cpp | 2 ++ 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 56f17a2..9b996e7 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -436,7 +436,8 @@ void DCCEXParser::parse(Print *stream, byte *com, bool blocking) { POWERMODE mode = opcode == '1' ? POWERMODE::ON : POWERMODE::OFF; DCC::setProgTrackSyncMain(false); // Only <1 JOIN> will set this on, all others set it off - if (params == 0) + if (params == 0 || + (MotorDriver::commonFaultPin && p[0] != HASH_KEYWORD_JOIN)) // commonFaultPin prevents individual track handling { DCCWaveform::mainTrack.setPowerMode(mode); DCCWaveform::progTrack.setPowerMode(mode); diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 439717e..4eed0cb 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -40,6 +40,7 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) { mainTrack.setPowerMode(POWERMODE::OFF); progTrack.setPowerMode(POWERMODE::OFF); MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable(); + MotorDriver::commonFaultPin = (mainDriver->getFaultPin() == progDriver->getFaultPin()); if (MotorDriver::usePWM) DIAG(F("\nWaveform using PWM pins for accuracy.")); else DIAG(F("\nWaveform accuracy limited by signal pin configuration.")); DCCTimer::begin(DCCWaveform::interruptHandler); @@ -109,7 +110,7 @@ void DCCWaveform::setPowerMode(POWERMODE mode) { } -void DCCWaveform::checkPowerOverload() { +void DCCWaveform::checkPowerOverload() { if (millis() - lastSampleTaken < sampleDelay) return; lastSampleTaken = millis(); int tripValue= motorDriver->getRawCurrentTripValue(); @@ -125,10 +126,23 @@ void DCCWaveform::checkPowerOverload() { lastCurrent=motorDriver->getCurrentRaw(); if (lastCurrent < 0) { // We have a fault pin condition to take care of - DIAG(F("\n*** %S FAULT PIN ACTIVE TOGGLE POWER ON THIS OR BOTH TRACKS ***\n"), isMainTrack ? F("MAIN") : F("PROG")); lastCurrent = -lastCurrent; + setPowerMode(POWERMODE::OVERLOAD); // Turn off, decide later how fast to turn on again + if (MotorDriver::commonFaultPin) { + if (lastCurrent <= tripValue) { + setPowerMode(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("\n*** COMMON FAULT PIN ACTIVE - TOGGLED POWER on %S ***\n"), isMainTrack ? F("MAIN") : F("PROG")); + } else { + DIAG(F("\n*** %S FAULT PIN ACTIVE - OVERLOAD ***\n"), isMainTrack ? F("MAIN") : F("PROG")); + if (lastCurrent < tripValue) { + lastCurrent = tripValue; // exaggerate + } + } } - if (lastCurrent <= tripValue) { + if (lastCurrent < tripValue) { sampleDelay = POWER_SAMPLE_ON_WAIT; if(power_good_counter<100) power_good_counter++; diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 6cc1d10..c9681d6 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -27,6 +27,7 @@ #define isLOW(fastpin) (!isHIGH(fastpin)) bool MotorDriver::usePWM=false; +bool MotorDriver::commonFaultPin=false; MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin, byte current_pin, float sense_factor, unsigned int trip_milliamps, byte fault_pin) { @@ -116,10 +117,15 @@ void MotorDriver::setSignal( bool high) { } } +/* + * Return the current reading as pin reading 0 to 1023. If the fault + * pin is activated return a negative current to show active fault pin. + * As there is no -0, ceat a little and return -1 in that case. + */ int MotorDriver::getCurrentRaw() { int current = analogRead(currentPin); if (faultPin != UNUSED_PIN && isLOW(fastFaultPin) && isHIGH(fastPowerPin)) - return -current; + return (current == 0 ? -1 : -current); return current; // IMPORTANT: This function can be called in Interrupt() time within the 56uS timer // The default analogRead takes ~100uS which is catastrphic diff --git a/MotorDriver.h b/MotorDriver.h index 2c6b230..b47ae95 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -46,6 +46,10 @@ class MotorDriver { } bool isPWMCapable(); static bool usePWM; + static bool commonFaultPin; // This is a stupid motor shield which has only a common fault pin for both outputs + inline byte getFaultPin() { + return faultPin; + } private: void getFastPin(const FSH* type,int pin, bool input, FASTPIN & result); diff --git a/MotorDrivers.h b/MotorDrivers.h index a277bbf..2ccf49d 100644 --- a/MotorDrivers.h +++ b/MotorDrivers.h @@ -29,8 +29,8 @@ // Pololu Motor Shield #define POLOLU_MOTOR_SHIELD F("POLOLU_MOTOR_SHIELD"), \ - new MotorDriver( 9, 7, UNUSED_PIN, -4, A0, 18, 3000, 12), \ - new MotorDriver(10, 8, UNUSED_PIN, UNUSED_PIN, A1, 18, 3000, UNUSED_PIN) + new MotorDriver( 9, 7, UNUSED_PIN, -4, A0, 18, 3000, 12), \ + new MotorDriver(10, 8, UNUSED_PIN, UNUSED_PIN, A1, 18, 3000, 12) // // Actually, on the Pololu MC33926 shield the enable lines are tied together on pin 4 and the // pins 9 and 10 work as "inverted brake" but as we turn on and off the tracks individually @@ -38,8 +38,8 @@ // version of the code always will be high. That means this config is not usable for generating // a railcom cuotout in the future. For that one must wire the second ^D2 to pin 2 and define // the motor driver like this: -// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12) -// new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, UNUSED_PIN) +// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12), \ +// new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, 12) // See Pololu dial_mc33926_shield_schematic.pdf and truth table on page 17 of the MC33926 data sheet. // Firebox Mk1 diff --git a/WiThrottle.cpp b/WiThrottle.cpp index d9b9ec7..62b638d 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -133,6 +133,8 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) { case 'P': if (cmd[1]=='P' && cmd[2]=='A' ) { //PPA power mode DCCWaveform::mainTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF); + if (MotorDriver::commonFaultPin) // commonFaultPin prevents individual track handling + DCCWaveform::progTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF); StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); lastPowerState = (DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); //remember power state sent for comparison later } From 947ef1d146ce3ecf4ca708c9c16d1a214f0c49a7 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 14 Feb 2021 23:32:44 +0000 Subject: [PATCH 2/8] Committing a SHA --- GITHUB_SHA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 8727263..9d5faa6 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "d4be9a8" +#define GITHUB_SHA "9368a69" From 5edac75a9eb2d1b45360b64e9918730ff6b5d8bc Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 15 Feb 2021 00:59:33 +0100 Subject: [PATCH 3/8] remove warning --- MotorDrivers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MotorDrivers.h b/MotorDrivers.h index 2ccf49d..21a845b 100644 --- a/MotorDrivers.h +++ b/MotorDrivers.h @@ -38,7 +38,7 @@ // version of the code always will be high. That means this config is not usable for generating // a railcom cuotout in the future. For that one must wire the second ^D2 to pin 2 and define // the motor driver like this: -// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12), \ +// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12) // new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, 12) // See Pololu dial_mc33926_shield_schematic.pdf and truth table on page 17 of the MC33926 data sheet. From 37fd5fe89363ac774419bf4964f51121a295d3ea Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 15 Feb 2021 00:01:49 +0000 Subject: [PATCH 4/8] Committing a SHA --- GITHUB_SHA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 9d5faa6..058d649 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "9368a69" +#define GITHUB_SHA "edeaad4" From d377468006da18d85df08ac981381a42632637c6 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 15 Feb 2021 10:35:05 +0100 Subject: [PATCH 5/8] only do the sha generation on master --- .github/workflows/sha.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sha.yml b/.github/workflows/sha.yml index a01e236..38210aa 100644 --- a/.github/workflows/sha.yml +++ b/.github/workflows/sha.yml @@ -13,6 +13,7 @@ jobs: # Set the type of machine to run on runs-on: ubuntu-latest + if: contains(github.ref, "master") steps: # Checks out a copy of your repository on the ubuntu-latest machine - name: Checkout code From 39cc9aecfc2d5ab725010321c195f43459517b9e Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 15 Feb 2021 10:53:51 +0100 Subject: [PATCH 6/8] yaml syntax --- .github/workflows/sha.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sha.yml b/.github/workflows/sha.yml index 38210aa..8aca1a5 100644 --- a/.github/workflows/sha.yml +++ b/.github/workflows/sha.yml @@ -13,7 +13,7 @@ jobs: # Set the type of machine to run on runs-on: ubuntu-latest - if: contains(github.ref, "master") + if: github.ref == 'refs/heads/master' steps: # Checks out a copy of your repository on the ubuntu-latest machine - name: Checkout code From a20516d0dbf20a223972a17e5bc45c2b37883647 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Fri, 19 Feb 2021 21:02:14 +0100 Subject: [PATCH 7/8] remove timeout from user config --- config.example.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/config.example.h b/config.example.h index e2dd822..bff7685 100644 --- a/config.example.h +++ b/config.example.h @@ -74,13 +74,6 @@ The configuration file for DCC-EX Command Station // // WIFI_CHANNEL: #define WIFI_CHANNEL 1 -// -///////////////////////////////////////////////////////////////////////////////////// -// -// Wifi connect timeout in milliseconds. Default is 14000 (14 seconds). You only need -// to set this if you have an extremely slow Wifi router. -// -//#define WIFI_CONNECT_TIMEOUT 14000 ///////////////////////////////////////////////////////////////////////////////////// // From a7d8ed2b1e0f762daa2e0c004fe277bb77b184ca Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sat, 20 Feb 2021 13:50:39 +0100 Subject: [PATCH 8/8] faultpin is common only if it exists ; make code prettier --- DCCWaveform.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 4eed0cb..7f26fe5 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -39,10 +39,15 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) { progTripValue = progDriver->mA2raw(TRIP_CURRENT_PROG); // need only calculate once hence static mainTrack.setPowerMode(POWERMODE::OFF); progTrack.setPowerMode(POWERMODE::OFF); + // Fault pin config for odd motor boards (example pololu) + MotorDriver::commonFaultPin = ((mainDriver->getFaultPin() == progDriver->getFaultPin()) + && (mainDriver->getFaultPin() != UNUSED_PIN)); + // Only use PWM if both pins are PWM capable. Otherwise JOIN does not work MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable(); - MotorDriver::commonFaultPin = (mainDriver->getFaultPin() == progDriver->getFaultPin()); - if (MotorDriver::usePWM) DIAG(F("\nWaveform using PWM pins for accuracy.")); - else DIAG(F("\nWaveform accuracy limited by signal pin configuration.")); + if (MotorDriver::usePWM) + DIAG(F("\nWaveform using PWM pins for accuracy.")); + else + DIAG(F("\nWaveform accuracy limited by signal pin configuration.")); DCCTimer::begin(DCCWaveform::interruptHandler); }