From 230a119cd0ce18901aa6304af715b0a57b824664 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Mon, 3 Jan 2022 10:15:10 +0000 Subject: [PATCH] ATTIMEOUT / IFTIMEOUT --- RMFT2.cpp | 23 ++++++++++++++++++++++- RMFT2.h | 7 ++++++- RMFT2MacroReset.h | 4 ++++ RMFTMacros.h | 2 ++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/RMFT2.cpp b/RMFT2.cpp index 8ca2e2f..e302baf 100644 --- a/RMFT2.cpp +++ b/RMFT2.cpp @@ -432,6 +432,7 @@ RMFT2::RMFT2(int progCtr) { speedo=0; forward=true; invert=false; + timeoutFlag=false; stackDepth=0; onTurnoutId=0; // Not handling an ONTHROW/ONCLOSE @@ -508,6 +509,7 @@ bool RMFT2::skipIfBlock() { case OPCODE_IFRANDOM: case OPCODE_IFRESERVE: case OPCODE_IFTHROWN: + case OPCODE_IFTIMEOUT: nest++; break; case OPCODE_ENDIF: @@ -591,10 +593,29 @@ void RMFT2::loop2() { break; case OPCODE_AT: + timeoutFlag=false; if (readSensor(operand)) break; delayMe(50); return; + case OPCODE_ATTIMEOUT1: // ATTIMEOUT(vpin,timeout) part 1 + timeoutStart=millis(); + timeoutFlag=false; + break; + + case OPCODE_ATTIMEOUT2: + if (readSensor(operand)) break; // success without timeout + if (millis()-timeoutStart > 100*GET_OPERAND(1)) { + timeoutFlag=true; + break; // and drop through + } + delayMe(50); + return; + + case OPCODE_IFTIMEOUT: // do next operand if timeout flag set + if (!timeoutFlag) if (!skipIfBlock()) return; + break; + case OPCODE_AFTER: // waits for sensor to hit and then remain off for 0.5 seconds. (must come after an AT operation) if (readSensor(operand)) { // reset timer to half a second and keep waiting @@ -646,7 +667,7 @@ void RMFT2::loop2() { case OPCODE_IF: // do next operand if sensor set if (!readSensor(operand)) if (!skipIfBlock()) return; break; - + case OPCODE_ELSE: // skip to matching ENDIF if (!skipIfBlock()) return; break; diff --git a/RMFT2.h b/RMFT2.h index 0ebbc02..821fb7a 100644 --- a/RMFT2.h +++ b/RMFT2.h @@ -31,6 +31,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE, OPCODE_FWD,OPCODE_REV,OPCODE_SPEED,OPCODE_INVERT_DIRECTION, OPCODE_RESERVE,OPCODE_FREE, OPCODE_AT,OPCODE_AFTER,OPCODE_AUTOSTART, + OPCODE_ATTIMEOUT1,OPCODE_ATTIMEOUT2,OPCODE_IFTIMEOUT, OPCODE_LATCH,OPCODE_UNLATCH,OPCODE_SET,OPCODE_RESET, OPCODE_IF,OPCODE_IFNOT,OPCODE_ENDIF,OPCODE_IFRANDOM,OPCODE_IFRESERVE, OPCODE_IFCLOSED, OPCODE_IFTHROWN,OPCODE_ELSE, @@ -127,8 +128,12 @@ private: RMFT2 *next; // loop chain int progCounter; // Byte offset of next route opcode in ROUTES table unsigned long delayStart; // Used by opcodes that must be recalled before completing - unsigned long waitAfter; // Used by OPCODE_AFTER unsigned long delayTime; + union { + unsigned long waitAfter; // Used by OPCODE_AFTER + unsigned long timeoutStart; // Used by OPCODE_ATTIMEOUT + }; + bool timeoutFlag; byte taskId; uint16_t loco; diff --git a/RMFT2MacroReset.h b/RMFT2MacroReset.h index cf31dcf..4cf2136 100644 --- a/RMFT2MacroReset.h +++ b/RMFT2MacroReset.h @@ -28,6 +28,7 @@ #undef ALIAS #undef AMBER #undef AT +#undef ATTIMEOUT #undef AUTOMATION #undef AUTOSTART #undef CALL @@ -60,6 +61,7 @@ #undef IFRANDOM #undef IFRESERVE #undef IFTHROWN +#undef IFTIMEOUT #undef INVERT_DIRECTION #undef JOIN #undef LATCH @@ -115,6 +117,7 @@ #define ALIAS(name,value) #define AMBER(signal_id) #define AT(sensor_id) +#define ATTIMEOUT(sensor_id,timeout_ms) #define AUTOMATION(id, description) #define AUTOSTART #define CALL(route) @@ -147,6 +150,7 @@ #define IFRANDOM(percent) #define IFTHROWN(turnout_id) #define IFRESERVE(block) +#define IFTIMEOUT #define INVERT_DIRECTION #define JOIN #define LATCH(sensor_id) diff --git a/RMFTMacros.h b/RMFTMacros.h index cd0e4cf..cc75af3 100644 --- a/RMFTMacros.h +++ b/RMFTMacros.h @@ -157,6 +157,7 @@ const FSH * RMFT2::getRosterFunctions(int16_t cabid) { #define ALIAS(name,value) #define AMBER(signal_id) OPCODE_AMBER,V(signal_id), #define AT(sensor_id) OPCODE_AT,V(sensor_id), +#define ATTIMEOUT(sensor_id,timeout) OPCODE_ATTIMEOUT1,0,0,OPCODE_ATTIMEOUT2,V(sensor_id),OPCODE_PAD,V(timeout/100L), #define AUTOMATION(id, description) OPCODE_AUTOMATION, V(id), #define AUTOSTART OPCODE_AUTOSTART,0,0, #define CALL(route) OPCODE_CALL,V(route), @@ -189,6 +190,7 @@ const FSH * RMFT2::getRosterFunctions(int16_t cabid) { #define IFRANDOM(percent) OPCODE_IFRANDOM,V(percent), #define IFRESERVE(block) OPCODE_IFRESERVE,V(block), #define IFTHROWN(turnout_id) OPCODE_IFTHROWN,V(turnout_id), +#define IFTIMEOUT OPCODE_IFTIMEOUT,0,0, #define INVERT_DIRECTION OPCODE_INVERT_DIRECTION,0,0, #define JOIN OPCODE_JOIN,0,0, #define LATCH(sensor_id) OPCODE_LATCH,V(sensor_id),