diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 0982510f..536eee7e 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -607,7 +607,24 @@ void RMFT2::loop2() { case OPCODE_INVERT_DIRECTION: invert= !invert; break; - + + case OPCODE_SAVESPEED: + if (loco) { + auto slot=LocoSlot::getSlot(loco,false); + if (slot) { + slot->saveSpeed(); + } + } + break; + + case OPCODE_RESTORESPEED: + if (loco) { + auto slot=LocoSlot::getSlot(loco,false); + + if (slot) DCC::setThrottle(loco,slot->getSavedSpeed() & 0x7F,DCC::getThrottleDirection(loco)); + } + break; + case OPCODE_RESERVE: if (getFlag(operand,SECTION_FLAG)) { if (loco) DCC::setThrottle(loco,1,DCC::getThrottleDirection(loco)); diff --git a/EXRAIL2.h b/EXRAIL2.h index 0a9e7ada..20802fab 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -35,7 +35,7 @@ // searching easier as a parameter can never be confused with an opcode. // enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,OPCODE_TOGGLE_TURNOUT, - OPCODE_FWD,OPCODE_REV,OPCODE_SPEED,OPCODE_INVERT_DIRECTION, + OPCODE_FWD,OPCODE_REV,OPCODE_SPEED,OPCODE_INVERT_DIRECTION,OPCODE_SAVESPEED,OPCODE_RESTORESPEED, OPCODE_MOMENTUM, OPCODE_RESERVE,OPCODE_FREE, OPCODE_AT,OPCODE_AFTER, diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index 18acd883..20f6cf75 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -153,6 +153,7 @@ #undef RED #undef RESERVE #undef RESET +#undef RESTORESPEED #undef RESUME #undef RETURN #undef REV @@ -165,6 +166,7 @@ #undef ROUTE_HIDDEN #undef ROUTE_DISABLED #undef ROUTE_CAPTION +#undef SAVESPEED #undef SENDLOCO #undef SEQUENCE #undef SERIAL @@ -1049,6 +1051,12 @@ * @param count... Number of consecutive pins, default 1 */ #define RESET(vpin,count...) +/** + * @def RESTORESPEED + * @brief Restore current loco speed + * @see SAVESPEED + */ +#define RESTORESPEED /** * @def RESUME * @brief Resumes PAUSEd tasks @@ -1140,6 +1148,12 @@ * @param caption */ #define ROUTE_CAPTION(sequence_id,caption) +/** + * @def SAVESPEED + * @brief Save current loco speed + * @see RESTORESPEED + */ +#define SAVESPEED /** * @def SENDLOCO(cab,sequence_id) * @brief Start a new task to drive the loco diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 484aae3a..9d8a7eee 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -602,6 +602,8 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup]; #define ROUTE_HIDDEN(id) OPCODE_ROUTE_HIDDEN,V(id), #define ROUTE_DISABLED(id) OPCODE_ROUTE_DISABLED,V(id), #define ROUTE_CAPTION(id,caption) PRINT(caption) +#define SAVESPEED OPCODE_SAVESPEED,0,0, +#define RESTORESPEED OPCODE_RESTORESPEED,0,0, #define SENDLOCO(cab,route) OPCODE_SENDLOCO,V(cab),OPCODE_PAD,V(route), #define SEQUENCE(id) OPCODE_SEQUENCE, V(id), #define SERIAL(msg) PRINT(msg) diff --git a/LocoSlot.cpp b/LocoSlot.cpp index 26a690df..256761aa 100644 --- a/LocoSlot.cpp +++ b/LocoSlot.cpp @@ -31,6 +31,7 @@ void LocoSlot::prepare(uint16_t locoId) { momentumA=MOMENTUM_USE_DEFAULT; momentumD=MOMENTUM_USE_DEFAULT; targetSpeed=128; + savedSpeed=128; blockOccupied=0; snifferSpeedCode=128; // default direction forward @@ -80,6 +81,11 @@ void LocoSlot::forget() { chainModified=true; } +void LocoSlot::saveSpeed() { + // targetSpeed should eventually to be the speed we want to reach and save + savedSpeed=targetSpeed; +} + /* static */ void LocoSlot::forgetAll() { // remove entire list LocoSlot * killnext=nullptr; diff --git a/LocoSlot.h b/LocoSlot.h index 85886fd4..98cd5e97 100644 --- a/LocoSlot.h +++ b/LocoSlot.h @@ -45,6 +45,7 @@ class LocoSlot { uint16_t blockOccupied; // railcom detected block byte targetSpeed; // speed set by throttle + byte savedSpeed; byte speedCode; // current DCC speed and direction byte snifferSpeedCode; // sniffer speed and direction byte momentumA; // momentum accelerating @@ -82,6 +83,8 @@ class LocoSlot { void setMomentumBase(uint32_t v) { momentum_base=v; } byte getTargetSpeed() { return targetSpeed; } void setTargetSpeed(byte v) { targetSpeed=v; } + byte getSavedSpeed() { return savedSpeed; } + void setSavedSpeed(byte v) { savedSpeed=v; } byte getSpeedCode() { return speedCode; } void setSpeedCode(byte v) { speedCode=v; } @@ -92,6 +95,7 @@ class LocoSlot { uint16_t getBlockOccupied() { return blockOccupied; } void setBlockOccupied(uint16_t v) { blockOccupied=v; } void forget(); + void saveSpeed(); }; #endif \ No newline at end of file