diff --git a/DCC.cpp b/DCC.cpp index 31f9373..bd9e6df 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -48,7 +48,7 @@ void DCC::begin(MotorDriver * mainDriver, MotorDriver* progDriver, byte timerNum } void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) { - byte speedCode = (tSpeed & 0x7F) + tDirection * 128; //speed codes range from 2-127 (0=stop, 1=emergency stop) + byte speedCode = (tSpeed & 0x7F) + tDirection * 128; setThrottle2(cab, speedCode); // retain speed for loco reminders updateLocoReminder(cab, speedCode ); @@ -456,8 +456,10 @@ int DCC::lookupSpeedTable(int locoId) { void DCC::updateLocoReminder(int loco, byte speedCode) { if (loco==0) { - // broadcast message - for (int reg = 0; reg < MAX_LOCOS; reg++) speedTable[reg].speedCode = speedCode; + // broadcast stop/estop but dont change direction + for (int reg = 0; reg < MAX_LOCOS; reg++) { + speedTable[reg].speedCode = (speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f); + } return; } diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 7ff0a3c..dc58bd8 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -147,16 +147,20 @@ void DCCEXParser::parse(Print * stream, byte *com, bool blocking) { case '\0': return; // filterCallback asked us to ignore case 't': // THROTTLE { - if (p[1] == 0) break; // ignore requests for throttle address 0 (returns 'X') + if (params!=4) break; + // Convert JMRI bizarre -1=emergency stop, 0-126 as speeds // to DCC 0=stop, 1= emergency stop, 2-127 speeds int tspeed=p[2]; if (tspeed>126 || tspeed<-1) break; // invalid JMRI speed code if (tspeed<0) tspeed=1; // emergency stop DCC speed else if (tspeed>0) tspeed++; // map 1-126 -> 2-127 + if (p[1] == 0 && tspeed>1) break; // ignore broadcasts of speed>1 + + if (p[3]<0 || p[3]>1) break; // invalid direction code + DCC::setThrottle(p[1],tspeed,p[3]); - // report speed 0 after emergency stop - StringFormatter::send(stream,F(""), p[0], p[2]<0?0:p[2],p[3]); + StringFormatter::send(stream,F(""), p[0], p[2],p[3]); return; } case 'f': // FUNCTION