mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 15:46:14 +01:00
Use aspect maps and add ability to use alternate light config (#422)
Idea to use a map to control the pins set for the different signal aspects, instead of just straight RED->redpin, AMBER->amberpin, GREEN->greenpin. There is a main map which does this and then an alternate map which may do anything. In the example, we use red -> amber/green -> green, which is the Deutsche Bahn signalling resolution (where physical signals are used rather than in-cab). This rewrites the LED section of the RMFT2::doSignal(), making it use the aspect map for even the features of merging red and green together for amber and the high-is-off setting. It adds 2 new automations: SIGNALA and SIGNALAH to allow the use of the alternate maps.
This commit is contained in:
parent
4e491a1e56
commit
445bfe7ebb
52
EXRAIL2.cpp
52
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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user