From 9d9c6edc2fab9e600492db7cda8f48c98568e9ca Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Fri, 10 Jul 2020 01:03:47 +0200 Subject: [PATCH 1/2] Pololu on Mega seems OK --- Config.h | 18 +++++++++++------- DCCWaveform.cpp | 1 + Hardware.cpp | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Config.h b/Config.h index aaf1d9e..597eff4 100644 --- a/Config.h +++ b/Config.h @@ -3,19 +3,23 @@ // This hardware configuration would normally be setup using a bunch of #ifdefs. -const byte MAIN_POWER_PIN = 3; -const byte MAIN_SIGNAL_PIN = 12; +const byte MAIN_POWER_PIN = 4; +const byte MAIN_SIGNAL_PIN = 7; const byte MAIN_SIGNAL_PIN_ALT = 0; // for hardware that flipflops signal pins const byte MAIN_SENSE_PIN = A0; const byte MAIN_BRAKE_PIN = 9; -const float MAIN_SENSE_FACTOR=1.717; // analgRead(MAIN_SENSE_PIN) * MAIN_SENSE_FACTOR = milliamps -const byte PROG_POWER_PIN = 11; -const byte PROG_SIGNAL_PIN = 13; +const int MAIN_MAX_MILLIAMPS=2000; +const float MAIN_SENSE_FACTOR=18; // analgRead(MAIN_SENSE_PIN) * MAIN_SENSE_FACTOR = milliamps + +const byte PROG_POWER_PIN = 2; +const byte PROG_SIGNAL_PIN = 8; const byte PROG_SIGNAL_PIN_ALT = 0; // for hardware that flipflops signal pins const byte PROG_SENSE_PIN = A1; -const byte PROG_BRAKE_PIN = 8; -const float PROG_SENSE_FACTOR=1.717; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps +const byte PROG_BRAKE_PIN = 10; + +const int PROG_MAX_MILLIAMPS=250; +const float PROG_SENSE_FACTOR=18; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps // Allocations with memory implications..! // Base system takes approx 900 bytes + 8 per loco. Turnouts, Sensors etc are dynamically created diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index c696575..e162555 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -73,6 +73,7 @@ POWERMODE DCCWaveform::getPowerMode() { void DCCWaveform::setPowerMode(POWERMODE mode) { powerMode = mode; Hardware::setPower(isMainTrack, mode == POWERMODE::ON); + Hardware::setBrake(isMainTrack, mode == POWERMODE::OFF); if (mode == POWERMODE::ON) delay(200); } diff --git a/Hardware.cpp b/Hardware.cpp index 04bf3d5..6bd189d 100644 --- a/Hardware.cpp +++ b/Hardware.cpp @@ -15,11 +15,13 @@ void Hardware::init() { pinMode(MAIN_POWER_PIN, OUTPUT); + pinMode(MAIN_BRAKE_PIN, OUTPUT); pinMode(MAIN_SIGNAL_PIN, OUTPUT); if (MAIN_SIGNAL_PIN_ALT) pinMode(MAIN_SIGNAL_PIN_ALT, OUTPUT); pinMode(MAIN_SENSE_PIN, INPUT); pinMode(PROG_POWER_PIN, OUTPUT); + pinMode(PROG_BRAKE_PIN, OUTPUT); pinMode(PROG_SIGNAL_PIN, OUTPUT); if (PROG_SIGNAL_PIN_ALT) pinMode(PROG_SIGNAL_PIN_ALT, OUTPUT); pinMode(PROG_SENSE_PIN, INPUT); From 0583fac41670611540a99abf2d10ae1440e966e1 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 12 Jul 2020 01:36:56 +0200 Subject: [PATCH 2/2] Expotential overcurrent handling #1 --- Config.h | 8 ++++++-- DCCEXParser.cpp | 4 ++-- DCCWaveform.cpp | 22 ++++++++++++++++------ DCCWaveform.h | 4 +++- Hardware.cpp | 14 +++++++++++--- StringFormatter.cpp | 1 + 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/Config.h b/Config.h index 597eff4..199ae3c 100644 --- a/Config.h +++ b/Config.h @@ -3,20 +3,24 @@ // This hardware configuration would normally be setup using a bunch of #ifdefs. +const byte UNUSED_PIN = 255; + const byte MAIN_POWER_PIN = 4; const byte MAIN_SIGNAL_PIN = 7; -const byte MAIN_SIGNAL_PIN_ALT = 0; // for hardware that flipflops signal pins +const byte MAIN_SIGNAL_PIN_ALT = UNUSED_PIN; // for hardware that flipflops signal pins const byte MAIN_SENSE_PIN = A0; const byte MAIN_BRAKE_PIN = 9; +const byte MAIN_FAULT_PIN = 12; const int MAIN_MAX_MILLIAMPS=2000; const float MAIN_SENSE_FACTOR=18; // analgRead(MAIN_SENSE_PIN) * MAIN_SENSE_FACTOR = milliamps const byte PROG_POWER_PIN = 2; const byte PROG_SIGNAL_PIN = 8; -const byte PROG_SIGNAL_PIN_ALT = 0; // for hardware that flipflops signal pins +const byte PROG_SIGNAL_PIN_ALT = UNUSED_PIN; // for hardware that flipflops signal pins const byte PROG_SENSE_PIN = A1; const byte PROG_BRAKE_PIN = 10; +const byte PROG_FAULT_PIN = UNUSED_PIN; const int PROG_MAX_MILLIAMPS=250; const float PROG_SENSE_FACTOR=18; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index f96cec8..584de3f 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -114,9 +114,9 @@ void DCCEXParser::parse(Print & stream, const byte *com, bool banAsync) { asyncBanned=banAsync; (void) EEPROM; // tell compiler not to warn thi is unused int p[MAX_PARAMS]; - byte params=splitValues(p, com); - if (com[0]=='<') com++; + while (com[0]=='<' || com[0]==' ') com++; // strip off any number of < or spaces + byte params=splitValues(p, com); byte opcode=com[0]; if (filterCallback) filterCallback(stream,opcode,params,p); diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index e162555..6d4a8d2 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -72,8 +72,9 @@ POWERMODE DCCWaveform::getPowerMode() { void DCCWaveform::setPowerMode(POWERMODE mode) { powerMode = mode; - Hardware::setPower(isMainTrack, mode == POWERMODE::ON); - Hardware::setBrake(isMainTrack, mode == POWERMODE::OFF); + bool ison = (mode == POWERMODE::ON); + Hardware::setPower(isMainTrack, ison); + Hardware::setBrake(isMainTrack, !ison); if (mode == POWERMODE::ON) delay(200); } @@ -89,11 +90,20 @@ void DCCWaveform::checkPowerOverload() { case POWERMODE::ON: // Check current lastCurrent = Hardware::getCurrentMilliamps(isMainTrack); - if (lastCurrent < POWER_SAMPLE_MAX) sampleDelay = POWER_SAMPLE_ON_WAIT; - else { + if (lastCurrent < POWER_SAMPLE_MAX) { + 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; + } + } else { setPowerMode(POWERMODE::OVERLOAD); - DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d ***\n"), isMainTrack ? F("MAIN") : F("PROG"), lastCurrent, POWER_SAMPLE_MAX); - sampleDelay = POWER_SAMPLE_OVERLOAD_WAIT; + DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d offtime=%l ***\n"), isMainTrack ? F("MAIN") : F("PROG"), lastCurrent, POWER_SAMPLE_MAX, power_sample_overload_wait); + power_good_counter=0; + sampleDelay = power_sample_overload_wait; + power_sample_overload_wait *= 4; } break; case POWERMODE::OVERLOAD: diff --git a/DCCWaveform.h b/DCCWaveform.h index fff524d..0cfb3c8 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -5,7 +5,7 @@ const int POWER_SAMPLE_MAX = 1000; // XXX only until correct short detection on prog rail is implemented const int POWER_SAMPLE_ON_WAIT = 100; const int POWER_SAMPLE_OFF_WAIT = 1000; -const int POWER_SAMPLE_OVERLOAD_WAIT = 4000; +const int POWER_SAMPLE_OVERLOAD_WAIT = 20; // ACK current analogRead values (vary depending on motor shield and cpu voltage) @@ -78,6 +78,8 @@ class DCCWaveform { POWERMODE powerMode; unsigned long lastSampleTaken; unsigned int sampleDelay; + unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT; + unsigned int power_good_counter = 0; // ACK management (Prog track only) bool ackPending; diff --git a/Hardware.cpp b/Hardware.cpp index 6bd189d..df33262 100644 --- a/Hardware.cpp +++ b/Hardware.cpp @@ -17,14 +17,16 @@ void Hardware::init() { pinMode(MAIN_POWER_PIN, OUTPUT); pinMode(MAIN_BRAKE_PIN, OUTPUT); pinMode(MAIN_SIGNAL_PIN, OUTPUT); - if (MAIN_SIGNAL_PIN_ALT) pinMode(MAIN_SIGNAL_PIN_ALT, OUTPUT); + if (MAIN_SIGNAL_PIN_ALT != UNUSED_PIN) pinMode(MAIN_SIGNAL_PIN_ALT, OUTPUT); pinMode(MAIN_SENSE_PIN, INPUT); + if (MAIN_FAULT_PIN != UNUSED_PIN) pinMode(MAIN_FAULT_PIN, INPUT); pinMode(PROG_POWER_PIN, OUTPUT); pinMode(PROG_BRAKE_PIN, OUTPUT); pinMode(PROG_SIGNAL_PIN, OUTPUT); - if (PROG_SIGNAL_PIN_ALT) pinMode(PROG_SIGNAL_PIN_ALT, OUTPUT); + if (PROG_SIGNAL_PIN_ALT != UNUSED_PIN) pinMode(PROG_SIGNAL_PIN_ALT, OUTPUT); pinMode(PROG_SENSE_PIN, INPUT); + if (PROG_FAULT_PIN != UNUSED_PIN) pinMode(PROG_FAULT_PIN, INPUT); } void Hardware::setPower(bool isMainTrack, bool on) { @@ -38,13 +40,19 @@ void Hardware::setSignal(bool isMainTrack, bool high) { byte pin = isMainTrack ? MAIN_SIGNAL_PIN : PROG_SIGNAL_PIN; byte pin2 = isMainTrack ? MAIN_SIGNAL_PIN_ALT : PROG_SIGNAL_PIN_ALT; WritePin(pin, high ? HIGH : LOW); - if (pin2) WritePin(pin2, high ? LOW : HIGH); + if (pin2 != UNUSED_PIN) WritePin(pin2, high ? LOW : HIGH); } int Hardware::getCurrentMilliamps(bool isMainTrack) { byte pin = isMainTrack ? MAIN_SENSE_PIN : PROG_SENSE_PIN; float factor = isMainTrack ? MAIN_SENSE_FACTOR : PROG_SENSE_FACTOR; + // tooo much crap for a interrupt routine. Will see how that goes. + byte faultpin = isMainTrack ? MAIN_FAULT_PIN : PROG_FAULT_PIN; + byte signalpin = isMainTrack ? MAIN_SIGNAL_PIN : PROG_SIGNAL_PIN; + + if (faultpin != UNUSED_PIN && digitalRead(faultpin) == LOW && digitalRead(signalpin) == HIGH) + return 6666; // IMPORTANT: This function can be called in Interrupt() time within the 56uS timer // The default analogRead takes ~100uS which is catastrphic // so analogReadFast is used here. (-2uS) diff --git a/StringFormatter.cpp b/StringFormatter.cpp index cab55b5..4fc1330 100644 --- a/StringFormatter.cpp +++ b/StringFormatter.cpp @@ -31,6 +31,7 @@ void StringFormatter::send2(Print & stream,const __FlashStringHelper* format, va case 's': stream.print(va_arg(args, char*)); break; case 'S': stream.print((const __FlashStringHelper*)va_arg(args, char*)); break; case 'd': stream.print(va_arg(args, int), DEC); break; + case 'l': stream.print(va_arg(args, long), DEC); break; case 'b': stream.print(va_arg(args, int), BIN); break; case 'o': stream.print(va_arg(args, int), OCT); break; case 'x': stream.print(va_arg(args, int), HEX); break;