From 8052090e0f1c47d7c87220cf1b925354539d1125 Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Fri, 22 Sep 2023 17:03:40 +0100 Subject: [PATCH 01/10] Added Single Track Power On/Off Added power On/Off <> commands --- CommandDistributor.cpp | 4 +- CommandDistributor.h | 2 +- DCCEXParser.cpp | 51 ++++++++++++++++--- TrackManager.cpp | 111 +++++++++++++++++++++++++---------------- TrackManager.h | 9 ++-- 5 files changed, 121 insertions(+), 56 deletions(-) diff --git a/CommandDistributor.cpp b/CommandDistributor.cpp index ee760b0..32f9874 100644 --- a/CommandDistributor.cpp +++ b/CommandDistributor.cpp @@ -269,6 +269,6 @@ void CommandDistributor::broadcastRaw(clientType type, char * msg) { broadcastReply(type, F("%s"),msg); } -void CommandDistributor::broadcastTrackState(const FSH* format,byte trackLetter,int16_t dcAddr) { - broadcastReply(COMMAND_TYPE, format,trackLetter,dcAddr); +void CommandDistributor::broadcastTrackState(const FSH* format,byte trackLetter,char pmode, int16_t dcAddr) { + broadcastReply(COMMAND_TYPE, format,trackLetter,pmode, dcAddr); } diff --git a/CommandDistributor.h b/CommandDistributor.h index a51d58a..99b9f1e 100644 --- a/CommandDistributor.h +++ b/CommandDistributor.h @@ -55,7 +55,7 @@ public : static int16_t retClockTime(); static void broadcastPower(); static void broadcastRaw(clientType type,char * msg); - static void broadcastTrackState(const FSH* format,byte trackLetter,int16_t dcAddr); + static void broadcastTrackState(const FSH* format,byte trackLetter,char pmode, int16_t dcAddr); template static void broadcastReply(clientType type, Targs... msg); static void forget(byte clientId); diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 29c252d..150070c 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -555,6 +555,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) bool main=false; bool prog=false; bool join=false; + bool singletrack=false; if (params > 1) break; if (params==0) { // All main=true; @@ -574,12 +575,28 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=true; } #endif + else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + uint8_t t = (p[0] - 'A'); + if (TrackManager::isProg(t)) { + main = false; + prog = true; + } + else + { + main=true; + prog=false; + } + singletrack=true; + if (main) TrackManager::SetMainTrackPower(POWERMODE::ON, t); + if (prog) TrackManager::SetProgTrackPower(POWERMODE::ON, t); + } else break; // will reply } TrackManager::setJoin(join); - if (main) TrackManager::setMainPower(POWERMODE::ON); - if (prog) TrackManager::setProgPower(POWERMODE::ON); - + if (!singletrack) { + if (main) TrackManager::setMainPower(POWERMODE::ON); + if (prog) TrackManager::setProgPower(POWERMODE::ON); + } CommandDistributor::broadcastPower(); return; } @@ -588,6 +605,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) { bool main=false; bool prog=false; + bool singletrack=false; if (params > 1) break; if (params==0) { // All main=true; @@ -601,17 +619,34 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG> prog=true; } -#endif +#endif + else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + uint8_t t = (p[0] - 'A'); + if (TrackManager::isProg(t)) { + main = false; + prog = true; + } + else + { + main=true; + prog=false; + } + singletrack=true; + if (main) TrackManager::SetMainTrackPower(POWERMODE::OFF, t); + if (prog) TrackManager::SetProgTrackPower(POWERMODE::OFF, t); + } + else break; // will reply } TrackManager::setJoin(false); + if (!singletrack) { if (main) TrackManager::setMainPower(POWERMODE::OFF); - if (prog) { - TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off - TrackManager::setProgPower(POWERMODE::OFF); + if (prog) { + TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off + TrackManager::setProgPower(POWERMODE::OFF); + } } - CommandDistributor::broadcastPower(); return; } diff --git a/TrackManager.cpp b/TrackManager.cpp index bd7c623..413fd95 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -353,32 +353,48 @@ void TrackManager::streamTrackState(Print* stream, byte t) { // null stream means send to commandDistributor for broadcast if (track[t]==NULL) return; auto format=F(""); + bool pstate = TrackManager::isPowerOn(t); + //char PMODE[] = "OFF"; + //if (pstate) PMODE="ON "; + //if (TrackManager::isPowerOn(t)) {char PMODE[] = "ON";} + // else {char PMODE[] = "OFF";} + switch(track[t]->getMode()) { case TRACK_MODE_MAIN: - format=F("<= %c MAIN>\n"); + format=F("<= %c MAIN %c>\n"); break; #ifndef DISABLE_PROG case TRACK_MODE_PROG: - format=F("<= %c PROG>\n"); + format=F("<= %c PROG %c>\n"); break; #endif case TRACK_MODE_NONE: - format=F("<= %c NONE>\n"); + format=F("<= %c NONE %c>\n"); break; case TRACK_MODE_EXT: - format=F("<= %c EXT>\n"); + format=F("<= %c EXT %c>\n"); break; case TRACK_MODE_DC: - format=F("<= %c DC %d>\n"); + format=F("<= %c DC %c %d>\n"); break; case TRACK_MODE_DCX: - format=F("<= %c DCX %d>\n"); + format=F("<= %c DCX %c %d>\n"); break; default: break; // unknown, dont care } - if (stream) StringFormatter::send(stream,format,'A'+t,trackDCAddr[t]); - else CommandDistributor::broadcastTrackState(format,'A'+t,trackDCAddr[t]); + switch (pstate) { + case true: + if (stream) StringFormatter::send(stream,format,'A'+t,"ON", trackDCAddr[t]); + else CommandDistributor::broadcastTrackState(format,'A'+t,"ON", trackDCAddr[t]); + break; + case false: + if (stream) StringFormatter::send(stream,format,'A'+t,"OFF", trackDCAddr[t]); + else CommandDistributor::broadcastTrackState(format,'A'+t,"OFF", trackDCAddr[t]); + break; + } + //if (stream) StringFormatter::send(stream,format,'A'+t,PMODE, trackDCAddr[t]); + //else CommandDistributor::broadcastTrackState(format,'A'+t,PMODE, trackDCAddr[t]); } byte TrackManager::nextCycleTrack=MAX_TRACKS; @@ -412,45 +428,51 @@ std::vectorTrackManager::getMainDrivers() { } #endif -void TrackManager::setPower2(bool setProg,POWERMODE mode) { +void TrackManager::setPower2(bool setProg,POWERMODE mode, bool doall, uint8_t thistrack) { if (!setProg) mainPowerGuess=mode; FOR_EACH_TRACK(t) { - MotorDriver * driver=track[t]; - if (!driver) continue; - switch (track[t]->getMode()) { - case TRACK_MODE_MAIN: - if (setProg) break; - // toggle brake before turning power on - resets overcurrent error - // on the Pololu board if brake is wired to ^D2. - // XXX see if we can make this conditional - driver->setBrake(true); - driver->setBrake(false); // DCC runs with brake off - driver->setPower(mode); - break; - case TRACK_MODE_DC: - case TRACK_MODE_DCX: - if (setProg) break; - driver->setBrake(true); // DC starts with brake on - applyDCSpeed(t); // speed match DCC throttles - driver->setPower(mode); - break; - case TRACK_MODE_PROG: - if (!setProg) break; - driver->setBrake(true); - driver->setBrake(false); - driver->setPower(mode); - break; - case TRACK_MODE_EXT: - driver->setBrake(true); - driver->setBrake(false); - driver->setPower(mode); - break; - case TRACK_MODE_NONE: - break; + if (doall==false && thistrack != t) break; + MotorDriver * driver=track[t]; + if (!driver) continue; + switch (track[t]->getMode()) { + case TRACK_MODE_MAIN: + if (setProg) break; + // toggle brake before turning power on - resets overcurrent error + // on the Pololu board if brake is wired to ^D2. + // XXX see if we can make this conditional + driver->setBrake(true); + driver->setBrake(false); // DCC runs with brake off + driver->setPower(mode); + break; + case TRACK_MODE_DC: + case TRACK_MODE_DCX: + if (setProg) break; + driver->setBrake(true); // DC starts with brake on + applyDCSpeed(t); // speed match DCC throttles + driver->setPower(mode); + break; + case TRACK_MODE_PROG: + if (!setProg) break; + driver->setBrake(true); + driver->setBrake(false); + driver->setPower(mode); + break; + case TRACK_MODE_EXT: + driver->setBrake(true); + driver->setBrake(false); + driver->setPower(mode); + break; + case TRACK_MODE_NONE: + break; } + } } - + +// void TrackManager::setTrackPower(bool progTrack,POWERMODE mode, uint8_t track) { +// // write the code for this. +// } + POWERMODE TrackManager::getProgPower() { FOR_EACH_TRACK(t) if (track[t]->getMode()==TRACK_MODE_PROG) @@ -526,3 +548,8 @@ bool TrackManager::isPowerOn(byte t) { return true; } +bool TrackManager::isProg(byte t) { + if (track[t]->getMode()==TRACK_MODE_PROG) + return true; + return false; +} \ No newline at end of file diff --git a/TrackManager.h b/TrackManager.h index 60d5f24..3f9c73f 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -60,10 +60,12 @@ class TrackManager { #ifdef ARDUINO_ARCH_ESP32 static std::vectorgetMainDrivers(); #endif - static void setPower2(bool progTrack,POWERMODE mode); + static void setPower2(bool progTrack,POWERMODE mode, bool doall, uint8_t thistrack); static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);} - static void setMainPower(POWERMODE mode) {setPower2(false,mode);} - static void setProgPower(POWERMODE mode) {setPower2(true,mode);} + static void setMainPower(POWERMODE mode) {setPower2(false,mode,true,0);} + static void setProgPower(POWERMODE mode) {setPower2(true,mode,true,0);} + static void SetMainTrackPower(POWERMODE mode, uint8_t track) {setPower2(false,mode,false,track);} + static void SetProgTrackPower(POWERMODE mode, uint8_t track) {setPower2(true,mode,false,track);} static const int16_t MAX_TRACKS=8; static bool setTrackMode(byte track, TRACK_MODE mode, int16_t DCaddr=0); @@ -80,6 +82,7 @@ class TrackManager { static void reportObsoleteCurrent(Print* stream); static void streamTrackState(Print* stream, byte t); static bool isPowerOn(byte t); + static bool isProg(byte t); static int16_t joinRelay; static bool progTrackSyncMain; // true when prog track is a siding switched to main From aacb980dc873cc52742d5840aebb215ef0b573ce Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Sun, 24 Sep 2023 15:40:42 +0100 Subject: [PATCH 02/10] Power control plus EXRAIL Power Control <0 A> etc plus EXRAIL SET_POWER Not yet fully tested. --- CommandDistributor.cpp | 4 ++-- CommandDistributor.h | 2 +- DCCEXParser.cpp | 18 ++++++++++------- EXRAIL2.cpp | 14 +++++++++++++ EXRAIL2.h | 2 +- EXRAIL2MacroReset.h | 2 ++ EXRAILMacros.h | 8 +++++++- TrackManager.cpp | 46 +++++++++++++++++------------------------- TrackManager.h | 15 +++++++++----- 9 files changed, 66 insertions(+), 45 deletions(-) diff --git a/CommandDistributor.cpp b/CommandDistributor.cpp index 32f9874..a521b52 100644 --- a/CommandDistributor.cpp +++ b/CommandDistributor.cpp @@ -269,6 +269,6 @@ void CommandDistributor::broadcastRaw(clientType type, char * msg) { broadcastReply(type, F("%s"),msg); } -void CommandDistributor::broadcastTrackState(const FSH* format,byte trackLetter,char pmode, int16_t dcAddr) { - broadcastReply(COMMAND_TYPE, format,trackLetter,pmode, dcAddr); +void CommandDistributor::broadcastTrackState(const FSH* format,byte trackLetter, int16_t dcAddr) { + broadcastReply(COMMAND_TYPE, format,trackLetter, dcAddr); } diff --git a/CommandDistributor.h b/CommandDistributor.h index 99b9f1e..d54ef31 100644 --- a/CommandDistributor.h +++ b/CommandDistributor.h @@ -55,7 +55,7 @@ public : static int16_t retClockTime(); static void broadcastPower(); static void broadcastRaw(clientType type,char * msg); - static void broadcastTrackState(const FSH* format,byte trackLetter,char pmode, int16_t dcAddr); + static void broadcastTrackState(const FSH* format,byte trackLetter, int16_t dcAddr); template static void broadcastReply(clientType type, Targs... msg); static void forget(byte clientId); diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 150070c..9c94f82 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -576,7 +576,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) } #endif else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> - uint8_t t = (p[0] - 'A'); + byte t = (p[0] - 'A'); + DIAG(F("Processing track - %d "), t); if (TrackManager::isProg(t)) { main = false; prog = true; @@ -587,8 +588,10 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=false; } singletrack=true; - if (main) TrackManager::SetMainTrackPower(POWERMODE::ON, t); - if (prog) TrackManager::SetProgTrackPower(POWERMODE::ON, t); + DIAG(F("Calling SetPower %d - %d - %d"), POWERMODE::ON, false, t); + if (main) TrackManager::setTrackPower(POWERMODE::ON, t); + //if (main) TrackManager::SetMainTrackPower(POWERMODE::ON, t); + //if (prog) TrackManager::SetProgTrackPower(POWERMODE::ON, t); } else break; // will reply } @@ -621,8 +624,9 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) } #endif else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> - uint8_t t = (p[0] - 'A'); - if (TrackManager::isProg(t)) { + byte t = (p[0] - 'A'); + DIAG(F("Processing track - %d "), t); + if (TrackManager::isProg(t)) { main = false; prog = true; } @@ -632,8 +636,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=false; } singletrack=true; - if (main) TrackManager::SetMainTrackPower(POWERMODE::OFF, t); - if (prog) TrackManager::SetProgTrackPower(POWERMODE::OFF, t); + DIAG(F("Calling SetPower %d - %d - %d"), POWERMODE::OFF, false, t); + if (main) TrackManager::setTrackPower(POWERMODE::OFF, t); } else break; // will reply diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index d6d2597..07f4768 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -780,6 +780,20 @@ void RMFT2::loop2() { TrackManager::setJoin(false); CommandDistributor::broadcastPower(); break; + + case OPCODE_SET_POWER: + // operand is TRACK_POWER , trackid + + switch (operand) { + case TRACK_POWER_0: + TrackManager::setTrackPower(POWERMODE::OFF, getOperand(1)); + break; + case TRACK_POWER_1: + TrackManager::setTrackPower(POWERMODE::ON, getOperand(1)); + break; + } + + break; case OPCODE_SET_TRACK: // operand is trackmode<<8 | track id diff --git a/EXRAIL2.h b/EXRAIL2.h index 8af36d2..ad399ec 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -59,7 +59,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE, OPCODE_ROSTER,OPCODE_KILLALL, OPCODE_ROUTE,OPCODE_AUTOMATION,OPCODE_SEQUENCE, OPCODE_ENDTASK,OPCODE_ENDEXRAIL, - OPCODE_SET_TRACK, + OPCODE_SET_TRACK,OPCODE_SET_POWER, OPCODE_ONRED,OPCODE_ONAMBER,OPCODE_ONGREEN, OPCODE_ONCHANGE, OPCODE_ONCLOCKTIME, diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index 11c598b..03e310e 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -138,6 +138,7 @@ #undef SERVO_SIGNAL #undef SET #undef SET_TRACK +#undef SET_POWER #undef SETLOCO #undef SIGNAL #undef SIGNALH @@ -275,6 +276,7 @@ #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) #define SET(pin) #define SET_TRACK(track,mode) +#define SET_POWER(track,onoff) #define SETLOCO(loco) #define SIGNAL(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin) diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 0784242..62b852a 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -63,6 +63,11 @@ // (10#mins)%100) #define STRIP_ZERO(value) 10##value%100 +// These constants help EXRAIL macros convert Track Power e.g. SET_POWER(A ON|OFF). +//const byte TRACK_POWER_0=0, TRACK_POWER_OFF=0; +//const byte TRACK_POWER_1=1, TRACK_POWER_ON=1; + + // Pass 1 Implements aliases #include "EXRAIL2MacroReset.h" #undef ALIAS @@ -407,11 +412,12 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = { #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) OPCODE_SERVOTURNOUT,V(id),OPCODE_PAD,V(pin),OPCODE_PAD,V(activeAngle),OPCODE_PAD,V(inactiveAngle),OPCODE_PAD,V(PCA9685::ProfileType::profile), #define SET(pin) OPCODE_SET,V(pin), #define SET_TRACK(track,mode) OPCODE_SET_TRACK,V(TRACK_MODE_##mode <<8 | TRACK_NUMBER_##track), +#define SET_POWER(track,onoff) OPCODE_SET_POWER,V(TRACK_POWER_##onoff, TRACK_NUMBER_##track), #define SETLOCO(loco) OPCODE_SETLOCO,V(loco), #define SIGNAL(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin) #define SPEED(speed) OPCODE_SPEED,V(speed), -#define START(route) OPCODE_START,V(route), +#define START(route) OPCODE_START,V(route), #define STOP OPCODE_SPEED,V(0), #define THROW(id) OPCODE_THROW,V(id), #ifndef IO_NO_HAL diff --git a/TrackManager.cpp b/TrackManager.cpp index 413fd95..ad7ef6a 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -354,47 +354,32 @@ void TrackManager::streamTrackState(Print* stream, byte t) { if (track[t]==NULL) return; auto format=F(""); bool pstate = TrackManager::isPowerOn(t); - //char PMODE[] = "OFF"; - //if (pstate) PMODE="ON "; - //if (TrackManager::isPowerOn(t)) {char PMODE[] = "ON";} - // else {char PMODE[] = "OFF";} - switch(track[t]->getMode()) { case TRACK_MODE_MAIN: - format=F("<= %c MAIN %c>\n"); + if (pstate) {format=F("<= %c MAIN ON \n");} else {format = F("<= %c MAIN OFF \n");} break; #ifndef DISABLE_PROG case TRACK_MODE_PROG: - format=F("<= %c PROG %c>\n"); + if (pstate) {format=F("<= %c PROG ON>\n");} else {format=F("<= %c PROG OFF>\n");} break; #endif case TRACK_MODE_NONE: - format=F("<= %c NONE %c>\n"); + if (pstate) {format=F("<= %c NONE %ON>\n");} else {format=F("<= %c NONE %OFF>\n");} break; case TRACK_MODE_EXT: - format=F("<= %c EXT %c>\n"); + if (pstate) {format=F("<= %c EXT ON>\n");} else {format=F("<= %c EXT OFF>\n");} break; case TRACK_MODE_DC: - format=F("<= %c DC %c %d>\n"); + if (pstate) {format=F("<= %c DC ON %d>\n");} else {format=F("<= %c DC OFF %d>\n");} break; case TRACK_MODE_DCX: - format=F("<= %c DCX %c %d>\n"); + if (pstate) {format=F("<= %c DCX ON %d>\n");} else {format=F("<= %c DCX OFF %d>\n");} break; default: break; // unknown, dont care } - switch (pstate) { - case true: - if (stream) StringFormatter::send(stream,format,'A'+t,"ON", trackDCAddr[t]); - else CommandDistributor::broadcastTrackState(format,'A'+t,"ON", trackDCAddr[t]); - break; - case false: - if (stream) StringFormatter::send(stream,format,'A'+t,"OFF", trackDCAddr[t]); - else CommandDistributor::broadcastTrackState(format,'A'+t,"OFF", trackDCAddr[t]); - break; - } - //if (stream) StringFormatter::send(stream,format,'A'+t,PMODE, trackDCAddr[t]); - //else CommandDistributor::broadcastTrackState(format,'A'+t,PMODE, trackDCAddr[t]); + if (stream) StringFormatter::send(stream,format,'A'+t, trackDCAddr[t]); + else CommandDistributor::broadcastTrackState(format,'A'+t, trackDCAddr[t]); } byte TrackManager::nextCycleTrack=MAX_TRACKS; @@ -428,10 +413,9 @@ std::vectorTrackManager::getMainDrivers() { } #endif -void TrackManager::setPower2(bool setProg,POWERMODE mode, bool doall, uint8_t thistrack) { +void TrackManager::setPower2(bool setProg,POWERMODE mode) { if (!setProg) mainPowerGuess=mode; FOR_EACH_TRACK(t) { - if (doall==false && thistrack != t) break; MotorDriver * driver=track[t]; if (!driver) continue; switch (track[t]->getMode()) { @@ -469,9 +453,15 @@ void TrackManager::setPower2(bool setProg,POWERMODE mode, bool doall, uint8_t th } } -// void TrackManager::setTrackPower(bool progTrack,POWERMODE mode, uint8_t track) { -// // write the code for this. -// } +void TrackManager::setTrackPower(POWERMODE mode, byte thistrack) { + + DIAG(F("SetPower Processing Track %d"), thistrack); + MotorDriver * driver=track[thistrack]; + if (!driver) return; + + driver->setPower(mode); + + } POWERMODE TrackManager::getProgPower() { FOR_EACH_TRACK(t) diff --git a/TrackManager.h b/TrackManager.h index 3f9c73f..c6eea5c 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -39,6 +39,10 @@ const byte TRACK_NUMBER_5=5, TRACK_NUMBER_F=5; const byte TRACK_NUMBER_6=6, TRACK_NUMBER_G=6; const byte TRACK_NUMBER_7=7, TRACK_NUMBER_H=7; +// These constants help EXRAIL macros convert Track Power e.g. SET_POWER(A ON|OFF). +const byte TRACK_POWER_0=0, TRACK_POWER_OFF=0; +const byte TRACK_POWER_1=1, TRACK_POWER_ON=1; + class TrackManager { public: static void Setup(const FSH * shieldName, @@ -60,12 +64,13 @@ class TrackManager { #ifdef ARDUINO_ARCH_ESP32 static std::vectorgetMainDrivers(); #endif - static void setPower2(bool progTrack,POWERMODE mode, bool doall, uint8_t thistrack); + static void setTrackPower(POWERMODE mode, byte thistrack); + static void setPower2(bool progTrack,POWERMODE mode); static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);} - static void setMainPower(POWERMODE mode) {setPower2(false,mode,true,0);} - static void setProgPower(POWERMODE mode) {setPower2(true,mode,true,0);} - static void SetMainTrackPower(POWERMODE mode, uint8_t track) {setPower2(false,mode,false,track);} - static void SetProgTrackPower(POWERMODE mode, uint8_t track) {setPower2(true,mode,false,track);} + static void setMainPower(POWERMODE mode) {setPower2(false,mode);} + static void setProgPower(POWERMODE mode) {setPower2(true,mode);} + + static const int16_t MAX_TRACKS=8; static bool setTrackMode(byte track, TRACK_MODE mode, int16_t DCaddr=0); From 9e3ae21bb8fc26e25b5e448498217cea53159207 Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Mon, 25 Sep 2023 09:59:17 +0100 Subject: [PATCH 03/10] Change to EXRAIL Set_Power Change to EXRAIL SET_Power --- DCCEXParser.cpp | 6 +----- EXRAILMacros.h | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 9c94f82..a8c257b 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -588,10 +588,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=false; } singletrack=true; - DIAG(F("Calling SetPower %d - %d - %d"), POWERMODE::ON, false, t); if (main) TrackManager::setTrackPower(POWERMODE::ON, t); - //if (main) TrackManager::SetMainTrackPower(POWERMODE::ON, t); - //if (prog) TrackManager::SetProgTrackPower(POWERMODE::ON, t); } else break; // will reply } @@ -622,7 +619,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG> prog=true; } -#endif +#endif <= else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> byte t = (p[0] - 'A'); DIAG(F("Processing track - %d "), t); @@ -636,7 +633,6 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=false; } singletrack=true; - DIAG(F("Calling SetPower %d - %d - %d"), POWERMODE::OFF, false, t); if (main) TrackManager::setTrackPower(POWERMODE::OFF, t); } diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 62b852a..b85b68a 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -412,7 +412,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = { #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) OPCODE_SERVOTURNOUT,V(id),OPCODE_PAD,V(pin),OPCODE_PAD,V(activeAngle),OPCODE_PAD,V(inactiveAngle),OPCODE_PAD,V(PCA9685::ProfileType::profile), #define SET(pin) OPCODE_SET,V(pin), #define SET_TRACK(track,mode) OPCODE_SET_TRACK,V(TRACK_MODE_##mode <<8 | TRACK_NUMBER_##track), -#define SET_POWER(track,onoff) OPCODE_SET_POWER,V(TRACK_POWER_##onoff, TRACK_NUMBER_##track), +#define SET_POWER(track,onoff) OPCODE_SET_POWER,V(TRACK_POWER_##onoff),OPCODE_PAD, V(TRACK_NUMBER_##track), #define SETLOCO(loco) OPCODE_SETLOCO,V(loco), #define SIGNAL(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin) From 17c004aecf558baa980bf9bb620cd7e456cf7969 Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Mon, 25 Sep 2023 14:32:54 +0100 Subject: [PATCH 04/10] Code corrections code corrections --- DCCEXParser.cpp | 37 ++++++++++++++++--------- EXRAIL2.cpp | 6 ++--- TrackManager.cpp | 70 +++++++++++++++++++++++++++++++++++------------- TrackManager.h | 2 +- 4 files changed, 81 insertions(+), 34 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index a8c257b..a68b398 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -556,6 +556,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) bool prog=false; bool join=false; bool singletrack=false; + byte t=0; if (params > 1) break; if (params==0) { // All main=true; @@ -576,8 +577,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) } #endif else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> - byte t = (p[0] - 'A'); - DIAG(F("Processing track - %d "), t); + t = (p[0] - 'A'); + //DIAG(F("Processing track - %d "), t); if (TrackManager::isProg(t)) { main = false; prog = true; @@ -588,7 +589,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=false; } singletrack=true; - if (main) TrackManager::setTrackPower(POWERMODE::ON, t); + } else break; // will reply } @@ -597,6 +598,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) if (main) TrackManager::setMainPower(POWERMODE::ON); if (prog) TrackManager::setProgPower(POWERMODE::ON); } + else { + if (main) TrackManager::setTrackPower(false, POWERMODE::ON, t); + if (prog) { + TrackManager::setTrackPower(true, POWERMODE::ON, t); + } + } CommandDistributor::broadcastPower(); return; } @@ -606,6 +613,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) bool main=false; bool prog=false; bool singletrack=false; + byte t=0; if (params > 1) break; if (params==0) { // All main=true; @@ -621,8 +629,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) } #endif <= else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> - byte t = (p[0] - 'A'); - DIAG(F("Processing track - %d "), t); + t = (p[0] - 'A'); + //DIAG(F("Processing track - %d "), t); if (TrackManager::isProg(t)) { main = false; prog = true; @@ -632,24 +640,29 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) main=true; prog=false; } - singletrack=true; - if (main) TrackManager::setTrackPower(POWERMODE::OFF, t); - } - + singletrack=true; + } else break; // will reply } TrackManager::setJoin(false); if (!singletrack) { - if (main) TrackManager::setMainPower(POWERMODE::OFF); + if (main) TrackManager::setMainPower(POWERMODE::OFF); + if (prog) { + TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off + TrackManager::setProgPower(POWERMODE::OFF); + } + } + else { + if (main) TrackManager::setTrackPower(false, POWERMODE::OFF, t); if (prog) { TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off - TrackManager::setProgPower(POWERMODE::OFF); + TrackManager::setTrackPower(true, POWERMODE::OFF, t); } } CommandDistributor::broadcastPower(); return; - } + } case '!': // ESTOP ALL DCC::setThrottle(0,1,1); // this broadcasts speed 1(estop) and sets all reminders to speed 1. diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 07f4768..8fd9532 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -783,13 +783,13 @@ void RMFT2::loop2() { case OPCODE_SET_POWER: // operand is TRACK_POWER , trackid - + //byte thistrack=getOperand(1); switch (operand) { case TRACK_POWER_0: - TrackManager::setTrackPower(POWERMODE::OFF, getOperand(1)); + TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), POWERMODE::OFF, getOperand(1)); break; case TRACK_POWER_1: - TrackManager::setTrackPower(POWERMODE::ON, getOperand(1)); + TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), POWERMODE::ON, getOperand(1)); break; } diff --git a/TrackManager.cpp b/TrackManager.cpp index ad7ef6a..d653645 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -364,16 +364,16 @@ void TrackManager::streamTrackState(Print* stream, byte t) { break; #endif case TRACK_MODE_NONE: - if (pstate) {format=F("<= %c NONE %ON>\n");} else {format=F("<= %c NONE %OFF>\n");} + if (pstate) {format=F("<= %c NONE ON>\n");} else {format=F("<= %c NONE OFF>\n");} break; case TRACK_MODE_EXT: if (pstate) {format=F("<= %c EXT ON>\n");} else {format=F("<= %c EXT OFF>\n");} break; case TRACK_MODE_DC: - if (pstate) {format=F("<= %c DC ON %d>\n");} else {format=F("<= %c DC OFF %d>\n");} + if (pstate) {format=F("<= %c DC %d ON>\n");} else {format=F("<= %c DC %d OFF>\n");} break; case TRACK_MODE_DCX: - if (pstate) {format=F("<= %c DCX ON %d>\n");} else {format=F("<= %c DCX OFF %d>\n");} + if (pstate) {format=F("<= %c DCX %d ON>\n");} else {format=F("<= %c DCX %d OFF>\n");} break; default: break; // unknown, dont care @@ -416,9 +416,51 @@ std::vectorTrackManager::getMainDrivers() { void TrackManager::setPower2(bool setProg,POWERMODE mode) { if (!setProg) mainPowerGuess=mode; FOR_EACH_TRACK(t) { - MotorDriver * driver=track[t]; - if (!driver) continue; - switch (track[t]->getMode()) { + TrackManager::setTrackPower(setProg, mode, t); + // MotorDriver * driver=track[t]; + // if (!driver) continue; + // switch (track[t]->getMode()) { + // case TRACK_MODE_MAIN: + // if (setProg) break; + // // toggle brake before turning power on - resets overcurrent error + // // on the Pololu board if brake is wired to ^D2. + // // XXX see if we can make this conditional + // driver->setBrake(true); + // driver->setBrake(false); // DCC runs with brake off + // driver->setPower(mode); + // break; + // case TRACK_MODE_DC: + // case TRACK_MODE_DCX: + // if (setProg) break; + // driver->setBrake(true); // DC starts with brake on + // applyDCSpeed(t); // speed match DCC throttles + // driver->setPower(mode); + // break; + // case TRACK_MODE_PROG: + // if (!setProg) break; + // driver->setBrake(true); + // driver->setBrake(false); + // driver->setPower(mode); + // break; + // case TRACK_MODE_EXT: + // driver->setBrake(true); + // driver->setBrake(false); + // driver->setPower(mode); + // break; + // case TRACK_MODE_NONE: + // break; + // } + + } +} + +void TrackManager::setTrackPower(bool setProg, POWERMODE mode, byte thistrack) { + + DIAG(F("SetTrackPower Processing Track %d"), thistrack); + MotorDriver * driver=track[thistrack]; + if (!driver) return; + + switch (track[thistrack]->getMode()) { case TRACK_MODE_MAIN: if (setProg) break; // toggle brake before turning power on - resets overcurrent error @@ -432,7 +474,7 @@ void TrackManager::setPower2(bool setProg,POWERMODE mode) { case TRACK_MODE_DCX: if (setProg) break; driver->setBrake(true); // DC starts with brake on - applyDCSpeed(t); // speed match DCC throttles + applyDCSpeed(thistrack); // speed match DCC throttles driver->setPower(mode); break; case TRACK_MODE_PROG: @@ -449,17 +491,9 @@ void TrackManager::setPower2(bool setProg,POWERMODE mode) { case TRACK_MODE_NONE: break; } - - } -} - -void TrackManager::setTrackPower(POWERMODE mode, byte thistrack) { - - DIAG(F("SetPower Processing Track %d"), thistrack); - MotorDriver * driver=track[thistrack]; - if (!driver) return; - - driver->setPower(mode); + if (mode == POWERMODE::ON) {DIAG(F("Power Track %d ON"), thistrack);} + else {DIAG(F("Power Track %d OFF"), thistrack);} + //driver->setPower(mode); } diff --git a/TrackManager.h b/TrackManager.h index c6eea5c..39f708a 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -64,7 +64,7 @@ class TrackManager { #ifdef ARDUINO_ARCH_ESP32 static std::vectorgetMainDrivers(); #endif - static void setTrackPower(POWERMODE mode, byte thistrack); + static void setTrackPower(bool setProg, POWERMODE mode, byte thistrack); static void setPower2(bool progTrack,POWERMODE mode); static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);} static void setMainPower(POWERMODE mode) {setPower2(false,mode);} From 2a46b960838e3d96e4577001afb24bd3ae7f8016 Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Tue, 26 Sep 2023 18:02:39 +0100 Subject: [PATCH 05/10] Updates to power Updates to powere routines and EXRAIL --- DCCEXParser.cpp | 175 +++++++++++++++++++++++++---------------------- TrackManager.cpp | 59 +++++----------- TrackManager.h | 5 +- 3 files changed, 114 insertions(+), 125 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index a68b398..aee7e05 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -552,84 +552,88 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) case '1': // POWERON <1 [MAIN|PROG|JOIN]> { - bool main=false; - bool prog=false; - bool join=false; - bool singletrack=false; - byte t=0; - if (params > 1) break; - if (params==0) { // All - main=true; - prog=true; - } - if (params==1) { - if (p[0]==HASH_KEYWORD_MAIN) { // <1 MAIN> - main=true; - } + bool main=false; + bool prog=false; + bool join=false; + bool singletrack=false; + //byte t=0; + if (params > 1) break; + if (params==0) { // All + main=true; + prog=true; + } + if (params==1) { + if (p[0]==HASH_KEYWORD_MAIN) { // <1 MAIN> + main=true; + } #ifndef DISABLE_PROG - else if (p[0] == HASH_KEYWORD_JOIN) { // <1 JOIN> - main=true; - prog=true; - join=true; - } - else if (p[0]==HASH_KEYWORD_PROG) { // <1 PROG> - prog=true; - } + else if (p[0] == HASH_KEYWORD_JOIN) { // <1 JOIN> + main=true; + prog=true; + join=true; + } + else if (p[0]==HASH_KEYWORD_PROG) { // <1 PROG> + prog=true; + } #endif - else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> - t = (p[0] - 'A'); - //DIAG(F("Processing track - %d "), t); - if (TrackManager::isProg(t)) { - main = false; - prog = true; - } - else - { - main=true; - prog=false; - } - singletrack=true; + else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + byte t = (p[0] - 'A'); + //DIAG(F("Processing track - %d "), t); + if (TrackManager::isProg(t)) { + main = false; + prog = true; + } + else + { + main=true; + prog=false; + } + singletrack=true; + if (main) TrackManager::setTrackPower(false, POWERMODE::ON, t); + if (prog) TrackManager::setTrackPower(true, POWERMODE::ON, t); + //CommandDistributor::broadcastPower(); + //TrackManager::streamTrackState(stream, t); + TrackManager::streamTrackState(NULL,t); + StringFormatter::send(stream, F("Track %d ON\n"), t); + return; + } + + else break; // will reply + } - } - else break; // will reply - } - TrackManager::setJoin(join); if (!singletrack) { + TrackManager::setJoin(join); if (main) TrackManager::setMainPower(POWERMODE::ON); if (prog) TrackManager::setProgPower(POWERMODE::ON); - } - else { - if (main) TrackManager::setTrackPower(false, POWERMODE::ON, t); - if (prog) { - TrackManager::setTrackPower(true, POWERMODE::ON, t); + CommandDistributor::broadcastPower(); + + return; } - } - CommandDistributor::broadcastPower(); - return; + } case '0': // POWEROFF <0 [MAIN | PROG] > { - bool main=false; - bool prog=false; - bool singletrack=false; - byte t=0; - if (params > 1) break; - if (params==0) { // All - main=true; - prog=true; - } - if (params==1) { - if (p[0]==HASH_KEYWORD_MAIN) { // <0 MAIN> - main=true; - } + bool main=false; + bool prog=false; + bool singletrack=false; + //byte t=0; + if (params > 1) break; + if (params==0) { // All + main=true; + prog=true; + } + if (params==1) { + if (p[0]==HASH_KEYWORD_MAIN) { // <0 MAIN> + main=true; + } #ifndef DISABLE_PROG - else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG> - prog=true; - } -#endif <= - else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> - t = (p[0] - 'A'); + else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG> + prog=true; + } +#endif + else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + byte t = (p[0] - 'A'); //DIAG(F("Processing track - %d "), t); if (TrackManager::isProg(t)) { main = false; @@ -640,28 +644,33 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) main=true; prog=false; } - singletrack=true; - } - else break; // will reply - } - - TrackManager::setJoin(false); - if (!singletrack) { - if (main) TrackManager::setMainPower(POWERMODE::OFF); + singletrack=true; + TrackManager::setJoin(false); + if (main) TrackManager::setTrackPower(false, POWERMODE::OFF, t); if (prog) { + TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off + TrackManager::setTrackPower(true, POWERMODE::OFF, t); + CommandDistributor::broadcastPower(); + } + StringFormatter::send(stream, F("Track %d OFF\n"), t); + TrackManager::streamTrackState(NULL, t); + return; + } + + else break; // will reply + } + + if (!singletrack) { + TrackManager::setJoin(false); + + if (main) TrackManager::setMainPower(POWERMODE::OFF); + if (prog) { TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off TrackManager::setProgPower(POWERMODE::OFF); } - } - else { - if (main) TrackManager::setTrackPower(false, POWERMODE::OFF, t); - if (prog) { - TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off - TrackManager::setTrackPower(true, POWERMODE::OFF, t); - } + CommandDistributor::broadcastPower(); + return; } - CommandDistributor::broadcastPower(); - return; } case '!': // ESTOP ALL diff --git a/TrackManager.cpp b/TrackManager.cpp index d653645..f66fb4d 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -26,7 +26,8 @@ #include "MotorDriver.h" #include "DCCTimer.h" #include "DIAG.h" -#include"CommandDistributor.h" +#include "CommandDistributor.h" +#include "DCCEXParser.h" // Virtualised Motor shield multi-track hardware Interface #define FOR_EACH_TRACK(t) for (byte t=0;t<=lastTrack;t++) @@ -319,6 +320,7 @@ bool TrackManager::parseJ(Print *stream, int16_t params, int16_t p[]) FOR_EACH_TRACK(t) streamTrackState(stream,t); return true; + } p[0]-=HASH_KEYWORD_A; // convert A... to 0.... @@ -378,8 +380,10 @@ void TrackManager::streamTrackState(Print* stream, byte t) { default: break; // unknown, dont care } - if (stream) StringFormatter::send(stream,format,'A'+t, trackDCAddr[t]); + + if (stream) StringFormatter::send(stream,format,'A'+t, trackDCAddr[t]); else CommandDistributor::broadcastTrackState(format,'A'+t, trackDCAddr[t]); + } byte TrackManager::nextCycleTrack=MAX_TRACKS; @@ -416,47 +420,16 @@ std::vectorTrackManager::getMainDrivers() { void TrackManager::setPower2(bool setProg,POWERMODE mode) { if (!setProg) mainPowerGuess=mode; FOR_EACH_TRACK(t) { + TrackManager::setTrackPower(setProg, mode, t); - // MotorDriver * driver=track[t]; - // if (!driver) continue; - // switch (track[t]->getMode()) { - // case TRACK_MODE_MAIN: - // if (setProg) break; - // // toggle brake before turning power on - resets overcurrent error - // // on the Pololu board if brake is wired to ^D2. - // // XXX see if we can make this conditional - // driver->setBrake(true); - // driver->setBrake(false); // DCC runs with brake off - // driver->setPower(mode); - // break; - // case TRACK_MODE_DC: - // case TRACK_MODE_DCX: - // if (setProg) break; - // driver->setBrake(true); // DC starts with brake on - // applyDCSpeed(t); // speed match DCC throttles - // driver->setPower(mode); - // break; - // case TRACK_MODE_PROG: - // if (!setProg) break; - // driver->setBrake(true); - // driver->setBrake(false); - // driver->setPower(mode); - // break; - // case TRACK_MODE_EXT: - // driver->setBrake(true); - // driver->setBrake(false); - // driver->setPower(mode); - // break; - // case TRACK_MODE_NONE: - // break; - // } } + return; } void TrackManager::setTrackPower(bool setProg, POWERMODE mode, byte thistrack) { - DIAG(F("SetTrackPower Processing Track %d"), thistrack); + //DIAG(F("SetTrackPower Processing Track %d"), thistrack); MotorDriver * driver=track[thistrack]; if (!driver) return; @@ -491,16 +464,22 @@ void TrackManager::setTrackPower(bool setProg, POWERMODE mode, byte thistrack) { case TRACK_MODE_NONE: break; } - if (mode == POWERMODE::ON) {DIAG(F("Power Track %d ON"), thistrack);} - else {DIAG(F("Power Track %d OFF"), thistrack);} - //driver->setPower(mode); } + void TrackManager::reportPowerChange(Print* stream, byte thistrack) { + // This function is for backward JMRI compatibility only + // It reports the first track only, as main, regardless of track settings. + // + int maxCurrent=track[0]->raw2mA(track[0]->getRawCurrentTripValue()); + StringFormatter::send(stream, F("\n"), + track[0]->raw2mA(track[0]->getCurrentRaw(false)), maxCurrent, maxCurrent); +} + POWERMODE TrackManager::getProgPower() { FOR_EACH_TRACK(t) if (track[t]->getMode()==TRACK_MODE_PROG) - return track[t]->getPower(); + return track[t]->getPower(); return POWERMODE::OFF; } diff --git a/TrackManager.h b/TrackManager.h index 39f708a..cf2d54b 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -64,12 +64,12 @@ class TrackManager { #ifdef ARDUINO_ARCH_ESP32 static std::vectorgetMainDrivers(); #endif - static void setTrackPower(bool setProg, POWERMODE mode, byte thistrack); + static void setPower2(bool progTrack,POWERMODE mode); static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);} static void setMainPower(POWERMODE mode) {setPower2(false,mode);} static void setProgPower(POWERMODE mode) {setPower2(true,mode);} - + static void setTrackPower(bool setProg, POWERMODE mode, byte thistrack); static const int16_t MAX_TRACKS=8; @@ -84,6 +84,7 @@ class TrackManager { static void sampleCurrent(); static void reportGauges(Print* stream); static void reportCurrent(Print* stream); + static void reportPowerChange(Print* stream, byte thistrack); static void reportObsoleteCurrent(Print* stream); static void streamTrackState(Print* stream, byte t); static bool isPowerOn(byte t); From 25bbfa4c6805bf03cdb188d6d7d3457eec9b642b Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Wed, 27 Sep 2023 14:46:48 +0100 Subject: [PATCH 06/10] Fix <1 JOIN> Fixed <1 JOIN> issue in TrackManager --- DCCEXParser.cpp | 15 +++++++++------ EXRAIL2.cpp | 4 ++-- TrackManager.cpp | 18 ++++++++++-------- TrackManager.h | 9 +++++---- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index aee7e05..c82175b 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -589,8 +589,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=false; } singletrack=true; - if (main) TrackManager::setTrackPower(false, POWERMODE::ON, t); - if (prog) TrackManager::setTrackPower(true, POWERMODE::ON, t); + if (main) TrackManager::setTrackPower(false, false, POWERMODE::ON, t); + if (prog) TrackManager::setTrackPower(true, false, POWERMODE::ON, t); //CommandDistributor::broadcastPower(); //TrackManager::streamTrackState(stream, t); TrackManager::streamTrackState(NULL,t); @@ -603,8 +603,11 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) if (!singletrack) { TrackManager::setJoin(join); - if (main) TrackManager::setMainPower(POWERMODE::ON); - if (prog) TrackManager::setProgPower(POWERMODE::ON); + if (join) TrackManager::setJoinPower(POWERMODE::ON); + else { + if (main) TrackManager::setMainPower(POWERMODE::ON); + if (prog) TrackManager::setProgPower(POWERMODE::ON); + } CommandDistributor::broadcastPower(); return; @@ -646,10 +649,10 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) } singletrack=true; TrackManager::setJoin(false); - if (main) TrackManager::setTrackPower(false, POWERMODE::OFF, t); + if (main) TrackManager::setTrackPower(false, false, POWERMODE::OFF, t); if (prog) { TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off - TrackManager::setTrackPower(true, POWERMODE::OFF, t); + TrackManager::setTrackPower(true, false, POWERMODE::OFF, t); CommandDistributor::broadcastPower(); } StringFormatter::send(stream, F("Track %d OFF\n"), t); diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 8fd9532..321872d 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -786,10 +786,10 @@ void RMFT2::loop2() { //byte thistrack=getOperand(1); switch (operand) { case TRACK_POWER_0: - TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), POWERMODE::OFF, getOperand(1)); + TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), false, POWERMODE::OFF, getOperand(1)); break; case TRACK_POWER_1: - TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), POWERMODE::ON, getOperand(1)); + TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), false, POWERMODE::ON, getOperand(1)); break; } diff --git a/TrackManager.cpp b/TrackManager.cpp index f66fb4d..dd27d85 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -417,17 +417,17 @@ std::vectorTrackManager::getMainDrivers() { } #endif -void TrackManager::setPower2(bool setProg,POWERMODE mode) { +void TrackManager::setPower2(bool setProg,bool setJoin, POWERMODE mode) { if (!setProg) mainPowerGuess=mode; FOR_EACH_TRACK(t) { - TrackManager::setTrackPower(setProg, mode, t); + TrackManager::setTrackPower(setProg, setJoin, mode, t); } return; } -void TrackManager::setTrackPower(bool setProg, POWERMODE mode, byte thistrack) { +void TrackManager::setTrackPower(bool setProg, bool setJoin, POWERMODE mode, byte thistrack) { //DIAG(F("SetTrackPower Processing Track %d"), thistrack); MotorDriver * driver=track[thistrack]; @@ -445,21 +445,23 @@ void TrackManager::setTrackPower(bool setProg, POWERMODE mode, byte thistrack) { break; case TRACK_MODE_DC: case TRACK_MODE_DCX: - if (setProg) break; + DIAG(F("Processing track - %d setProg %d"), thistrack, setProg); + if (setProg || setJoin) {DIAG(F("Nowt to do")); break;} driver->setBrake(true); // DC starts with brake on applyDCSpeed(thistrack); // speed match DCC throttles driver->setPower(mode); + DIAG(F("Doing it anyway")); break; case TRACK_MODE_PROG: - if (!setProg) break; + if (!setProg && !setJoin) break; driver->setBrake(true); driver->setBrake(false); driver->setPower(mode); break; case TRACK_MODE_EXT: - driver->setBrake(true); - driver->setBrake(false); - driver->setPower(mode); + driver->setBrake(true); + driver->setBrake(false); + driver->setPower(mode); break; case TRACK_MODE_NONE: break; diff --git a/TrackManager.h b/TrackManager.h index cf2d54b..21b8d59 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -65,11 +65,12 @@ class TrackManager { static std::vectorgetMainDrivers(); #endif - static void setPower2(bool progTrack,POWERMODE mode); + static void setPower2(bool progTrack,bool joinTrack,POWERMODE mode); static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);} - static void setMainPower(POWERMODE mode) {setPower2(false,mode);} - static void setProgPower(POWERMODE mode) {setPower2(true,mode);} - static void setTrackPower(bool setProg, POWERMODE mode, byte thistrack); + static void setMainPower(POWERMODE mode) {setPower2(false,false,mode);} + static void setProgPower(POWERMODE mode) {setPower2(true,false,mode);} + static void setJoinPower(POWERMODE mode) {setPower2(false,true,mode);} + static void setTrackPower(bool setProg, bool setJoin, POWERMODE mode, byte thistrack); static const int16_t MAX_TRACKS=8; From 52cfc187543a487cde464a40fd7c7904284dca98 Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Thu, 28 Sep 2023 15:02:30 +0100 Subject: [PATCH 07/10] Remove Diags not needed Tidy up Diags and responses - use HASH_KEYWORD in place of 'A' --- DCCEXParser.cpp | 21 ++++++++++++--------- TrackManager.cpp | 7 +++---- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index c82175b..a561561 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -157,6 +157,7 @@ const int16_t HASH_KEYWORD_VPIN=-415; const int16_t HASH_KEYWORD_A='A'; const int16_t HASH_KEYWORD_C='C'; const int16_t HASH_KEYWORD_G='G'; +const int16_t HASH_KEYWORD_H='H'; const int16_t HASH_KEYWORD_I='I'; const int16_t HASH_KEYWORD_O='O'; const int16_t HASH_KEYWORD_P='P'; @@ -576,7 +577,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=true; } #endif - else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + //else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + else if (p[0] >= HASH_KEYWORD_A && p[0] <= HASH_KEYWORD_H) { // <1 A-H> byte t = (p[0] - 'A'); //DIAG(F("Processing track - %d "), t); if (TrackManager::isProg(t)) { @@ -591,10 +593,10 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) singletrack=true; if (main) TrackManager::setTrackPower(false, false, POWERMODE::ON, t); if (prog) TrackManager::setTrackPower(true, false, POWERMODE::ON, t); + + StringFormatter::send(stream, F("<1 %c>\n"), t+'A'); //CommandDistributor::broadcastPower(); - //TrackManager::streamTrackState(stream, t); - TrackManager::streamTrackState(NULL,t); - StringFormatter::send(stream, F("Track %d ON\n"), t); + //TrackManager::streamTrackState(NULL,t); return; } @@ -635,7 +637,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=true; } #endif - else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + //else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H> + else if (p[0] >= HASH_KEYWORD_A && p[0] <= HASH_KEYWORD_H) { // <1 A-H> byte t = (p[0] - 'A'); //DIAG(F("Processing track - %d "), t); if (TrackManager::isProg(t)) { @@ -652,11 +655,11 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) if (main) TrackManager::setTrackPower(false, false, POWERMODE::OFF, t); if (prog) { TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off - TrackManager::setTrackPower(true, false, POWERMODE::OFF, t); - CommandDistributor::broadcastPower(); + TrackManager::setTrackPower(true, false, POWERMODE::OFF, t); } - StringFormatter::send(stream, F("Track %d OFF\n"), t); - TrackManager::streamTrackState(NULL, t); + StringFormatter::send(stream, F("<0 %c>\n"), t+'A'); + //CommandDistributor::broadcastPower(); + //TrackManager::streamTrackState(NULL, t); return; } diff --git a/TrackManager.cpp b/TrackManager.cpp index dd27d85..bab202d 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -358,7 +358,7 @@ void TrackManager::streamTrackState(Print* stream, byte t) { bool pstate = TrackManager::isPowerOn(t); switch(track[t]->getMode()) { case TRACK_MODE_MAIN: - if (pstate) {format=F("<= %c MAIN ON \n");} else {format = F("<= %c MAIN OFF \n");} + if (pstate) {format=F("<= %c MAIN ON>\n");} else {format = F("<= %c MAIN OFF>\n");} break; #ifndef DISABLE_PROG case TRACK_MODE_PROG: @@ -445,12 +445,11 @@ void TrackManager::setTrackPower(bool setProg, bool setJoin, POWERMODE mode, byt break; case TRACK_MODE_DC: case TRACK_MODE_DCX: - DIAG(F("Processing track - %d setProg %d"), thistrack, setProg); - if (setProg || setJoin) {DIAG(F("Nowt to do")); break;} + //DIAG(F("Processing track - %d setProg %d"), thistrack, setProg); + if (setProg || setJoin) break; driver->setBrake(true); // DC starts with brake on applyDCSpeed(thistrack); // speed match DCC throttles driver->setPower(mode); - DIAG(F("Doing it anyway")); break; case TRACK_MODE_PROG: if (!setProg && !setJoin) break; From fe618d0b854a200dec5ce670e24dc92587735464 Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Fri, 6 Oct 2023 19:11:11 +0100 Subject: [PATCH 08/10] Add getModeName() Add facility to get the name of the track mode --- .gitignore | 1 + TrackManager.cpp | 22 +++++++++++++++++++++- TrackManager.h | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6237359..482da70 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ myFilter.cpp my*.h !my*.example.h compile_commands.json +newcode.txt.old diff --git a/TrackManager.cpp b/TrackManager.cpp index bab202d..3ea9877 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -556,4 +556,24 @@ bool TrackManager::isProg(byte t) { if (track[t]->getMode()==TRACK_MODE_PROG) return true; return false; -} \ No newline at end of file +} + +byte TrackManager::returnMode(byte t) { + return (track[t]->getMode()); +} + +static const char* TrackManager::getModeName(byte Mode) { + + //DIAG(F("PowerMode %d"), Mode); + +switch (Mode) + { + case 1: return "NONE"; + case 2: return "MAIN"; + case 4: return "PROG"; + case 8: return "DC"; + case 16: return "DCX"; + case 32: return "EXT"; + default: return "----"; + } +} diff --git a/TrackManager.h b/TrackManager.h index 21b8d59..486057a 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -90,6 +90,8 @@ class TrackManager { static void streamTrackState(Print* stream, byte t); static bool isPowerOn(byte t); static bool isProg(byte t); + static byte returnMode(byte t); + static const char* getModeName(byte Mode); static int16_t joinRelay; static bool progTrackSyncMain; // true when prog track is a siding switched to main From 68fd56e7fccc74be4c06a11eae04c8bec846538e Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Tue, 10 Oct 2023 11:52:46 +0100 Subject: [PATCH 09/10] Added returnDCAddr Added function to return DC address --- TrackManager.cpp | 7 ++++++- TrackManager.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/TrackManager.cpp b/TrackManager.cpp index 3ea9877..7d86de0 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -356,6 +356,7 @@ void TrackManager::streamTrackState(Print* stream, byte t) { if (track[t]==NULL) return; auto format=F(""); bool pstate = TrackManager::isPowerOn(t); + switch(track[t]->getMode()) { case TRACK_MODE_MAIN: if (pstate) {format=F("<= %c MAIN ON>\n");} else {format = F("<= %c MAIN OFF>\n");} @@ -562,7 +563,11 @@ byte TrackManager::returnMode(byte t) { return (track[t]->getMode()); } -static const char* TrackManager::getModeName(byte Mode) { +int16_t TrackManager::returnDCAddr(byte t) { + return (trackDCAddr[t]); +} + +const char* TrackManager::getModeName(byte Mode) { //DIAG(F("PowerMode %d"), Mode); diff --git a/TrackManager.h b/TrackManager.h index 486057a..d197751 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -91,6 +91,7 @@ class TrackManager { static bool isPowerOn(byte t); static bool isProg(byte t); static byte returnMode(byte t); + static int16_t returnDCAddr(byte t); static const char* getModeName(byte Mode); static int16_t joinRelay; From a092e06a6fec69159de22e14127524d53e65a20c Mon Sep 17 00:00:00 2001 From: Colin Murdoch Date: Tue, 10 Oct 2023 12:11:49 +0100 Subject: [PATCH 10/10] Update .gitignore added UserAddin.txt to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 482da70..759b739 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ my*.h !my*.example.h compile_commands.json newcode.txt.old +UserAddin.txt