1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-24 16:46:13 +01:00

Compare commits

...

24 Commits

Author SHA1 Message Date
peteGSX
4fcd81a118 Update version 2023-09-10 07:18:54 +10:00
peteGSX
eb450dbd89
Merge branch 'devel' into add-turntable-object 2023-09-10 07:13:16 +10:00
peteGSX
a0562fdf5c Update defines to match changes in devel 2023-09-10 07:06:27 +10:00
peteGSX
7ee2c29a52 Include HAL create with EXTT_TURNTABLE 2023-09-10 05:30:48 +10:00
Colin Murdoch
dca023ffd7 Update version.h
Added ONOVERLOAD and AFTEROVERLOAD as 5.1.4
2023-09-07 20:27:25 +01:00
Colin Murdoch
4eef9581fe Merge branch 'devel-plus-onoverload' into devel 2023-09-07 20:23:17 +01:00
Colin Murdoch
ab393047c1 Update MotorDriver.cpp
Replace duplicate call to EXRAIL with single in overload.
2023-09-06 11:20:23 +01:00
Colin Murdoch
1ac104704e Update TrackManager.cpp
Reverse logic in TM::IisPowerOn()
2023-09-05 20:52:18 +01:00
Colin Murdoch
2f8e915b1e Added AFTEROVERLOAD
Added the AFTEROVERLOAD option - as yet untested.
2023-09-05 12:21:09 +01:00
Harald Barth
44d8154223 version number update 2023-08-30 23:57:49 +02:00
Harald Barth
01919b33df Make parser more fool proof 2023-08-30 23:55:39 +02:00
Harald Barth
26ddd27ecf let user disable <D > command in favour for HAL on the Uno platform 2023-08-29 14:27:38 +02:00
Harald Barth
2c64f10da8 Merge branch 'devel' of https://github.com/DCC-EX/CommandStation-EX into devel 2023-08-25 19:14:25 +02:00
Harald Barth
25426d076d version number update 2023-08-25 19:14:03 +02:00
Harald Barth
3453da0671 Bugfix: ESP32 30ms off time 2023-08-25 19:12:47 +02:00
Colin Murdoch
fb226311e5 Update myHal.cpp_example.txt
Added missing ::create to LiquidCrystal HAL definition
2023-08-24 14:54:33 +01:00
Colin Murdoch
6392c74ead Update myHal.cpp_example.txt
Added missing ::create to LiquidCrystal
2023-08-24 14:53:01 +01:00
Harald Barth
25f8852af6 call devel for 5.1.X version number update 2023-08-24 10:09:38 +02:00
Harald Barth
9842ea8a42 Bugfix: execute 30ms off time before rejoin 2023-08-24 10:07:25 +02:00
peteGSX
fa0aa27d46 Add OPCODE list to DCCEXParser.cpp 2023-08-24 10:07:15 +02:00
kempe63
4b2c0702a4 Update version.h
Update version.h for IO_PCA9555 changes
2023-08-18 11:40:34 +01:00
kempe63
e27cceeb74 Update PCA9555.h inconsistencies to IO_MCP23017.h causing IO_PCA9555.h compile error when configure for Mux
Updated Class PCA9555 definition reflecting changes in IO_MCP23017.h to support PCA9548 mux. Checked with PCA9555 base board, compiles and run EXRAIL script with  output driver
2023-08-18 11:30:37 +01:00
Colin Murdoch
247763ac00 Code Corrections
Code corrections
2023-08-12 19:10:35 +01:00
Colin Murdoch
e327e0ae8d Added ONOVERLOAD
Added code changes to create ONOVERLOAD command in EXRAIL
2023-08-12 18:40:48 +01:00
14 changed files with 184 additions and 34 deletions

View File

@ -351,7 +351,7 @@ void DCCACK::callback(int value) {
switch (callbackState) { switch (callbackState) {
case AFTER_READ: case AFTER_READ:
if (ackManagerRejoin && autoPowerOff) { if (ackManagerRejoin && !autoPowerOff) {
progDriver->setPower(POWERMODE::OFF); progDriver->setPower(POWERMODE::OFF);
callbackStart=millis(); callbackStart=millis();
callbackState=WAITING_30; callbackState=WAITING_30;

View File

@ -25,6 +25,79 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. * along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/ */
/*
List of single character OPCODEs in use for reference.
When determining a new OPCODE for a new feature, refer to this list as the source of truth.
Once a new OPCODE is decided upon, update this list.
Character, Usage
/, |EX-R| interactive commands
-, Remove from reminder table
=, |TM| configuration
!, Emergency stop
@, Reserved for future use - LCD messages to JMRI
#, Request number of supported cabs/locos; heartbeat
+, WiFi AT commands
?, Reserved for future use
0, Track power off
1, Track power on
a, DCC accessory control
A,
b, Write CV bit on main
B, Write CV bit
c, Request current command
C,
d,
D, Diagnostic commands
e, Erase EEPROM
E, Store configuration in EEPROM
f, Loco decoder function control (deprecated)
F, Loco decoder function control
g,
G,
h,
H, Turnout state broadcast
i, Reserved for future use - Turntable object broadcast
I, Reserved for future use - Turntable object command and control
j, Throttle responses
J, Throttle queries
k, Reserved for future use - Potentially Railcom
K, Reserved for future use - Potentially Railcom
l, Loco speedbyte/function map broadcast
L,
m,
M, Write DCC packet
n,
N,
o,
O, Output broadcast
p, Broadcast power state
P, Write DCC packet
q, Sensor deactivated
Q, Sensor activated
r, Broadcast address read on programming track
R, Read CVs
s, Display status
S, Sensor configuration
t, Cab/loco update command
T, Turnout configuration/control
u, Reserved for user commands
U, Reserved for user commands
v,
V, Verify CVs
w, Write CV on main
W, Write CV
x,
X, Invalid command
y,
Y, Output broadcast
z,
Z, Output configuration/control
*/
#include "StringFormatter.h" #include "StringFormatter.h"
#include "DCCEXParser.h" #include "DCCEXParser.h"
#include "DCC.h" #include "DCC.h"
@ -383,10 +456,14 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
#ifndef DISABLE_PROG #ifndef DISABLE_PROG
case 'w': // WRITE CV on MAIN <w CAB CV VALUE> case 'w': // WRITE CV on MAIN <w CAB CV VALUE>
if (params != 3)
break;
DCC::writeCVByteMain(p[0], p[1], p[2]); DCC::writeCVByteMain(p[0], p[1], p[2]);
return; return;
case 'b': // WRITE CV BIT ON MAIN <b CAB CV BIT VALUE> case 'b': // WRITE CV BIT ON MAIN <b CAB CV BIT VALUE>
if (params != 4)
break;
DCC::writeCVBitMain(p[0], p[1], p[2], p[3]); DCC::writeCVBitMain(p[0], p[1], p[2], p[3]);
return; return;
#endif #endif
@ -417,8 +494,10 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
DCC::setLocoId(p[0],callback_Wloco); DCC::setLocoId(p[0],callback_Wloco);
else if (params == 4) // WRITE CV ON PROG <W CV VALUE [CALLBACKNUM] [CALLBACKSUB]> else if (params == 4) // WRITE CV ON PROG <W CV VALUE [CALLBACKNUM] [CALLBACKSUB]>
DCC::writeCVByte(p[0], p[1], callback_W4); DCC::writeCVByte(p[0], p[1], callback_W4);
else // WRITE CV ON PROG <W CV VALUE> else if (params == 2) // WRITE CV ON PROG <W CV VALUE>
DCC::writeCVByte(p[0], p[1], callback_W); DCC::writeCVByte(p[0], p[1], callback_W);
else
break;
return; return;
case 'V': // VERIFY CV ON PROG <V CV VALUE> <V CV BIT 0|1> case 'V': // VERIFY CV ON PROG <V CV VALUE> <V CV BIT 0|1>
@ -438,7 +517,9 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
} }
break; break;
case 'B': // WRITE CV BIT ON PROG <B CV BIT VALUE CALLBACKNUM CALLBACKSUB> case 'B': // WRITE CV BIT ON PROG <B CV BIT VALUE CALLBACKNUM CALLBACKSUB> or <B CV BIT VALUE>
if (params != 3 && params != 5)
break;
if (!stashCallback(stream, p, ringStream)) if (!stashCallback(stream, p, ringStream))
break; break;
DCC::writeCVBit(p[0], p[1], p[2], callback_B); DCC::writeCVBit(p[0], p[1], p[2], callback_B);
@ -570,12 +651,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
case ' ': // < > case ' ': // < >
StringFormatter::send(stream, F("\n")); StringFormatter::send(stream, F("\n"));
return; return;
#ifndef DISABLE_DIAG
case 'D': // < > case 'D': // < >
if (parseD(stream, params, p)) if (parseD(stream, params, p))
return; return;
return; break;
#endif
case '=': // <= Track manager control > case '=': // <= Track manager control >
if (TrackManager::parseJ(stream, params, p)) if (TrackManager::parseJ(stream, params, p))
return; return;

View File

@ -2,7 +2,7 @@
* © 2021 Neil McKechnie * © 2021 Neil McKechnie
* © 2021-2023 Harald Barth * © 2021-2023 Harald Barth
* © 2020-2023 Chris Harlow * © 2020-2023 Chris Harlow
* © 2022 Colin Murdoch * © 2022-2023 Colin Murdoch
* All rights reserved. * All rights reserved.
* *
* This file is part of CommandStation-EX * This file is part of CommandStation-EX
@ -99,6 +99,7 @@ LookList * RMFT2::onClockLookup=NULL;
#ifndef IO_NO_HAL #ifndef IO_NO_HAL
LookList * RMFT2::onRotateLookup=NULL; LookList * RMFT2::onRotateLookup=NULL;
#endif #endif
LookList * RMFT2::onOverloadLookup=NULL;
#define GET_OPCODE GETHIGHFLASH(RMFT2::RouteCode,progCounter) #define GET_OPCODE GETHIGHFLASH(RMFT2::RouteCode,progCounter)
#define SKIPOP progCounter+=3 #define SKIPOP progCounter+=3
@ -183,6 +184,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
#ifndef IO_NO_HAL #ifndef IO_NO_HAL
onRotateLookup=LookListLoader(OPCODE_ONROTATE); onRotateLookup=LookListLoader(OPCODE_ONROTATE);
#endif #endif
onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD);
// Second pass startup, define any turnouts or servos, set signals red // Second pass startup, define any turnouts or servos, set signals red
// add sequences onRoutines to the lookups // add sequences onRoutines to the lookups
@ -202,6 +204,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
case OPCODE_AT: case OPCODE_AT:
case OPCODE_ATTIMEOUT2: case OPCODE_ATTIMEOUT2:
case OPCODE_AFTER: case OPCODE_AFTER:
case OPCODE_AFTEROVERLOAD:
case OPCODE_IF: case OPCODE_IF:
case OPCODE_IFNOT: { case OPCODE_IFNOT: {
int16_t pin = (int16_t)operand; int16_t pin = (int16_t)operand;
@ -259,7 +262,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
case OPCODE_EXTTTURNTABLE: { case OPCODE_EXTTTURNTABLE: {
VPIN id=operand; VPIN id=operand;
VPIN pin=getOperand(progCounter,1); VPIN pin=getOperand(progCounter,1);
int home=getOperand(progCounter,2); int home=getOperand(progCounter,3);
setTurntableHiddenState(EXTTTurntable::create(id,pin)); setTurntableHiddenState(EXTTTurntable::create(id,pin));
Turntable *tto=Turntable::get(id); Turntable *tto=Turntable::get(id);
tto->addPosition(0,0,home); tto->addPosition(0,0,home);
@ -738,6 +741,16 @@ void RMFT2::loop2() {
if (millis()-waitAfter < 500 ) return; if (millis()-waitAfter < 500 ) return;
break; break;
case OPCODE_AFTEROVERLOAD: // waits for the power to be turned back on - either by power routine or button
if (!TrackManager::isPowerOn(operand)) {
// reset timer to half a second and keep waiting
waitAfter=millis();
delayMe(50);
return;
}
if (millis()-waitAfter < 500 ) return;
break;
case OPCODE_LATCH: case OPCODE_LATCH:
setFlag(operand,LATCH_FLAG); setFlag(operand,LATCH_FLAG);
break; break;
@ -1060,6 +1073,7 @@ void RMFT2::loop2() {
case OPCODE_TTADDPOSITION: // Turntable position definition ignored at runtime case OPCODE_TTADDPOSITION: // Turntable position definition ignored at runtime
case OPCODE_ONROTATE: case OPCODE_ONROTATE:
#endif #endif
case OPCODE_ONOVERLOAD:
break; break;
@ -1221,6 +1235,16 @@ void RMFT2::clockEvent(int16_t clocktime, bool change) {
} }
} }
void RMFT2::powerEvent(int16_t track, bool overload) {
// Hunt for an ONOVERLOAD for this item
if (Diag::CMD)
DIAG(F("Looking for Power event on track : %c"), track);
if (overload) {
handleEvent(F("POWER"),onOverloadLookup,track);
}
}
void RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) { void RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) {
int pc= handlers->find(id); int pc= handlers->find(id);
if (pc<0) return; if (pc<0) return;

View File

@ -1,7 +1,7 @@
/* /*
* © 2021 Neil McKechnie * © 2021 Neil McKechnie
* © 2020-2022 Chris Harlow * © 2020-2022 Chris Harlow
* © 2022 Colin Murdoch * © 2022-2023 Colin Murdoch
* © 2023 Harald Barth * © 2023 Harald Barth
* All rights reserved. * All rights reserved.
* *
@ -36,7 +36,8 @@
enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE, enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
OPCODE_FWD,OPCODE_REV,OPCODE_SPEED,OPCODE_INVERT_DIRECTION, OPCODE_FWD,OPCODE_REV,OPCODE_SPEED,OPCODE_INVERT_DIRECTION,
OPCODE_RESERVE,OPCODE_FREE, OPCODE_RESERVE,OPCODE_FREE,
OPCODE_AT,OPCODE_AFTER,OPCODE_AUTOSTART, OPCODE_AT,OPCODE_AFTER,
OPCODE_AFTEROVERLOAD,OPCODE_AUTOSTART,
OPCODE_ATGTE,OPCODE_ATLT, OPCODE_ATGTE,OPCODE_ATLT,
OPCODE_ATTIMEOUT1,OPCODE_ATTIMEOUT2, OPCODE_ATTIMEOUT1,OPCODE_ATTIMEOUT2,
OPCODE_LATCH,OPCODE_UNLATCH,OPCODE_SET,OPCODE_RESET, OPCODE_LATCH,OPCODE_UNLATCH,OPCODE_SET,OPCODE_RESET,
@ -67,6 +68,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
OPCODE_TTADDPOSITION,OPCODE_DCCTURNTABLE,OPCODE_EXTTTURNTABLE, OPCODE_TTADDPOSITION,OPCODE_DCCTURNTABLE,OPCODE_EXTTTURNTABLE,
OPCODE_ONROTATE,OPCODE_ROTATE,OPCODE_IFTTPOSITION,OPCODE_WAITFORTT, OPCODE_ONROTATE,OPCODE_ROTATE,OPCODE_IFTTPOSITION,OPCODE_WAITFORTT,
#endif #endif
OPCODE_ONOVERLOAD,
// OPcodes below this point are skip-nesting IF operations // OPcodes below this point are skip-nesting IF operations
// placed here so that they may be skipped as a group // placed here so that they may be skipped as a group
@ -136,6 +138,7 @@ class LookList {
static void changeEvent(int16_t id, bool change); static void changeEvent(int16_t id, bool change);
static void clockEvent(int16_t clocktime, bool change); static void clockEvent(int16_t clocktime, bool change);
static void rotateEvent(int16_t id, bool change); static void rotateEvent(int16_t id, bool change);
static void powerEvent(int16_t track, bool overload);
static const int16_t SERVO_SIGNAL_FLAG=0x4000; static const int16_t SERVO_SIGNAL_FLAG=0x4000;
static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000; static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000;
static const int16_t DCC_SIGNAL_FLAG=0x1000; static const int16_t DCC_SIGNAL_FLAG=0x1000;
@ -202,6 +205,7 @@ private:
#ifndef IO_NO_HAL #ifndef IO_NO_HAL
static LookList * onRotateLookup; static LookList * onRotateLookup;
#endif #endif
static LookList * onOverloadLookup;
// Local variables - exist for each instance/task // Local variables - exist for each instance/task
RMFT2 *next; // loop chain RMFT2 *next; // loop chain

View File

@ -1,6 +1,6 @@
/* /*
* © 2020-2022 Chris Harlow. All rights reserved. * © 2020-2022 Chris Harlow. All rights reserved.
* © 2022 Colin Murdoch * © 2022-2023 Colin Murdoch
* © 2023 Harald Barth * © 2023 Harald Barth
* *
* This file is part of CommandStation-EX * This file is part of CommandStation-EX
@ -27,6 +27,7 @@
#undef ACTIVATE #undef ACTIVATE
#undef ACTIVATEL #undef ACTIVATEL
#undef AFTER #undef AFTER
#undef AFTEROVERLOAD
#undef ALIAS #undef ALIAS
#undef AMBER #undef AMBER
#undef ANOUT #undef ANOUT
@ -96,6 +97,7 @@
#undef ONTIME #undef ONTIME
#undef ONCLOCKTIME #undef ONCLOCKTIME
#undef ONCLOCKMINS #undef ONCLOCKMINS
#undef ONOVERLOAD
#undef ONGREEN #undef ONGREEN
#undef ONRED #undef ONRED
#undef ONROTATE #undef ONROTATE
@ -162,6 +164,7 @@
#define ACTIVATE(addr,subaddr) #define ACTIVATE(addr,subaddr)
#define ACTIVATEL(addr) #define ACTIVATEL(addr)
#define AFTER(sensor_id) #define AFTER(sensor_id)
#define AFTEROVERLOAD(track_id)
#define ALIAS(name,value...) #define ALIAS(name,value...)
#define AMBER(signal_id) #define AMBER(signal_id)
#define ANOUT(vpin,value,param1,param2) #define ANOUT(vpin,value,param1,param2)
@ -189,7 +192,7 @@
#define ENDTASK #define ENDTASK
#define ESTOP #define ESTOP
#define EXRAIL #define EXRAIL
#define EXTT_TURNTABLE(id,vpin,home,description) #define EXTT_TURNTABLE(id,vpin,i2c_address,home,description)
#define FADE(pin,value,ms) #define FADE(pin,value,ms)
#define FOFF(func) #define FOFF(func)
#define FOLLOW(route) #define FOLLOW(route)
@ -228,6 +231,7 @@
#define ONTIME(value) #define ONTIME(value)
#define ONCLOCKTIME(hours,mins) #define ONCLOCKTIME(hours,mins)
#define ONCLOCKMINS(mins) #define ONCLOCKMINS(mins)
#define ONOVERLOAD(track_id)
#define ONDEACTIVATE(addr,subaddr) #define ONDEACTIVATE(addr,subaddr)
#define ONDEACTIVATEL(linear) #define ONDEACTIVATEL(linear)
#define ONCLOSE(turnout_id) #define ONCLOSE(turnout_id)

View File

@ -1,7 +1,7 @@
/* /*
* © 2021 Neil McKechnie * © 2021 Neil McKechnie
* © 2020-2022 Chris Harlow * © 2020-2022 Chris Harlow
* © 2022 Colin Murdoch * © 2022-2023 Colin Murdoch
* © 2023 Harald Barth * © 2023 Harald Barth
* All rights reserved. * All rights reserved.
* *
@ -70,9 +70,12 @@
#include "myAutomation.h" #include "myAutomation.h"
// Pass 1h Implements HAL macro by creating exrailHalSetup function // Pass 1h Implements HAL macro by creating exrailHalSetup function
// Also allows creating EXTurntable object
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef HAL #undef HAL
#define HAL(haltype,params...) haltype::create(params); #define HAL(haltype,params...) haltype::create(params);
#undef EXTT_TURNTABLE
#define EXTT_TURNTABLE(id,vpin,i2c_address,home,description...) EXTurntable::create(vpin,1,i2c_address);
void exrailHalSetup() { void exrailHalSetup() {
#include "myAutomation.h" #include "myAutomation.h"
} }
@ -194,7 +197,7 @@ const FSH * RMFT2::getTurnoutDescription(int16_t turnoutid) {
#undef DCC_TURNTABLE #undef DCC_TURNTABLE
#define DCC_TURNTABLE(id,home,description...) O_DESC(id,description) #define DCC_TURNTABLE(id,home,description...) O_DESC(id,description)
#undef EXTT_TURNTABLE #undef EXTT_TURNTABLE
#define EXTT_TURNTABLE(id,vpin,home,description...) O_DESC(id,description) #define EXTT_TURNTABLE(id,vpin,i2c_address,home,description...) O_DESC(id,description)
const FSH * RMFT2::getTurntableDescription(int16_t turntableId) { const FSH * RMFT2::getTurntableDescription(int16_t turntableId) {
switch (turntableId) { switch (turntableId) {
@ -283,6 +286,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = {
#define ACTIVATE(addr,subaddr) OPCODE_DCCACTIVATE,V(addr<<3 | subaddr<<1 | 1), #define ACTIVATE(addr,subaddr) OPCODE_DCCACTIVATE,V(addr<<3 | subaddr<<1 | 1),
#define ACTIVATEL(addr) OPCODE_DCCACTIVATE,V((addr+3)<<1 | 1), #define ACTIVATEL(addr) OPCODE_DCCACTIVATE,V((addr+3)<<1 | 1),
#define AFTER(sensor_id) OPCODE_AT,V(sensor_id),OPCODE_AFTER,V(sensor_id), #define AFTER(sensor_id) OPCODE_AT,V(sensor_id),OPCODE_AFTER,V(sensor_id),
#define AFTEROVERLOAD(track_id) OPCODE_AFTEROVERLOAD,V(TRACK_NUMBER_##track_id),
#define ALIAS(name,value...) #define ALIAS(name,value...)
#define AMBER(signal_id) OPCODE_AMBER,V(signal_id), #define AMBER(signal_id) OPCODE_AMBER,V(signal_id),
#define ANOUT(vpin,value,param1,param2) OPCODE_SERVO,V(vpin),OPCODE_PAD,V(value),OPCODE_PAD,V(param1),OPCODE_PAD,V(param2), #define ANOUT(vpin,value,param1,param2) OPCODE_SERVO,V(vpin),OPCODE_PAD,V(value),OPCODE_PAD,V(param1),OPCODE_PAD,V(param2),
@ -313,7 +317,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = {
#define ESTOP OPCODE_SPEED,V(1), #define ESTOP OPCODE_SPEED,V(1),
#define EXRAIL #define EXRAIL
#ifndef IO_NO_HAL #ifndef IO_NO_HAL
#define EXTT_TURNTABLE(id,vpin,home,description...) OPCODE_EXTTTURNTABLE,V(id),OPCODE_PAD,V(vpin),OPCODE_PAD,V(home), #define EXTT_TURNTABLE(id,vpin,i2c_address,home,description...) OPCODE_EXTTTURNTABLE,V(id),OPCODE_PAD,V(vpin),OPCODE_PAD,V(i2c_address),OPCODE_PAD,V(home),
#endif #endif
#define FADE(pin,value,ms) OPCODE_SERVO,V(pin),OPCODE_PAD,V(value),OPCODE_PAD,V(PCA9685::ProfileType::UseDuration|PCA9685::NoPowerOff),OPCODE_PAD,V(ms/100L), #define FADE(pin,value,ms) OPCODE_SERVO,V(pin),OPCODE_PAD,V(value),OPCODE_PAD,V(PCA9685::ProfileType::UseDuration|PCA9685::NoPowerOff),OPCODE_PAD,V(ms/100L),
#define FOFF(func) OPCODE_FOFF,V(func), #define FOFF(func) OPCODE_FOFF,V(func),
@ -356,6 +360,7 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = {
#define ONTIME(value) OPCODE_ONTIME,V(value), #define ONTIME(value) OPCODE_ONTIME,V(value),
#define ONCLOCKTIME(hours,mins) OPCODE_ONTIME,V((STRIP_ZERO(hours)*60)+STRIP_ZERO(mins)), #define ONCLOCKTIME(hours,mins) OPCODE_ONTIME,V((STRIP_ZERO(hours)*60)+STRIP_ZERO(mins)),
#define ONCLOCKMINS(mins) ONCLOCKTIME(25,mins) #define ONCLOCKMINS(mins) ONCLOCKTIME(25,mins)
#define ONOVERLOAD(track_id) OPCODE_ONOVERLOAD,V(TRACK_NUMBER_##track_id),
#define ONDEACTIVATE(addr,subaddr) OPCODE_ONDEACTIVATE,V(addr<<2|subaddr), #define ONDEACTIVATE(addr,subaddr) OPCODE_ONDEACTIVATE,V(addr<<2|subaddr),
#define ONDEACTIVATEL(linear) OPCODE_ONDEACTIVATE,V(linear+3), #define ONDEACTIVATEL(linear) OPCODE_ONDEACTIVATE,V(linear+3),
#define ONGREEN(signal_id) OPCODE_ONGREEN,V(signal_id), #define ONGREEN(signal_id) OPCODE_ONGREEN,V(signal_id),

View File

@ -1 +1 @@
#define GITHUB_SHA "devel-202308102205Z" #define GITHUB_SHA "devel-202308302157Z"

View File

@ -30,8 +30,8 @@
class PCA9555 : public GPIOBase<uint16_t> { class PCA9555 : public GPIOBase<uint16_t> {
public: public:
static void create(VPIN vpin, int nPins, uint8_t I2CAddress, int interruptPin=-1) { static void create(VPIN vpin, uint8_t nPins, I2CAddress i2cAddress, int interruptPin=-1) {
new PCA9555(vpin, min(nPins,16), I2CAddress, interruptPin); if (checkNoOverlap(vpin, nPins, i2cAddress)) new PCA9555(vpin,nPins, i2cAddress, interruptPin);
} }
// Constructor // Constructor

View File

@ -4,6 +4,7 @@
* © 2021 Fred Decker * © 2021 Fred Decker
* © 2020-2023 Harald Barth * © 2020-2023 Harald Barth
* © 2020-2021 Chris Harlow * © 2020-2021 Chris Harlow
* © 2023 Colin Murdoch
* All rights reserved. * All rights reserved.
* *
* This file is part of CommandStation-EX * This file is part of CommandStation-EX
@ -26,6 +27,7 @@
#include "DCCWaveform.h" #include "DCCWaveform.h"
#include "DCCTimer.h" #include "DCCTimer.h"
#include "DIAG.h" #include "DIAG.h"
#include "EXRAIL2.h"
unsigned long MotorDriver::globalOverloadStart = 0; unsigned long MotorDriver::globalOverloadStart = 0;
@ -614,6 +616,8 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) {
power_sample_overload_wait *= 2; power_sample_overload_wait *= 2;
if (power_sample_overload_wait > POWER_SAMPLE_RETRY_MAX) if (power_sample_overload_wait > POWER_SAMPLE_RETRY_MAX)
power_sample_overload_wait = POWER_SAMPLE_RETRY_MAX; power_sample_overload_wait = POWER_SAMPLE_RETRY_MAX;
DIAG(F("Calling EXRAIL"));
RMFT2::powerEvent(trackno, true); // Tell EXRAIL we have an overload
// power on test // power on test
DIAG(F("TRACK %c POWER RESTORE (after %4M)"), trackno + 'A', mslpc); DIAG(F("TRACK %c POWER RESTORE (after %4M)"), trackno + 'A', mslpc);
setPower(POWERMODE::ALERT); setPower(POWERMODE::ALERT);

View File

@ -1,6 +1,7 @@
/* /*
* © 2022 Chris Harlow * © 2022 Chris Harlow
* © 2022 Harald Barth * © 2022 Harald Barth
* © 2023 Colin Murdoch
* All rights reserved. * All rights reserved.
* *
* This file is part of DCC++EX * This file is part of DCC++EX
@ -53,7 +54,7 @@ bool TrackManager::progTrackSyncMain=false;
bool TrackManager::progTrackBoosted=false; bool TrackManager::progTrackBoosted=false;
int16_t TrackManager::joinRelay=UNUSED_PIN; int16_t TrackManager::joinRelay=UNUSED_PIN;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
byte TrackManager::tempProgTrack=MAX_TRACKS+1; byte TrackManager::tempProgTrack=MAX_TRACKS+1; // MAX_TRACKS+1 is the unused flag
#endif #endif
#ifdef ANALOG_READ_INTERRUPT #ifdef ANALOG_READ_INTERRUPT
@ -505,7 +506,12 @@ void TrackManager::setJoin(bool joined) {
} }
} else { } else {
if (tempProgTrack != MAX_TRACKS+1) { if (tempProgTrack != MAX_TRACKS+1) {
// as setTrackMode with TRACK_MODE_PROG defaults to
// power off, we will take the current power state
// of our track and then preserve that state.
POWERMODE tPTmode = track[tempProgTrack]->getPower(); //get current power status of this track
setTrackMode(tempProgTrack, TRACK_MODE_PROG); setTrackMode(tempProgTrack, TRACK_MODE_PROG);
track[tempProgTrack]->setPower(tPTmode); //set track status as it was before
tempProgTrack = MAX_TRACKS+1; tempProgTrack = MAX_TRACKS+1;
} }
} }
@ -513,3 +519,10 @@ void TrackManager::setJoin(bool joined) {
progTrackSyncMain=joined; progTrackSyncMain=joined;
if (joinRelay!=UNUSED_PIN) digitalWrite(joinRelay,joined?HIGH:LOW); if (joinRelay!=UNUSED_PIN) digitalWrite(joinRelay,joined?HIGH:LOW);
} }
bool TrackManager::isPowerOn(byte t) {
if (track[t]->getPower()!=POWERMODE::ON)
return false;
return true;
}

View File

@ -1,6 +1,8 @@
/* /*
* © 2022 Chris Harlow * © 2022 Chris Harlow
* © 2022 Harald Barth * © 2022 Harald Barth
* © 2023 Colin Murdoch
*
* All rights reserved. * All rights reserved.
* *
* This file is part of CommandStation-EX * This file is part of CommandStation-EX
@ -77,6 +79,7 @@ class TrackManager {
static void reportCurrent(Print* stream); static void reportCurrent(Print* stream);
static void reportObsoleteCurrent(Print* stream); static void reportObsoleteCurrent(Print* stream);
static void streamTrackState(Print* stream, byte t); static void streamTrackState(Print* stream, byte t);
static bool isPowerOn(byte t);
static int16_t joinRelay; static int16_t joinRelay;
static bool progTrackSyncMain; // true when prog track is a siding switched to main static bool progTrackSyncMain; // true when prog track is a siding switched to main

View File

@ -219,7 +219,11 @@
// The HAL is disabled by default on Nano and Uno platforms, because of limited flash space. // The HAL is disabled by default on Nano and Uno platforms, because of limited flash space.
// //
#if defined(ARDUINO_AVR_NANO) || defined(ARDUINO_AVR_UNO) #if defined(ARDUINO_AVR_NANO) || defined(ARDUINO_AVR_UNO)
#define IO_NO_HAL #if defined(DISABLE_DIAG) && defined(DISABLE_EEPROM) && defined(DISABLE_PROG)
#warning you have sacrificed DIAG for HAL
#else
#define IO_NO_HAL
#endif
#endif #endif
#if __has_include ( "myAutomation.h") #if __has_include ( "myAutomation.h")

View File

@ -51,7 +51,7 @@ void halSetup() {
// Create a 20x4 LCD display device as display number 2 // Create a 20x4 LCD display device as display number 2
// (line 0 is written by EX-RAIL 'SCREEN(2, 0, "text")'). // (line 0 is written by EX-RAIL 'SCREEN(2, 0, "text")').
// HALDisplay<LiquidCrystal>(2, 0x27, 20, 4); // HALDisplay<LiquidCrystal>::create(2, 0x27, 20, 4);
//======================================================================= //=======================================================================

View File

@ -3,8 +3,16 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "5.0.1" #define VERSION "5.1.5"
// 5.0.1 - Check bad AT firmware version // 5.1.5 - Added turntable object and EXRAIL commands
// - <I ...>, <JO ...>, <JP ...> - turntable commands
// - DCC_TURNTABLE, EXTT_TURNTABLE, IFTTPOSITION, ONROTATE, ROTATE, ROTATE_DCC, TT_ADDPOSITION, WAITFORTT EXRAIL
// 5.1.4 - Added ONOVERLOAD & AFTEROVERLOAD to EXRAIL
// 5.1.3 - Make parser more fool proof
// 5.1.2 - Bugfix: ESP32 30ms off time
// 5.1.1 - Check bad AT firmware version
// - Update IO_PCA9555.h reflecting IO_MCP23017.h changes to support PCA9548 mux
// 5.0.1 - Bugfix: execute 30ms off time before rejoin
// 5.0.0 - Make 4.2.69 the 5.0.0 release // 5.0.0 - Make 4.2.69 the 5.0.0 release
// 4.2.69 - Bugfix: Make <!> work in DC mode // 4.2.69 - Bugfix: Make <!> work in DC mode
// 4.2.68 - Rename track mode OFF to NONE // 4.2.68 - Rename track mode OFF to NONE