diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index b262600..1550e58 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -292,6 +292,15 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) return; break; + case 'A': //switch current reporting on/off + if (params==2) { // + { + DCCWaveform::mainTrack.setRMSMode(p[0], stream); + DCCWaveform::progTrack.setRMSMode(p[1], stream); + } + return; + } + break; case 'a': // ACCESSORY or { int address; @@ -487,9 +496,16 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) case 'c': // SEND METER RESPONSES // - StringFormatter::send(stream, F("\n"), DCCWaveform::mainTrack.getCurrentmA(), + if (params==0) + { + StringFormatter::send(stream, F("\n"), round(DCCWaveform::mainTrack.getCurrentmA()), DCCWaveform::mainTrack.getMaxmA(), DCCWaveform::mainTrack.getTripmA()); - StringFormatter::send(stream, F("\n"), DCCWaveform::mainTrack.get1024Current()); //'a' message deprecated, remove once JMRI 4.22 is available +// StringFormatter::send(stream, F("\n"), DCCWaveform::mainTrack.get1024Current()); //'a' message deprecated, remove once JMRI 4.22 is available + } + else + if (p[0]== 0) + StringFormatter::send(stream, F("\n"), round(DCCWaveform::mainTrack.getCurrentRMS()), round(DCCWaveform::progTrack.getCurrentRMS()), + DCCWaveform::mainTrack.getMaxmA(), DCCWaveform::mainTrack.getTripmA()); return; case 'Q': // SENSORS diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 2c5ab9a..18cbf58 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -24,6 +24,7 @@ #include +#include "StringFormatter.h" #include "DCCWaveform.h" #include "DCCTimer.h" #include "DIAG.h" @@ -134,10 +135,17 @@ void DCCWaveform::checkPowerOverload(bool ackManagerActive) { switch (powerMode) { case POWERMODE::OFF: sampleDelay = POWER_SAMPLE_OFF_WAIT; + if (sendCurrentSample || (accuSize > 0)) + StringFormatter::send(outStream, F("\n"), isMainTrack ? 0 : 1, 0); break; case POWERMODE::ON: // Check current lastCurrent=motorDriver->getCurrentRaw(); + if (sendCurrentSample) + StringFormatter::send(outStream, F("\n"), isMainTrack ? 0 : 1, getCurrentmA()); + else + if (accuSize > 0) + currAccu = (currAccu * accuFact) + (sq((float)getCurrentmA())); if (lastCurrent < 0) { // We have a fault pin condition to take care of lastCurrent = -lastCurrent; diff --git a/DCCWaveform.h b/DCCWaveform.h index 3838b8e..08cd63c 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -72,6 +72,22 @@ class DCCWaveform { return motorDriver->raw2mA(lastCurrent); return 0; } + inline void setRMSMode(byte newMode, Print* stream) { //0: OFF 1: Broadcast mA Reading >1: Internal calc buffer size + outStream = stream; + sendCurrentSample = newMode == 1; + accuSize = newMode; + if (newMode > 1) + { + accuFact = (float)(newMode - 1) / newMode; + currAccu = 0; + } + } + inline float getCurrentRMS() { + if (accuSize == 0) + return 0; + else + return sqrt(currAccu / accuSize); + } inline int getMaxmA() { if (maxmA == 0) { //only calculate this for first request, it doesn't change maxmA = motorDriver->raw2mA(motorDriver->getRawCurrentTripValue()); //TODO: replace with actual max value or calc @@ -102,6 +118,10 @@ class DCCWaveform { inline bool canMeasureCurrent() { return motorDriver->canMeasureCurrent(); }; + inline void setReportCurrent(bool newStatus, Print *stream) { + sendCurrentSample = newStatus; + outStream = stream; + }; inline void setAckLimit(int mA) { ackLimitmA = mA; } @@ -153,6 +173,11 @@ class DCCWaveform { unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT; unsigned int power_good_counter = 0; + bool sendCurrentSample; + Print* outStream; + volatile double currAccu = 0; + byte accuSize = 0; + float accuFact = 0; // ACK management (Prog track only) volatile bool ackPending; volatile bool ackDetected;