diff --git a/CommandDistributor.cpp b/CommandDistributor.cpp
index 9bde2593..dcbce4fd 100644
--- a/CommandDistributor.cpp
+++ b/CommandDistributor.cpp
@@ -118,6 +118,12 @@ void CommandDistributor::broadcastLoco(byte slot) {
#endif
}
+void CommandDistributor::broadcastCurrent(uint8_t track, uint16_t value)
+{
+ StringFormatter::send(broadcastBufferWriter,F("\n"), track, value);
+ broadcast(false);
+}
+
void CommandDistributor::broadcastPower() {
bool main=DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON;
bool prog=DCCWaveform::progTrack.getPowerMode()==POWERMODE::ON;
diff --git a/CommandDistributor.h b/CommandDistributor.h
index a9af3bbd..868cb784 100644
--- a/CommandDistributor.h
+++ b/CommandDistributor.h
@@ -32,6 +32,7 @@ public :
static void broadcastSensor(int16_t id, bool value);
static void broadcastTurnout(int16_t id, bool isClosed);
static void broadcastPower();
+ static void broadcastCurrent(uint8_t track, uint16_t value);
static void broadcastText(const FSH * msg);
static void forget(byte clientId);
private:
diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp
index b2626001..7e3c78fa 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) && (p[0] <= 1) && (p[1] <= 1)) { // currently only 0,1 higher values reserved for buffer size for local calculation
+ {
+ DCCWaveform::mainTrack.setRMSMode(p[0]);
+ DCCWaveform::progTrack.setRMSMode(p[1]);
+ }
+ 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 2c5ab9a7..6dd8fe83 100644
--- a/DCCWaveform.cpp
+++ b/DCCWaveform.cpp
@@ -28,6 +28,7 @@
#include "DCCTimer.h"
#include "DIAG.h"
#include "freeMemory.h"
+#include "CommandDistributor.h"
DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true);
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
@@ -134,10 +135,17 @@ void DCCWaveform::checkPowerOverload(bool ackManagerActive) {
switch (powerMode) {
case POWERMODE::OFF:
sampleDelay = POWER_SAMPLE_OFF_WAIT;
+ if (sendCurrentSample) // || (accuSize > 0))
+ CommandDistributor::broadcastCurrent(isMainTrack ? 0 : 1, 0);
break;
case POWERMODE::ON:
// Check current
lastCurrent=motorDriver->getCurrentRaw();
+ if (sendCurrentSample) // || (accuSize > 0))
+ CommandDistributor::broadcastCurrent(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;
@@ -287,7 +295,10 @@ void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repea
void DCCWaveform::setAckBaseline() {
if (isMainTrack) return;
+ pinMode(7, OUTPUT);
int baseline=motorDriver->getCurrentRaw();
+ for (int i = 0; i < 32; i++)
+ baseline = max(baseline, motorDriver->getCurrentRaw());
ackThreshold= baseline + motorDriver->mA2raw(ackLimitmA);
if (Diag::ACK) DIAG(F("ACK baseline=%d/%dmA Threshold=%d/%dmA Duration between %uus and %uus"),
baseline,motorDriver->raw2mA(baseline),
@@ -295,6 +306,32 @@ void DCCWaveform::setAckBaseline() {
minAckPulseDuration, maxAckPulseDuration);
}
+/*
+void DCCWaveform::setAckBaseline() {
+ if (isMainTrack) return;
+ int baseline = motorDriver->getCurrentRaw();
+
+ int baselinemin = baseline;
+ int baselinemax = baseline;
+ int newSample = 0;
+ for (int i = 0; i < 32; i++)
+ {
+ newSample = motorDriver->getCurrentRaw();
+ baselinemax = max(baselinemax, newSample);
+ baselinemin = min(baselinemin, newSample);
+ }
+ baseline = baselinemax;
+ ackThreshold= baseline + motorDriver->mA2raw(ackLimitmA);
+
+ if (Diag::ACK) DIAG(F("ACK min %d max %d"), baselinemin, baselinemax);
+
+ if (Diag::ACK) DIAG(F("ACK baseline=%d/%dmA Threshold=%d/%dmA Duration between %uus and %uus"),
+ baseline,motorDriver->raw2mA(baseline),
+ ackThreshold,motorDriver->raw2mA(ackThreshold),
+ minAckPulseDuration, maxAckPulseDuration);
+}
+*/
+
void DCCWaveform::setAckPending() {
if (isMainTrack) return;
ackMaxCurrent=0;
@@ -325,7 +362,9 @@ void DCCWaveform::checkAck() {
return;
}
+ digitalWrite(7, !digitalRead(7));
int current=motorDriver->getCurrentRaw();
+ digitalWrite(7, current > ackThreshold);
numAckSamples++;
if (current > ackMaxCurrent) ackMaxCurrent=current;
// An ACK is a pulse lasting between minAckPulseDuration and maxAckPulseDuration uSecs (refer @haba)
diff --git a/DCCWaveform.h b/DCCWaveform.h
index 3838b8ea..77dec2c1 100644
--- a/DCCWaveform.h
+++ b/DCCWaveform.h
@@ -25,6 +25,7 @@
#define DCCWaveform_h
#include "MotorDriver.h"
+#include "StringFormatter.h"
// Wait times for power management. Unit: milliseconds
const int POWER_SAMPLE_ON_WAIT = 100;
@@ -57,7 +58,6 @@ class DCCWaveform {
static void loop(bool ackManagerActive);
static DCCWaveform mainTrack;
static DCCWaveform progTrack;
-
void beginTrack();
void setPowerMode(POWERMODE);
POWERMODE getPowerMode();
@@ -72,6 +72,21 @@ class DCCWaveform {
return motorDriver->raw2mA(lastCurrent);
return 0;
}
+ inline void setRMSMode(byte newMode) { //0: OFF 1: Broadcast mA Reading >1: Internal calc buffer size
+ sendCurrentSample = (newMode == 0x01);
+// 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
@@ -153,6 +168,10 @@ class DCCWaveform {
unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT;
unsigned int power_good_counter = 0;
+ bool sendCurrentSample = false;
+// volatile double currAccu = 0;
+// byte accuSize = 0;
+// float accuFact = 0;
// ACK management (Prog track only)
volatile bool ackPending;
volatile bool ackDetected;
diff --git a/MotorDrivers.h b/MotorDrivers.h
index cfb0dd84..6a9c8ee6 100644
--- a/MotorDrivers.h
+++ b/MotorDrivers.h
@@ -47,8 +47,8 @@
//
// Arduino standard Motor Shield
#define STANDARD_MOTOR_SHIELD F("STANDARD_MOTOR_SHIELD"), \
- new MotorDriver(3, 12, UNUSED_PIN, UNUSED_PIN, A0, 2.99, 2000, UNUSED_PIN), \
- new MotorDriver(11, 13, UNUSED_PIN, UNUSED_PIN, A1, 2.99, 2000, UNUSED_PIN)
+ new MotorDriver(3, 12, UNUSED_PIN, UNUSED_PIN, A0, 65.54, 7000, UNUSED_PIN), \
+ new MotorDriver(11, 13, UNUSED_PIN, UNUSED_PIN, A1, 65.54, 7000, UNUSED_PIN)
// Pololu Motor Shield
#define POLOLU_MOTOR_SHIELD F("POLOLU_MOTOR_SHIELD"), \
diff --git a/SerialManager.cpp b/SerialManager.cpp
index 87172276..16c95195 100644
--- a/SerialManager.cpp
+++ b/SerialManager.cpp
@@ -21,6 +21,8 @@
#include "SerialManager.h"
#include "DCCEXParser.h"
+#include "DCCWaveform.h"
+
SerialManager * SerialManager::first=NULL;
SerialManager::SerialManager(Stream * myserial) {
@@ -78,5 +80,4 @@ void SerialManager::loop2() {
if (bufferLength < (COMMAND_BUFFER_SIZE-1)) buffer[bufferLength++] = ch;
}
}
-
}
diff --git a/StringFormatter.cpp b/StringFormatter.cpp
index 73a910ff..28ee86de 100644
--- a/StringFormatter.cpp
+++ b/StringFormatter.cpp
@@ -29,13 +29,12 @@
#include "LCDDisplay.h"
-bool Diag::ACK=false;
+bool Diag::ACK=true;
bool Diag::CMD=false;
bool Diag::WIFI=false;
bool Diag::WITHROTTLE=false;
bool Diag::ETHERNET=false;
bool Diag::LCN=false;
-
void StringFormatter::diag( const FSH* input...) {
if (!diagSerial) return;