diff --git a/CVReader.ino b/CVReader.ino index 913e1b4..6ae7f53 100644 --- a/CVReader.ino +++ b/CVReader.ino @@ -71,7 +71,14 @@ DCCEXParser serialParser; // Try monitoring the memory #include "freeMemory.h" +// TODO: this should be automated instead of ifdef +#if defined(ARDUINO_AVR_MEGA2560) int minMemory=32767; +#elif defined(ARDUINO_AVR_UNO) +int minMemory=2048; +#else +#error CANNOT COMPILE - Unkown board, can not determine amount of RAM available. +#endif void setup() { @@ -89,8 +96,10 @@ void setup() { // and a 9600 baud rate. // setup(serial, F(router name), F(password) , port) // +#ifdef WIFI Serial1.begin(115200); WifiInterface::setup(Serial1, F("BTHub5-M6PT"), F("49de8d4862"),3532); // (3532 is 0xDCC decimal... ) +#endif // This is just for demonstration purposes DIAG(F("\n===== CVReader demonstrating DCC::getLocoId() call ==========\n")); @@ -116,7 +125,9 @@ void loop() { serialParser.loop(Serial); // Responsibility 3: Optionally handle any incoming WiFi traffic +#ifdef WIFI WifiInterface::loop(Serial1); +#endif // Your additional code e.g. Report any decrease in memory int freeNow=freeMemory(); diff --git a/Config.h b/Config.h index e3e22d5..e827f06 100644 --- a/Config.h +++ b/Config.h @@ -1,22 +1,29 @@ #ifndef Config_h #define Config_h +// Define this if you have a WiFi board on Serial1 +// #define WIFI + // This hardware configuration would normally be setup using a bunch of #ifdefs. +const byte UNUSED_PIN = 255; + const byte MAIN_POWER_PIN = 3; const byte MAIN_SIGNAL_PIN = 12; -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 = UNUSED_PIN; const int MAIN_MAX_MILLIAMPS=2000; const float MAIN_SENSE_FACTOR=2.99; // analgRead(MAIN_SENSE_PIN) * MAIN_SENSE_FACTOR = milliamps const byte PROG_POWER_PIN = 11; const byte PROG_SIGNAL_PIN = 13; -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 = 8; +const byte PROG_FAULT_PIN = UNUSED_PIN; const int PROG_MAX_MILLIAMPS=250; const float PROG_SENSE_FACTOR=2.99; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index e6ee023..9c317b5 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -93,7 +93,9 @@ POWERMODE DCCWaveform::getPowerMode() { void DCCWaveform::setPowerMode(POWERMODE mode) { powerMode = mode; - Hardware::setPower(isMainTrack, mode == POWERMODE::ON); + bool ison = (mode == POWERMODE::ON); + Hardware::setPower(isMainTrack, ison); + Hardware::setBrake(isMainTrack, !ison); if (mode == POWERMODE::ON) delay(200); } @@ -112,13 +114,20 @@ void DCCWaveform::checkPowerOverload() { case POWERMODE::ON: // Check current lastCurrent = Hardware::getCurrentRaw(isMainTrack); - if (lastCurrent <= tripValue) sampleDelay = POWER_SAMPLE_ON_WAIT; - else { + 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; + } else { setPowerMode(POWERMODE::OVERLOAD); unsigned int mA=Hardware::getCurrentMilliamps(isMainTrack,lastCurrent); unsigned int maxmA=Hardware::getCurrentMilliamps(isMainTrack,tripValue); - DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d ***\n"), isMainTrack ? F("MAIN") : F("PROG"), mA, maxmA); - sampleDelay = POWER_SAMPLE_OVERLOAD_WAIT; + DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d offtime=%l ***\n"), isMainTrack ? F("MAIN") : F("PROG"), mA, maxmA, power_sample_overload_wait); + power_good_counter=0; + sampleDelay = power_sample_overload_wait; + power_sample_overload_wait *= 2; } break; case POWERMODE::OVERLOAD: diff --git a/DCCWaveform.h b/DCCWaveform.h index 3fc8015..f97c388 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -22,7 +22,7 @@ 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; const int MIN_ACK_PULSE_DURATION = 3000; const int MAX_ACK_PULSE_DURATION = 8500; @@ -97,7 +97,9 @@ class DCCWaveform { unsigned int sampleDelay; int rawCurrentTripValue; static const int ACK_CURRENT_TRIP=1000; // During ACK processing limit can be higher - + unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT; + unsigned int power_good_counter = 0; + // ACK management (Prog track only) bool ackPending; bool ackDetected; diff --git a/Hardware.cpp b/Hardware.cpp index dc5b323..2cfd1c4 100644 --- a/Hardware.cpp +++ b/Hardware.cpp @@ -33,14 +33,18 @@ 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) { @@ -54,10 +58,16 @@ 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::getCurrentRaw(bool isMainTrack) { + // 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 32767; // MAXINT because we don't know the actual current, return as high as we can // 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 29ae772..6fa1a9e 100644 --- a/StringFormatter.cpp +++ b/StringFormatter.cpp @@ -51,6 +51,7 @@ void StringFormatter::send2(Print & stream,const __FlashStringHelper* format, va case 'E': printEscapes(stream,(const __FlashStringHelper*)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;