mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-25 00:56:13 +01:00
Compare commits
No commits in common. "399030d8ae7a88e3334ab6ba49d4e4e926999bbb" and "aa1f25fc7292bce7240a190f844a20258973fcaf" have entirely different histories.
399030d8ae
...
aa1f25fc72
|
@ -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;
|
||||||
ledcSetup(cnt_channel, 1000, 8);
|
|
||||||
ledcAttachPin(pin, cnt_channel);
|
ledcAttachPin(pin, cnt_channel);
|
||||||
|
ledcSetup(cnt_channel, 1000, 8);
|
||||||
} else {
|
} else {
|
||||||
ledcAttachPin(pin, pin_to_channel[pin]);
|
ledcAttachPin(pin, pin_to_channel[pin]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define GITHUB_SHA "devel-202307250927Z"
|
#define GITHUB_SHA "devel-202307091003Z"
|
||||||
|
|
|
@ -278,7 +278,6 @@ 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,
|
||||||
|
@ -287,7 +286,6 @@ 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;
|
||||||
|
@ -306,13 +304,11 @@ 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
|
||||||
|
@ -351,35 +347,7 @@ 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;
|
||||||
|
@ -505,31 +473,29 @@ 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 powerModeChange = (powerMode != lastPowerMode);
|
bool newPowerMode = (powerMode != lastPowerMode);
|
||||||
unsigned long now = micros();
|
unsigned long now = micros();
|
||||||
if (powerModeChange)
|
if (newPowerMode)
|
||||||
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 (powerModeChange)
|
if (newPowerMode)
|
||||||
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 (powerModeChange) {
|
if (newPowerMode) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -539,7 +505,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
@ -550,7 +515,6 @@ 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;
|
||||||
|
|
|
@ -27,10 +27,6 @@
|
||||||
#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)
|
||||||
|
@ -149,7 +145,6 @@ 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);
|
||||||
|
@ -208,12 +203,6 @@ 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
|
||||||
|
@ -290,7 +279,6 @@ 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
|
||||||
|
|
|
@ -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 (track[t]->getMode()==findmode) \
|
if (trackMode[t]==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,6 +44,7 @@ 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;
|
||||||
|
@ -73,7 +74,7 @@ void TrackManager::sampleCurrent() {
|
||||||
waiting = false;
|
waiting = false;
|
||||||
tr++;
|
tr++;
|
||||||
if (tr > lastTrack) tr = 0;
|
if (tr > lastTrack) tr = 0;
|
||||||
if (lastTrack < 2 || track[tr]->getMode() & TRACK_MODE_PROG) {
|
if (lastTrack < 2 || trackMode[tr] & 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.
|
||||||
|
@ -84,7 +85,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 (track[tr]->getMode() & ( TRACK_MODE_MAIN|TRACK_MODE_PROG|TRACK_MODE_DC|TRACK_MODE_DCX|TRACK_MODE_EXT )) {
|
if (trackMode[tr] & ( 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;
|
||||||
|
@ -137,10 +138,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;
|
||||||
}
|
}
|
||||||
|
@ -182,15 +183,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 (track[t]->getMode()==TRACK_MODE_DC) track[t]->setDCSignal(speedbyte);
|
if (trackMode[t]==TRACK_MODE_DC) track[t]->setDCSignal(speedbyte);
|
||||||
else if (track[t]->getMode()==TRACK_MODE_DCX) track[t]->setDCSignal(speedbyte ^ 128);
|
else if (trackMode[t]==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 Mode=%d"),trackToSet+'A', mode);
|
//DIAG(F("Track=%c"),trackToSet+'A');
|
||||||
// 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()) {
|
||||||
|
@ -217,9 +218,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 (track[t]->getMode()==TRACK_MODE_PROG && t != trackToSet) {
|
if (trackMode[t]==TRACK_MODE_PROG && t != trackToSet) {
|
||||||
track[t]->setPower(POWERMODE::OFF);
|
track[t]->setPower(POWERMODE::OFF);
|
||||||
track[t]->setMode(TRACK_MODE_OFF);
|
trackMode[t]=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);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +228,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
|
||||||
}
|
}
|
||||||
track[trackToSet]->setMode(mode);
|
trackMode[trackToSet]=mode;
|
||||||
trackDCAddr[trackToSet]=dcAddr;
|
trackDCAddr[trackToSet]=dcAddr;
|
||||||
streamTrackState(NULL,trackToSet);
|
streamTrackState(NULL,trackToSet);
|
||||||
|
|
||||||
|
@ -254,7 +255,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 (track[t]->getMode()==TRACK_MODE_DC || track[t]->getMode()==TRACK_MODE_DCX) {
|
if (trackMode[t]==TRACK_MODE_DC || trackMode[t]==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
|
||||||
|
@ -262,7 +263,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 (track[t]->getMode()==TRACK_MODE_MAIN || track[t]->getMode()==TRACK_MODE_PROG) {
|
} else if (trackMode[t]==TRACK_MODE_MAIN || trackMode[t]==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;
|
||||||
|
@ -300,7 +301,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 (track[t]->getMode()==TRACK_MODE_DCX)
|
if (trackMode[t]==TRACK_MODE_DCX)
|
||||||
speedByte = speedByte ^ 128; // reverse direction bit
|
speedByte = speedByte ^ 128; // reverse direction bit
|
||||||
track[t]->setDCSignal(speedByte);
|
track[t]->setDCSignal(speedByte);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +347,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(track[t]->getMode()) {
|
switch(trackMode[t]) {
|
||||||
case TRACK_MODE_MAIN:
|
case TRACK_MODE_MAIN:
|
||||||
format=F("<= %c MAIN>\n");
|
format=F("<= %c MAIN>\n");
|
||||||
break;
|
break;
|
||||||
|
@ -386,13 +387,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: track[nextCycleTrack]->getMode()==TRACK_MODE_PROG;
|
bool useProgLimit=dontLimitProg? false: trackMode[nextCycleTrack]==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 (track[t]->getMode()==TRACK_MODE_PROG) return track[t];
|
if (trackMode[t]==TRACK_MODE_PROG) return track[t];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +401,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 (track[t]->getMode()==TRACK_MODE_MAIN) v.push_back(track[t]);
|
if (trackMode[t]==TRACK_MODE_MAIN) v.push_back(track[t]);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -410,7 +411,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 (track[t]->getMode()) {
|
switch (trackMode[t]) {
|
||||||
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
|
||||||
|
@ -446,8 +447,8 @@ void TrackManager::setPower2(bool setProg,POWERMODE mode) {
|
||||||
|
|
||||||
POWERMODE TrackManager::getProgPower() {
|
POWERMODE TrackManager::getProgPower() {
|
||||||
FOR_EACH_TRACK(t)
|
FOR_EACH_TRACK(t)
|
||||||
if (track[t]->getMode()==TRACK_MODE_PROG)
|
if (trackMode[t]==TRACK_MODE_PROG)
|
||||||
return track[t]->getPower();
|
return track[t]->getPower();
|
||||||
return POWERMODE::OFF;
|
return POWERMODE::OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +492,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 (track[t]->getMode()==TRACK_MODE_PROG) {
|
if (trackMode[t]==TRACK_MODE_PROG) {
|
||||||
tempProgTrack = t;
|
tempProgTrack = t;
|
||||||
setTrackMode(t, TRACK_MODE_MAIN);
|
setTrackMode(t, TRACK_MODE_MAIN);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
#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;
|
||||||
|
@ -96,6 +100,7 @@ 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
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
|
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
#define VERSION "4.2.66"
|
#define VERSION "4.2.65"
|
||||||
// 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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user