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

Compare commits

..

11 Commits

Author SHA1 Message Date
Harald Barth
399030d8ae make variable frequency a compile option 2023-07-25 12:51:23 +02:00
Harald Barth
4c7e11ddc1 version 2023-07-25 11:30:08 +02:00
Harald Barth
495bbf66bf better variable name 2023-07-25 11:23:36 +02:00
Harald Barth
2950ef010a diag 2023-07-18 01:25:38 +02:00
Harald Barth
c2eb5f23b4 restrict to relevant TRACK_MODE(s) 2023-07-17 09:42:39 +02:00
Harald Barth
94648ead28 versiontag 2023-07-17 02:31:00 +02:00
Harald Barth
ec0499e9da throttleInrush() (tested on ESP32) 2023-07-17 02:30:11 +02:00
Harald Barth
9b75026eef change from trackMode[t] to track[t]->{get,set}Mode 2023-07-17 02:26:29 +02:00
Harald Barth
6036ff9b15 ESP32: ledcSetup before ledcAttach 2023-07-17 02:22:35 +02:00
Harald Barth
6476a7aac2 version 2023-07-14 23:11:22 +02:00
Harald Barth
0edf34bfe2 inrush test ESP32 only 2023-07-14 23:10:50 +02:00
7 changed files with 79 additions and 35 deletions

View File

@ -180,8 +180,8 @@ void DCCTimer::DCCEXanalogWrite(uint8_t pin, int value) {
return; return;
} }
pin_to_channel[pin] = --cnt_channel; pin_to_channel[pin] = --cnt_channel;
ledcAttachPin(pin, cnt_channel);
ledcSetup(cnt_channel, 1000, 8); ledcSetup(cnt_channel, 1000, 8);
ledcAttachPin(pin, cnt_channel);
} else { } else {
ledcAttachPin(pin, pin_to_channel[pin]); ledcAttachPin(pin, pin_to_channel[pin]);
} }

View File

@ -1 +1 @@
#define GITHUB_SHA "devel-202307091003Z" #define GITHUB_SHA "devel-202307250927Z"

View File

@ -278,6 +278,7 @@ void MotorDriver::startCurrentFromHW() {
#endif //ANALOG_READ_INTERRUPT #endif //ANALOG_READ_INTERRUPT
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#ifdef VARIABLE_TONES
uint16_t taurustones[28] = { 165, 175, 196, 220, uint16_t taurustones[28] = { 165, 175, 196, 220,
247, 262, 294, 330, 247, 262, 294, 330,
349, 392, 440, 494, 349, 392, 440, 494,
@ -286,6 +287,7 @@ uint16_t taurustones[28] = { 165, 175, 196, 220,
330, 284, 262, 247, 330, 284, 262, 247,
220, 196, 175, 165 }; 220, 196, 175, 165 };
#endif #endif
#endif
void MotorDriver::setDCSignal(byte speedcode) { void MotorDriver::setDCSignal(byte speedcode) {
if (brakePin == UNUSED_PIN) if (brakePin == UNUSED_PIN)
return; return;
@ -304,11 +306,13 @@ void MotorDriver::setDCSignal(byte speedcode) {
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
{ {
int f = 131; int f = 131;
#ifdef VARIABLE_TONES
if (tSpeed > 2) { if (tSpeed > 2) {
if (tSpeed <= 58) { if (tSpeed <= 58) {
f = taurustones[ (tSpeed-2)/2 ] ; f = taurustones[ (tSpeed-2)/2 ] ;
} }
} }
#endif
DCCTimer::DCCEXanalogWriteFrequency(brakePin, f); // set DC PWM frequency to 100Hz XXX May move to setup DCCTimer::DCCEXanalogWriteFrequency(brakePin, f); // set DC PWM frequency to 100Hz XXX May move to setup
} }
#endif #endif
@ -347,7 +351,35 @@ void MotorDriver::setDCSignal(byte speedcode) {
interrupts(); interrupts();
} }
} }
void MotorDriver::throttleInrush(bool on) {
if (brakePin == UNUSED_PIN)
return;
if ( !(trackMode & (TRACK_MODE_MAIN | TRACK_MODE_PROG | TRACK_MODE_EXT)))
return;
byte duty = on ? 208 : 0;
if (invertBrake)
duty = 255-duty;
#if defined(ARDUINO_ARCH_ESP32)
if(on) {
DCCTimer::DCCEXanalogWrite(brakePin,duty);
DCCTimer::DCCEXanalogWriteFrequency(brakePin, 62500);
} else {
ledcDetachPin(brakePin);
}
#else
if(on){
#if defined(ARDUINO_AVR_UNO)
TCCR2B = (TCCR2B & B11111000) | B00000001; // div 1 is max
#endif
#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560)
TCCR2B = (TCCR2B & B11111000) | B00000001; // div 1 is max
TCCR4B = (TCCR4B & B11111000) | B00000001; // div 1 is max
TCCR5B = (TCCR5B & B11111000) | B00000001; // div 1 is max
#endif
}
analogWrite(brakePin,duty);
#endif
}
unsigned int MotorDriver::raw2mA( int raw) { unsigned int MotorDriver::raw2mA( int raw) {
//DIAG(F("%d = %d * %d / %d"), (int32_t)raw * senseFactorInternal / senseScale, raw, senseFactorInternal, senseScale); //DIAG(F("%d = %d * %d / %d"), (int32_t)raw * senseFactorInternal / senseScale, raw, senseFactorInternal, senseScale);
return (int32_t)raw * senseFactorInternal / senseScale; return (int32_t)raw * senseFactorInternal / senseScale;
@ -473,29 +505,31 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) {
case POWERMODE::ALERT: { case POWERMODE::ALERT: {
// set local flags that handle how much is output to diag (do not output duplicates) // set local flags that handle how much is output to diag (do not output duplicates)
bool notFromOverload = (lastPowerMode != POWERMODE::OVERLOAD); bool notFromOverload = (lastPowerMode != POWERMODE::OVERLOAD);
bool newPowerMode = (powerMode != lastPowerMode); bool powerModeChange = (powerMode != lastPowerMode);
unsigned long now = micros(); unsigned long now = micros();
if (newPowerMode) if (powerModeChange)
lastBadSample = now; lastBadSample = now;
lastPowerMode = POWERMODE::ALERT; lastPowerMode = POWERMODE::ALERT;
// check how long we have been in this state // check how long we have been in this state
unsigned long mslpc = microsSinceLastPowerChange(POWERMODE::ALERT); unsigned long mslpc = microsSinceLastPowerChange(POWERMODE::ALERT);
if(checkFault()) { if(checkFault()) {
throttleInrush(true);
lastBadSample = now; lastBadSample = now;
unsigned long timeout = checkCurrent(useProgLimit) ? POWER_SAMPLE_IGNORE_FAULT_HIGH : POWER_SAMPLE_IGNORE_FAULT_LOW; unsigned long timeout = checkCurrent(useProgLimit) ? POWER_SAMPLE_IGNORE_FAULT_HIGH : POWER_SAMPLE_IGNORE_FAULT_LOW;
if ( mslpc < timeout) { if ( mslpc < timeout) {
if (newPowerMode) if (powerModeChange)
DIAG(F("TRACK %c FAULT PIN (%M ignore)"), trackno + 'A', timeout); DIAG(F("TRACK %c FAULT PIN (%M ignore)"), trackno + 'A', timeout);
break; break;
} }
DIAG(F("TRACK %c FAULT PIN detected after %4M. Pause %4M)"), trackno + 'A', mslpc, power_sample_overload_wait); DIAG(F("TRACK %c FAULT PIN detected after %4M. Pause %4M)"), trackno + 'A', mslpc, power_sample_overload_wait);
throttleInrush(false);
setPower(POWERMODE::OVERLOAD); setPower(POWERMODE::OVERLOAD);
break; break;
} }
if (checkCurrent(useProgLimit)) { if (checkCurrent(useProgLimit)) {
lastBadSample = now; lastBadSample = now;
if (mslpc < POWER_SAMPLE_IGNORE_CURRENT) { if (mslpc < POWER_SAMPLE_IGNORE_CURRENT) {
if (newPowerMode) { if (powerModeChange) {
unsigned int mA=raw2mA(lastCurrent); unsigned int mA=raw2mA(lastCurrent);
DIAG(F("TRACK %c CURRENT (%M ignore) %dmA"), trackno + 'A', POWER_SAMPLE_IGNORE_CURRENT, mA); DIAG(F("TRACK %c CURRENT (%M ignore) %dmA"), trackno + 'A', POWER_SAMPLE_IGNORE_CURRENT, mA);
} }
@ -505,6 +539,7 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) {
unsigned int maxmA=raw2mA(tripValue); unsigned int maxmA=raw2mA(tripValue);
DIAG(F("TRACK %c POWER OVERLOAD %4dmA (max %4dmA) detected after %4M. Pause %4M"), DIAG(F("TRACK %c POWER OVERLOAD %4dmA (max %4dmA) detected after %4M. Pause %4M"),
trackno + 'A', mA, maxmA, mslpc, power_sample_overload_wait); trackno + 'A', mA, maxmA, mslpc, power_sample_overload_wait);
throttleInrush(false);
setPower(POWERMODE::OVERLOAD); setPower(POWERMODE::OVERLOAD);
break; break;
} }
@ -515,6 +550,7 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) {
unsigned int mA=raw2mA(lastCurrent); unsigned int mA=raw2mA(lastCurrent);
DIAG(F("TRACK %c NORMAL (after %M/%M) %dmA"), trackno + 'A', goodtime, mslpc, mA); DIAG(F("TRACK %c NORMAL (after %M/%M) %dmA"), trackno + 'A', goodtime, mslpc, mA);
} }
throttleInrush(false);
setPower(POWERMODE::ON); setPower(POWERMODE::ON);
} }
break; break;

View File

@ -27,6 +27,10 @@
#include "IODevice.h" #include "IODevice.h"
#include "DCCTimer.h" #include "DCCTimer.h"
// use powers of two so we can do logical and/or on the track modes in if clauses.
enum TRACK_MODE : byte {TRACK_MODE_OFF = 1, TRACK_MODE_MAIN = 2, TRACK_MODE_PROG = 4,
TRACK_MODE_DC = 8, TRACK_MODE_DCX = 16, TRACK_MODE_EXT = 32};
#define setHIGH(fastpin) *fastpin.inout |= fastpin.maskHIGH #define setHIGH(fastpin) *fastpin.inout |= fastpin.maskHIGH
#define setLOW(fastpin) *fastpin.inout &= fastpin.maskLOW #define setLOW(fastpin) *fastpin.inout &= fastpin.maskLOW
#define isHIGH(fastpin) (*fastpin.inout & fastpin.maskHIGH) #define isHIGH(fastpin) (*fastpin.inout & fastpin.maskHIGH)
@ -145,6 +149,7 @@ class MotorDriver {
}; };
inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); }; inline pinpair getSignalPin() { return pinpair(signalPin,signalPin2); };
void setDCSignal(byte speedByte); void setDCSignal(byte speedByte);
void throttleInrush(bool on);
inline void detachDCSignal() { inline void detachDCSignal() {
#if defined(__arm__) #if defined(__arm__)
pinMode(brakePin, OUTPUT); pinMode(brakePin, OUTPUT);
@ -203,6 +208,12 @@ class MotorDriver {
bool sampleCurrentFromHW(); bool sampleCurrentFromHW();
void startCurrentFromHW(); void startCurrentFromHW();
#endif #endif
inline void setMode(TRACK_MODE m) {
trackMode = m;
};
inline TRACK_MODE getMode() {
return trackMode;
};
private: private:
char trackLetter = '?'; char trackLetter = '?';
bool isProgTrack = false; // tells us if this is a prog track bool isProgTrack = false; // tells us if this is a prog track
@ -279,6 +290,7 @@ class MotorDriver {
static const int TRIP_CURRENT_PROG=250; static const int TRIP_CURRENT_PROG=250;
unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT; unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT;
unsigned int power_good_counter = 0; unsigned int power_good_counter = 0;
TRACK_MODE trackMode = TRACK_MODE_OFF; // we assume off at startup
}; };
#endif #endif

View File

@ -31,7 +31,7 @@
#define APPLY_BY_MODE(findmode,function) \ #define APPLY_BY_MODE(findmode,function) \
FOR_EACH_TRACK(t) \ FOR_EACH_TRACK(t) \
if (trackMode[t]==findmode) \ if (track[t]->getMode()==findmode) \
track[t]->function; track[t]->function;
#ifndef DISABLE_PROG #ifndef DISABLE_PROG
const int16_t HASH_KEYWORD_PROG = -29718; const int16_t HASH_KEYWORD_PROG = -29718;
@ -44,7 +44,6 @@ const int16_t HASH_KEYWORD_EXT = 8201; // External DCC signal
const int16_t HASH_KEYWORD_A = 65; // parser makes single chars the ascii. const int16_t HASH_KEYWORD_A = 65; // parser makes single chars the ascii.
MotorDriver * TrackManager::track[MAX_TRACKS]; MotorDriver * TrackManager::track[MAX_TRACKS];
TRACK_MODE TrackManager::trackMode[MAX_TRACKS];
int16_t TrackManager::trackDCAddr[MAX_TRACKS]; int16_t TrackManager::trackDCAddr[MAX_TRACKS];
POWERMODE TrackManager::mainPowerGuess=POWERMODE::OFF; POWERMODE TrackManager::mainPowerGuess=POWERMODE::OFF;
@ -74,7 +73,7 @@ void TrackManager::sampleCurrent() {
waiting = false; waiting = false;
tr++; tr++;
if (tr > lastTrack) tr = 0; if (tr > lastTrack) tr = 0;
if (lastTrack < 2 || trackMode[tr] & TRACK_MODE_PROG) { if (lastTrack < 2 || track[tr]->getMode() & TRACK_MODE_PROG) {
return; // We could continue but for prog track we return; // We could continue but for prog track we
// rather do it in next interrupt beacuse // rather do it in next interrupt beacuse
// that gives us well defined sampling point. // that gives us well defined sampling point.
@ -85,7 +84,7 @@ void TrackManager::sampleCurrent() {
if (!waiting) { if (!waiting) {
// look for a valid track to sample or until we are around // look for a valid track to sample or until we are around
while (true) { while (true) {
if (trackMode[tr] & ( TRACK_MODE_MAIN|TRACK_MODE_PROG|TRACK_MODE_DC|TRACK_MODE_DCX|TRACK_MODE_EXT )) { if (track[tr]->getMode() & ( TRACK_MODE_MAIN|TRACK_MODE_PROG|TRACK_MODE_DC|TRACK_MODE_DCX|TRACK_MODE_EXT )) {
track[tr]->startCurrentFromHW(); track[tr]->startCurrentFromHW();
// for scope debug track[1]->setBrake(1); // for scope debug track[1]->setBrake(1);
waiting = true; waiting = true;
@ -138,10 +137,10 @@ void TrackManager::Setup(const FSH * shieldname,
} }
void TrackManager::addTrack(byte t, MotorDriver* driver) { void TrackManager::addTrack(byte t, MotorDriver* driver) {
trackMode[t]=TRACK_MODE_OFF;
track[t]=driver; track[t]=driver;
if (driver) { if (driver) {
track[t]->setPower(POWERMODE::OFF); track[t]->setPower(POWERMODE::OFF);
track[t]->setMode(TRACK_MODE_OFF);
track[t]->setTrackLetter('A'+t); track[t]->setTrackLetter('A'+t);
lastTrack=t; lastTrack=t;
} }
@ -183,15 +182,15 @@ void TrackManager::setPROGSignal( bool on) {
void TrackManager::setDCSignal(int16_t cab, byte speedbyte) { void TrackManager::setDCSignal(int16_t cab, byte speedbyte) {
FOR_EACH_TRACK(t) { FOR_EACH_TRACK(t) {
if (trackDCAddr[t]!=cab) continue; if (trackDCAddr[t]!=cab) continue;
if (trackMode[t]==TRACK_MODE_DC) track[t]->setDCSignal(speedbyte); if (track[t]->getMode()==TRACK_MODE_DC) track[t]->setDCSignal(speedbyte);
else if (trackMode[t]==TRACK_MODE_DCX) track[t]->setDCSignal(speedbyte ^ 128); else if (track[t]->getMode()==TRACK_MODE_DCX) track[t]->setDCSignal(speedbyte ^ 128);
} }
} }
bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr) { bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr) {
if (trackToSet>lastTrack || track[trackToSet]==NULL) return false; if (trackToSet>lastTrack || track[trackToSet]==NULL) return false;
//DIAG(F("Track=%c"),trackToSet+'A'); //DIAG(F("Track=%c Mode=%d"),trackToSet+'A', mode);
// DC tracks require a motorDriver that can set brake! // DC tracks require a motorDriver that can set brake!
if ((mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX) if ((mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX)
&& !track[trackToSet]->brakeCanPWM()) { && !track[trackToSet]->brakeCanPWM()) {
@ -218,9 +217,9 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
#endif #endif
// only allow 1 track to be prog // only allow 1 track to be prog
FOR_EACH_TRACK(t) FOR_EACH_TRACK(t)
if (trackMode[t]==TRACK_MODE_PROG && t != trackToSet) { if (track[t]->getMode()==TRACK_MODE_PROG && t != trackToSet) {
track[t]->setPower(POWERMODE::OFF); track[t]->setPower(POWERMODE::OFF);
trackMode[t]=TRACK_MODE_OFF; track[t]->setMode(TRACK_MODE_OFF);
track[t]->makeProgTrack(false); // revoke prog track special handling track[t]->makeProgTrack(false); // revoke prog track special handling
streamTrackState(NULL,t); streamTrackState(NULL,t);
} }
@ -228,7 +227,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
} else { } else {
track[trackToSet]->makeProgTrack(false); // only the prog track knows it's type track[trackToSet]->makeProgTrack(false); // only the prog track knows it's type
} }
trackMode[trackToSet]=mode; track[trackToSet]->setMode(mode);
trackDCAddr[trackToSet]=dcAddr; trackDCAddr[trackToSet]=dcAddr;
streamTrackState(NULL,trackToSet); streamTrackState(NULL,trackToSet);
@ -255,7 +254,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
// DC tracks must not have the DCC PWM switched on // DC tracks must not have the DCC PWM switched on
// so we globally turn it off if one of the PWM // so we globally turn it off if one of the PWM
// capable tracks is now DC or DCX. // capable tracks is now DC or DCX.
if (trackMode[t]==TRACK_MODE_DC || trackMode[t]==TRACK_MODE_DCX) { if (track[t]->getMode()==TRACK_MODE_DC || track[t]->getMode()==TRACK_MODE_DCX) {
if (track[t]->isPWMCapable()) { if (track[t]->isPWMCapable()) {
canDo=false; // this track is capable but can not run PWM canDo=false; // this track is capable but can not run PWM
break; // in this mode, so abort and prevent globally below break; // in this mode, so abort and prevent globally below
@ -263,7 +262,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
track[t]->trackPWM=false; // this track sure can not run with PWM track[t]->trackPWM=false; // this track sure can not run with PWM
//DIAG(F("Track %c trackPWM 0 (not capable)"), t+'A'); //DIAG(F("Track %c trackPWM 0 (not capable)"), t+'A');
} }
} else if (trackMode[t]==TRACK_MODE_MAIN || trackMode[t]==TRACK_MODE_PROG) { } else if (track[t]->getMode()==TRACK_MODE_MAIN || track[t]->getMode()==TRACK_MODE_PROG) {
track[t]->trackPWM = track[t]->isPWMCapable(); // trackPWM is still a guess here track[t]->trackPWM = track[t]->isPWMCapable(); // trackPWM is still a guess here
//DIAG(F("Track %c trackPWM %d"), t+'A', track[t]->trackPWM); //DIAG(F("Track %c trackPWM %d"), t+'A', track[t]->trackPWM);
canDo &= track[t]->trackPWM; canDo &= track[t]->trackPWM;
@ -301,7 +300,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
void TrackManager::applyDCSpeed(byte t) { void TrackManager::applyDCSpeed(byte t) {
uint8_t speedByte=DCC::getThrottleSpeedByte(trackDCAddr[t]); uint8_t speedByte=DCC::getThrottleSpeedByte(trackDCAddr[t]);
if (trackMode[t]==TRACK_MODE_DCX) if (track[t]->getMode()==TRACK_MODE_DCX)
speedByte = speedByte ^ 128; // reverse direction bit speedByte = speedByte ^ 128; // reverse direction bit
track[t]->setDCSignal(speedByte); track[t]->setDCSignal(speedByte);
} }
@ -347,7 +346,7 @@ void TrackManager::streamTrackState(Print* stream, byte t) {
// null stream means send to commandDistributor for broadcast // null stream means send to commandDistributor for broadcast
if (track[t]==NULL) return; if (track[t]==NULL) return;
auto format=F(""); auto format=F("");
switch(trackMode[t]) { switch(track[t]->getMode()) {
case TRACK_MODE_MAIN: case TRACK_MODE_MAIN:
format=F("<= %c MAIN>\n"); format=F("<= %c MAIN>\n");
break; break;
@ -387,13 +386,13 @@ void TrackManager::loop() {
if (nextCycleTrack>lastTrack) nextCycleTrack=0; if (nextCycleTrack>lastTrack) nextCycleTrack=0;
if (track[nextCycleTrack]==NULL) return; if (track[nextCycleTrack]==NULL) return;
MotorDriver * motorDriver=track[nextCycleTrack]; MotorDriver * motorDriver=track[nextCycleTrack];
bool useProgLimit=dontLimitProg? false: trackMode[nextCycleTrack]==TRACK_MODE_PROG; bool useProgLimit=dontLimitProg? false: track[nextCycleTrack]->getMode()==TRACK_MODE_PROG;
motorDriver->checkPowerOverload(useProgLimit, nextCycleTrack); motorDriver->checkPowerOverload(useProgLimit, nextCycleTrack);
} }
MotorDriver * TrackManager::getProgDriver() { MotorDriver * TrackManager::getProgDriver() {
FOR_EACH_TRACK(t) FOR_EACH_TRACK(t)
if (trackMode[t]==TRACK_MODE_PROG) return track[t]; if (track[t]->getMode()==TRACK_MODE_PROG) return track[t];
return NULL; return NULL;
} }
@ -401,7 +400,7 @@ MotorDriver * TrackManager::getProgDriver() {
std::vector<MotorDriver *>TrackManager::getMainDrivers() { std::vector<MotorDriver *>TrackManager::getMainDrivers() {
std::vector<MotorDriver *> v; std::vector<MotorDriver *> v;
FOR_EACH_TRACK(t) FOR_EACH_TRACK(t)
if (trackMode[t]==TRACK_MODE_MAIN) v.push_back(track[t]); if (track[t]->getMode()==TRACK_MODE_MAIN) v.push_back(track[t]);
return v; return v;
} }
#endif #endif
@ -411,7 +410,7 @@ void TrackManager::setPower2(bool setProg,POWERMODE mode) {
FOR_EACH_TRACK(t) { FOR_EACH_TRACK(t) {
MotorDriver * driver=track[t]; MotorDriver * driver=track[t];
if (!driver) continue; if (!driver) continue;
switch (trackMode[t]) { switch (track[t]->getMode()) {
case TRACK_MODE_MAIN: case TRACK_MODE_MAIN:
if (setProg) break; if (setProg) break;
// toggle brake before turning power on - resets overcurrent error // toggle brake before turning power on - resets overcurrent error
@ -447,8 +446,8 @@ void TrackManager::setPower2(bool setProg,POWERMODE mode) {
POWERMODE TrackManager::getProgPower() { POWERMODE TrackManager::getProgPower() {
FOR_EACH_TRACK(t) FOR_EACH_TRACK(t)
if (trackMode[t]==TRACK_MODE_PROG) if (track[t]->getMode()==TRACK_MODE_PROG)
return track[t]->getPower(); return track[t]->getPower();
return POWERMODE::OFF; return POWERMODE::OFF;
} }
@ -492,7 +491,7 @@ void TrackManager::setJoin(bool joined) {
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
if (joined) { if (joined) {
FOR_EACH_TRACK(t) { FOR_EACH_TRACK(t) {
if (trackMode[t]==TRACK_MODE_PROG) { if (track[t]->getMode()==TRACK_MODE_PROG) {
tempProgTrack = t; tempProgTrack = t;
setTrackMode(t, TRACK_MODE_MAIN); setTrackMode(t, TRACK_MODE_MAIN);
break; break;

View File

@ -27,10 +27,6 @@
#include "MotorDriver.h" #include "MotorDriver.h"
// Virtualised Motor shield multi-track hardware Interface // Virtualised Motor shield multi-track hardware Interface
// use powers of two so we can do logical and/or on the track modes in if clauses.
enum TRACK_MODE : byte {TRACK_MODE_OFF = 1, TRACK_MODE_MAIN = 2, TRACK_MODE_PROG = 4,
TRACK_MODE_DC = 8, TRACK_MODE_DCX = 16, TRACK_MODE_EXT = 32};
// These constants help EXRAIL macros say SET_TRACK(2,mode) OR SET_TRACK(C,mode) etc. // These constants help EXRAIL macros say SET_TRACK(2,mode) OR SET_TRACK(C,mode) etc.
const byte TRACK_NUMBER_0=0, TRACK_NUMBER_A=0; const byte TRACK_NUMBER_0=0, TRACK_NUMBER_A=0;
const byte TRACK_NUMBER_1=1, TRACK_NUMBER_B=1; const byte TRACK_NUMBER_1=1, TRACK_NUMBER_B=1;
@ -100,7 +96,6 @@ class TrackManager {
static POWERMODE mainPowerGuess; static POWERMODE mainPowerGuess;
static void applyDCSpeed(byte t); static void applyDCSpeed(byte t);
static TRACK_MODE trackMode[MAX_TRACKS];
static int16_t trackDCAddr[MAX_TRACKS]; // dc address if TRACK_MODE_DC or TRACK_MODE_DCX static int16_t trackDCAddr[MAX_TRACKS]; // dc address if TRACK_MODE_DC or TRACK_MODE_DCX
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
static byte tempProgTrack; // holds the prog track number during join static byte tempProgTrack; // holds the prog track number during join

View File

@ -3,7 +3,9 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "4.2.65" #define VERSION "4.2.66"
// 4.2.66 - Throttle inrush current by applying PWM to brake pin when
// fault pin goes active
// 4.2.65 - new config WIFI_FORCE_AP option // 4.2.65 - new config WIFI_FORCE_AP option
// 4.2.63 - completely new overcurrent detection // 4.2.63 - completely new overcurrent detection
// - ESP32 protect from race in RMT code // - ESP32 protect from race in RMT code