diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 1d97e7f..eb824df 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -1074,37 +1074,41 @@ int16_t RMFT2::getSignalSlot(int16_t id) { return; } - if (sigtype== DCC_SIGNAL_FLAG) { // redpin,amberpin are the DCC addr,subaddr DCC::setAccessory(redpin,amberpin, rag!=SIGNAL_RED); return; } - // LED or similar 3 pin signal, (all pins zero would be a virtual signal) - // If amberpin is zero, synthesise amber from red+green - const byte SIMAMBER=0x00; - if (rag==SIGNAL_AMBER && (amberpin==0)) rag=SIMAMBER; // special case this func only - - // Manage invert (HIGH on) pins - bool aHigh=sigid & ACTIVE_HIGH_SIGNAL_FLAG; - - // set the three pins - if (redpin) { - bool redval=(rag==SIGNAL_RED || rag==SIMAMBER); - if (!aHigh) redval=!redval; - IODevice::write(redpin,redval); - } - if (amberpin) { - bool amberval=(rag==SIGNAL_AMBER); - if (!aHigh) amberval=!amberval; - IODevice::write(amberpin,amberval); - } - if (greenpin) { - bool greenval=(rag==SIGNAL_GREEN || rag==SIMAMBER); - if (!aHigh) greenval=!greenval; - IODevice::write(greenpin,greenval); + // we duck out early for a virtual signal + if (!(redpin | amberpin | greenpin)) return; + + // at this point we have some kind of LED signal, so we're going to do everything by manipulation of the aspect map + int16_t aspect_map = (sigid & SIGNAL_USE_ALT_MAP_FLAG) ? SIGNAL_ALT_ASPECT : SIGNAL_MAIN_ASPECT; + + // in the case of red and green available and amber not, synthesise SIGNAL_AMBER from red + // and green aspects, leaving the other bits of the aspect untouched + if (redpin && greenpin && !amberpin) + aspect_map = (aspect_map & 0707) | ((aspect_map & 0700) >> 3) | ((aspect_map & 07) << 3); + + // invert the aspect map if HIGH is "off" + if (sigid & ACTIVE_HIGH_SIGNAL_FLAG) + aspect_map = 0777 - (aspect_map & 0777) + + int8_t pin_map = 0; + + switch (rag) { + case SIGNAL_RED: + pin_map = (aspect_map & 0700) >> 6; break; + case SIGNAL_AMBER: + pin_map = (aspect_map & 070) >> 3; break; + case SIGNAL_GREEN: + pin_map = aspect_map & 07; break; } + + if (redpin) IODevice::write(redpin, !!(pin_map & 04)); + if (amberpin) IODevice::write(amberpin, !!(pin_map & 02)); + if (greenpin) IODevice::write(greenpin, !!(pin_map & 01)); } /* static */ bool RMFT2::isSignal(int16_t id,char rag) { diff --git a/EXRAIL2.h b/EXRAIL2.h index 4d106e6..98bd01c 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -130,6 +130,7 @@ class LookList { static void activateEvent(int16_t addr, bool active); static void changeEvent(int16_t id, bool change); static void clockEvent(int16_t clocktime, bool change); + static const int16_t SIGNAL_USE_ALT_MAP_FLAG=0x8000; static const int16_t SERVO_SIGNAL_FLAG=0x4000; static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000; static const int16_t DCC_SIGNAL_FLAG=0x1000; diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index 588a417..b251ef7 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -130,17 +130,19 @@ #undef SERVO_SIGNAL #undef SET #undef SET_TRACK -#undef SETLOCO -#undef SIGNAL -#undef SIGNALH -#undef SPEED -#undef START -#undef STOP -#undef THROW -#undef TURNOUT +#undef SETLOCO +#undef SIGNAL +#undef SIGNALH +#undef SIGNALA +#undef SIGNALAH +#undef SPEED +#undef START +#undef STOP +#undef THROW +#undef TURNOUT #undef TURNOUTL #undef UNJOIN -#undef UNLATCH +#undef UNLATCH #undef VIRTUAL_SIGNAL #undef VIRTUAL_TURNOUT #undef WAITFOR diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 4bbabfc..7d78b4c 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -234,6 +234,11 @@ const FSH * RMFT2::getRosterFunctions(int16_t id) { #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 SIGNALA +#define SIGNALA(redpin,amberpin,greenpin) redpin | RMFT2::SIGNAL_USE_ALT_MAP_FLAG,redpin,amberpin,greenpin, +#undef SIGNALAH +#define SIGNALAH(redpin,amberpin,greenpin) redpin | RMFT2::ACTIVE_HIGH_SIGNAL_FLAG | RMFT2::SIGNAL_USE_ALT_MAP_FLAG, \ + redpin,amberpin,greenpin, #undef SERVO_SIGNAL #define SERVO_SIGNAL(vpin,redval,amberval,greenval) vpin | RMFT2::SERVO_SIGNAL_FLAG,redval,amberval,greenval, #undef DCC_SIGNAL diff --git a/config.example.h b/config.example.h index 0f136f9..6d809bd 100644 --- a/config.example.h +++ b/config.example.h @@ -261,7 +261,7 @@ The configuration file for DCC-EX Command Station // 2. The app will be bigger that 1.2MB, so the default partition scheme will not // work any more. You need to choose a partition scheme with 2MB (or bigger). // For example "NO OTA (2MB APP, 2MB SPIFFS)" in the Arduino IDE. -// 3. There is no securuity (PIN) implemented. Everyone in radio range can pair +// 3. There is no security (PIN) implemented. Everyone in radio range can pair // with your CS. // //#define SERIAL_BT_COMMANDS @@ -278,3 +278,15 @@ The configuration file for DCC-EX Command Station //#define SABERTOOTH 1 ///////////////////////////////////////////////////////////////////////////////////// +// don't change this, this defines the main aspect as RED -> red pin, AMBER -> amber +// pin, and GREEN -> green pin +// these are octal int16_t types defining aspect and pin map: +// -----------N/A----------- ---RED--- --AMBER-- --GREEN-- +// r a g r a g r a g +// | f | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// +#define SIGNAL_MAIN_ASPECT 0421 +// this defines an alternate aspect (eg. here, the Deutsche Bahn RED -> red pin, +// AMBER -> amber pin and green pin, GREEN -> green pin) +// These can be selected with the SIGNALA and SIGNALAH automations in myAutomation.h +#define SIGNAL_ALT_ASPECT 0431