mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 21:01:25 +01:00
various spelling fixes to comments
This commit is contained in:
parent
28d60d4984
commit
2dab0155e2
@ -33,7 +33,7 @@ For more information just check our code or read https://google.github.io/styleg
|
|||||||
|
|
||||||
1. Clone the repository on your local machine
|
1. Clone the repository on your local machine
|
||||||
2. Create a working branch using the format "username-featurename" ex: "git branch -b frightrisk-turnouts"
|
2. Create a working branch using the format "username-featurename" ex: "git branch -b frightrisk-turnouts"
|
||||||
3. Commit offen, ex: "git add ." and then "git commit -m "description of your changes"
|
3. Commit often, ex: "git add ." and then "git commit -m "description of your changes"
|
||||||
4. Push your changes to our repository "git push"
|
4. Push your changes to our repository "git push"
|
||||||
5. When you are ready, issue a pull request for your changes to be merged into the main branch
|
5. When you are ready, issue a pull request for your changes to be merged into the main branch
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ Contributors who do not follow the be nice rule in good faith may face temporary
|
|||||||
|
|
||||||
## How Can I Contribute?
|
## How Can I Contribute?
|
||||||
|
|
||||||
The DCC-EX Team has several projects and sub teams where you can help donate your epertise. See the sections below for the project or projects you are interested in.
|
The DCC-EX Team has several projects and sub teams where you can help donate your expertise. See the sections below for the project or projects you are interested in.
|
||||||
|
|
||||||
### Development
|
### Development
|
||||||
### Documentation
|
### Documentation
|
||||||
|
@ -67,7 +67,7 @@ void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream
|
|||||||
ring=stream;
|
ring=stream;
|
||||||
|
|
||||||
// First check if the client is not known
|
// First check if the client is not known
|
||||||
// yet and in that case determinine type
|
// yet and in that case determine type
|
||||||
// NOTE: First character of transmission determines if this
|
// NOTE: First character of transmission determines if this
|
||||||
// client is using the DCC++ protocol where all commands start
|
// client is using the DCC++ protocol where all commands start
|
||||||
// with '<'
|
// with '<'
|
||||||
@ -98,7 +98,7 @@ void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream
|
|||||||
DIAG(F("OUTBOUND FULL processing cmd:%s"),buffer);
|
DIAG(F("OUTBOUND FULL processing cmd:%s"),buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DIAG(F("CD parse: was alredy committed")); //XXX Could have been committed by broadcastClient?!
|
DIAG(F("CD parse: was already committed")); //XXX Could have been committed by broadcastClient?!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ void setup()
|
|||||||
|
|
||||||
DIAG(F("License GPLv3 fsf.org (c) dcc-ex.com"));
|
DIAG(F("License GPLv3 fsf.org (c) dcc-ex.com"));
|
||||||
|
|
||||||
// Initialise HAL layer before reading EEprom or setting up MotorDrivers
|
// Initialise HAL layer before reading EEprom or setting up MotorDrivers
|
||||||
IODevice::begin();
|
IODevice::begin();
|
||||||
|
|
||||||
// As the setup of a motor shield may require a read of the current sense input from the ADC,
|
// As the setup of a motor shield may require a read of the current sense input from the ADC,
|
||||||
@ -110,7 +110,7 @@ void setup()
|
|||||||
// Responsibility 3: Start the DCC engine.
|
// Responsibility 3: Start the DCC engine.
|
||||||
DCC::begin();
|
DCC::begin();
|
||||||
|
|
||||||
// Start RMFT aka EX-RAIL (ignored if no automnation)
|
// Start RMFT aka EX-RAIL (ignored if no automation)
|
||||||
RMFT::begin();
|
RMFT::begin();
|
||||||
|
|
||||||
|
|
||||||
|
18
DCC.cpp
18
DCC.cpp
@ -43,7 +43,7 @@
|
|||||||
// It has no visibility of the hardware, timers, interrupts
|
// It has no visibility of the hardware, timers, interrupts
|
||||||
// nor of the waveform issues such as preambles, start bits checksums or cutouts.
|
// nor of the waveform issues such as preambles, start bits checksums or cutouts.
|
||||||
//
|
//
|
||||||
// Nor should it have to deal with JMRI responsess other than the OK/FAIL
|
// Nor should it have to deal with JMRI responses other than the OK/FAIL
|
||||||
// or cv value returned. I will move that back to the JMRI interface later
|
// or cv value returned. I will move that back to the JMRI interface later
|
||||||
//
|
//
|
||||||
// The interface to the waveform generator is narrowed down to merely:
|
// The interface to the waveform generator is narrowed down to merely:
|
||||||
@ -250,7 +250,7 @@ void DCC::setAccessory(int address, byte port, bool gate, byte onoff /*= 2*/) {
|
|||||||
// >1 => send both on and off packets.
|
// >1 => send both on and off packets.
|
||||||
|
|
||||||
// An accessory has an address, 4 ports and 2 gates (coils) each. That's how
|
// An accessory has an address, 4 ports and 2 gates (coils) each. That's how
|
||||||
// the initial decoders were orgnized and that influenced how the DCC
|
// the initial decoders were organized and that influenced how the DCC
|
||||||
// standard was made.
|
// standard was made.
|
||||||
#ifdef DIAG_IO
|
#ifdef DIAG_IO
|
||||||
DIAG(F("DCC::setAccessory(%d,%d,%d)"), address, port, gate);
|
DIAG(F("DCC::setAccessory(%d,%d,%d)"), address, port, gate);
|
||||||
@ -262,7 +262,7 @@ void DCC::setAccessory(int address, byte port, bool gate, byte onoff /*= 2*/) {
|
|||||||
return;
|
return;
|
||||||
byte b[2];
|
byte b[2];
|
||||||
|
|
||||||
// first byte is of the form 10AAAAAA, where AAAAAA represent 6 least signifcant bits of accessory address
|
// first byte is of the form 10AAAAAA, where AAAAAA represent 6 least significant bits of accessory address
|
||||||
// second byte is of the form 1AAACPPG, where C is 1 for on, PP the ports 0 to 3 and G the gate (coil).
|
// second byte is of the form 1AAACPPG, where C is 1 for on, PP the ports 0 to 3 and G the gate (coil).
|
||||||
b[0] = address % 64 + 128;
|
b[0] = address % 64 + 128;
|
||||||
b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
|
b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
|
||||||
@ -365,7 +365,7 @@ const ackOp FLASH READ_BIT_PROG[] = {
|
|||||||
const ackOp FLASH WRITE_BYTE_PROG[] = {
|
const ackOp FLASH WRITE_BYTE_PROG[] = {
|
||||||
BASELINE,
|
BASELINE,
|
||||||
WB,WACK,ITC1, // Write and callback(1) if ACK
|
WB,WACK,ITC1, // Write and callback(1) if ACK
|
||||||
// handle decoders that dont ack a write
|
// handle decoders that don't ack a write
|
||||||
VB,WACK,ITC1, // validate byte and callback(1) if correct
|
VB,WACK,ITC1, // validate byte and callback(1) if correct
|
||||||
CALLFAIL // callback (-1)
|
CALLFAIL // callback (-1)
|
||||||
};
|
};
|
||||||
@ -467,7 +467,7 @@ const ackOp FLASH LOCO_ID_PROG[] = {
|
|||||||
V0, WACK, MERGE,
|
V0, WACK, MERGE,
|
||||||
V0, WACK, MERGE,
|
V0, WACK, MERGE,
|
||||||
VB, WACK, NAKFAIL, // verify merged byte and return -1 it if not acked ok
|
VB, WACK, NAKFAIL, // verify merged byte and return -1 it if not acked ok
|
||||||
COMBINELOCOID, // Combile byte with stash to make long locoid and callback
|
COMBINELOCOID, // Combine byte with stash to make long locoid and callback
|
||||||
|
|
||||||
// ITSKIP Skips to here if CV 29 bit 5 was zero. so read CV 1 and return that
|
// ITSKIP Skips to here if CV 29 bit 5 was zero. so read CV 1 and return that
|
||||||
SKIPTARGET,
|
SKIPTARGET,
|
||||||
@ -489,7 +489,7 @@ const ackOp FLASH SHORT_LOCO_ID_PROG[] = {
|
|||||||
BASELINE,
|
BASELINE,
|
||||||
SETCV,(ackOp)19,
|
SETCV,(ackOp)19,
|
||||||
SETBYTE, (ackOp)0,
|
SETBYTE, (ackOp)0,
|
||||||
WB,WACK, // ignore dedcoder without cv19 support
|
WB,WACK, // ignore decoder without cv19 support
|
||||||
// Turn off long address flag
|
// Turn off long address flag
|
||||||
SETCV,(ackOp)29,
|
SETCV,(ackOp)29,
|
||||||
SETBIT,(ackOp)5,
|
SETBIT,(ackOp)5,
|
||||||
@ -632,12 +632,12 @@ bool DCC::issueReminder(int reg) {
|
|||||||
case 4: // remind function group 4 F13-F20
|
case 4: // remind function group 4 F13-F20
|
||||||
if (flags & FN_GROUP_4)
|
if (flags & FN_GROUP_4)
|
||||||
setFunctionInternal(loco,222, ((functions>>13)& 0xFF));
|
setFunctionInternal(loco,222, ((functions>>13)& 0xFF));
|
||||||
flags&= ~FN_GROUP_4; // dont send them again
|
flags&= ~FN_GROUP_4; // don't send them again
|
||||||
break;
|
break;
|
||||||
case 5: // remind function group 5 F21-F28
|
case 5: // remind function group 5 F21-F28
|
||||||
if (flags & FN_GROUP_5)
|
if (flags & FN_GROUP_5)
|
||||||
setFunctionInternal(loco,223, ((functions>>21)& 0xFF));
|
setFunctionInternal(loco,223, ((functions>>21)& 0xFF));
|
||||||
flags&= ~FN_GROUP_5; // dont send them again
|
flags&= ~FN_GROUP_5; // don't send them again
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
loopStatus++;
|
loopStatus++;
|
||||||
@ -691,7 +691,7 @@ int DCC::lookupSpeedTable(int locoId, bool autoCreate) {
|
|||||||
void DCC::updateLocoReminder(int loco, byte speedCode) {
|
void DCC::updateLocoReminder(int loco, byte speedCode) {
|
||||||
|
|
||||||
if (loco==0) {
|
if (loco==0) {
|
||||||
// broadcast stop/estop but dont change direction
|
// broadcast stop/estop but don't change direction
|
||||||
for (int reg = 0; reg <= highestUsedReg; reg++) {
|
for (int reg = 0; reg <= highestUsedReg; reg++) {
|
||||||
if (speedTable[reg].loco==0) continue;
|
if (speedTable[reg].loco==0) continue;
|
||||||
byte newspeed=(speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f);
|
byte newspeed=(speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f);
|
||||||
|
12
DCCACK.cpp
12
DCCACK.cpp
@ -77,12 +77,12 @@ void DCCACK::Setup(int cv, byte byteValueOrBitnum, ackOp const program[], ACK_C
|
|||||||
progDriver=TrackManager::getProgDriver();
|
progDriver=TrackManager::getProgDriver();
|
||||||
if (progDriver==NULL) {
|
if (progDriver==NULL) {
|
||||||
TrackManager::setJoin(ackManagerRejoin);
|
TrackManager::setJoin(ackManagerRejoin);
|
||||||
callback(-3); // we dont have a prog track!
|
callback(-3); // we don't have a prog track!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!progDriver->canMeasureCurrent()) {
|
if (!progDriver->canMeasureCurrent()) {
|
||||||
TrackManager::setJoin(ackManagerRejoin);
|
TrackManager::setJoin(ackManagerRejoin);
|
||||||
callback(-2); // our prog track cant measure current
|
callback(-2); // our prog track can't measure current
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ void DCCACK::Setup(int wordval, ackOp const program[], ACK_CALLBACK callback) {
|
|||||||
|
|
||||||
const byte RESET_MIN=8; // tuning of reset counter before sending message
|
const byte RESET_MIN=8; // tuning of reset counter before sending message
|
||||||
|
|
||||||
// checkRessets return true if the caller should yield back to loop and try later.
|
// checkResets return true if the caller should yield back to loop and try later.
|
||||||
bool DCCACK::checkResets(uint8_t numResets) {
|
bool DCCACK::checkResets(uint8_t numResets) {
|
||||||
return DCCWaveform::progTrack.getResets() < numResets;
|
return DCCWaveform::progTrack.getResets() < numResets;
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ void DCCACK::loop() {
|
|||||||
break; // we have a genuine ACK result
|
break; // we have a genuine ACK result
|
||||||
}
|
}
|
||||||
case ITC0:
|
case ITC0:
|
||||||
case ITC1: // If True Callback(0 or 1) (if prevous WACK got an ACK)
|
case ITC1: // If True Callback(0 or 1) (if previous WACK got an ACK)
|
||||||
if (ackReceived) {
|
if (ackReceived) {
|
||||||
callback(opcode==ITC0?0:1);
|
callback(opcode==ITC0?0:1);
|
||||||
return;
|
return;
|
||||||
@ -375,8 +375,8 @@ void DCCACK::callback(int value) {
|
|||||||
if (millis()-callbackStart < 100) break;
|
if (millis()-callbackStart < 100) break;
|
||||||
// stable after power maintained for 100mS
|
// stable after power maintained for 100mS
|
||||||
|
|
||||||
// If we are going to power off anyway, it doesnt matter
|
// If we are going to power off anyway, it doesn't matter
|
||||||
// but if we will keep the power on, we must off it for 30mS
|
// but if we will keep the power on, we must turn it off for 30mS
|
||||||
if (autoPowerOff) callbackState=READY;
|
if (autoPowerOff) callbackState=READY;
|
||||||
else { // Need to cycle power off and on
|
else { // Need to cycle power off and on
|
||||||
progDriver->setPower(POWERMODE::OFF);
|
progDriver->setPower(POWERMODE::OFF);
|
||||||
|
@ -176,7 +176,7 @@ RingStream *DCCEXParser::stashRingStream = NULL;
|
|||||||
byte DCCEXParser::stashTarget=0;
|
byte DCCEXParser::stashTarget=0;
|
||||||
|
|
||||||
// This is a JMRI command parser.
|
// This is a JMRI command parser.
|
||||||
// It doesnt know how the string got here, nor how it gets back.
|
// It doesn't know how the string got here, nor how it gets back.
|
||||||
// It knows nothing about hardware or tracks... it just parses strings and
|
// It knows nothing about hardware or tracks... it just parses strings and
|
||||||
// calls the corresponding DCC api.
|
// calls the corresponding DCC api.
|
||||||
// Non-DCC things like turnouts, pins and sensors are handled in additional JMRI interface classes.
|
// Non-DCC things like turnouts, pins and sensors are handled in additional JMRI interface classes.
|
||||||
@ -625,12 +625,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
#ifndef DISABLE_EEPROM
|
#ifndef DISABLE_EEPROM
|
||||||
case 'E': // STORE EPROM <E>
|
case 'E': // STORE EEPROM <E>
|
||||||
EEStore::store();
|
EEStore::store();
|
||||||
StringFormatter::send(stream, F("<e %d %d %d>\n"), EEStore::eeStore->data.nTurnouts, EEStore::eeStore->data.nSensors, EEStore::eeStore->data.nOutputs);
|
StringFormatter::send(stream, F("<e %d %d %d>\n"), EEStore::eeStore->data.nTurnouts, EEStore::eeStore->data.nSensors, EEStore::eeStore->data.nOutputs);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'e': // CLEAR EPROM <e>
|
case 'e': // CLEAR EEPROM <e>
|
||||||
EEStore::clear();
|
EEStore::clear();
|
||||||
StringFormatter::send(stream, F("<O>\n"));
|
StringFormatter::send(stream, F("<O>\n"));
|
||||||
return;
|
return;
|
||||||
@ -980,7 +980,7 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[])
|
|||||||
{
|
{
|
||||||
if (params == 0)
|
if (params == 0)
|
||||||
return false;
|
return false;
|
||||||
bool onOff = (params > 0) && (p[1] == 1 || p[1] == HASH_KEYWORD_ON); // dont care if other stuff or missing... just means off
|
bool onOff = (params > 0) && (p[1] == 1 || p[1] == HASH_KEYWORD_ON); // don't care if other stuff or missing... just means off
|
||||||
switch (p[0])
|
switch (p[0])
|
||||||
{
|
{
|
||||||
case HASH_KEYWORD_CABS: // <D CABS>
|
case HASH_KEYWORD_CABS: // <D CABS>
|
||||||
@ -1042,7 +1042,7 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[])
|
|||||||
#endif
|
#endif
|
||||||
case HASH_KEYWORD_RESET:
|
case HASH_KEYWORD_RESET:
|
||||||
DCCTimer::reset();
|
DCCTimer::reset();
|
||||||
break; // and <X> if we didnt restart
|
break; // and <X> if we didn't restart
|
||||||
|
|
||||||
|
|
||||||
#ifndef DISABLE_EEPROM
|
#ifndef DISABLE_EEPROM
|
||||||
|
13
DCCRMT.cpp
13
DCCRMT.cpp
@ -123,10 +123,13 @@ RMTChannel::RMTChannel(pinpair pins, bool isMain) {
|
|||||||
config.channel = channel = (rmt_channel_t)ch;
|
config.channel = channel = (rmt_channel_t)ch;
|
||||||
config.clk_div = RMT_CLOCK_DIVIDER;
|
config.clk_div = RMT_CLOCK_DIVIDER;
|
||||||
config.gpio_num = (gpio_num_t)pins.pin;
|
config.gpio_num = (gpio_num_t)pins.pin;
|
||||||
config.mem_block_num = 2; // With longest DCC packet 11 inc checksum (future expansion)
|
|
||||||
// number of bits needed is 22preamble + start +
|
// With longest DCC packet (11 bytes, including checksum (future expansion)):
|
||||||
// 11*9 + extrazero + EOT = 124
|
// number of bits needed is PREAMBLE_BITS_PROG (22) + start (1) +
|
||||||
// 2 mem block of 64 RMT items should be enough
|
// data bytes (11*9) + extrazero (1) + EOT (1) = 124
|
||||||
|
//
|
||||||
|
// 2 mem blocks of 64 RMT items should be enough
|
||||||
|
config.mem_block_num = 2;
|
||||||
|
|
||||||
ESP_ERROR_CHECK(rmt_config(&config));
|
ESP_ERROR_CHECK(rmt_config(&config));
|
||||||
addPin(pins.invpin, true);
|
addPin(pins.invpin, true);
|
||||||
@ -166,7 +169,7 @@ const byte transmitMask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
|||||||
|
|
||||||
int RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCount=0) {
|
int RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCount=0) {
|
||||||
//int RMTChannel::RMTfillData(dccPacket packet) {
|
//int RMTChannel::RMTfillData(dccPacket packet) {
|
||||||
// dataReady: Signals to then interrupt routine. It is set when
|
// dataReady: Signals to the interrupt routine. It is set when
|
||||||
// we have data in the channel buffer which can be copied out
|
// we have data in the channel buffer which can be copied out
|
||||||
// to the HW. dataRepeat on the other hand signals back to
|
// to the HW. dataRepeat on the other hand signals back to
|
||||||
// the caller of this function if the data has been sent enough
|
// the caller of this function if the data has been sent enough
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
* Other shields may be jumpered to PWM pins or run directly using the software interrupt.
|
* Other shields may be jumpered to PWM pins or run directly using the software interrupt.
|
||||||
*
|
*
|
||||||
* Because the PWM-based waveform is effectively set half a cycle after the software version,
|
* Because the PWM-based waveform is effectively set half a cycle after the software version,
|
||||||
* it is not acceptable to drive the two tracks on different methiods or it would cause
|
* it is not acceptable to drive the two tracks on different methods or it would cause
|
||||||
* problems for <1 JOIN> etc.
|
* problems for <1 JOIN> etc.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -98,7 +98,7 @@ private:
|
|||||||
|
|
||||||
// Class ADCee implements caching of the ADC value for platforms which
|
// Class ADCee implements caching of the ADC value for platforms which
|
||||||
// have a too slow ADC read to wait for. On these platforms the ADC is
|
// have a too slow ADC read to wait for. On these platforms the ADC is
|
||||||
// scanned continiously in the background from an ISR. On such
|
// scanned continuously in the background from an ISR. On such
|
||||||
// architectures that use the analog read during DCC waveform with
|
// architectures that use the analog read during DCC waveform with
|
||||||
// specially configured ADC, for example AVR, init must be called
|
// specially configured ADC, for example AVR, init must be called
|
||||||
// PRIOR to the start of the waveform. It returns the current value so
|
// PRIOR to the start of the waveform. It returns the current value so
|
||||||
|
@ -121,7 +121,7 @@ int DCCTimer::freeMemory() {
|
|||||||
|
|
||||||
void DCCTimer::reset() {
|
void DCCTimer::reset() {
|
||||||
wdt_enable( WDTO_15MS); // set Arduino watchdog timer for 15ms
|
wdt_enable( WDTO_15MS); // set Arduino watchdog timer for 15ms
|
||||||
delay(50); // wait for the prescaller time to expire
|
delay(50); // wait for the prescaler time to expire
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ void ADCee::scan() {
|
|||||||
// 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 (mask & usedpins) {
|
if (mask & usedpins) {
|
||||||
// start new ADC aquire on id
|
// start new ADC acquire on id
|
||||||
#if defined(ADCSRB) && defined(MUX5)
|
#if defined(ADCSRB) && defined(MUX5)
|
||||||
if (ADCusesHighPort) { // if we ever have started to use high pins)
|
if (ADCusesHighPort) { // if we ever have started to use high pins)
|
||||||
if (id > 7) // if we use a high ADC pin
|
if (id > 7) // if we use a high ADC pin
|
||||||
|
@ -73,7 +73,7 @@ int DCCTimer::getMinimumFreeMemory() {
|
|||||||
int DCCTimer::freeMemory() {
|
int DCCTimer::freeMemory() {
|
||||||
return ESP.getFreeHeap();
|
return ESP.getFreeHeap();
|
||||||
}
|
}
|
||||||
#endif
|
#endif // ESP8266
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
|
|||||||
timerAlarmEnable(timer);
|
timerAlarmEnable(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do not support to use PWM to make the Waveform on ESP
|
// We do not support using PWM to make the Waveform on ESP
|
||||||
bool IRAM_ATTR DCCTimer::isPWMPin(byte pin) {
|
bool IRAM_ATTR DCCTimer::isPWMPin(byte pin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ HardwareSerial Serial1(PB7, PA15); // Rx=PB7, Tx=PA15 -- CN7 pins 17 and 21 - F
|
|||||||
HardwareSerial Serial6(PA12, PA11); // Rx=PA12, Tx=PA11 -- CN10 pins 12 and 14 - F411RE
|
HardwareSerial Serial6(PA12, PA11); // Rx=PA12, Tx=PA11 -- CN10 pins 12 and 14 - F411RE
|
||||||
#elif defined(ARDUINO_NUCLEO_F446RE)
|
#elif defined(ARDUINO_NUCLEO_F446RE)
|
||||||
// Nucleo-64 boards don't have additional serial ports defined by default
|
// Nucleo-64 boards don't have additional serial ports defined by default
|
||||||
// On the F446RE, Serial1 isn't really useable as it's Rx/Tx pair sit on already used D2/D10 pins
|
// On the F446RE, Serial1 isn't really useable as its Rx/Tx pair sit on already used D2/D10 pins
|
||||||
// HardwareSerial Serial1(PA10, PB6); // Rx=PA10 (D2), Tx=PB6 (D10) -- CN10 pins 17 and 9 - F446RE
|
// HardwareSerial Serial1(PA10, PB6); // Rx=PA10 (D2), Tx=PB6 (D10) -- CN10 pins 17 and 9 - F446RE
|
||||||
// Serial2 is defined to use USART2 by default, but is in fact used as the diag console
|
// Serial2 is defined to use USART2 by default, but is in fact used as the diag console
|
||||||
// via the debugger on the Nucleo-64. It is therefore unavailable for other DCC-EX uses like WiFi, DFPlayer, etc.
|
// via the debugger on the Nucleo-64. It is therefore unavailable for other DCC-EX uses like WiFi, DFPlayer, etc.
|
||||||
@ -369,7 +369,7 @@ void ADCee::scan() {
|
|||||||
// 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 (mask & usedpins) {
|
if (mask & usedpins) {
|
||||||
// start new ADC aquire on id
|
// start new ADC acquire on id
|
||||||
ADC1->SQR3 = analogchans[id]; //1st conversion in regular sequence
|
ADC1->SQR3 = analogchans[id]; //1st conversion in regular sequence
|
||||||
ADC1->CR2 |= (1 << 30); //Start 1st conversion SWSTART
|
ADC1->CR2 |= (1 << 30); //Start 1st conversion SWSTART
|
||||||
#ifdef DEBUG_ADC
|
#ifdef DEBUG_ADC
|
||||||
|
@ -52,7 +52,7 @@ void DCCTimer::setPWM(byte pin, bool high) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DCCTimer::clearPWM() {
|
void DCCTimer::clearPWM() {
|
||||||
// Do nothing unless we implent HA
|
// Do nothing unless we implement HA
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__IMXRT1062__) //Teensy 4.0 and Teensy 4.1
|
#if defined(__IMXRT1062__) //Teensy 4.0 and Teensy 4.1
|
||||||
|
@ -36,7 +36,7 @@ DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true);
|
|||||||
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
|
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
|
||||||
|
|
||||||
|
|
||||||
// This bitmask has 9 entries as each byte is trasmitted as a zero + 8 bits.
|
// This bitmask has 9 entries as each byte is transmitted as a zero + 8 bits.
|
||||||
const byte bitMask[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
const byte bitMask[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||||
|
|
||||||
const byte idlePacket[] = {0xFF, 0x00, 0xFF};
|
const byte idlePacket[] = {0xFF, 0x00, 0xFF};
|
||||||
@ -88,7 +88,7 @@ void DCCWaveform::interruptHandler() {
|
|||||||
mainTrack.state=stateTransform[mainTrack.state];
|
mainTrack.state=stateTransform[mainTrack.state];
|
||||||
progTrack.state=stateTransform[progTrack.state];
|
progTrack.state=stateTransform[progTrack.state];
|
||||||
|
|
||||||
// WAVE_PENDING means we dont yet know what the next bit is
|
// WAVE_PENDING means we don't yet know what the next bit is
|
||||||
if (mainTrack.state==WAVE_PENDING) mainTrack.interrupt2();
|
if (mainTrack.state==WAVE_PENDING) mainTrack.interrupt2();
|
||||||
if (progTrack.state==WAVE_PENDING) progTrack.interrupt2();
|
if (progTrack.state==WAVE_PENDING) progTrack.interrupt2();
|
||||||
else DCCACK::checkAck(progTrack.getResets());
|
else DCCACK::checkAck(progTrack.getResets());
|
||||||
@ -99,7 +99,7 @@ void DCCWaveform::interruptHandler() {
|
|||||||
// An instance of this class handles the DCC transmissions for one track. (main or prog)
|
// An instance of this class handles the DCC transmissions for one track. (main or prog)
|
||||||
// Interrupts are marshalled via the statics.
|
// Interrupts are marshalled via the statics.
|
||||||
// A track has a current transmit buffer, and a pending buffer.
|
// A track has a current transmit buffer, and a pending buffer.
|
||||||
// When the current buffer is exhausted, either the pending buffer (if there is one waiting) or an idle buffer.
|
// When the current buffer is exhausted, send either the pending buffer (if there is one waiting) or an idle buffer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ void DCCWaveform::interrupt2() {
|
|||||||
//end of Byte
|
//end of Byte
|
||||||
bits_sent = 0;
|
bits_sent = 0;
|
||||||
bytes_sent++;
|
bytes_sent++;
|
||||||
// if this is the last byte, prepere for next packet
|
// if this is the last byte, prepare for next packet
|
||||||
if (bytes_sent >= transmitLength) {
|
if (bytes_sent >= transmitLength) {
|
||||||
// end of transmission buffer... repeat or switch to next message
|
// end of transmission buffer... repeat or switch to next message
|
||||||
bytes_sent = 0;
|
bytes_sent = 0;
|
||||||
@ -247,7 +247,7 @@ void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repea
|
|||||||
pendingPacket[byteCount] = checksum;
|
pendingPacket[byteCount] = checksum;
|
||||||
pendingLength = byteCount + 1;
|
pendingLength = byteCount + 1;
|
||||||
pendingRepeats = repeats;
|
pendingRepeats = repeats;
|
||||||
// DIAG repeated commands (accesories)
|
// DIAG repeated commands (accessories)
|
||||||
// if (pendingRepeats > 0)
|
// if (pendingRepeats > 0)
|
||||||
// DIAG(F("Repeats=%d on %s track"), pendingRepeats, isMainTrack ? "MAIN" : "PROG");
|
// DIAG(F("Repeats=%d on %s track"), pendingRepeats, isMainTrack ? "MAIN" : "PROG");
|
||||||
// The resets will be zero not only now but as well repeats packets into the future
|
// The resets will be zero not only now but as well repeats packets into the future
|
||||||
|
@ -70,7 +70,7 @@ const int16_t HASH_KEYWORD_RED=26099;
|
|||||||
const int16_t HASH_KEYWORD_AMBER=18713;
|
const int16_t HASH_KEYWORD_AMBER=18713;
|
||||||
const int16_t HASH_KEYWORD_GREEN=-31493;
|
const int16_t HASH_KEYWORD_GREEN=-31493;
|
||||||
|
|
||||||
// One instance of RMFT clas is used for each "thread" in the automation.
|
// One instance of RMFT class is used for each "thread" in the automation.
|
||||||
// Each thread manages a loco on a journey through the layout, and/or may manage a scenery automation.
|
// Each thread manages a loco on a journey through the layout, and/or may manage a scenery automation.
|
||||||
// The threads exist in a ring, each time through loop() the next thread in the ring is serviced.
|
// The threads exist in a ring, each time through loop() the next thread in the ring is serviced.
|
||||||
|
|
||||||
@ -1145,7 +1145,7 @@ 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;
|
||||||
|
|
||||||
// Check we dont already have a task running this handler
|
// Check we don't already have a task running this handler
|
||||||
RMFT2 * task=loopTask;
|
RMFT2 * task=loopTask;
|
||||||
while(task) {
|
while(task) {
|
||||||
if (task->onEventStartPosition==pc) {
|
if (task->onEventStartPosition==pc) {
|
||||||
@ -1231,8 +1231,8 @@ void RMFT2::thrungeString(uint32_t strfar, thrunger mode, byte id) {
|
|||||||
stream->write(c);
|
stream->write(c);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// UNO/NANO CPUs dont have high memory
|
// UNO/NANO CPUs don't have high memory
|
||||||
// 32 bit cpus dont care anyway
|
// 32 bit cpus don't care anyway
|
||||||
stream->print((FSH *)strfar);
|
stream->print((FSH *)strfar);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ void I2CManagerClass::begin(void) {
|
|||||||
setTimeout(1000); // use 1ms timeout for probes
|
setTimeout(1000); // use 1ms timeout for probes
|
||||||
|
|
||||||
#if defined(I2C_EXTENDED_ADDRESS)
|
#if defined(I2C_EXTENDED_ADDRESS)
|
||||||
// First count the multiplexers and switch off all subbuses
|
// First count the multiplexers and switch off all subBuses
|
||||||
_muxCount = 0;
|
_muxCount = 0;
|
||||||
for (uint8_t muxNo=I2CMux_0; muxNo <= I2CMux_7; muxNo++) {
|
for (uint8_t muxNo=I2CMux_0; muxNo <= I2CMux_7; muxNo++) {
|
||||||
if (I2CManager.muxSelectSubBus({(I2CMux)muxNo, SubBus_None})==I2C_STATUS_OK)
|
if (I2CManager.muxSelectSubBus({(I2CMux)muxNo, SubBus_None})==I2C_STATUS_OK)
|
||||||
@ -117,8 +117,8 @@ void I2CManagerClass::begin(void) {
|
|||||||
// Enumerate all I2C devices that are connected via multiplexer,
|
// Enumerate all I2C devices that are connected via multiplexer,
|
||||||
// i.e. that respond when only one multiplexer has one subBus enabled
|
// i.e. that respond when only one multiplexer has one subBus enabled
|
||||||
// and the device doesn't respond when the mux subBus is disabled.
|
// and the device doesn't respond when the mux subBus is disabled.
|
||||||
// If any probes time out, then assume that the subbus is dead and
|
// If any probes time out, then assume that the subBus is dead and
|
||||||
// don't do any more on that subbus.
|
// don't do any more on that subBus.
|
||||||
for (uint8_t muxNo=I2CMux_0; muxNo <= I2CMux_7; muxNo++) {
|
for (uint8_t muxNo=I2CMux_0; muxNo <= I2CMux_7; muxNo++) {
|
||||||
uint8_t muxAddr = I2C_MUX_BASE_ADDRESS + muxNo;
|
uint8_t muxAddr = I2C_MUX_BASE_ADDRESS + muxNo;
|
||||||
if (exists(muxAddr)) {
|
if (exists(muxAddr)) {
|
||||||
@ -131,8 +131,8 @@ void I2CManagerClass::begin(void) {
|
|||||||
// De-select subbus
|
// De-select subbus
|
||||||
muxSelectSubBus({(I2CMux)muxNo, SubBus_None});
|
muxSelectSubBus({(I2CMux)muxNo, SubBus_None});
|
||||||
if (!exists(addr)) {
|
if (!exists(addr)) {
|
||||||
// Device responds when subbus selected but not when
|
// Device responds when subBus selected but not when
|
||||||
// subbus disabled - ergo it must be on subbus!
|
// subbus disabled - ergo it must be on subBus!
|
||||||
found = true;
|
found = true;
|
||||||
DIAG(F("I2C Device found at {I2CMux_%d,SubBus_%d,0x%x}, %S?"),
|
DIAG(F("I2C Device found at {I2CMux_%d,SubBus_%d,0x%x}, %S?"),
|
||||||
muxNo, subBus, addr, guessI2CDeviceType(addr));
|
muxNo, subBus, addr, guessI2CDeviceType(addr));
|
||||||
|
@ -171,7 +171,7 @@ enum I2CSubBus : uint8_t {
|
|||||||
SubBus_7 = 7,
|
SubBus_7 = 7,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
SubBus_No, // Number of subbuses (highest + 1)
|
SubBus_No, // Number of sub-buses (highest + 1)
|
||||||
SubBus_None = 254, // Disable all sub-buses on selected mux
|
SubBus_None = 254, // Disable all sub-buses on selected mux
|
||||||
SubBus_All = 255, // Enable all sub-buses (not supported by some multiplexers)
|
SubBus_All = 255, // Enable all sub-buses (not supported by some multiplexers)
|
||||||
};
|
};
|
||||||
@ -344,7 +344,7 @@ private:
|
|||||||
void toHex(const uint8_t value, char *buffer);
|
void toHex(const uint8_t value, char *buffer);
|
||||||
void addressWarning() {
|
void addressWarning() {
|
||||||
if (!_addressWarningDone) {
|
if (!_addressWarningDone) {
|
||||||
DIAG(F("WARNIING: Extended I2C address used but not supported in this configuration"));
|
DIAG(F("WARNING: Extended I2C address used but not supported in this configuration"));
|
||||||
_addressWarningDone = true;
|
_addressWarningDone = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,7 +430,7 @@ public:
|
|||||||
void setClock(uint32_t speed);
|
void setClock(uint32_t speed);
|
||||||
// Force clock speed
|
// Force clock speed
|
||||||
void forceClock(uint32_t speed);
|
void forceClock(uint32_t speed);
|
||||||
// setTimeout sets the timout value for I2C transactions (milliseconds).
|
// setTimeout sets the timeout value for I2C transactions (milliseconds).
|
||||||
void setTimeout(unsigned long);
|
void setTimeout(unsigned long);
|
||||||
// Check if specified I2C address is responding.
|
// Check if specified I2C address is responding.
|
||||||
uint8_t checkAddress(I2CAddress address);
|
uint8_t checkAddress(I2CAddress address);
|
||||||
|
@ -329,7 +329,7 @@ IODevice *IODevice::findDeviceFollowing(VPIN vpin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Private helper function to check for vpin overlap. Run during setup only.
|
// Private helper function to check for vpin overlap. Run during setup only.
|
||||||
// returns true if pins DONT overlap with existing device
|
// returns true if pins DO NOT overlap with existing device
|
||||||
// TODO: Move the I2C address reservation and checks into the I2CManager code.
|
// TODO: Move the I2C address reservation and checks into the I2CManager code.
|
||||||
// That will enable non-HAL devices to reserve I2C addresses too.
|
// That will enable non-HAL devices to reserve I2C addresses too.
|
||||||
bool IODevice::checkNoOverlap(VPIN firstPin, uint8_t nPins, I2CAddress i2cAddress) {
|
bool IODevice::checkNoOverlap(VPIN firstPin, uint8_t nPins, I2CAddress i2cAddress) {
|
||||||
|
@ -83,7 +83,7 @@ private:
|
|||||||
|
|
||||||
void _begin() {
|
void _begin() {
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
// Initialise EX-IOExander device
|
// Initialise EX-IOExpander device
|
||||||
I2CManager.begin();
|
I2CManager.begin();
|
||||||
if (I2CManager.exists(_I2CAddress)) {
|
if (I2CManager.exists(_I2CAddress)) {
|
||||||
// Send config, if EXIOPINS returned, we're good, setup pin buffers, otherwise go offline
|
// Send config, if EXIOPINS returned, we're good, setup pin buffers, otherwise go offline
|
||||||
@ -252,7 +252,7 @@ private:
|
|||||||
// changes and notify them to subscribers, to avoid the need for polling - see IO_GPIOBase.h).
|
// changes and notify them to subscribers, to avoid the need for polling - see IO_GPIOBase.h).
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
reportError(status, false); // report eror but don't go offline.
|
reportError(status, false); // report error but don't go offline.
|
||||||
|
|
||||||
_readState = RDS_IDLE;
|
_readState = RDS_IDLE;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void EXTurntable::_writeAnalogue(VPIN vpin, int value, uint8_t activity, uint16_
|
|||||||
I2CManager.write(_I2CAddress, 3, stepsMSB, stepsLSB, activity);
|
I2CManager.write(_I2CAddress, 3, stepsMSB, stepsLSB, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display Turnetable-EX device driver info.
|
// Display Turntable-EX device driver info.
|
||||||
void EXTurntable::_display() {
|
void EXTurntable::_display() {
|
||||||
DIAG(F("EX-Turntable I2C:%s Configured on Vpins:%u-%u %S"), _I2CAddress.toString(), (int)_firstVpin,
|
DIAG(F("EX-Turntable I2C:%s Configured on Vpins:%u-%u %S"), _I2CAddress.toString(), (int)_firstVpin,
|
||||||
(int)_firstVpin+_nPins-1, (_deviceState==DEVSTATE_FAILED) ? F("OFFLINE") : F(""));
|
(int)_firstVpin+_nPins-1, (_deviceState==DEVSTATE_FAILED) ? F("OFFLINE") : F(""));
|
||||||
|
@ -80,7 +80,7 @@ private:
|
|||||||
// Initiate the device
|
// Initiate the device
|
||||||
void _begin() {
|
void _begin() {
|
||||||
uint8_t _status;
|
uint8_t _status;
|
||||||
// Attempt to initilalise device
|
// Attempt to initialise device
|
||||||
I2CManager.begin();
|
I2CManager.begin();
|
||||||
if (I2CManager.exists(_I2CAddress)) {
|
if (I2CManager.exists(_I2CAddress)) {
|
||||||
// Send RE_RDY, must receive RE_RDY to be online
|
// Send RE_RDY, must receive RE_RDY to be online
|
||||||
|
@ -102,7 +102,7 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i
|
|||||||
getFastPin(F("BRAKE"),brakePin,fastBrakePin);
|
getFastPin(F("BRAKE"),brakePin,fastBrakePin);
|
||||||
// if brake is used for railcom cutout we need to do PORTX register trick here as well
|
// if brake is used for railcom cutout we need to do PORTX register trick here as well
|
||||||
pinMode(brakePin, OUTPUT);
|
pinMode(brakePin, OUTPUT);
|
||||||
setBrake(true); // start with brake on in case we hace DC stuff going on
|
setBrake(true); // start with brake on in case we have DC stuff going on
|
||||||
} else {
|
} else {
|
||||||
brakePin=UNUSED_PIN;
|
brakePin=UNUSED_PIN;
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This conversion performed at compile time so the remainder of the code never needs
|
// This conversion performed at compile time so the remainder of the code never needs
|
||||||
// float calculations or libraray code.
|
// float calculations or library code.
|
||||||
senseFactorInternal=sense_factor * senseScale;
|
senseFactorInternal=sense_factor * senseScale;
|
||||||
tripMilliamps=trip_milliamps;
|
tripMilliamps=trip_milliamps;
|
||||||
#ifdef MAX_CURRENT
|
#ifdef MAX_CURRENT
|
||||||
@ -145,7 +145,7 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i
|
|||||||
// This would mean that the values obtained from the ADC never
|
// This would mean that the values obtained from the ADC never
|
||||||
// can reach the trip value. So independent of the current, the
|
// can reach the trip value. So independent of the current, the
|
||||||
// short circuit protection would never trip. So we adjust the
|
// short circuit protection would never trip. So we adjust the
|
||||||
// trip value so that it is tiggered when the ADC reports it's
|
// trip value so that it is triggered when the ADC reports its
|
||||||
// maximum value instead.
|
// maximum value instead.
|
||||||
|
|
||||||
// DIAG(F("Changing short detection value from %d to %d mA"),
|
// DIAG(F("Changing short detection value from %d to %d mA"),
|
||||||
@ -179,7 +179,7 @@ void MotorDriver::setPower(POWERMODE mode) {
|
|||||||
globalOverloadStart = lastPowerChange[(int)mode];
|
globalOverloadStart = lastPowerChange[(int)mode];
|
||||||
bool on=(mode==POWERMODE::ON || mode ==POWERMODE::ALERT);
|
bool on=(mode==POWERMODE::ON || mode ==POWERMODE::ALERT);
|
||||||
if (on) {
|
if (on) {
|
||||||
// when switching a track On, we need to check the crrentOffset with the pin OFF
|
// when switching a track On, we need to check the currentOffset with the pin OFF
|
||||||
if (powerMode==POWERMODE::OFF && currentPin!=UNUSED_PIN) {
|
if (powerMode==POWERMODE::OFF && currentPin!=UNUSED_PIN) {
|
||||||
senseOffset = ADCee::read(currentPin);
|
senseOffset = ADCee::read(currentPin);
|
||||||
DIAG(F("Track %c sensOffset=%d"),trackLetter,senseOffset);
|
DIAG(F("Track %c sensOffset=%d"),trackLetter,senseOffset);
|
||||||
@ -247,7 +247,7 @@ int MotorDriver::getCurrentRaw(bool fromISR) {
|
|||||||
/*
|
/*
|
||||||
* This should only be called in interrupt context
|
* This should only be called in interrupt context
|
||||||
* Copies current value from HW to cached value in
|
* Copies current value from HW to cached value in
|
||||||
* Motordriver.
|
* MotorDriver.
|
||||||
*/
|
*/
|
||||||
#pragma GCC push_options
|
#pragma GCC push_options
|
||||||
#pragma GCC optimize ("-O3")
|
#pragma GCC optimize ("-O3")
|
||||||
@ -293,7 +293,7 @@ void MotorDriver::setDCSignal(byte speedcode) {
|
|||||||
return;
|
return;
|
||||||
switch(brakePin) {
|
switch(brakePin) {
|
||||||
#if defined(ARDUINO_AVR_UNO)
|
#if defined(ARDUINO_AVR_UNO)
|
||||||
// Not worth doin something here as:
|
// Not worth doing something here as:
|
||||||
// If we are on pin 9 or 10 we are on Timer1 and we can not touch Timer1 as that is our DCC source.
|
// If we are on pin 9 or 10 we are on Timer1 and we can not touch Timer1 as that is our DCC source.
|
||||||
// If we are on pin 5 or 6 we are on Timer 0 ad we can not touch Timer0 as that is millis() etc.
|
// If we are on pin 5 or 6 we are on Timer 0 ad we can not touch Timer0 as that is millis() etc.
|
||||||
// We are most likely not on pin 3 or 11 as no known motor shield has that as brake.
|
// We are most likely not on pin 3 or 11 as no known motor shield has that as brake.
|
||||||
@ -324,7 +324,7 @@ void MotorDriver::setDCSignal(byte speedcode) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// spedcoode is a dcc speed & direction
|
// speedcoode is a dcc speed & direction
|
||||||
byte tSpeed=speedcode & 0x7F; // DCC Speed with 0,1 stop and speed steps 2 to 127
|
byte tSpeed=speedcode & 0x7F; // DCC Speed with 0,1 stop and speed steps 2 to 127
|
||||||
byte tDir=speedcode & 0x80;
|
byte tDir=speedcode & 0x80;
|
||||||
byte brake;
|
byte brake;
|
||||||
@ -461,7 +461,7 @@ void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & res
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// checkPowerOverload(useProgLimit, trackno)
|
// checkPowerOverload(useProgLimit, trackno)
|
||||||
// bool useProgLimit: Trackmanager knows if this track is in prog mode or in main mode
|
// bool useProgLimit: Trackmanager knows if this track is in prog mode or in main mode
|
||||||
// byte trackno: trackmanager knows it's number (could be skipped?)
|
// byte trackno: trackmanager knows its number (could be skipped?)
|
||||||
//
|
//
|
||||||
// Short ciruit handling strategy:
|
// Short ciruit handling strategy:
|
||||||
//
|
//
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
// STANDARD shield on an ESPDUINO-32 (ESP32 in Uno form factor). The shield must be eiter the
|
// STANDARD shield on an ESPDUINO-32 (ESP32 in Uno form factor). The shield must be either the
|
||||||
// 3.3V compatible R3 version or it has to be modified to not supply more than 3.3V to the
|
// 3.3V compatible R3 version or it has to be modified to not supply more than 3.3V to the
|
||||||
// analog inputs. Here we use analog inputs A2 and A3 as A0 and A1 are wired in a way so that
|
// analog inputs. Here we use analog inputs A2 and A3 as A0 and A1 are wired in a way so that
|
||||||
// they are not useable at the same time as WiFi (what a bummer). The numbers below are the
|
// they are not useable at the same time as WiFi (what a bummer). The numbers below are the
|
||||||
@ -118,7 +118,7 @@
|
|||||||
// pins 9 and 10 work as "inverted brake" but as we turn on and off the tracks individually
|
// pins 9 and 10 work as "inverted brake" but as we turn on and off the tracks individually
|
||||||
// via the power pins we above use 9 and 10 as power pins and 4 as "inverted brake" which in this
|
// via the power pins we above use 9 and 10 as power pins and 4 as "inverted brake" which in this
|
||||||
// version of the code always will be high. That means this config is not usable for generating
|
// version of the code always will be high. That means this config is not usable for generating
|
||||||
// a railcom cuotout in the future. For that one must wire the second ^D2 to pin 2 and define
|
// a railcom cutout in the future. For that one must wire the second ^D2 to pin 2 and define
|
||||||
// the motor driver like this:
|
// the motor driver like this:
|
||||||
// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12)
|
// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12)
|
||||||
// new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, 12)
|
// new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, 12)
|
||||||
@ -171,7 +171,7 @@
|
|||||||
new MotorDriver(5, 4, UNUSED_PIN, UNUSED_PIN, UNUSED_PIN, 1.0, 1100, UNUSED_PIN)
|
new MotorDriver(5, 4, UNUSED_PIN, UNUSED_PIN, UNUSED_PIN, 1.0, 1100, UNUSED_PIN)
|
||||||
|
|
||||||
// This is an example how to setup a motor shield definition for a motor shield connected
|
// This is an example how to setup a motor shield definition for a motor shield connected
|
||||||
// to an NANO EVERY board. You have to make the connectons from the shield to the board
|
// to an NANO EVERY board. You have to make the connections from the shield to the board
|
||||||
// as in this example or adjust the values yourself.
|
// as in this example or adjust the values yourself.
|
||||||
#define NANOEVERY_EXAMPLE F("NANOEVERY_EXAMPLE"), \
|
#define NANOEVERY_EXAMPLE F("NANOEVERY_EXAMPLE"), \
|
||||||
new MotorDriver(5, 6, UNUSED_PIN, UNUSED_PIN, A0, 2.99, 1500, UNUSED_PIN),\
|
new MotorDriver(5, 6, UNUSED_PIN, UNUSED_PIN, A0, 2.99, 1500, UNUSED_PIN),\
|
||||||
@ -180,7 +180,7 @@
|
|||||||
// This is an example how to stack two standard motor shields. The upper shield
|
// This is an example how to stack two standard motor shields. The upper shield
|
||||||
// needs pins 3 8 9 11 12 13 A0 A1 disconnected from the lower shield and
|
// needs pins 3 8 9 11 12 13 A0 A1 disconnected from the lower shield and
|
||||||
// jumpered instead like this: 2-3 6-8 7-9 4-13 5-11 10-12 A0-A4 A1-A5
|
// jumpered instead like this: 2-3 6-8 7-9 4-13 5-11 10-12 A0-A4 A1-A5
|
||||||
// Pin assigment table:
|
// Pin assignment table:
|
||||||
// 2 Enable C jumpered
|
// 2 Enable C jumpered
|
||||||
// 3 Enable A direct
|
// 3 Enable A direct
|
||||||
// 4 Dir D jumpered
|
// 4 Dir D jumpered
|
||||||
|
10
Outputs.cpp
10
Outputs.cpp
@ -23,7 +23,7 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
||||||
DCC++ BASE STATION supports optional OUTPUT control of any unused Arduino Pins for custom purposes.
|
DCC++ BASE STATION supports optional OUTPUT control of any unused Arduino Pins for custom purposes.
|
||||||
Pins can be activited or de-activated. The default is to set ACTIVE pins HIGH and INACTIVE pins LOW.
|
Pins can be activated or de-activated. The default is to set ACTIVE pins HIGH and INACTIVE pins LOW.
|
||||||
However, this default behavior can be inverted for any pin in which case ACTIVE=LOW and INACTIVE=HIGH.
|
However, this default behavior can be inverted for any pin in which case ACTIVE=LOW and INACTIVE=HIGH.
|
||||||
|
|
||||||
Definitions and state (ACTIVE/INACTIVE) for pins are retained in EEPROM and restored on power-up.
|
Definitions and state (ACTIVE/INACTIVE) for pins are retained in EEPROM and restored on power-up.
|
||||||
@ -35,9 +35,9 @@ To have this sketch utilize one or more Arduino pins as custom outputs, first de
|
|||||||
output definitions using the following variation of the "Z" command:
|
output definitions using the following variation of the "Z" command:
|
||||||
|
|
||||||
<Z ID PIN IFLAG>: creates a new output ID, with specified PIN and IFLAG values.
|
<Z ID PIN IFLAG>: creates a new output ID, with specified PIN and IFLAG values.
|
||||||
if output ID already exists, it is updated with specificed PIN and IFLAG.
|
if output ID already exists, it is updated with specified PIN and IFLAG.
|
||||||
note: output state will be immediately set to ACTIVE/INACTIVE and pin will be set to HIGH/LOW
|
note: output state will be immediately set to ACTIVE/INACTIVE and pin will be set to HIGH/LOW
|
||||||
according to IFLAG value specifcied (see below).
|
according to IFLAG value specified (see below).
|
||||||
returns: <O> if successful and <X> if unsuccessful (e.g. out of memory)
|
returns: <O> if successful and <X> if unsuccessful (e.g. out of memory)
|
||||||
|
|
||||||
<Z ID>: deletes definition of output ID
|
<Z ID>: deletes definition of output ID
|
||||||
@ -61,8 +61,8 @@ where
|
|||||||
1 = state of pin set on power-up, or when first created, to either ACTIVE of INACTIVE
|
1 = state of pin set on power-up, or when first created, to either ACTIVE of INACTIVE
|
||||||
depending on IFLAG, bit 2
|
depending on IFLAG, bit 2
|
||||||
|
|
||||||
IFLAG, bit 2: 0 = state of pin set to INACTIVE uponm power-up or when first created
|
IFLAG, bit 2: 0 = state of pin set to INACTIVE upon power-up or when first created
|
||||||
1 = state of pin set to ACTIVE uponm power-up or when first created
|
1 = state of pin set to ACTIVE upon power-up or when first created
|
||||||
|
|
||||||
Once all outputs have been properly defined, use the <E> command to store their definitions to EEPROM.
|
Once all outputs have been properly defined, use the <E> command to store their definitions to EEPROM.
|
||||||
If you later make edits/additions/deletions to the output definitions, you must invoke the <E> command if you want those
|
If you later make edits/additions/deletions to the output definitions, you must invoke the <E> command if you want those
|
||||||
|
@ -6,7 +6,7 @@ Currently, our products include the following:
|
|||||||
* [EX-CommandStation](https://github.com/DCC-EX/CommandStation-EX/releases)
|
* [EX-CommandStation](https://github.com/DCC-EX/CommandStation-EX/releases)
|
||||||
* [EX-WebThrottle](https://github.com/DCC-EX/exWebThrottle)
|
* [EX-WebThrottle](https://github.com/DCC-EX/exWebThrottle)
|
||||||
* [EX-Installer](https://github.com/DCC-EX/EX-Installer)
|
* [EX-Installer](https://github.com/DCC-EX/EX-Installer)
|
||||||
* [EX-MotoShield8874](https://dcc-ex.com/reference/hardware/motorboards/ex-motor-shield-8874.html#gsc.tab=0)
|
* [EX-MotorShield8874](https://dcc-ex.com/reference/hardware/motorboards/ex-motor-shield-8874.html#gsc.tab=0)
|
||||||
* [EX-DCCInspector](https://github.com/DCC-EX/DCCInspector-EX)
|
* [EX-DCCInspector](https://github.com/DCC-EX/DCCInspector-EX)
|
||||||
* [EX-Toolbox](https://github.com/DCC-EX/EX-Toolbox)
|
* [EX-Toolbox](https://github.com/DCC-EX/EX-Toolbox)
|
||||||
* [EX-Turntable](https://github.com/DCC-EX/EX-Turntable)
|
* [EX-Turntable](https://github.com/DCC-EX/EX-Turntable)
|
||||||
@ -18,7 +18,7 @@ Details of these projects can be found on [our web site](https://dcc-ex.com/).
|
|||||||
|
|
||||||
# What’s in this Repository?
|
# What’s in this Repository?
|
||||||
|
|
||||||
This repository, CommandStation-EX, contains a complete DCC-EX *EX-CommmandStation* sketch designed for compiling and uploading into an Arduino Uno, Mega, or Nano.
|
This repository, CommandStation-EX, contains a complete DCC-EX *EX-CommandStation* sketch designed for compiling and uploading into an Arduino Uno, Mega, or Nano.
|
||||||
|
|
||||||
To utilize this sketch, you can use the following:
|
To utilize this sketch, you can use the following:
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ Track Manger (TM from now on) is an integral part of DCC++EX software that is re
|
|||||||
- Intercepting throttle commands to locos running on DC tracks.
|
- Intercepting throttle commands to locos running on DC tracks.
|
||||||
- Handling user or EXRAIL commands to switch track status.
|
- Handling user or EXRAIL commands to switch track status.
|
||||||
|
|
||||||
In the default scenario of a single DCC track and a PROG track, the TM behaves as for the previous versions of DCC++EX so if thats what you want, you dont need to mess with it.
|
In the default scenario of a single DCC track and a PROG track, the TM behaves as for the previous versions of DCC++EX so if thats what you want, you don't need to mess with it.
|
||||||
|
|
||||||
The TM is able to handle up to 8 separate track domains. Each domain requires a hardware driver to supply track voltage. A typical motor driver shield supplies two tracks, which is what we have used in the past as main and prog.
|
The TM is able to handle up to 8 separate track domains. Each domain requires a hardware driver to supply track voltage. A typical motor driver shield supplies two tracks, which is what we have used in the past as main and prog.
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ The easiest way to consider the wiring is to treat each track individually (eith
|
|||||||
You will require,for each track, on the Arduino:
|
You will require,for each track, on the Arduino:
|
||||||
- A GPIO pin (or a HAL vpin perhaps on an I2C extender, code TBA!!!) to switch power.
|
- A GPIO pin (or a HAL vpin perhaps on an I2C extender, code TBA!!!) to switch power.
|
||||||
- A GPIO pin to switch the signal direction
|
- A GPIO pin to switch the signal direction
|
||||||
- A GPIO pin with PWM capability to switch the Brake (you may omit this if you dont want any DC capability)
|
- A GPIO pin with PWM capability to switch the Brake (you may omit this if you don't want any DC capability)
|
||||||
- Optionally An Analog pin to read the current (unless your hardware cant do that, perhaps its just feeding a booster)
|
- Optionally An Analog pin to read the current (unless your hardware cant do that, perhaps its just feeding a booster)
|
||||||
- Optionally a GPIO fault pin if thats how your hardware works. (NOT recommended as you're going to run out of pins)
|
- Optionally a GPIO fault pin if thats how your hardware works. (NOT recommended as you're going to run out of pins)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
// NOTE: The use of a marker byte without an escape algorithm means
|
// NOTE: The use of a marker byte without an escape algorithm means
|
||||||
// RingStream is unsuitable for binary data. Should binary data need to be
|
// RingStream is unsuitable for binary data. Should binary data need to be
|
||||||
// streamed it will be necessary to implementr an escape strategy to handle the
|
// streamed it will be necessary to implement an escape strategy to handle the
|
||||||
// marker char when embedded in data.
|
// marker char when embedded in data.
|
||||||
|
|
||||||
#include "RingStream.h"
|
#include "RingStream.h"
|
||||||
|
@ -31,11 +31,11 @@ class RingStream : public Print {
|
|||||||
virtual size_t write(uint8_t b);
|
virtual size_t write(uint8_t b);
|
||||||
|
|
||||||
// This availableForWrite function is subverted from its original intention so that a caller
|
// This availableForWrite function is subverted from its original intention so that a caller
|
||||||
// can destinguish between a normal stream and a RingStream.
|
// can distinguish between a normal stream and a RingStream.
|
||||||
// The Arduino compiler does not support runtime dynamic cast to perform
|
// The Arduino compiler does not support runtime dynamic cast to perform
|
||||||
// an instranceOf check.
|
// an instanceOf check.
|
||||||
// This is necessary since the Print functions are mostly not virtual so
|
// This is necessary since the Print functions are mostly not virtual so
|
||||||
// we cant override the print(__FlashStringHelper *) function.
|
// we can't override the print(__FlashStringHelper *) function.
|
||||||
virtual int availableForWrite() override;
|
virtual int availableForWrite() override;
|
||||||
using Print::write;
|
using Print::write;
|
||||||
size_t printFlash(const FSH * flashBuffer);
|
size_t printFlash(const FSH * flashBuffer);
|
||||||
|
@ -81,7 +81,7 @@ public:
|
|||||||
static void checkAll();
|
static void checkAll();
|
||||||
static void printAll(Print *stream);
|
static void printAll(Print *stream);
|
||||||
static unsigned long lastReadCycle; // value of micros at start of last read cycle
|
static unsigned long lastReadCycle; // value of micros at start of last read cycle
|
||||||
static const unsigned int cycleInterval = 10000; // min time between consecutive reads of each sensor in microsecs.
|
static const unsigned int cycleInterval = 10000; // min time between consecutive reads of each sensor in microseconds.
|
||||||
// should not be less than device scan cycle time.
|
// should not be less than device scan cycle time.
|
||||||
static const unsigned int minReadCount = 1; // number of additional scans before acting on change
|
static const unsigned int minReadCount = 1; // number of additional scans before acting on change
|
||||||
// E.g. 1 means that a change is ignored for one scan and actioned on the next.
|
// E.g. 1 means that a change is ignored for one scan and actioned on the next.
|
||||||
|
@ -76,8 +76,8 @@ void TrackManager::sampleCurrent() {
|
|||||||
if (tr > lastTrack) tr = 0;
|
if (tr > lastTrack) tr = 0;
|
||||||
if (lastTrack < 2 || track[tr]->getMode() & 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 because
|
||||||
// that gives us well defined sampling point.
|
// that gives us a well defined sampling point.
|
||||||
// For other tracks we care less unless we
|
// For other tracks we care less unless we
|
||||||
// have only few (max 2) tracks.
|
// have only few (max 2) tracks.
|
||||||
}
|
}
|
||||||
@ -231,14 +231,14 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
|
|||||||
}
|
}
|
||||||
track[trackToSet]->makeProgTrack(true); // set for prog track special handling
|
track[trackToSet]->makeProgTrack(true); // set for prog track special handling
|
||||||
} else {
|
} else {
|
||||||
track[trackToSet]->makeProgTrack(false); // only the prog track knows it's type
|
track[trackToSet]->makeProgTrack(false); // only the prog track knows its type
|
||||||
}
|
}
|
||||||
track[trackToSet]->setMode(mode);
|
track[trackToSet]->setMode(mode);
|
||||||
trackDCAddr[trackToSet]=dcAddr;
|
trackDCAddr[trackToSet]=dcAddr;
|
||||||
streamTrackState(NULL,trackToSet);
|
streamTrackState(NULL,trackToSet);
|
||||||
|
|
||||||
// When a track is switched, we must clear any side effects of its previous
|
// When a track is switched, we must clear any side effects of its previous
|
||||||
// state, otherwise trains run away or just dont move.
|
// state, otherwise trains run away or just don't move.
|
||||||
|
|
||||||
// This can be done BEFORE the PWM-Timer evaluation (methinks)
|
// This can be done BEFORE the PWM-Timer evaluation (methinks)
|
||||||
if (!(mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX)) {
|
if (!(mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX)) {
|
||||||
@ -374,7 +374,7 @@ void TrackManager::streamTrackState(Print* stream, byte t) {
|
|||||||
format=F("<= %c DCX %d>\n");
|
format=F("<= %c DCX %d>\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break; // unknown, dont care
|
break; // unknown, don't care
|
||||||
}
|
}
|
||||||
if (stream) StringFormatter::send(stream,format,'A'+t,trackDCAddr[t]);
|
if (stream) StringFormatter::send(stream,format,'A'+t,trackDCAddr[t]);
|
||||||
else CommandDistributor::broadcastTrackState(format,'A'+t,trackDCAddr[t]);
|
else CommandDistributor::broadcastTrackState(format,'A'+t,trackDCAddr[t]);
|
||||||
|
@ -393,7 +393,7 @@ void WiThrottle::checkHeartbeat(RingStream * stream) {
|
|||||||
if (myLocos[loco].throttle!='\0') {
|
if (myLocos[loco].throttle!='\0') {
|
||||||
if (Diag::WITHROTTLE) DIAG(F("%l eStopping cab %d"),millis(),myLocos[loco].cab);
|
if (Diag::WITHROTTLE) DIAG(F("%l eStopping cab %d"),millis(),myLocos[loco].cab);
|
||||||
DCC::setThrottle(myLocos[loco].cab, 1, DCC::getThrottleDirection(myLocos[loco].cab)); // speed 1 is eStop
|
DCC::setThrottle(myLocos[loco].cab, 1, DCC::getThrottleDirection(myLocos[loco].cab)); // speed 1 is eStop
|
||||||
heartBeat=millis(); // We have just stopped everyting, we don't need to do that again at next loop.
|
heartBeat=millis(); // We have just stopped everything, we don't need to do that again at next loop.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if it does come back, the throttle should re-acquire
|
// if it does come back, the throttle should re-acquire
|
||||||
@ -419,7 +419,7 @@ void WiThrottle::checkHeartbeat(RingStream * stream) {
|
|||||||
StringFormatter::send(stream,F("M%cA%c%d<;>R%d\n"),
|
StringFormatter::send(stream,F("M%cA%c%d<;>R%d\n"),
|
||||||
throttle, lors , cab, DCC::getThrottleDirection(cab));
|
throttle, lors , cab, DCC::getThrottleDirection(cab));
|
||||||
|
|
||||||
// compare the DCC functionmap with the local copy and send changes
|
// compare the DCC function map with the local copy and send changes
|
||||||
uint32_t dccFunctionMap=DCC::getFunctionMap(cab);
|
uint32_t dccFunctionMap=DCC::getFunctionMap(cab);
|
||||||
uint32_t myFunctionMap=myLocos[loco].functionMap;
|
uint32_t myFunctionMap=myLocos[loco].functionMap;
|
||||||
myLocos[loco].functionMap=dccFunctionMap;
|
myLocos[loco].functionMap=dccFunctionMap;
|
||||||
|
@ -136,7 +136,7 @@ bool WifiESP::setup(const char *SSid,
|
|||||||
// clean start
|
// clean start
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.disconnect(true);
|
WiFi.disconnect(true);
|
||||||
// differnet settings that did not improve for haba
|
// different settings that did not improve for haba
|
||||||
// WiFi.useStaticBuffers(true);
|
// WiFi.useStaticBuffers(true);
|
||||||
// WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
// WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
||||||
// WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SECURITY);
|
// WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SECURITY);
|
||||||
@ -376,7 +376,7 @@ void WifiESP::loop() {
|
|||||||
// is not necessarily yielding to a low
|
// is not necessarily yielding to a low
|
||||||
// prio task. On core1 this is not a problem
|
// prio task. On core1 this is not a problem
|
||||||
// as there the wdt is disabled by the
|
// as there the wdt is disabled by the
|
||||||
// arduio IDE startup routines.
|
// arduino IDE startup routines.
|
||||||
if (xPortGetCoreID() == 0)
|
if (xPortGetCoreID() == 0)
|
||||||
feedTheDog0();
|
feedTheDog0();
|
||||||
yield();
|
yield();
|
||||||
|
@ -120,7 +120,7 @@ bool WifiInterface::setup(long serial_link_speed,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We guess here that in all architctures that have a Serial3
|
// We guess here that in all architectures that have a Serial3
|
||||||
// we can use it for our purpose.
|
// we can use it for our purpose.
|
||||||
#if NUM_SERIAL > 2 && !defined(SERIAL3_COMMANDS)
|
#if NUM_SERIAL > 2 && !defined(SERIAL3_COMMANDS)
|
||||||
if (wifiUp == WIFI_NOAT)
|
if (wifiUp == WIFI_NOAT)
|
||||||
@ -255,7 +255,7 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password,
|
|||||||
} else {
|
} else {
|
||||||
// later version supports CWJAP_CUR
|
// later version supports CWJAP_CUR
|
||||||
StringFormatter::send(wifiStream, F("AT+CWHOSTNAME=\"%S\"\r\n"), hostname); // Set Host name for Wifi Client
|
StringFormatter::send(wifiStream, F("AT+CWHOSTNAME=\"%S\"\r\n"), hostname); // Set Host name for Wifi Client
|
||||||
checkForOK(2000, true); // dont care if not supported
|
checkForOK(2000, true); // don't care if not supported
|
||||||
|
|
||||||
StringFormatter::send(wifiStream, F("AT+CWJAP_CUR=\"%S\",\"%S\"\r\n"), SSid, password);
|
StringFormatter::send(wifiStream, F("AT+CWJAP_CUR=\"%S\",\"%S\"\r\n"), SSid, password);
|
||||||
ipOK = checkForOK(WIFI_CONNECT_TIMEOUT, true);
|
ipOK = checkForOK(WIFI_CONNECT_TIMEOUT, true);
|
||||||
@ -340,7 +340,7 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password,
|
|||||||
if(!oldCmd) { // no idea to test this on old firmware
|
if(!oldCmd) { // no idea to test this on old firmware
|
||||||
StringFormatter::send(wifiStream, F("AT+MDNS=1,\"%S\",\"withrottle\",%d\r\n"),
|
StringFormatter::send(wifiStream, F("AT+MDNS=1,\"%S\",\"withrottle\",%d\r\n"),
|
||||||
hostname, port); // mDNS responder
|
hostname, port); // mDNS responder
|
||||||
checkForOK(1000, true); // dont care if not supported
|
checkForOK(1000, true); // don't care if not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
StringFormatter::send(wifiStream, F("AT+CIPSERVER=1,%d\r\n"), port); // turn on server on port
|
StringFormatter::send(wifiStream, F("AT+CIPSERVER=1,%d\r\n"), port); // turn on server on port
|
||||||
@ -379,7 +379,7 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password,
|
|||||||
// This function is used to allow users to enter <+ commands> through the DCCEXParser
|
// This function is used to allow users to enter <+ commands> through the DCCEXParser
|
||||||
// <+command> sends AT+command to the ES and returns to the caller.
|
// <+command> sends AT+command to the ES and returns to the caller.
|
||||||
// Once the user has made whatever changes to the AT commands, a <+X> command can be used
|
// Once the user has made whatever changes to the AT commands, a <+X> command can be used
|
||||||
// to force on the connectd flag so that the loop will start picking up wifi traffic.
|
// to force on the connected flag so that the loop will start picking up wifi traffic.
|
||||||
// If the settings are corrupted <+RST> will clear this and then you must restart the arduino.
|
// If the settings are corrupted <+RST> will clear this and then you must restart the arduino.
|
||||||
|
|
||||||
// Using the <+> command with no command string causes the code to enter an echo loop so that all
|
// Using the <+> command with no command string causes the code to enter an echo loop so that all
|
||||||
@ -410,7 +410,7 @@ void WifiInterface::ATCommand(HardwareSerial * stream,const byte * command) {
|
|||||||
|
|
||||||
if (*command=='X') {
|
if (*command=='X') {
|
||||||
connected = true;
|
connected = true;
|
||||||
DIAG(F("++++++ Wifi Connction forced on ++++++++"));
|
DIAG(F("++++++ Wifi Connection forced on ++++++++"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StringFormatter:: send(wifiStream, F("AT+%s\r\n"), command);
|
StringFormatter:: send(wifiStream, F("AT+%s\r\n"), command);
|
||||||
|
@ -64,7 +64,7 @@ The configuration file for DCC-EX Command Station
|
|||||||
// If you want to restrict the maximum current LOWER than what your
|
// If you want to restrict the maximum current LOWER than what your
|
||||||
// motor shield can provide, you can do that here. For example if you
|
// motor shield can provide, you can do that here. For example if you
|
||||||
// have a motor shield that can provide 5A and your power supply can
|
// have a motor shield that can provide 5A and your power supply can
|
||||||
// only provide 2.5A then you should restict the maximum current to
|
// only provide 2.5A then you should restrict the maximum current to
|
||||||
// 2.25A (90% of 2.5A) so that DCC-EX does shut off the track before
|
// 2.25A (90% of 2.5A) so that DCC-EX does shut off the track before
|
||||||
// your PS does shut DCC-EX. MAX_CURRENT is in mA so for this example
|
// your PS does shut DCC-EX. MAX_CURRENT is in mA so for this example
|
||||||
// it would be 2250, adjust the number according to your PS. If your
|
// it would be 2250, adjust the number according to your PS. If your
|
||||||
@ -224,7 +224,7 @@ The configuration file for DCC-EX Command Station
|
|||||||
|
|
||||||
// If you have issues with that the direction of the accessory commands is
|
// If you have issues with that the direction of the accessory commands is
|
||||||
// reversed (for example when converting from another CS to DCC-EX) then
|
// reversed (for example when converting from another CS to DCC-EX) then
|
||||||
// you can use this to reverse the sense of all accessory commmands sent
|
// you can use this to reverse the sense of all accessory commands sent
|
||||||
// over DCC++. This #define likewise inverts the behaviour of the <a> command
|
// over DCC++. This #define likewise inverts the behaviour of the <a> command
|
||||||
// for triggering DCC Accessory Decoders, so that <a addr subaddr 0> generates a
|
// for triggering DCC Accessory Decoders, so that <a addr subaddr 0> generates a
|
||||||
// DCC packet with D=1 (close turnout) and <a addr subaddr 1> generates D=0
|
// DCC packet with D=1 (close turnout) and <a addr subaddr 1> generates D=0
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
// 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
|
||||||
// 4.2.67 - AVR: Pin specific timer register seting
|
// 4.2.67 - AVR: Pin specific timer register setting
|
||||||
// - Protect Uno user from choosing DC(X)
|
// - Protect Uno user from choosing DC(X)
|
||||||
// - More Nucleo variant defines
|
// - More Nucleo variant defines
|
||||||
// - GPIO PCA9555 / TCA9555 support
|
// - GPIO PCA9555 / TCA9555 support
|
||||||
@ -68,7 +68,7 @@
|
|||||||
// 4.2.34 - Completely fix EX-IOExpander analogue inputs
|
// 4.2.34 - Completely fix EX-IOExpander analogue inputs
|
||||||
// 4.2.33 - Fix EX-IOExpander non-working analogue inputs
|
// 4.2.33 - Fix EX-IOExpander non-working analogue inputs
|
||||||
// 4.2.32 - Fix LCD/Display bugfixes from 4.2.29
|
// 4.2.32 - Fix LCD/Display bugfixes from 4.2.29
|
||||||
// 4.2.31 - Removes EXRAIL statup from top of file. (BREAKING CHANGE !!)
|
// 4.2.31 - Removes EXRAIL startup from top of file. (BREAKING CHANGE !!)
|
||||||
// Just add AUTOSTART to the top of your myAutomation.h to restore this function.
|
// Just add AUTOSTART to the top of your myAutomation.h to restore this function.
|
||||||
// 4.2.30 - Fixes/enhancements to EX-IOExpander device driver.
|
// 4.2.30 - Fixes/enhancements to EX-IOExpander device driver.
|
||||||
// 4.2.29 - Bugfix Scroll LCD without empty lines and consistent
|
// 4.2.29 - Bugfix Scroll LCD without empty lines and consistent
|
||||||
@ -189,7 +189,7 @@
|
|||||||
// EX-RAIL “ROSTER” Engines Id & Function key layout on Engine Driver or WiThrottle
|
// EX-RAIL “ROSTER” Engines Id & Function key layout on Engine Driver or WiThrottle
|
||||||
// EX-RAIL DCC++EX Commands to Control EX-RAIL via JMRI Send pane and IDE Serial monitors
|
// EX-RAIL DCC++EX Commands to Control EX-RAIL via JMRI Send pane and IDE Serial monitors
|
||||||
// New JMRI feature enhancements;
|
// New JMRI feature enhancements;
|
||||||
// Reads DCC++EX EEPROM & automatically uploades any Signals, DCC Turnouts, Servo Turnouts, Vpin Turnouts , & Output pane
|
// Reads DCC++EX EEPROM & automatically uploads any Signals, DCC Turnouts, Servo Turnouts, Vpin Turnouts , & Output pane
|
||||||
// Turnout class revised to expand turnout capabilities, new commands added.
|
// Turnout class revised to expand turnout capabilities, new commands added.
|
||||||
// Provides for multiple additional DCC++EX WiFi connections as accessory controllers or CS for a programming track when Motor Shields are added
|
// Provides for multiple additional DCC++EX WiFi connections as accessory controllers or CS for a programming track when Motor Shields are added
|
||||||
// Supports Multiple Command Station connections and individual tracking of Send DCC++ Command panes and DCC++ Traffic Monitor panes
|
// Supports Multiple Command Station connections and individual tracking of Send DCC++ Command panes and DCC++ Traffic Monitor panes
|
||||||
@ -213,7 +213,7 @@
|
|||||||
// Can define border between long and short addresses
|
// Can define border between long and short addresses
|
||||||
// Turnout and accessory states (thrown/closed = 0/1 or 1/0) can be set to match RCN-213
|
// Turnout and accessory states (thrown/closed = 0/1 or 1/0) can be set to match RCN-213
|
||||||
// Bugfix: one-off error in CIPSEND drop
|
// Bugfix: one-off error in CIPSEND drop
|
||||||
// Bugfix: disgnostic display of ack pulses >32kus
|
// Bugfix: diagnostic display of ack pulses >32kus
|
||||||
// Bugfix: Current read from wrong ADC during interrupt
|
// Bugfix: Current read from wrong ADC during interrupt
|
||||||
// 3.2.0 Development Release Includes all of 3.1.1 thru 3.1.7 enhancements
|
// 3.2.0 Development Release Includes all of 3.1.1 thru 3.1.7 enhancements
|
||||||
// 3.1.7 Bugfix: Unknown locos should have speed forward
|
// 3.1.7 Bugfix: Unknown locos should have speed forward
|
||||||
|
Loading…
Reference in New Issue
Block a user