From 4300a3fdac613994c10538b25882b834e2802913 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 6 Feb 2022 13:56:51 +0000 Subject: [PATCH 1/2] UNTESTED SERVO_SIGNAL SERVO_SIGNAL definition in EXRAIL SERVO_SIGNAL(vpin, redpos, amberpos, greenpos) use RED/AMBER/GREEN as for led signals. --- EXRAIL2.cpp | 46 +++++++++++++++++++++++++++++++++------------ EXRAIL2.h | 4 +++- EXRAIL2MacroReset.h | 2 ++ EXRAILMacros.h | 7 +++++-- version.h | 2 +- 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index af6f0a1..9316a78 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -913,23 +913,45 @@ void RMFT2::kill(const FSH * reason, int operand) { /* static */ void RMFT2::doSignal(VPIN id,bool red, bool amber, bool green) { //if (diag) DIAG(F(" dosignal %d"),id); - for (int sigpos=0;;sigpos+=3) { - VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos); + for (int sigpos=0;;sigpos+=4) { //if (diag) DIAG(F("red=%d"),redpin); - if (redpin==0) { + VPIN sigid=GETFLASHW(RMFT2::SignalDefinitions+sigpos); + if (sigid==0) { // end of signal list DIAG(F("EXRAIL Signal %d not defined"), id); return; // signal not found } - if (redpin==id) { - VPIN amberpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1); - VPIN greenpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+2); - //if (diag) DIAG(F("signal %d %d %d"),redpin,amberpin,greenpin); - // If amberpin is zero, synthesise amber from red+green - IODevice::write(redpin,red || (amber && (amberpin==0))); - if (amberpin) IODevice::write(amberpin,amber); - if (greenpin) IODevice::write(greenpin,green || (amber && (amberpin==0))); - return; + // sigid is the signal id used in RED/AMBER/GREEN macro + // for a LED signal it will be same as redpin + // but for a servo signal it will also have SERVER_SIGNAL_FLAG set. + + if ((sigid & ~SERVO_SIGNAL_FLAG)!= id) continue; // keep looking + + // Correct signal definition found, get the rag values + VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1); + VPIN amberpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+2); + VPIN greenpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+3); + //if (diag) DIAG(F("signal %d %d %d"),redpin,amberpin,greenpin); + + if (sigid & SERVO_SIGNAL_FLAG) { + // A servo signal, the pin numbers are actually servo positions + // Note, setting a signal to a zero position has no effect. + int16_t servopos= red? redpin: (green? greenpin : amberpin); + if (servopos!=0) IODevice::writeAnalogue(id,servopos,PCA9685::Bounce); + return; } + + // LED or similar 3 pin signal + // If amberpin is zero, synthesise amber from red+green + if (amber && (amberpin==0)) { + red=true; + green=true; + } + + // set the three pins + if (redpin) IODevice::write(redpin,red); + if (amberpin) IODevice::write(amberpin,amber); + if (greenpin) IODevice::write(greenpin,green); + return; } } diff --git a/EXRAIL2.h b/EXRAIL2.h index b44ada6..0004720 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -93,7 +93,9 @@ class LookList { static void emitTurnoutDescription(Print* stream,int16_t id); static const byte rosterNameCount; static void emitWithrottleRoster(Print * stream); - static const FSH * getRosterFunctions(int16_t cabid); + static const FSH * getRosterFunctions(int16_t cabid); + static const int16_t SERVO_SIGNAL_FLAG=0x4000; + private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ; diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index 852eb70..0ddf9ba 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -97,6 +97,7 @@ #undef SERVO #undef SERVO2 #undef SERVO_TURNOUT +#undef SERVO_SIGNAL #undef SET #undef SETLOCO #undef SIGNAL @@ -185,6 +186,7 @@ #define SERIAL3(msg) #define SERVO(id,position,profile) #define SERVO2(id,position,duration) +#define SERVO_SIGNAL(vpin,redpos,amberpos,greenpos) #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) #define SET(pin) #define SETLOCO(loco) diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 7efb445..ddba9a7 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -146,10 +146,12 @@ const FSH * RMFT2::getRosterFunctions(int16_t cabid) { // Pass 8 Signal definitions #include "EXRAIL2MacroReset.h" #undef SIGNAL -#define SIGNAL(redpin,amberpin,greenpin) redpin,amberpin,greenpin, +#define SIGNAL(redpin,amberpin,greenpin) redpin,redpin,amberpin,greenpin, +#undef SERVO_SIGNAL +#define SERVO_SIGNAL(vpin,redval,amberval,greenval) vpin | RMFT2::SERVO_SIGNAL_FLAG,redval,amberval,greenval, const FLASH int16_t RMFT2::SignalDefinitions[] = { #include "myAutomation.h" - 0,0,0 }; + 0,0,0,0 }; // Last Pass : create main routes table // Only undef the macros, not dummy them. @@ -234,6 +236,7 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = { #define SERIAL3(msg) PRINT(msg) #define SERVO(id,position,profile) OPCODE_SERVO,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(PCA9685::profile),OPCODE_PAD,V(0), #define SERVO2(id,position,ms) OPCODE_SERVO,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(PCA9685::Instant),OPCODE_PAD,V(ms/100L), +#define SERVO_SIGNAL(vpin,redpos,amberpos,greenpos) #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 SETLOCO(loco) OPCODE_SETLOCO,V(loco), diff --git a/version.h b/version.h index c34d926..e387614 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,7 @@ #include "StringFormatter.h" -#define VERSION "3.2.0 rc13" +#define VERSION "4.0.1 ServoSignalTest" // 3.2.0 Major functional and non-functional changes. // New HAL added for I/O (digital and analogue inputs and outputs, servos etc). // Support for MCP23008, MCP23017 and PCF9584 I2C GPIO Extender modules. From 367e400d75f816b7cf52d83269f41e8bd9136140 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Fri, 18 Mar 2022 13:46:07 +0000 Subject: [PATCH 2/2] SIGNALH, ATGTE, ATLT UNTESTED --- EXRAIL2.cpp | 25 ++++++++++++++++++++----- EXRAIL2.h | 2 ++ EXRAIL2MacroReset.h | 6 ++++++ EXRAILMacros.h | 5 +++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 870db23..2bb75c5 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -594,6 +594,18 @@ void RMFT2::loop2() { delayMe(50); return; + case OPCODE_ATGTE: // wait for analog sensor>= value + timeoutFlag=false; + if (IODevice::readAnalogue(operand) >= (int)(GET_OPERAND(1))) break; + delayMe(50); + return; + + case OPCODE_ATLT: // wait for analog sensor < value + timeoutFlag=false; + if (IODevice::readAnalogue(operand) < (int)(GET_OPERAND(1))) break; + delayMe(50); + return; + case OPCODE_ATTIMEOUT1: // ATTIMEOUT(vpin,timeout) part 1 timeoutStart=millis(); timeoutFlag=false; @@ -928,9 +940,9 @@ void RMFT2::kill(const FSH * reason, int operand) { } // sigid is the signal id used in RED/AMBER/GREEN macro // for a LED signal it will be same as redpin - // but for a servo signal it will also have SERVER_SIGNAL_FLAG set. + // but for a servo signal it will also have SERVO_SIGNAL_FLAG set. - if ((sigid & ~SERVO_SIGNAL_FLAG)!= id) continue; // keep looking + if ((sigid & ~SERVO_SIGNAL_FLAG & ~ACTIVE_HIGH_SIGNAL_FLAG)!= id) continue; // keep looking // Correct signal definition found, get the rag values VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1); @@ -953,10 +965,13 @@ void RMFT2::kill(const FSH * reason, int operand) { green=true; } + // Manage invert (HIGH on) pins + bool aHigh=sigid & ACTIVE_HIGH_SIGNAL_FLAG; + // set the three pins - if (redpin) IODevice::write(redpin,red); - if (amberpin) IODevice::write(amberpin,amber); - if (greenpin) IODevice::write(greenpin,green); + if (redpin) IODevice::write(redpin,red^aHigh); + if (amberpin) IODevice::write(amberpin,amber^aHigh); + if (greenpin) IODevice::write(greenpin,green^aHigh); return; } } diff --git a/EXRAIL2.h b/EXRAIL2.h index d841323..fb81d44 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -33,6 +33,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_ATGTE,OPCODE_ATLT, OPCODE_ATTIMEOUT1,OPCODE_ATTIMEOUT2,OPCODE_IFTIMEOUT, OPCODE_LATCH,OPCODE_UNLATCH,OPCODE_SET,OPCODE_RESET, OPCODE_IF,OPCODE_IFNOT,OPCODE_ENDIF,OPCODE_IFRANDOM,OPCODE_IFRESERVE, @@ -95,6 +96,7 @@ class LookList { static void emitWithrottleRoster(Print * stream); static const FSH * getRosterFunctions(int16_t cabid); static const int16_t SERVO_SIGNAL_FLAG=0x4000; + static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000; private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index aeae7e4..4456679 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -29,6 +29,8 @@ #undef ALIAS #undef AMBER #undef AT +#undef ATGTE +#undef ATLT #undef ATTIMEOUT #undef AUTOMATION #undef AUTOSTART @@ -103,6 +105,7 @@ #undef SET #undef SETLOCO #undef SIGNAL +#undef SIGNALH #undef SPEED #undef START #undef STOP @@ -121,6 +124,8 @@ #define ALIAS(name,value) #define AMBER(signal_id) #define AT(sensor_id) +#define ATGTE(sensor_id,value) +#define ATLT(sensor_id,value) #define ATTIMEOUT(sensor_id,timeout_ms) #define AUTOMATION(id, description) #define AUTOSTART @@ -195,6 +200,7 @@ #define SET(pin) #define SETLOCO(loco) #define SIGNAL(redpin,amberpin,greenpin) +#define SIGNALH(redpin,amberpin,greenpin) #define SPEED(speed) #define START(route) #define STOP diff --git a/EXRAILMacros.h b/EXRAILMacros.h index b4c6406..1f143f0 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -149,6 +149,8 @@ const FSH * RMFT2::getRosterFunctions(int16_t cabid) { #include "EXRAIL2MacroReset.h" #undef SIGNAL #define SIGNAL(redpin,amberpin,greenpin) redpin,redpin,amberpin,greenpin, +#undef SIGNALH +#define SIGNALH(redpin,amberpin,greenpin) redpin | RMFT2::ACTIVE_HIGH_SIGNAL_FLAG,redpin,amberpin,greenpin, #undef SERVO_SIGNAL #define SERVO_SIGNAL(vpin,redval,amberval,greenval) vpin | RMFT2::SERVO_SIGNAL_FLAG,redval,amberval,greenval, const FLASH int16_t RMFT2::SignalDefinitions[] = { @@ -171,6 +173,8 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = { #define ALIAS(name,value) #define AMBER(signal_id) OPCODE_AMBER,V(signal_id), #define AT(sensor_id) OPCODE_AT,V(sensor_id), +#define ATGTE(sensor_id,value) OPCODE_ATGTE,V(sensor_id),OPCODE_PAD,V(value), +#define ATLT(sensor_id,value) OPCODE_ATLT,V(sensor_id),OPCODE_PAD,V(value), #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, @@ -245,6 +249,7 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = { #define SET(pin) OPCODE_SET,V(pin), #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 STOP OPCODE_SPEED,V(0),