diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 94b711e..40ea635 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -732,11 +732,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) for (uint8_t p = 0; p < posCount; p++) { StringFormatter::send(stream, F("getPositionValue(p); + int16_t angle = tto->getPositionAngle(p); #ifdef EXRAIL_ACTIVE tpdesc = RMFT2::getTurntablePositionDescription(id, p); #endif if (tpdesc == NULL) tpdesc = F(""); - StringFormatter::send(stream, F(" %d %d %d \"%S\""), id, p, value, tpdesc); + StringFormatter::send(stream, F(" %d %d %d %d \"%S\""), id, p, value, angle, tpdesc); StringFormatter::send(stream, F(">\n")); } } @@ -1107,44 +1108,54 @@ bool DCCEXParser::parseI(Print *stream, int16_t params, int16_t p[]) } return true; - case 2: // | - rotate or create DCC turntable + case 2: // - rotate a DCC turntable { Turntable *tto = Turntable::get(p[0]); - if (p[1] == HASH_KEYWORD_DCC) { // Create a DCC turntable - if (tto) return false; - if (!DCCTurntable::create(p[0])) return false; - Turntable *tto = Turntable::get(p[0]); - tto->addPosition(0, 0); - } else { // Otherwise move a DCC turntable - if (tto && !tto->isEXTT()) { - if (!tto->setPosition(p[0], p[1])) return false; - } else { - return false; - } + if (tto && !tto->isEXTT()) { + if (!tto->setPosition(p[0], p[1])) return false; + } else { + return false; } } return true; - case 3: // rotate to position for EX-Turntable + case 3: // | - rotate to position for EX-Turntable or create DCC turntable { Turntable *tto = Turntable::get(p[0]); - if (!tto) return false; - if (!tto->isEXTT()) return false; - if (!tto->setPosition(p[0], p[1], p[2])) return false; + if (p[1] == HASH_KEYWORD_DCC) { + if (tto || p[2] < 0 || p[2] > 3600) return false; + if (!DCCTurntable::create(p[0])) return false; + Turntable *tto = Turntable::get(p[0]); + tto->addPosition(0, 0, p[2]); + } else { + if (!tto) return false; + if (!tto->isEXTT()) return false; + if (!tto->setPosition(p[0], p[1], p[2])) return false; + } } return true; - case 4: // | create an EXTT turntable or add position + case 4: // create an EXTT turntable { Turntable *tto = Turntable::get(p[0]); if (p[1] == HASH_KEYWORD_EXTT) { - if (tto) return false; + if (tto || p[3] < 0 || p[3] > 3600) return false; if (!EXTTTurntable::create(p[0], (VPIN)p[2])) return false; Turntable *tto = Turntable::get(p[0]); - tto->addPosition(0, p[3]); - } else if (p[1] == HASH_KEYWORD_ADD) { - if (!tto) return false; - tto->addPosition(p[2], p[3]); + tto->addPosition(0, 0, p[3]); + } else { + return false; + } + } + return true; + + case 5: // add a position + { + Turntable *tto = Turntable::get(p[0]); + if (p[1] == HASH_KEYWORD_ADD) { + // tto must exist, no more than 48 positions, angle 0 - 3600 + if (!tto || p[2] > 48 || p[4] < 0 || p[4] > 3600) return false; + tto->addPosition(p[2], p[3], p[4]); StringFormatter::send(stream, F("\n")); } else { return false; diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 2d379a7..32d2795 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -53,6 +53,7 @@ #include "CommandDistributor.h" #include "TrackManager.h" #include "Turntables.h" +#include "IODevice.h" // Command parsing keywords const int16_t HASH_KEYWORD_EXRAIL=15435; @@ -248,9 +249,10 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) { #ifndef IO_NO_HAL case OPCODE_DCCTURNTABLE: { VPIN id=operand; + int home=getOperand(progCounter,1); setTurntableHiddenState(DCCTurntable::create(id)); Turntable *tto=Turntable::get(id); - tto->addPosition(0,0); + tto->addPosition(0,0,home); break; } @@ -260,7 +262,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) { int home=getOperand(progCounter,2); setTurntableHiddenState(EXTTTurntable::create(id,pin)); Turntable *tto=Turntable::get(id); - tto->addPosition(0,home); + tto->addPosition(0,0,home); break; } @@ -268,8 +270,9 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) { VPIN id=operand; int position=getOperand(progCounter,1); int value=getOperand(progCounter,2); + int angle=getOperand(progCounter,3); Turntable *tto=Turntable::get(id); - tto->addPosition(position,value); + tto->addPosition(position,value,angle); break; } #endif diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index efe91a5..b54a9d9 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -119,6 +119,7 @@ #undef REV #undef ROSTER #undef ROTATE +#undef ROTATE_DCC #undef ROUTE #undef SENDLOCO #undef SEQUENCE @@ -174,7 +175,7 @@ #define CALL(route) #define CLOSE(id) #define DCC_SIGNAL(id,add,subaddr) -#define DCC_TURNTABLE(id,description) +#define DCC_TURNTABLE(id,home,description) #define DEACTIVATE(addr,subaddr) #define DEACTIVATEL(addr) #define DELAY(mindelay) @@ -252,6 +253,7 @@ #define RETURN #define REV(speed) #define ROTATE(turntable_id,position,activity) +#define ROTATE_DCC(turntable_id,position) #define ROSTER(cab,name,funcmap...) #define ROUTE(id,description) #define SENDLOCO(cab,route) @@ -276,7 +278,7 @@ #define START(route) #define STOP #define THROW(id) -#define TT_ADDPOSITION(turntable_id,position,value,description) +#define TT_ADDPOSITION(turntable_id,position,value,angle,description...) #define TURNOUT(id,addr,subaddr,description...) #define TURNOUTL(id,addr,description...) #define UNJOIN diff --git a/EXRAILMacros.h b/EXRAILMacros.h index e3ce129..440a619 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -192,7 +192,7 @@ const FSH * RMFT2::getTurnoutDescription(int16_t turnoutid) { // Pass to get turntable descriptions (optional) #include "EXRAIL2MacroReset.h" #undef DCC_TURNTABLE -#define DCC_TURNTABLE(id,description...) O_DESC(id,description) +#define DCC_TURNTABLE(id,home,description...) O_DESC(id,description) #undef EXTT_TURNTABLE #define EXTT_TURNTABLE(id,vpin,home,description...) O_DESC(id,description) @@ -207,7 +207,7 @@ const FSH * RMFT2::getTurntableDescription(int16_t turntableId) { // Pass to get turntable position descriptions (optional) #include "EXRAIL2MacroReset.h" #undef TT_ADDPOSITION -#define TT_ADDPOSITION(turntable_id,position,value,description...) T_DESC(turntable_id,position,description) +#define TT_ADDPOSITION(turntable_id,position,value,home,description...) T_DESC(turntable_id,position,description) const FSH * RMFT2::getTurntablePositionDescription(int16_t turntableId, uint8_t positionId) { #include "myAutomation.h" @@ -296,7 +296,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = { #define CALL(route) OPCODE_CALL,V(route), #define CLOSE(id) OPCODE_CLOSE,V(id), #ifndef IO_NO_HAL -#define DCC_TURNTABLE(id,description...) OPCODE_DCCTURNTABLE,V(id), +#define DCC_TURNTABLE(id,home,description...) OPCODE_DCCTURNTABLE,V(id),OPCODE_PAD,V(home), #endif #define DEACTIVATE(addr,subaddr) OPCODE_DCCACTIVATE,V(addr<<3 | subaddr<<1), #define DEACTIVATEL(addr) OPCODE_DCCACTIVATE,V((addr+3)<<1), @@ -383,7 +383,8 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = { #define REV(speed) OPCODE_REV,V(speed), #define ROSTER(cabid,name,funcmap...) #ifndef IO_NO_HAL -#define ROTATE(id,position,activity) OPCODE_ROTATE,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(activity), +#define ROTATE(id,position,activity) OPCODE_ROTATE,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(EXTurntable::activity), +#define ROTATE_DCC(id,position) OPCODE_ROTATE,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(0), #endif #define ROUTE(id, description) OPCODE_ROUTE, V(id), #define SENDLOCO(cab,route) OPCODE_SENDLOCO,V(cab),OPCODE_PAD,V(route), @@ -409,7 +410,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = { #define STOP OPCODE_SPEED,V(0), #define THROW(id) OPCODE_THROW,V(id), #ifndef IO_NO_HAL -#define TT_ADDPOSITION(id,position,value,description...) OPCODE_TTADDPOSITION,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(value), +#define TT_ADDPOSITION(id,position,value,angle,description...) OPCODE_TTADDPOSITION,V(id),OPCODE_PAD,V(position),OPCODE_PAD,V(value),OPCODE_PAD,V(angle), #endif #define TURNOUT(id,addr,subaddr,description...) OPCODE_TURNOUT,V(id),OPCODE_PAD,V(addr),OPCODE_PAD,V(subaddr), #define TURNOUTL(id,addr,description...) TURNOUT(id,(addr-1)/4+1,(addr-1)%4, description) diff --git a/Turntables.cpp b/Turntables.cpp index d43a515..ba143cb 100644 --- a/Turntables.cpp +++ b/Turntables.cpp @@ -58,8 +58,8 @@ void Turntable::add(Turntable *tto) { } // Add a position -void Turntable::addPosition(uint8_t idx, uint16_t value) { - _turntablePositions.insert(idx, value); +void Turntable::addPosition(uint8_t idx, uint16_t value, uint16_t angle) { + _turntablePositions.insert(idx, value, angle); } // Get value for position @@ -74,6 +74,18 @@ uint16_t Turntable::getPositionValue(uint8_t position) { return false; } +// Get value for position +uint16_t Turntable::getPositionAngle(uint8_t position) { + TurntablePosition* currentPosition = _turntablePositions.getHead(); + while (currentPosition) { + if (currentPosition->index == position) { + return currentPosition->angle; + } + currentPosition = currentPosition->next; + } + return false; +} + // Get the count of positions associated with the turntable uint8_t Turntable::getPositionCount() { TurntablePosition* currentPosition = _turntablePositions.getHead(); @@ -115,6 +127,7 @@ uint8_t Turntable::getPosition(uint16_t id) { return tto->getPosition(); } +// Got the moving state of the specified turntable bool Turntable::ttMoving(uint16_t id) { Turntable *tto = get(id); if (!tto) return false; diff --git a/Turntables.h b/Turntables.h index e7b7415..6c15bab 100644 --- a/Turntables.h +++ b/Turntables.h @@ -36,9 +36,6 @@ enum { TURNTABLE_DCC = 1, }; -// Callback needs to return a bool: 1 = moving, 0 = stopped -typedef void (*EXTT_CALLBACK)(bool moving); - /************************************************************************************* * Turntable positions. * @@ -46,17 +43,18 @@ typedef void (*EXTT_CALLBACK)(bool moving); struct TurntablePosition { uint8_t index; uint16_t data; + uint16_t angle; TurntablePosition* next; - TurntablePosition(uint8_t idx, uint16_t value) : index(idx), data(value), next(nullptr) {} + TurntablePosition(uint8_t idx, uint16_t value, uint16_t angle) : index(idx), data(value), angle(angle), next(nullptr) {} }; class TurntablePositionList { public: TurntablePositionList() : head(nullptr) {} - void insert(uint8_t idx, uint16_t value) { - TurntablePosition* newPosition = new TurntablePosition(idx, value); + void insert(uint8_t idx, uint16_t value, uint16_t angle) { + TurntablePosition* newPosition = new TurntablePosition(idx, value, angle); if(!head) { head = newPosition; } else { @@ -158,8 +156,9 @@ public: inline uint16_t getId() { return _turntableData.id; } inline Turntable *next() { return _nextTurntable; } void printState(Print *stream); - void addPosition(uint8_t idx, uint16_t value); + void addPosition(uint8_t idx, uint16_t value, uint16_t angle); uint16_t getPositionValue(uint8_t position); + uint16_t getPositionAngle(uint8_t position); uint8_t getPositionCount(); bool isMoving() { return _isMoving; } void setMoving(bool moving) { _isMoving=moving; }