mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-23 08:06:13 +01:00
format/indentation change only
This commit is contained in:
parent
1934fdd0e1
commit
b0915e8332
|
@ -41,9 +41,8 @@ void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream
|
||||||
ringClient=stream->peekTargetMark();
|
ringClient=stream->peekTargetMark();
|
||||||
if (buffer[0] == '<') {
|
if (buffer[0] == '<') {
|
||||||
clients[clientId]=COMMAND_TYPE;
|
clients[clientId]=COMMAND_TYPE;
|
||||||
DCCEXParser::parse(stream, buffer, ring);
|
DCCEXParser::parse(stream, buffer, ring);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
clients[clientId]=WITHROTTLE_TYPE;
|
clients[clientId]=WITHROTTLE_TYPE;
|
||||||
WiThrottle::getThrottle(clientId)->parse(ring, buffer);
|
WiThrottle::getThrottle(clientId)->parse(ring, buffer);
|
||||||
}
|
}
|
||||||
|
@ -68,32 +67,32 @@ void CommandDistributor::broadcast(bool includeWithrottleClients) {
|
||||||
if (ringClient!=NO_CLIENT) ring->commit();
|
if (ringClient!=NO_CLIENT) ring->commit();
|
||||||
|
|
||||||
/* loop through ring clients */
|
/* loop through ring clients */
|
||||||
for (byte clientId=0; clientId<sizeof(clients); clientId++) {
|
for (byte clientId=0; clientId<sizeof(clients); clientId++) {
|
||||||
if (clients[clientId]==NONE_TYPE) continue;
|
if (clients[clientId]==NONE_TYPE) continue;
|
||||||
if ( clients[clientId]==WITHROTTLE_TYPE && !includeWithrottleClients) continue;
|
if ( clients[clientId]==WITHROTTLE_TYPE && !includeWithrottleClients) continue;
|
||||||
ring->mark(clientId);
|
ring->mark(clientId);
|
||||||
broadcastBufferWriter->printBuffer(ring);
|
broadcastBufferWriter->printBuffer(ring);
|
||||||
ring->commit();
|
ring->commit();
|
||||||
}
|
}
|
||||||
if (ringClient!=NO_CLIENT) ring->mark(ringClient);
|
if (ringClient!=NO_CLIENT) ring->mark(ringClient);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
broadcastBufferWriter->flush();
|
broadcastBufferWriter->flush();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// For a UNO/NANO we can broadcast direct to just one Serial instead of the ring
|
// For a UNO/NANO we can broadcast direct to just one Serial instead of the ring
|
||||||
// Redirect ring output ditrect to Serial
|
// Redirect ring output ditrect to Serial
|
||||||
#define broadcastBufferWriter &Serial
|
#define broadcastBufferWriter &Serial
|
||||||
// and ignore the internal broadcast call.
|
// and ignore the internal broadcast call.
|
||||||
void CommandDistributor::broadcast(bool includeWithrottleClients) {
|
void CommandDistributor::broadcast(bool includeWithrottleClients) {
|
||||||
(void)includeWithrottleClients;
|
(void)includeWithrottleClients;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
|
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
|
||||||
StringFormatter::send(broadcastBufferWriter,F("<%c %d>\n"), on?'Q':'q', id);
|
StringFormatter::send(broadcastBufferWriter,F("<%c %d>\n"), on?'Q':'q', id);
|
||||||
broadcast(false);
|
broadcast(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
|
void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
|
||||||
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
|
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
|
||||||
|
@ -104,12 +103,12 @@ void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
|
||||||
StringFormatter::send(broadcastBufferWriter,F("PTA%c%d\n"), isClosed?'2':'4', id);
|
StringFormatter::send(broadcastBufferWriter,F("PTA%c%d\n"), isClosed?'2':'4', id);
|
||||||
#endif
|
#endif
|
||||||
broadcast(true);
|
broadcast(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandDistributor::broadcastLoco(byte slot) {
|
void CommandDistributor::broadcastLoco(byte slot) {
|
||||||
DCC::LOCO * sp=&DCC::speedTable[slot];
|
DCC::LOCO * sp=&DCC::speedTable[slot];
|
||||||
StringFormatter::send(broadcastBufferWriter,F("<l %d %d %d %l>\n"),
|
StringFormatter::send(broadcastBufferWriter,F("<l %d %d %d %l>\n"),
|
||||||
sp->loco,slot,sp->speedCode,sp->functions);
|
sp->loco,slot,sp->speedCode,sp->functions);
|
||||||
broadcast(false);
|
broadcast(false);
|
||||||
#if defined(WIFI_ON) | defined(ETHERNET_ON)
|
#if defined(WIFI_ON) | defined(ETHERNET_ON)
|
||||||
WiThrottle::markForBroadcast(sp->loco);
|
WiThrottle::markForBroadcast(sp->loco);
|
||||||
|
@ -133,5 +132,3 @@ void CommandDistributor::broadcastPower() {
|
||||||
LCD(2,F("Power %S%S"),state=='1'?F("On"):F("Off"),reason);
|
LCD(2,F("Power %S%S"),state=='1'?F("On"):F("Off"),reason);
|
||||||
broadcast(true);
|
broadcast(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ void setup()
|
||||||
// This block is still executed for DIAGS if LCD not in use
|
// This block is still executed for DIAGS if LCD not in use
|
||||||
LCD(0,F("DCC++ EX v%S"),F(VERSION));
|
LCD(0,F("DCC++ EX v%S"),F(VERSION));
|
||||||
LCD(1,F("Lic GPLv3"));
|
LCD(1,F("Lic GPLv3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Responsibility 2: Start all the communications before the DCC engine
|
// Responsibility 2: Start all the communications before the DCC engine
|
||||||
// Start the WiFi interface on a MEGA, Uno cannot currently handle WiFi
|
// Start the WiFi interface on a MEGA, Uno cannot currently handle WiFi
|
||||||
|
@ -96,14 +96,14 @@ void setup()
|
||||||
// Invoke any DCC++EX commands in the form "SETUP("xxxx");"" found in optional file mySetup.h.
|
// Invoke any DCC++EX commands in the form "SETUP("xxxx");"" found in optional file mySetup.h.
|
||||||
// This can be used to create turnouts, outputs, sensors etc. through the normal text commands.
|
// This can be used to create turnouts, outputs, sensors etc. through the normal text commands.
|
||||||
#if __has_include ( "mySetup.h")
|
#if __has_include ( "mySetup.h")
|
||||||
#define SETUP(cmd) DCCEXParser::parse(F(cmd))
|
#define SETUP(cmd) DCCEXParser::parse(F(cmd))
|
||||||
#include "mySetup.h"
|
#include "mySetup.h"
|
||||||
#undef SETUP
|
#undef SETUP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LCN_SERIAL)
|
#if defined(LCN_SERIAL)
|
||||||
LCN_SERIAL.begin(115200);
|
LCN_SERIAL.begin(115200);
|
||||||
LCN::init(LCN_SERIAL);
|
LCN::init(LCN_SERIAL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LCD(3,F("Ready"));
|
LCD(3,F("Ready"));
|
||||||
|
@ -121,7 +121,7 @@ void loop()
|
||||||
// Responsibility 2: handle any incoming commands on USB connection
|
// Responsibility 2: handle any incoming commands on USB connection
|
||||||
SerialManager::loop();
|
SerialManager::loop();
|
||||||
|
|
||||||
// Responsibility 3: Optionally handle any incoming WiFi traffic
|
// Responsibility 3: Optionally handle any incoming WiFi traffic
|
||||||
#if WIFI_ON
|
#if WIFI_ON
|
||||||
WifiInterface::loop();
|
WifiInterface::loop();
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,7 +132,7 @@ void loop()
|
||||||
RMFT::loop(); // ignored if no automation
|
RMFT::loop(); // ignored if no automation
|
||||||
|
|
||||||
#if defined(LCN_SERIAL)
|
#if defined(LCN_SERIAL)
|
||||||
LCN::loop();
|
LCN::loop();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LCDDisplay::loop(); // ignored if LCD not in use
|
LCDDisplay::loop(); // ignored if LCD not in use
|
||||||
|
@ -146,8 +146,7 @@ void loop()
|
||||||
static int ramLowWatermark = __INT_MAX__; // replaced on first loop
|
static int ramLowWatermark = __INT_MAX__; // replaced on first loop
|
||||||
|
|
||||||
int freeNow = minimumFreeMemory();
|
int freeNow = minimumFreeMemory();
|
||||||
if (freeNow < ramLowWatermark)
|
if (freeNow < ramLowWatermark) {
|
||||||
{
|
|
||||||
ramLowWatermark = freeNow;
|
ramLowWatermark = freeNow;
|
||||||
LCD(3,F("Free RAM=%5db"), ramLowWatermark);
|
LCD(3,F("Free RAM=%5db"), ramLowWatermark);
|
||||||
}
|
}
|
||||||
|
|
2
DCC.cpp
2
DCC.cpp
|
@ -200,7 +200,7 @@ void DCC::changeFn( int cab, int16_t functionNumber) {
|
||||||
if (reg<0) return;
|
if (reg<0) return;
|
||||||
unsigned long funcmask = (1UL<<functionNumber);
|
unsigned long funcmask = (1UL<<functionNumber);
|
||||||
speedTable[reg].functions ^= funcmask;
|
speedTable[reg].functions ^= funcmask;
|
||||||
updateGroupflags(speedTable[reg].groupFlags, functionNumber);
|
updateGroupflags(speedTable[reg].groupFlags, functionNumber);
|
||||||
CommandDistributor::broadcastLoco(reg);
|
CommandDistributor::broadcastLoco(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
577
WiThrottle.cpp
577
WiThrottle.cpp
|
@ -117,11 +117,11 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
||||||
for(Turnout *tt=Turnout::first();tt!=NULL;tt=tt->next()){
|
for(Turnout *tt=Turnout::first();tt!=NULL;tt=tt->next()){
|
||||||
int id=tt->getId();
|
int id=tt->getId();
|
||||||
StringFormatter::send(stream,F("]\\[%d}|{"), id);
|
StringFormatter::send(stream,F("]\\[%d}|{"), id);
|
||||||
#ifdef RMFT_ACTIVE
|
#ifdef RMFT_ACTIVE
|
||||||
RMFT2::emitTurnoutDescription(stream,id);
|
RMFT2::emitTurnoutDescription(stream,id);
|
||||||
#else
|
#else
|
||||||
StringFormatter::send(stream,F("%d"), id);
|
StringFormatter::send(stream,F("%d"), id);
|
||||||
#endif
|
#endif
|
||||||
StringFormatter::send(stream,F("}|{%c"), Turnout::isClosed(id)?'2':'4');
|
StringFormatter::send(stream,F("}|{%c"), Turnout::isClosed(id)?'2':'4');
|
||||||
}
|
}
|
||||||
StringFormatter::send(stream,F("\n"));
|
StringFormatter::send(stream,F("\n"));
|
||||||
|
@ -134,105 +134,104 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
||||||
#ifdef RMFT_ACTIVE
|
#ifdef RMFT_ACTIVE
|
||||||
RMFT2::emitWithrottleRouteList(stream);
|
RMFT2::emitWithrottleRouteList(stream);
|
||||||
#endif
|
#endif
|
||||||
// allow heartbeat to slow down once all metadata sent
|
// allow heartbeat to slow down once all metadata sent
|
||||||
StringFormatter::send(stream,F("*%d\n"),HEARTBEAT_SECONDS);
|
StringFormatter::send(stream,F("*%d\n"),HEARTBEAT_SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cmd[0]) {
|
while (cmd[0]) {
|
||||||
switch (cmd[0]) {
|
switch (cmd[0]) {
|
||||||
case '*': // heartbeat control
|
case '*': // heartbeat control
|
||||||
if (cmd[1]=='+') heartBeatEnable=true;
|
if (cmd[1]=='+') heartBeatEnable=true;
|
||||||
else if (cmd[1]=='-') heartBeatEnable=false;
|
else if (cmd[1]=='-') heartBeatEnable=false;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if (cmd[1]=='P' && cmd[2]=='A' ) { //PPA power mode
|
if (cmd[1]=='P' && cmd[2]=='A' ) { //PPA power mode
|
||||||
DCCWaveform::mainTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
DCCWaveform::mainTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
||||||
if (MotorDriver::commonFaultPin) // commonFaultPin prevents individual track handling
|
if (MotorDriver::commonFaultPin) // commonFaultPin prevents individual track handling
|
||||||
DCCWaveform::progTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
DCCWaveform::progTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
||||||
CommandDistributor::broadcastPower();
|
CommandDistributor::broadcastPower();
|
||||||
}
|
}
|
||||||
#if defined(RMFT_ACTIVE)
|
#if defined(RMFT_ACTIVE)
|
||||||
else if (cmd[1]=='R' && cmd[2]=='A' && cmd[3]=='2' ) { // Route activate
|
else if (cmd[1]=='R' && cmd[2]=='A' && cmd[3]=='2' ) { // Route activate
|
||||||
// exrail routes are RA2Rn , Animations are RA2An
|
// exrail routes are RA2Rn , Animations are RA2An
|
||||||
int route=getInt(cmd+5);
|
int route=getInt(cmd+5);
|
||||||
uint16_t cab=cmd[4]=='A' ? mostRecentCab : 0;
|
uint16_t cab=cmd[4]=='A' ? mostRecentCab : 0;
|
||||||
RMFT2::createNewTask(route, cab);
|
RMFT2::createNewTask(route, cab);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (cmd[1]=='T' && cmd[2]=='A') { // PTA accessory toggle
|
else if (cmd[1]=='T' && cmd[2]=='A') { // PTA accessory toggle
|
||||||
int id=getInt(cmd+4);
|
int id=getInt(cmd+4);
|
||||||
if (!Turnout::exists(id)) {
|
if (!Turnout::exists(id)) {
|
||||||
// If turnout does not exist, create it
|
// If turnout does not exist, create it
|
||||||
int addr = ((id - 1) / 4) + 1;
|
int addr = ((id - 1) / 4) + 1;
|
||||||
int subaddr = (id - 1) % 4;
|
int subaddr = (id - 1) % 4;
|
||||||
DCCTurnout::create(id,addr,subaddr);
|
DCCTurnout::create(id,addr,subaddr);
|
||||||
StringFormatter::send(stream, F("HmTurnout %d created\n"),id);
|
StringFormatter::send(stream, F("HmTurnout %d created\n"),id);
|
||||||
}
|
}
|
||||||
switch (cmd[3]) {
|
switch (cmd[3]) {
|
||||||
// T and C according to RCN-213 where 0 is Stop, Red, Thrown, Diverging.
|
// T and C according to RCN-213 where 0 is Stop, Red, Thrown, Diverging.
|
||||||
case 'T':
|
case 'T':
|
||||||
Turnout::setClosed(id,false);
|
Turnout::setClosed(id,false);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
Turnout::setClosed(id,true);
|
Turnout::setClosed(id,true);
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
Turnout::setClosed(id,!Turnout::isClosed(id));
|
Turnout::setClosed(id,!Turnout::isClosed(id));
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
Turnout::setClosed(id,true);
|
Turnout::setClosed(id,true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
StringFormatter::send(stream, F("PTA%c%d\n"),Turnout::isClosed(id)?'2':'4',id );
|
StringFormatter::send(stream, F("PTA%c%d\n"),Turnout::isClosed(id)?'2':'4',id );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'N': // Heartbeat (2), only send if connection completed by 'HU' message
|
case 'N': // Heartbeat (2), only send if connection completed by 'HU' message
|
||||||
if (initSent) {
|
if (initSent) {
|
||||||
StringFormatter::send(stream, F("*%d\n"),HEARTBEAT_SECONDS); // return timeout value
|
StringFormatter::send(stream, F("*%d\n"),HEARTBEAT_SECONDS); // return timeout value
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'M': // multithrottle
|
case 'M': // multithrottle
|
||||||
multithrottle(stream, cmd);
|
multithrottle(stream, cmd);
|
||||||
break;
|
break;
|
||||||
case 'H': // send initial connection info after receiving "HU" message
|
case 'H': // send initial connection info after receiving "HU" message
|
||||||
if (cmd[1] == 'U') {
|
if (cmd[1] == 'U') {
|
||||||
StringFormatter::send(stream,F("VN2.0\nHTDCC-EX\nRL0\n"));
|
StringFormatter::send(stream,F("VN2.0\nHTDCC-EX\nRL0\n"));
|
||||||
StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA));
|
StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA));
|
||||||
StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[THROW}|{2]\\[CLOSE}|{4\n"));
|
StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[THROW}|{2]\\[CLOSE}|{4\n"));
|
||||||
StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON);
|
StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON);
|
||||||
#ifdef RMFT_ACTIVE
|
#ifdef RMFT_ACTIVE
|
||||||
RMFT2::emitWithrottleRoster(stream);
|
RMFT2::emitWithrottleRoster(stream);
|
||||||
#endif
|
#endif
|
||||||
// set heartbeat to 1 second because we need to sync the metadata
|
// set heartbeat to 1 second because we need to sync the metadata
|
||||||
StringFormatter::send(stream,F("*1\n"));
|
StringFormatter::send(stream,F("*1\n"));
|
||||||
initSent = true;
|
initSent = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Q': //
|
case 'Q': //
|
||||||
LOOPLOCOS('*', -1) { // tell client to drop any locos still assigned to this WiThrottle
|
LOOPLOCOS('*', -1) { // tell client to drop any locos still assigned to this WiThrottle
|
||||||
if (myLocos[loco].throttle!='\0') {
|
if (myLocos[loco].throttle!='\0') {
|
||||||
StringFormatter::send(stream, F("M%c-%c%d<;>\n"), myLocos[loco].throttle, LorS(myLocos[loco].cab), myLocos[loco].cab);
|
StringFormatter::send(stream, F("M%c-%c%d<;>\n"), myLocos[loco].throttle, LorS(myLocos[loco].cab), myLocos[loco].cab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) Quit"),millis(),clientid);
|
if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) Quit"),millis(),clientid);
|
||||||
delete this;
|
delete this;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// skip over cmd until 0 or past \r or \n
|
|
||||||
while(*cmd !='\0' && *cmd != '\r' && *cmd !='\n') cmd++;
|
|
||||||
if (*cmd!='\0') cmd++; // skip \r or \n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int WiThrottle::getInt(byte * cmd) {
|
|
||||||
int i=0;
|
|
||||||
while (cmd[0]>='0' && cmd[0]<='9') {
|
|
||||||
i=i*10 + (cmd[0]-'0');
|
|
||||||
cmd++;
|
|
||||||
}
|
}
|
||||||
return i;
|
// skip over cmd until 0 or past \r or \n
|
||||||
|
while(*cmd !='\0' && *cmd != '\r' && *cmd !='\n') cmd++;
|
||||||
|
if (*cmd!='\0') cmd++; // skip \r or \n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WiThrottle::getInt(byte * cmd) {
|
||||||
|
int i=0;
|
||||||
|
while (cmd[0]>='0' && cmd[0]<='9') {
|
||||||
|
i=i*10 + (cmd[0]-'0');
|
||||||
|
cmd++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WiThrottle::getLocoId(byte * cmd) {
|
int WiThrottle::getLocoId(byte * cmd) {
|
||||||
|
@ -242,183 +241,183 @@ int WiThrottle::getLocoId(byte * cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
|
void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
|
||||||
char throttleChar=cmd[1];
|
char throttleChar=cmd[1];
|
||||||
int locoid=getLocoId(cmd+3); // -1 for *
|
int locoid=getLocoId(cmd+3); // -1 for *
|
||||||
byte * aval=cmd;
|
byte * aval=cmd;
|
||||||
while(*aval !=';' && *aval !='\0') aval++;
|
while(*aval !=';' && *aval !='\0') aval++;
|
||||||
if (*aval) aval+=2; // skip ;>
|
if (*aval) aval+=2; // skip ;>
|
||||||
|
|
||||||
// DIAG(F("Multithrottle aval=%c cab=%d"), aval[0],locoid);
|
// DIAG(F("Multithrottle aval=%c cab=%d"), aval[0],locoid);
|
||||||
switch(cmd[2]) {
|
switch(cmd[2]) {
|
||||||
case '+': // add loco request
|
case '+': // add loco request
|
||||||
if (cmd[3]=='*') {
|
if (cmd[3]=='*') {
|
||||||
// M+* means get loco from prog track, then join tracks ready to drive away
|
// M+* means get loco from prog track, then join tracks ready to drive away
|
||||||
// Stash the things the callback will need later
|
// Stash the things the callback will need later
|
||||||
stashStream= stream;
|
stashStream= stream;
|
||||||
stashClient=stream->peekTargetMark();
|
stashClient=stream->peekTargetMark();
|
||||||
stashThrottleChar=throttleChar;
|
stashThrottleChar=throttleChar;
|
||||||
stashInstance=this;
|
stashInstance=this;
|
||||||
// ask DCC to call us back when the loco id has been read
|
// ask DCC to call us back when the loco id has been read
|
||||||
DCC::getLocoId(getLocoCallback); // will remove any previous join
|
DCC::getLocoId(getLocoCallback); // will remove any previous join
|
||||||
return; // return nothing in stream as response is sent later in the callback
|
return; // return nothing in stream as response is sent later in the callback
|
||||||
}
|
}
|
||||||
//return error if address zero requested
|
//return error if address zero requested
|
||||||
if (locoid==0) {
|
if (locoid==0) {
|
||||||
StringFormatter::send(stream, F("HMAddress '0' not supported!\n"), cmd[3] ,locoid);
|
StringFormatter::send(stream, F("HMAddress '0' not supported!\n"), cmd[3] ,locoid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//return error if L or S from request doesn't match DCC++ assumptions
|
//return error if L or S from request doesn't match DCC++ assumptions
|
||||||
if (cmd[3] != LorS(locoid)) {
|
if (cmd[3] != LorS(locoid)) {
|
||||||
StringFormatter::send(stream, F("HMLength '%c' not valid for %d!\n"), cmd[3] ,locoid);
|
StringFormatter::send(stream, F("HMLength '%c' not valid for %d!\n"), cmd[3] ,locoid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//use first empty "slot" on this client's list, will be added to DCC registration list
|
//use first empty "slot" on this client's list, will be added to DCC registration list
|
||||||
for (int loco=0;loco<MAX_MY_LOCO;loco++) {
|
for (int loco=0;loco<MAX_MY_LOCO;loco++) {
|
||||||
if (myLocos[loco].throttle=='\0') {
|
if (myLocos[loco].throttle=='\0') {
|
||||||
myLocos[loco].throttle=throttleChar;
|
myLocos[loco].throttle=throttleChar;
|
||||||
myLocos[loco].cab=locoid;
|
myLocos[loco].cab=locoid;
|
||||||
myLocos[loco].functionMap=DCC::getFunctionMap(locoid);
|
myLocos[loco].functionMap=DCC::getFunctionMap(locoid);
|
||||||
myLocos[loco].broadcastPending=true; // means speed/dir will be sent later
|
myLocos[loco].broadcastPending=true; // means speed/dir will be sent later
|
||||||
mostRecentCab=locoid;
|
mostRecentCab=locoid;
|
||||||
StringFormatter::send(stream, F("M%c+%c%d<;>\n"), throttleChar, cmd[3] ,locoid); //tell client to add loco
|
StringFormatter::send(stream, F("M%c+%c%d<;>\n"), throttleChar, cmd[3] ,locoid); //tell client to add loco
|
||||||
int fkeys=29;
|
int fkeys=29;
|
||||||
myLocos[loco].functionToggles=1<<2; // F2 (HORN) is a non-toggle
|
myLocos[loco].functionToggles=1<<2; // F2 (HORN) is a non-toggle
|
||||||
|
|
||||||
#ifdef RMFT_ACTIVE
|
#ifdef RMFT_ACTIVE
|
||||||
const char * functionNames=(char *) RMFT2::getRosterFunctions(locoid);
|
const char * functionNames=(char *) RMFT2::getRosterFunctions(locoid);
|
||||||
if (!functionNames) {
|
if (!functionNames) {
|
||||||
// no roster, use presets as above
|
// no roster, use presets as above
|
||||||
}
|
}
|
||||||
else if (GETFLASH(functionNames)=='\0') {
|
else if (GETFLASH(functionNames)=='\0') {
|
||||||
// "" = Roster but no functions given
|
// "" = Roster but no functions given
|
||||||
fkeys=0;
|
fkeys=0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// we have function names...
|
// we have function names...
|
||||||
// scan names list emitting names, counting functions and
|
// scan names list emitting names, counting functions and
|
||||||
// flagging non-toggling things like horn.
|
// flagging non-toggling things like horn.
|
||||||
myLocos[loco].functionToggles =0;
|
myLocos[loco].functionToggles =0;
|
||||||
StringFormatter::send(stream, F("M%cL%c%d<;>]\\["), throttleChar,cmd[3],locoid);
|
StringFormatter::send(stream, F("M%cL%c%d<;>]\\["), throttleChar,cmd[3],locoid);
|
||||||
fkeys=0;
|
fkeys=0;
|
||||||
bool firstchar=true;
|
bool firstchar=true;
|
||||||
for (int fx=0;;fx++) {
|
for (int fx=0;;fx++) {
|
||||||
char c=GETFLASH(functionNames+fx);
|
char c=GETFLASH(functionNames+fx);
|
||||||
if (c=='\0') {
|
if (c=='\0') {
|
||||||
fkeys++;
|
fkeys++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c=='/') {
|
if (c=='/') {
|
||||||
fkeys++;
|
fkeys++;
|
||||||
StringFormatter::send(stream,F("]\\["));
|
StringFormatter::send(stream,F("]\\["));
|
||||||
firstchar=true;
|
firstchar=true;
|
||||||
}
|
}
|
||||||
else if (firstchar && c=='*') {
|
else if (firstchar && c=='*') {
|
||||||
myLocos[loco].functionToggles |= 1UL<<fkeys;
|
myLocos[loco].functionToggles |= 1UL<<fkeys;
|
||||||
firstchar=false;
|
firstchar=false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
firstchar=false;
|
firstchar=false;
|
||||||
stream->write(c);
|
stream->write(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StringFormatter::send(stream,F("\n"));
|
StringFormatter::send(stream,F("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(int fKey=0; fKey<fkeys; fKey++) {
|
for(int fKey=0; fKey<fkeys; fKey++) {
|
||||||
int fstate=DCC::getFn(locoid,fKey);
|
int fstate=DCC::getFn(locoid,fKey);
|
||||||
if (fstate>=0) StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,fstate,fKey);
|
if (fstate>=0) StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,fstate,fKey);
|
||||||
}
|
}
|
||||||
//speed and direction will be published at next broadcast cycle
|
//speed and direction will be published at next broadcast cycle
|
||||||
StringFormatter::send(stream, F("M%cA%c%d<;>s1\n"), throttleChar, cmd[3], locoid); //default speed step 128
|
StringFormatter::send(stream, F("M%cA%c%d<;>s1\n"), throttleChar, cmd[3], locoid); //default speed step 128
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StringFormatter::send(stream, F("HMMax locos (%d) exceeded, %d not added!\n"), MAX_MY_LOCO ,locoid);
|
StringFormatter::send(stream, F("HMMax locos (%d) exceeded, %d not added!\n"), MAX_MY_LOCO ,locoid);
|
||||||
break;
|
break;
|
||||||
case '-': // remove loco(s) from this client (leave in DCC registration)
|
case '-': // remove loco(s) from this client (leave in DCC registration)
|
||||||
LOOPLOCOS(throttleChar, locoid) {
|
LOOPLOCOS(throttleChar, locoid) {
|
||||||
myLocos[loco].throttle='\0';
|
myLocos[loco].throttle='\0';
|
||||||
StringFormatter::send(stream, F("M%c-%c%d<;>\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab);
|
StringFormatter::send(stream, F("M%c-%c%d<;>\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
locoAction(stream,aval, throttleChar, locoid);
|
locoAction(stream,aval, throttleChar, locoid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar, int cab){
|
void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar, int cab){
|
||||||
// Note cab=-1 for all cabs in the consist called throttleChar.
|
// Note cab=-1 for all cabs in the consist called throttleChar.
|
||||||
// DIAG(F("Loco Action aval=%c%c throttleChar=%c, cab=%d"), aval[0],aval[1],throttleChar, cab);
|
// DIAG(F("Loco Action aval=%c%c throttleChar=%c, cab=%d"), aval[0],aval[1],throttleChar, cab);
|
||||||
(void) stream;
|
(void) stream;
|
||||||
switch (aval[0]) {
|
switch (aval[0]) {
|
||||||
case 'V': // Vspeed
|
case 'V': // Vspeed
|
||||||
{
|
{
|
||||||
int witSpeed=getInt(aval+1);
|
int witSpeed=getInt(aval+1);
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
mostRecentCab=myLocos[loco].cab;
|
mostRecentCab=myLocos[loco].cab;
|
||||||
DCC::setThrottle(myLocos[loco].cab, WiTToDCCSpeed(witSpeed), DCC::getThrottleDirection(myLocos[loco].cab));
|
DCC::setThrottle(myLocos[loco].cab, WiTToDCCSpeed(witSpeed), DCC::getThrottleDirection(myLocos[loco].cab));
|
||||||
// SetThrottle will cause speed change broadcast
|
// SetThrottle will cause speed change broadcast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'F': // Function key pressed/released
|
case 'F': // Function key pressed/released
|
||||||
{
|
{
|
||||||
bool pressed=aval[1]=='1';
|
bool pressed=aval[1]=='1';
|
||||||
int fKey = getInt(aval+2);
|
int fKey = getInt(aval+2);
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
bool unsetOnRelease = myLocos[loco].functionToggles & (1L<<fKey);
|
bool unsetOnRelease = myLocos[loco].functionToggles & (1L<<fKey);
|
||||||
if (unsetOnRelease) DCC::setFn(myLocos[loco].cab,fKey, pressed);
|
if (unsetOnRelease) DCC::setFn(myLocos[loco].cab,fKey, pressed);
|
||||||
else if (pressed) DCC::changeFn(myLocos[loco].cab, fKey);
|
else if (pressed) DCC::changeFn(myLocos[loco].cab, fKey);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'q':
|
case 'q':
|
||||||
if (aval[1]=='V' || aval[1]=='R' ) { //qV or qR
|
if (aval[1]=='V' || aval[1]=='R' ) { //qV or qR
|
||||||
// just flag the loco for broadcast and it will happen.
|
// just flag the loco for broadcast and it will happen.
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
myLocos[loco].broadcastPending=true;
|
myLocos[loco].broadcastPending=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
{
|
{
|
||||||
bool forward=aval[1]!='0';
|
bool forward=aval[1]!='0';
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
mostRecentCab=myLocos[loco].cab;
|
mostRecentCab=myLocos[loco].cab;
|
||||||
DCC::setThrottle(myLocos[loco].cab, DCC::getThrottleSpeed(myLocos[loco].cab), forward);
|
DCC::setThrottle(myLocos[loco].cab, DCC::getThrottleSpeed(myLocos[loco].cab), forward);
|
||||||
// setThrottle will cause a broadcast so notification will be sent
|
// setThrottle will cause a broadcast so notification will be sent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
//Emergency Stop (speed code 1)
|
//Emergency Stop (speed code 1)
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
DCC::setThrottle(myLocos[loco].cab, 1, DCC::getThrottleDirection(myLocos[loco].cab));
|
DCC::setThrottle(myLocos[loco].cab, 1, DCC::getThrottleDirection(myLocos[loco].cab));
|
||||||
// setThrottle will cause a broadcast so notification will be sent
|
// setThrottle will cause a broadcast so notification will be sent
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'I': // Idle, set speed to 0
|
case 'I': // Idle, set speed to 0
|
||||||
case 'Q': // Quit, set speed to 0
|
case 'Q': // Quit, set speed to 0
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
mostRecentCab=myLocos[loco].cab;
|
mostRecentCab=myLocos[loco].cab;
|
||||||
DCC::setThrottle(myLocos[loco].cab, 0, DCC::getThrottleDirection(myLocos[loco].cab));
|
DCC::setThrottle(myLocos[loco].cab, 0, DCC::getThrottleDirection(myLocos[loco].cab));
|
||||||
// setThrottle will cause a broadcast so notification will be sent
|
// setThrottle will cause a broadcast so notification will be sent
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert between DCC++ speed values and WiThrottle speed values
|
// convert between DCC++ speed values and WiThrottle speed values
|
||||||
int WiThrottle::DCCToWiTSpeed(int DCCSpeed) {
|
int WiThrottle::DCCToWiTSpeed(int DCCSpeed) {
|
||||||
if (DCCSpeed == 0) return 0; //stop is stop
|
if (DCCSpeed == 0) return 0; //stop is stop
|
||||||
if (DCCSpeed == 1) return -1; //eStop value
|
if (DCCSpeed == 1) return -1; //eStop value
|
||||||
return DCCSpeed - 1; //offset others by 1
|
return DCCSpeed - 1; //offset others by 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert between WiThrottle speed values and DCC++ speed values
|
// convert between WiThrottle speed values and DCC++ speed values
|
||||||
int WiThrottle::WiTToDCCSpeed(int WiTSpeed) {
|
int WiThrottle::WiTToDCCSpeed(int WiTSpeed) {
|
||||||
if (WiTSpeed == 0) return 0; //stop is stop
|
if (WiTSpeed == 0) return 0; //stop is stop
|
||||||
if (WiTSpeed == -1) return 1; //eStop value
|
if (WiTSpeed == -1) return 1; //eStop value
|
||||||
|
@ -428,7 +427,7 @@ int WiThrottle::WiTToDCCSpeed(int WiTSpeed) {
|
||||||
void WiThrottle::loop(RingStream * stream) {
|
void WiThrottle::loop(RingStream * stream) {
|
||||||
// for each WiThrottle, check the heartbeat and broadcast needed
|
// for each WiThrottle, check the heartbeat and broadcast needed
|
||||||
for (WiThrottle* wt=firstThrottle; wt!=NULL ; wt=wt->nextThrottle)
|
for (WiThrottle* wt=firstThrottle; wt!=NULL ; wt=wt->nextThrottle)
|
||||||
wt->checkHeartbeat(stream);
|
wt->checkHeartbeat(stream);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -436,7 +435,7 @@ void WiThrottle::loop(RingStream * stream) {
|
||||||
void WiThrottle::checkHeartbeat(RingStream * stream) {
|
void WiThrottle::checkHeartbeat(RingStream * stream) {
|
||||||
// if eStop time passed... eStop any locos still assigned to this client and then drop the connection
|
// if eStop time passed... eStop any locos still assigned to this client and then drop the connection
|
||||||
if(heartBeatEnable && (millis()-heartBeat > ESTOP_SECONDS*1000)) {
|
if(heartBeatEnable && (millis()-heartBeat > ESTOP_SECONDS*1000)) {
|
||||||
if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) eStop(%ds) timeout, drop connection"), millis(), clientid, ESTOP_SECONDS);
|
if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) eStop(%ds) timeout, drop connection"), millis(), clientid, ESTOP_SECONDS);
|
||||||
LOOPLOCOS('*', -1) {
|
LOOPLOCOS('*', -1) {
|
||||||
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);
|
||||||
|
@ -445,45 +444,45 @@ void WiThrottle::checkHeartbeat(RingStream * stream) {
|
||||||
}
|
}
|
||||||
delete this;
|
delete this;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send any outstanding speed/direction/function changes for this clients locos
|
// send any outstanding speed/direction/function changes for this clients locos
|
||||||
// Changes may have been caused by this client, or another non-Withrottle or Exrail
|
// Changes may have been caused by this client, or another non-Withrottle or Exrail
|
||||||
bool streamHasBeenMarked=false;
|
bool streamHasBeenMarked=false;
|
||||||
LOOPLOCOS('*', -1) {
|
LOOPLOCOS('*', -1) {
|
||||||
if (myLocos[loco].throttle!='\0' && myLocos[loco].broadcastPending) {
|
if (myLocos[loco].throttle!='\0' && myLocos[loco].broadcastPending) {
|
||||||
if (!streamHasBeenMarked) {
|
if (!streamHasBeenMarked) {
|
||||||
stream->mark(clientid);
|
stream->mark(clientid);
|
||||||
streamHasBeenMarked=true;
|
streamHasBeenMarked=true;
|
||||||
}
|
}
|
||||||
myLocos[loco].broadcastPending=false;
|
myLocos[loco].broadcastPending=false;
|
||||||
int cab=myLocos[loco].cab;
|
int cab=myLocos[loco].cab;
|
||||||
char lors=LorS(cab);
|
char lors=LorS(cab);
|
||||||
char throttle=myLocos[loco].throttle;
|
char throttle=myLocos[loco].throttle;
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>V%d\n"),
|
StringFormatter::send(stream,F("M%cA%c%d<;>V%d\n"),
|
||||||
throttle, lors , cab, DCCToWiTSpeed(DCC::getThrottleSpeed(cab)));
|
throttle, lors , cab, DCCToWiTSpeed(DCC::getThrottleSpeed(cab)));
|
||||||
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 functionmap 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;
|
||||||
|
|
||||||
// loop the maps sending any bit changed
|
// loop the maps sending any bit changed
|
||||||
// Loop is terminated as soon as no changes are left
|
// Loop is terminated as soon as no changes are left
|
||||||
for (byte fn=0;dccFunctionMap!=myFunctionMap;fn++) {
|
for (byte fn=0;dccFunctionMap!=myFunctionMap;fn++) {
|
||||||
if ((dccFunctionMap&1) != (myFunctionMap&1)) {
|
if ((dccFunctionMap&1) != (myFunctionMap&1)) {
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>F%c%d\n"),
|
StringFormatter::send(stream,F("M%cA%c%d<;>F%c%d\n"),
|
||||||
throttle, lors , cab, (dccFunctionMap&1)?'1':'0',fn);
|
throttle, lors , cab, (dccFunctionMap&1)?'1':'0',fn);
|
||||||
}
|
}
|
||||||
// shift just checked bit off end of both maps
|
// shift just checked bit off end of both maps
|
||||||
dccFunctionMap>>=1;
|
dccFunctionMap>>=1;
|
||||||
myFunctionMap>>=1;
|
myFunctionMap>>=1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (streamHasBeenMarked) stream->commit();
|
}
|
||||||
|
if (streamHasBeenMarked) stream->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiThrottle::markForBroadcast(int cab) {
|
void WiThrottle::markForBroadcast(int cab) {
|
||||||
|
@ -492,13 +491,13 @@ void WiThrottle::markForBroadcast(int cab) {
|
||||||
}
|
}
|
||||||
void WiThrottle::markForBroadcast2(int cab) {
|
void WiThrottle::markForBroadcast2(int cab) {
|
||||||
LOOPLOCOS('*', cab) {
|
LOOPLOCOS('*', cab) {
|
||||||
myLocos[loco].broadcastPending=true;
|
myLocos[loco].broadcastPending=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char WiThrottle::LorS(int cab) {
|
char WiThrottle::LorS(int cab) {
|
||||||
return (cab<=HIGHEST_SHORT_ADDR)?'S':'L';
|
return (cab<=HIGHEST_SHORT_ADDR)?'S':'L';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drive Away feature. Callback handling
|
// Drive Away feature. Callback handling
|
||||||
|
|
|
@ -335,10 +335,10 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password,
|
||||||
void WifiInterface::ATCommand(HardwareSerial * stream,const byte * command) {
|
void WifiInterface::ATCommand(HardwareSerial * stream,const byte * command) {
|
||||||
command++;
|
command++;
|
||||||
if (*command=='\0') { // User gave <+> command
|
if (*command=='\0') { // User gave <+> command
|
||||||
stream->print(F("\nES AT command passthrough mode, use ! to exit\n"));
|
stream->print(F("\nES AT command passthrough mode, use ! to exit\n"));
|
||||||
while(stream->available()) stream->read(); // Drain serial input first
|
while(stream->available()) stream->read(); // Drain serial input first
|
||||||
bool startOfLine=true;
|
bool startOfLine=true;
|
||||||
while(true) {
|
while(true) {
|
||||||
while (wifiStream->available()) stream->write(wifiStream->read());
|
while (wifiStream->available()) stream->write(wifiStream->read());
|
||||||
if (stream->available()) {
|
if (stream->available()) {
|
||||||
int cx=stream->read();
|
int cx=stream->read();
|
||||||
|
@ -348,19 +348,19 @@ void WifiInterface::ATCommand(HardwareSerial * stream,const byte * command) {
|
||||||
else startOfLine=false;
|
else startOfLine=false;
|
||||||
stream->write(cx);
|
stream->write(cx);
|
||||||
wifiStream->write(cx);
|
wifiStream->write(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stream->print(F("Passthrough Ended"));
|
stream->print(F("Passthrough Ended"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*command=='X') {
|
if (*command=='X') {
|
||||||
connected = true;
|
connected = true;
|
||||||
DIAG(F("++++++ Wifi Connction forced on ++++++++"));
|
DIAG(F("++++++ Wifi Connction forced on ++++++++"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StringFormatter:: send(wifiStream, F("AT+%s\r\n"), command);
|
StringFormatter:: send(wifiStream, F("AT+%s\r\n"), command);
|
||||||
checkForOK(10000, true);
|
checkForOK(10000, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user