1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-24 21:21:24 +01:00

Added Single Track Power On/Off

Added power On/Off <> commands
This commit is contained in:
Colin Murdoch 2023-09-22 17:03:40 +01:00
parent 7a305e179c
commit 8052090e0f
5 changed files with 121 additions and 56 deletions

View File

@ -269,6 +269,6 @@ void CommandDistributor::broadcastRaw(clientType type, char * msg) {
broadcastReply(type, F("%s"),msg); broadcastReply(type, F("%s"),msg);
} }
void CommandDistributor::broadcastTrackState(const FSH* format,byte trackLetter,int16_t dcAddr) { void CommandDistributor::broadcastTrackState(const FSH* format,byte trackLetter,char pmode, int16_t dcAddr) {
broadcastReply(COMMAND_TYPE, format,trackLetter,dcAddr); broadcastReply(COMMAND_TYPE, format,trackLetter,pmode, dcAddr);
} }

View File

@ -55,7 +55,7 @@ public :
static int16_t retClockTime(); static int16_t retClockTime();
static void broadcastPower(); static void broadcastPower();
static void broadcastRaw(clientType type,char * msg); 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<typename... Targs> static void broadcastReply(clientType type, Targs... msg); template<typename... Targs> static void broadcastReply(clientType type, Targs... msg);
static void forget(byte clientId); static void forget(byte clientId);

View File

@ -555,6 +555,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
bool main=false; bool main=false;
bool prog=false; bool prog=false;
bool join=false; bool join=false;
bool singletrack=false;
if (params > 1) break; if (params > 1) break;
if (params==0) { // All if (params==0) { // All
main=true; main=true;
@ -574,12 +575,28 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
prog=true; 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::ON, t);
if (prog) TrackManager::SetProgTrackPower(POWERMODE::ON, t);
}
else break; // will reply <X> else break; // will reply <X>
} }
TrackManager::setJoin(join); TrackManager::setJoin(join);
if (main) TrackManager::setMainPower(POWERMODE::ON); if (!singletrack) {
if (prog) TrackManager::setProgPower(POWERMODE::ON); if (main) TrackManager::setMainPower(POWERMODE::ON);
if (prog) TrackManager::setProgPower(POWERMODE::ON);
}
CommandDistributor::broadcastPower(); CommandDistributor::broadcastPower();
return; return;
} }
@ -588,6 +605,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
{ {
bool main=false; bool main=false;
bool prog=false; bool prog=false;
bool singletrack=false;
if (params > 1) break; if (params > 1) break;
if (params==0) { // All if (params==0) { // All
main=true; main=true;
@ -602,16 +620,33 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
prog=true; 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 <X> else break; // will reply <X>
} }
TrackManager::setJoin(false); TrackManager::setJoin(false);
if (!singletrack) {
if (main) TrackManager::setMainPower(POWERMODE::OFF); if (main) TrackManager::setMainPower(POWERMODE::OFF);
if (prog) { if (prog) {
TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off
TrackManager::setProgPower(POWERMODE::OFF); TrackManager::setProgPower(POWERMODE::OFF);
}
} }
CommandDistributor::broadcastPower(); CommandDistributor::broadcastPower();
return; return;
} }

View File

@ -353,32 +353,48 @@ void TrackManager::streamTrackState(Print* stream, byte t) {
// null stream means send to commandDistributor for broadcast // null stream means send to commandDistributor for broadcast
if (track[t]==NULL) return; if (track[t]==NULL) return;
auto format=F(""); 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()) { switch(track[t]->getMode()) {
case TRACK_MODE_MAIN: case TRACK_MODE_MAIN:
format=F("<= %c MAIN>\n"); format=F("<= %c MAIN %c>\n");
break; break;
#ifndef DISABLE_PROG #ifndef DISABLE_PROG
case TRACK_MODE_PROG: case TRACK_MODE_PROG:
format=F("<= %c PROG>\n"); format=F("<= %c PROG %c>\n");
break; break;
#endif #endif
case TRACK_MODE_NONE: case TRACK_MODE_NONE:
format=F("<= %c NONE>\n"); format=F("<= %c NONE %c>\n");
break; break;
case TRACK_MODE_EXT: case TRACK_MODE_EXT:
format=F("<= %c EXT>\n"); format=F("<= %c EXT %c>\n");
break; break;
case TRACK_MODE_DC: case TRACK_MODE_DC:
format=F("<= %c DC %d>\n"); format=F("<= %c DC %c %d>\n");
break; break;
case TRACK_MODE_DCX: case TRACK_MODE_DCX:
format=F("<= %c DCX %d>\n"); format=F("<= %c DCX %c %d>\n");
break; break;
default: default:
break; // unknown, dont care break; // unknown, dont care
} }
if (stream) StringFormatter::send(stream,format,'A'+t,trackDCAddr[t]); switch (pstate) {
else CommandDistributor::broadcastTrackState(format,'A'+t,trackDCAddr[t]); 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; byte TrackManager::nextCycleTrack=MAX_TRACKS;
@ -412,45 +428,51 @@ std::vector<MotorDriver *>TrackManager::getMainDrivers() {
} }
#endif #endif
void TrackManager::setPower2(bool setProg,POWERMODE mode) { void TrackManager::setPower2(bool setProg,POWERMODE mode, bool doall, uint8_t thistrack) {
if (!setProg) mainPowerGuess=mode; if (!setProg) mainPowerGuess=mode;
FOR_EACH_TRACK(t) { FOR_EACH_TRACK(t) {
MotorDriver * driver=track[t]; if (doall==false && thistrack != t) break;
if (!driver) continue; MotorDriver * driver=track[t];
switch (track[t]->getMode()) { if (!driver) continue;
case TRACK_MODE_MAIN: switch (track[t]->getMode()) {
if (setProg) break; case TRACK_MODE_MAIN:
// toggle brake before turning power on - resets overcurrent error if (setProg) break;
// on the Pololu board if brake is wired to ^D2. // toggle brake before turning power on - resets overcurrent error
// XXX see if we can make this conditional // on the Pololu board if brake is wired to ^D2.
driver->setBrake(true); // XXX see if we can make this conditional
driver->setBrake(false); // DCC runs with brake off driver->setBrake(true);
driver->setPower(mode); driver->setBrake(false); // DCC runs with brake off
break; driver->setPower(mode);
case TRACK_MODE_DC: break;
case TRACK_MODE_DCX: case TRACK_MODE_DC:
if (setProg) break; case TRACK_MODE_DCX:
driver->setBrake(true); // DC starts with brake on if (setProg) break;
applyDCSpeed(t); // speed match DCC throttles driver->setBrake(true); // DC starts with brake on
driver->setPower(mode); applyDCSpeed(t); // speed match DCC throttles
break; driver->setPower(mode);
case TRACK_MODE_PROG: break;
if (!setProg) break; case TRACK_MODE_PROG:
driver->setBrake(true); if (!setProg) break;
driver->setBrake(false); driver->setBrake(true);
driver->setPower(mode); driver->setBrake(false);
break; driver->setPower(mode);
case TRACK_MODE_EXT: break;
driver->setBrake(true); case TRACK_MODE_EXT:
driver->setBrake(false); driver->setBrake(true);
driver->setPower(mode); driver->setBrake(false);
break; driver->setPower(mode);
case TRACK_MODE_NONE: break;
break; case TRACK_MODE_NONE:
break;
} }
} }
} }
// void TrackManager::setTrackPower(bool progTrack,POWERMODE mode, uint8_t track) {
// // write the code for this.
// }
POWERMODE TrackManager::getProgPower() { POWERMODE TrackManager::getProgPower() {
FOR_EACH_TRACK(t) FOR_EACH_TRACK(t)
if (track[t]->getMode()==TRACK_MODE_PROG) if (track[t]->getMode()==TRACK_MODE_PROG)
@ -526,3 +548,8 @@ bool TrackManager::isPowerOn(byte t) {
return true; return true;
} }
bool TrackManager::isProg(byte t) {
if (track[t]->getMode()==TRACK_MODE_PROG)
return true;
return false;
}

View File

@ -60,10 +60,12 @@ class TrackManager {
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
static std::vector<MotorDriver *>getMainDrivers(); static std::vector<MotorDriver *>getMainDrivers();
#endif #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 setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);}
static void setMainPower(POWERMODE mode) {setPower2(false,mode);} static void setMainPower(POWERMODE mode) {setPower2(false,mode,true,0);}
static void setProgPower(POWERMODE mode) {setPower2(true,mode);} 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 const int16_t MAX_TRACKS=8;
static bool setTrackMode(byte track, TRACK_MODE mode, int16_t DCaddr=0); 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 reportObsoleteCurrent(Print* stream);
static void streamTrackState(Print* stream, byte t); static void streamTrackState(Print* stream, byte t);
static bool isPowerOn(byte t); static bool isPowerOn(byte t);
static bool isProg(byte t);
static int16_t joinRelay; static int16_t joinRelay;
static bool progTrackSyncMain; // true when prog track is a siding switched to main static bool progTrackSyncMain; // true when prog track is a siding switched to main