Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Current measurement #260

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CommandDistributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ void CommandDistributor::broadcastLoco(byte slot) {
#endif
}

void CommandDistributor::broadcastCurrent(uint8_t track, uint16_t value)
{
StringFormatter::send(broadcastBufferWriter,F("<a %d %d>\n"), track, value);
broadcast(false);
}

void CommandDistributor::broadcastPower() {
bool main=DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON;
bool prog=DCCWaveform::progTrack.getPowerMode()==POWERMODE::ON;
Expand Down
1 change: 1 addition & 0 deletions CommandDistributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 18 additions & 2 deletions DCCEXParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) { // <A MAINSTATUS PROGSTATUS> 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 <a ADDRESS SUBADDRESS ACTIVATE> or <a LINEARADDRESS ACTIVATE>
{
int address;
Expand Down Expand Up @@ -487,9 +496,16 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)

case 'c': // SEND METER RESPONSES <c>
// <c MeterName value C/V unit min max res warn>
StringFormatter::send(stream, F("<c CurrentMAIN %d C Milli 0 %d 1 %d>\n"), DCCWaveform::mainTrack.getCurrentmA(),
// if (params==0)
{
StringFormatter::send(stream, F("<c CurrentMAIN %d C Milli 0 %d 1 %d>\n"), round(DCCWaveform::mainTrack.getCurrentmA()),
DCCWaveform::mainTrack.getMaxmA(), DCCWaveform::mainTrack.getTripmA());
StringFormatter::send(stream, F("<a %d>\n"), DCCWaveform::mainTrack.get1024Current()); //'a' message deprecated, remove once JMRI 4.22 is available
// StringFormatter::send(stream, F("<a %d>\n"), DCCWaveform::mainTrack.get1024Current()); //'a' message deprecated, remove once JMRI 4.22 is available
}
// else
// if (p[0]== 0)
// StringFormatter::send(stream, F("<c CurrentMAIN %d %d C Milli 0 %d 1 %d>\n"), round(DCCWaveform::mainTrack.getCurrentRMS()), round(DCCWaveform::progTrack.getCurrentRMS()),
// DCCWaveform::mainTrack.getMaxmA(), DCCWaveform::mainTrack.getTripmA());
return;

case 'Q': // SENSORS <Q>
Expand Down
39 changes: 39 additions & 0 deletions DCCWaveform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -287,14 +295,43 @@ 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),
ackThreshold,motorDriver->raw2mA(ackThreshold),
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;
Expand Down Expand Up @@ -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)
Expand Down
21 changes: 20 additions & 1 deletion DCCWaveform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -57,7 +58,6 @@ class DCCWaveform {
static void loop(bool ackManagerActive);
static DCCWaveform mainTrack;
static DCCWaveform progTrack;

void beginTrack();
void setPowerMode(POWERMODE);
POWERMODE getPowerMode();
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions MotorDrivers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"), \
Expand Down
3 changes: 2 additions & 1 deletion SerialManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#include "SerialManager.h"
#include "DCCEXParser.h"
#include "DCCWaveform.h"

SerialManager * SerialManager::first=NULL;

SerialManager::SerialManager(Stream * myserial) {
Expand Down Expand Up @@ -78,5 +80,4 @@ void SerialManager::loop2() {
if (bufferLength < (COMMAND_BUFFER_SIZE-1)) buffer[bufferLength++] = ch;
}
}

}
3 changes: 1 addition & 2 deletions StringFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down