diff --git a/DCCpp_Uno/Accessories.cpp b/DCCpp/Accessories.cpp similarity index 99% rename from DCCpp_Uno/Accessories.cpp rename to DCCpp/Accessories.cpp index b027508..ec1f0bd 100644 --- a/DCCpp_Uno/Accessories.cpp +++ b/DCCpp/Accessories.cpp @@ -61,7 +61,7 @@ the directions of any Turnouts being monitored or controlled by a separate inter #include "Accessories.h" #include "SerialCommand.h" -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "EEStore.h" #include #include "Comm.h" @@ -85,7 +85,7 @@ void Turnout::activate(int s){ /////////////////////////////////////////////////////////////////////////////// -Turnout* Turnout::get(int n){ +Turnout *Turnout::get(int n){ Turnout *tt; for(tt=firstTurnout;tt!=NULL && tt->data.id!=n;tt=tt->nextTurnout); return(tt); diff --git a/DCCpp_Uno/Accessories.h b/DCCpp/Accessories.h similarity index 100% rename from DCCpp_Uno/Accessories.h rename to DCCpp/Accessories.h diff --git a/DCCpp_Uno/Comm.h b/DCCpp/Comm.h similarity index 100% rename from DCCpp_Uno/Comm.h rename to DCCpp/Comm.h diff --git a/DCCpp_Uno/Config.h b/DCCpp/Config.h similarity index 100% rename from DCCpp_Uno/Config.h rename to DCCpp/Config.h diff --git a/DCCpp_Uno/CurrentMonitor.cpp b/DCCpp/CurrentMonitor.cpp similarity index 98% rename from DCCpp_Uno/CurrentMonitor.cpp rename to DCCpp/CurrentMonitor.cpp index 5149d2a..efdb83a 100644 --- a/DCCpp_Uno/CurrentMonitor.cpp +++ b/DCCpp/CurrentMonitor.cpp @@ -7,7 +7,7 @@ Part of DCC++ BASE STATION for the Arduino **********************************************************************/ -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "CurrentMonitor.h" #include "Comm.h" diff --git a/DCCpp_Uno/CurrentMonitor.h b/DCCpp/CurrentMonitor.h similarity index 100% rename from DCCpp_Uno/CurrentMonitor.h rename to DCCpp/CurrentMonitor.h diff --git a/DCCpp_Uno/DCCpp_Uno.h b/DCCpp/DCCpp.h similarity index 99% rename from DCCpp_Uno/DCCpp_Uno.h rename to DCCpp/DCCpp.h index d0f5f8b..df7d3d5 100644 --- a/DCCpp_Uno/DCCpp_Uno.h +++ b/DCCpp/DCCpp.h @@ -1,6 +1,6 @@ /********************************************************************** -DCCpp_Uno.h +DCCpp.h COPYRIGHT (c) 2013-2016 Gregg E. Berman Part of DCC++ BASE STATION for the Arduino diff --git a/DCCpp_Uno/DCCpp_Uno.ino b/DCCpp/DCCpp.ino similarity index 97% rename from DCCpp_Uno/DCCpp_Uno.ino rename to DCCpp/DCCpp.ino index 9378374..02a71f0 100644 --- a/DCCpp_Uno/DCCpp_Uno.ino +++ b/DCCpp/DCCpp.ino @@ -91,7 +91,7 @@ methods for updating and queuing according to text commands sent by the user the main operations track and one that controls the programming track. For the main operations track, packets to store cab throttle settings are stored in -registers numbered 1 through MAX_MAIN_REGISTERS (as defined in DCCpp_Uno.h). +registers numbered 1 through MAX_MAIN_REGISTERS (as defined in DCCpp.h). It is generally considered good practice to continuously send throttle control packets to every cab so that if an engine should momentarily lose electrical connectivity with the tracks, it will very quickly receive another throttle control signal as soon as connectivity is @@ -129,7 +129,7 @@ For the Mega, the OC1B output is produced directly on pin 12, so no jumper is ne Motor Shield's DIRECTION A input. However, one small jumper wire is needed to connect the Mega's OC3B output (pin 2) to the Motor Shield's DIRECTION B input (pin 13). -Other Motor Shields may require different sets of jumper or configurations (see Config.h and DCCpp_Uno.h for details). +Other Motor Shields may require different sets of jumper or configurations (see Config.h and DCCpp.h for details). When configured as such, the CHANNEL A and CHANNEL B outputs of the Motor Shield may be connected directly to the tracks. This software assumes CHANNEL A is connected @@ -168,7 +168,7 @@ DCC++ BASE STATION is configured through the Config.h file that contains all use // BEGIN BY INCLUDING THE HEADER FILES FOR EACH MODULE -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "PacketRegister.h" #include "CurrentMonitor.h" #include "Sensor.h" @@ -177,6 +177,7 @@ DCC++ BASE STATION is configured through the Config.h file that contains all use #include "EEStore.h" #include "Config.h" #include "Comm.h" +#include "DccServer.h" void showConfiguration(); @@ -209,7 +210,9 @@ void loop(){ progMonitor.check(); } - Sensor::check(); // check sensors for activate/de-activate + Sensor::check(); // check sensors for activate/de-activate + RemoteOutput::check(); // check outputs for any new required uploads between DCC++ MASTER and DCC++ SERVER + DccServer::check(); } // loop @@ -231,8 +234,8 @@ void setup(){ pinMode(A5,INPUT); // if pin A5 is grounded upon start-up, print system configuration and halt digitalWrite(A5,HIGH); - if(!digitalRead(A5)) - showConfiguration(); +// if(!digitalRead(A5)) +// showConfiguration(); Serial.print(""); + Serial.print(""); +// DccServer::setServer(DccServer::serverID); // Start WIRE in SERVER MODE address loaded from EEPROM (0-119, where 0=DCC++ MASTER, else DCC++ BOOSTER) + #if COMM_TYPE == 1 #ifdef IP_ADDRESS Ethernet.begin(mac,IP_ADDRESS); // Start networking using STATIC IP Address @@ -267,6 +275,8 @@ void setup(){ Serial.print(Ethernet.localIP()); Serial.print(">"); #endif + + DccServer::init(); // set up DCC++ Server // CONFIGURE TIMER_1 TO OUTPUT 50% DUTY CYCLE DCC SIGNALS ON OC1B INTERRUPT PINS diff --git a/DCCpp/DccServer.cpp b/DCCpp/DccServer.cpp new file mode 100644 index 0000000..b9752a0 --- /dev/null +++ b/DCCpp/DccServer.cpp @@ -0,0 +1,461 @@ +/********************************************************************** + +DccServer.cpp +COPYRIGHT (c) 2013-2016 Gregg E. Berman + +Part of DCC++ BASE STATION for the Arduino + +**********************************************************************/ +/********************************************************************** + +DCC++ BASE STATION supports the use of multiple Arduinos communicating +via the Arduino's built-in TWI/I2C Interface, utilizing Arduino's WIRE library. +Each Arduino requires a unique SERVER ID from 0 through 119. This address +is set interactively with the command, and saved to EEPROM when +the command is issued. + +When multiple Arduinos are used, one acts as the DCC++ MASTER and all others +are DCC++ BOOSTERS. + +* The DCC++ MASTER must have a SERVER ID of 0. +* DCC++ BOOSTERS must have a unique SERVER ID from 1 through 119 + +**********************************************************************/ + +#include "DCCpp.h" +#include "Comm.h" +#include "DccServer.h" +#include "EEStore.h" + +/////////////////////////////////////////////////////////////////////////////// + +void DccServer::status(){ + + INTERFACE.print(""); +} + +/////////////////////////////////////////////////////////////////////////////// + +void DccServer::parse(char *c){ + int n; + + switch(sscanf(c,"%d",&n)){ + + case 1: // argument is serverID (0=DCC++ MASTER, 1-119=DCC++ BOOSTER) + if(n>=0 && n<=119){ + INTERFACE.print(""); + serverID=n; + init(); + } else { + INTERFACE.print(""); + } + break; + + case -1: // no arguments + status(); + break; + + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void DccServer::init(){ + + digitalWrite(SCL,HIGH); // set TWI lines to utilize internal pull-up resistors + digitalWrite(SDA,HIGH); + + bitClear(TWSR,TWPS0); // set TWI pre-scaler to 1 + bitClear(TWSR,TWPS1); + TWBR=72; // with pre-scaler set to 1 above, this yields a TWI frequency of 100kHz + + state=READY; // set TWI state + + TWAR=(serverID+1) << 1; // set WIRE ADDRESS = SERVER ID + 1 + + if(serverID>0) // this is a DCC++ SERVER + bitSet(TWAR,TWGCE); // enable recognition of general call address (0x00) + + TWCR=(1<data.serverID; +} + +/////////////////////////////////////////////////////////////////////////////// + +void DccServer::store(){ + EEStore::eeStore->data.serverID=DccServer::serverID; +} + +/////////////////////////////////////////////////////////////////////////////// + +//void DccServer::setServer(int id){ + +// serverID=id; + +// Wire.end(); +// Wire.onReceive(receiveWire); +// Wire.begin(serverID+1); // set as WIRE SERVER with ID+1 (yielding address between 1 and 120) +//} + +/////////////////////////////////////////////////////////////////////////////// + +//void DccServer::setMaster(){ + +// Wire.end(); +// Wire.begin(); // set as WIRE MASTER +//} + +/////////////////////////////////////////////////////////////////////////////// + +// void DccServer::upload(Sensor *tt){ + +// setMaster(); // convert to WIRE MASTER +// Wire.beginTransmission(1); // 1 is always the WIRE address of DCC++ MASTER (SERVER ID = 0) +// Wire.write(tt->active?"Q":"q"); +// Wire.write(highByte(tt->data.snum)); +// Wire.write(lowByte(tt->data.snum)); +// Wire.write(0); // dummy byte -- must always have 4 bytes so all transmissions look alike (needed for proper WIRE arbitration) +// tt->uploaded=(Wire.endTransmission()==0); +// setServer(serverID); // revert back to WIRE SERVER + +// } + +/////////////////////////////////////////////////////////////////////////////// + +//void DccServer::upload(Output *tt){ + +// setMaster(); // convert to WIRE MASTER +// Wire.beginTransmission(1); // 1 is always the WIRE address of DCC++ MASTER (SERVER ID = 0) +// Wire.write(tt->data.oStatus==0?"y":"Y"); // relay status of local output to DCC++ MASTER +// Wire.write(highByte(tt->data.id)); +// Wire.write(lowByte(tt->data.id)); +// Wire.write(serverID); +// tt->uploaded=(Wire.endTransmission()==0); +// setServer(serverID); // revert back to WIRE SERVER + + +//} + +/////////////////////////////////////////////////////////////////////////////// + +void DccServer::refresh(){ + + if(serverID>0) // only applicable for the DCC++ MASTER + return; + + twiWrite(rUploaded,-1,'G',0,0,0); + +} + +/////////////////////////////////////////////////////////////////////////////// + +void DccServer::twiWrite(boolean &t, byte s, byte b0, byte b1, byte b2, byte b3){ + + if(state!=READY) // do not proceed if TWI is already doing something else + return; + + TWCR=(1<active=(rData[0]=='Q'); // set active status + } else { + tt=RemoteSensor::create(w); // create remoteSensor + tt->active=(rData[0]=='Q'); // set active status + if(!tt->active) // not active, and was just created + break; // do not report inactive sensors when just created + } + + INTERFACE.print("<"); + INTERFACE.print(char(rData[0])); + INTERFACE.print(w); + INTERFACE.print(">"); + break; + + case 'Y': // output activated + case 'y': // output de-activated + RemoteOutput *ss; + w=word(rData[1],rData[2]); + ss=RemoteOutput::get(w); // get remoteOutput + + if(ss==NULL) // remoteOutput does not yet exist + ss=RemoteOutput::create(w,rData[3]); // create with output ID and serverID + + ss->active=(rData[0]=='Y'); // set active status + + INTERFACE.print("active?" 1>":" 0>"); + break; + + case 'Z': // activate output requested + Output *rr; + w=word(rData[1],rData[2]); + rr=Output::get(w); + if(rr!=NULL) + rr->activate(rData[3]); + break; + + case 'G': // status refresh requested - will cause a DCC++ SERVER to re-send all OUTPUTS and SENSORS to DCC++ MASTER + + for(Output *tt=Output::firstOutput;tt!=NULL;tt=tt->nextOutput) // set upload status for all local OUTPUTS to false + tt->uploaded=false; + + for(Sensor *tt=Sensor::firstSensor;tt!=NULL;tt=tt->nextSensor) // set upload status for all local SENSORS to false + tt->uploaded=false; + + break; + + } // switch + + state=READY; + TWCR=(1<nextSensor!=NULL) + tt=tt->nextSensor; + tt->nextSensor=(RemoteSensor *)calloc(1,sizeof(RemoteSensor)); + tt=tt->nextSensor; + } + + tt->snum=snum; + return(tt); + +} + +/////////////////////////////////////////////////////////////////////////////// + +RemoteSensor *RemoteSensor::get(int n){ + RemoteSensor *tt; + for(tt=firstSensor;tt!=NULL && tt->snum!=n;tt=tt->nextSensor); + return(tt); +} + +/////////////////////////////////////////////////////////////////////////////// + +void RemoteSensor::status(){ + RemoteSensor *tt; + + for(tt=firstSensor;tt!=NULL;tt=tt->nextSensor){ + INTERFACE.print(tt->active?"snum); + INTERFACE.print(">"); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +RemoteOutput *RemoteOutput::create(int snum, int serverID){ + RemoteOutput *tt; + + if(firstOutput==NULL){ + firstOutput=(RemoteOutput *)calloc(1,sizeof(RemoteOutput)); + tt=firstOutput; + } else if((tt=get(snum))==NULL){ + tt=firstOutput; + while(tt->nextOutput!=NULL) + tt=tt->nextOutput; + tt->nextOutput=(RemoteOutput *)calloc(1,sizeof(RemoteOutput)); + tt=tt->nextOutput; + } + + tt->snum=snum; + tt->serverID=serverID; + tt->uploaded=true; + return(tt); + +} + +/////////////////////////////////////////////////////////////////////////////// + +RemoteOutput *RemoteOutput::get(int n){ + RemoteOutput *tt; + for(tt=firstOutput;tt!=NULL && tt->snum!=n;tt=tt->nextOutput); + return(tt); +} + +/////////////////////////////////////////////////////////////////////////////// + +void RemoteOutput::status(){ + RemoteOutput *tt; + + for(tt=firstOutput;tt!=NULL;tt=tt->nextOutput){ + INTERFACE.print("snum); + INTERFACE.print(tt->active?" 1>":" 0>"); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void RemoteOutput::activate(int s){ + activeDesired=(s>0); + uploaded=false; +} + +/////////////////////////////////////////////////////////////////////////////// + +void RemoteOutput::check(){ + + if(DccServer::serverID>0){ // this is a DCC++ SERVER - must upload LOCAL output definitions to DCC++ MASTER + + for(Output *tt=Output::firstOutput;tt!=NULL;tt=tt->nextOutput){ + if(!tt->uploaded) + DccServer::twiWrite(tt->uploaded,0,tt->data.oStatus==0?'y':'Y',highByte(tt->data.id),lowByte(tt->data.id),DccServer::serverID); + } + } else { // this is a DCC++ MASTER - must upload any REMOTE OUTPUT commands to DCC++ SERVER + + for(RemoteOutput *tt=RemoteOutput::firstOutput;tt!=NULL;tt=tt->nextOutput){ + if(!tt->uploaded) + DccServer::twiWrite(tt->uploaded,tt->serverID,'Z',highByte(tt->snum),lowByte(tt->snum),tt->activeDesired?1:0); + } + } + +} + +/////////////////////////////////////////////////////////////////////////////// + +byte DccServer::serverID; +volatile byte DccServer::rDataIdx; +volatile byte DccServer::rData[TWI_BUF_SIZE]; +volatile byte DccServer::wDataIdx; +volatile byte DccServer::wData[TWI_BUF_SIZE]; +volatile byte DccServer::state; +boolean *DccServer::uploaded; +boolean DccServer::rUploaded; +volatile byte DccServer::wAddress; +RemoteSensor *RemoteSensor::firstSensor=NULL; +RemoteOutput *RemoteOutput::firstOutput=NULL; + +/////////////////////////////////////////////////////////////////////////////// + +ISR(TWI_vect){ + + switch(TWSR){ + + case 0x08: // START transmitted + TWDR=DccServer::wAddress; // load SLA+W + TWCR=(1< /////////////////////////////////////////////////////////////////////////////// @@ -28,6 +29,7 @@ void EEStore::init(){ eeStore->data.nTurnouts=0; eeStore->data.nSensors=0; eeStore->data.nOutputs=0; + eeStore->data.serverID=0; EEPROM.put(0,eeStore->data); } @@ -35,7 +37,7 @@ void EEStore::init(){ Turnout::load(); // load turnout definitions Sensor::load(); // load sensor definitions Output::load(); // load output definitions - + DccServer::load(); // load DCC++ server definitions } /////////////////////////////////////////////////////////////////////////////// @@ -46,6 +48,7 @@ void EEStore::clear(){ eeStore->data.nTurnouts=0; eeStore->data.nSensors=0; eeStore->data.nOutputs=0; + eeStore->data.serverID=0; EEPROM.put(0,eeStore->data); } @@ -57,6 +60,7 @@ void EEStore::store(){ Turnout::store(); Sensor::store(); Output::store(); + DccServer::store(); EEPROM.put(0,eeStore->data); } diff --git a/DCCpp_Uno/EEStore.h b/DCCpp/EEStore.h similarity index 97% rename from DCCpp_Uno/EEStore.h rename to DCCpp/EEStore.h index f7d2dec..e17450f 100644 --- a/DCCpp_Uno/EEStore.h +++ b/DCCpp/EEStore.h @@ -17,6 +17,7 @@ struct EEStoreData{ int nTurnouts; int nSensors; int nOutputs; + int serverID; }; struct EEStore{ diff --git a/DCCpp_Uno/Outputs.cpp b/DCCpp/Outputs.cpp similarity index 95% rename from DCCpp_Uno/Outputs.cpp rename to DCCpp/Outputs.cpp index fe2ddef..95c5c52 100644 --- a/DCCpp_Uno/Outputs.cpp +++ b/DCCpp/Outputs.cpp @@ -73,10 +73,11 @@ the state of any outputs being monitored or controlled by a separate interface o #include "Outputs.h" #include "SerialCommand.h" -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "EEStore.h" #include #include "Comm.h" +#include "DccServer.h" /////////////////////////////////////////////////////////////////////////////// @@ -91,11 +92,13 @@ void Output::activate(int s){ INTERFACE.print(" 0>"); else INTERFACE.print(" 1>"); + + uploaded=false; } /////////////////////////////////////////////////////////////////////////////// -Output* Output::get(int n){ +Output *Output::get(int n){ Output *tt; for(tt=firstOutput;tt!=NULL && tt->data.id!=n;tt=tt->nextOutput); return(tt); @@ -153,15 +156,22 @@ void Output::show(int n){ void Output::parse(char *c){ int n,s,m; Output *t; + RemoteOutput *r; switch(sscanf(c,"%d %d %d",&n,&s,&m)){ case 2: // argument is string with id number of output followed by zero (LOW) or one (HIGH) t=get(n); - if(t!=NULL) + if(t!=NULL){ // this matches local OUTPUT t->activate(s); - else + } else { + r=RemoteOutput::get(n); // this matches remote OUTPUT + if(r!=NULL){ + r->activate(s); + } else { // this does not match any OUTPUT INTERFACE.print(""); + } + } break; case 3: // argument is string with id number of output followed by a pin number and invert flag @@ -212,6 +222,7 @@ void Output::store(){ } } + /////////////////////////////////////////////////////////////////////////////// Output *Output::create(int id, int pin, int iFlag, int v){ @@ -238,6 +249,7 @@ Output *Output::create(int id, int pin, int iFlag, int v){ tt->data.pin=pin; tt->data.iFlag=iFlag; tt->data.oStatus=0; + tt->uploaded=false; if(v==1){ tt->data.oStatus=bitRead(tt->data.iFlag,1)?bitRead(tt->data.iFlag,2):0; // sets status to 0 (INACTIVE) is bit 1 of iFlag=0, otherwise set to value of bit 2 of iFlag diff --git a/DCCpp_Uno/Outputs.h b/DCCpp/Outputs.h similarity index 97% rename from DCCpp_Uno/Outputs.h rename to DCCpp/Outputs.h index 1748bce..8800897 100644 --- a/DCCpp_Uno/Outputs.h +++ b/DCCpp/Outputs.h @@ -22,6 +22,7 @@ struct OutputData { struct Output{ static Output *firstOutput; int num; + boolean uploaded; struct OutputData data; Output *nextOutput; void activate(int s); diff --git a/DCCpp_Uno/PacketRegister.cpp b/DCCpp/PacketRegister.cpp similarity index 99% rename from DCCpp_Uno/PacketRegister.cpp rename to DCCpp/PacketRegister.cpp index 2d69d60..5040f02 100644 --- a/DCCpp_Uno/PacketRegister.cpp +++ b/DCCpp/PacketRegister.cpp @@ -7,7 +7,7 @@ Part of DCC++ BASE STATION for the Arduino **********************************************************************/ -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "PacketRegister.h" #include "Comm.h" diff --git a/DCCpp_Uno/PacketRegister.h b/DCCpp/PacketRegister.h similarity index 100% rename from DCCpp_Uno/PacketRegister.h rename to DCCpp/PacketRegister.h diff --git a/DCCpp_Uno/Sensor.cpp b/DCCpp/Sensor.cpp similarity index 94% rename from DCCpp_Uno/Sensor.cpp rename to DCCpp/Sensor.cpp index 11fca36..9ea7707 100644 --- a/DCCpp_Uno/Sensor.cpp +++ b/DCCpp/Sensor.cpp @@ -55,11 +55,12 @@ decide to ignore the return and only react to triggers. **********************************************************************/ -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "Sensor.h" #include "EEStore.h" #include #include "Comm.h" +#include "DccServer.h" /////////////////////////////////////////////////////////////////////////////// @@ -74,12 +75,18 @@ void Sensor::check(){ INTERFACE.print("data.snum); INTERFACE.print(">"); + tt->uploaded=false; } else if(tt->active && tt->signal>0.9){ tt->active=false; INTERFACE.print("data.snum); INTERFACE.print(">"); + tt->uploaded=false; } + + if(DccServer::serverID>0 && !tt->uploaded) // this is not DCC++ MASTER, and just-changed (or just-created) sensor status has not been uploaded + DccServer::twiWrite(tt->uploaded,0,tt->active?'Q':'q',highByte(tt->data.snum),lowByte(tt->data.snum),0); + } // loop over all sensors } // Sensor::check @@ -110,6 +117,7 @@ Sensor *Sensor::create(int snum, int pin, int pullUp, int v){ tt->data.pin=pin; tt->data.pullUp=(pullUp==0?LOW:HIGH); tt->active=false; + tt->uploaded=false; tt->signal=1; pinMode(pin,INPUT); // set mode to input digitalWrite(pin,pullUp); // don't use Arduino's internal pull-up resistors for external infrared sensors --- each sensor must have its own 1K external pull-up resistor @@ -122,11 +130,12 @@ Sensor *Sensor::create(int snum, int pin, int pullUp, int v){ /////////////////////////////////////////////////////////////////////////////// -Sensor* Sensor::get(int n){ +Sensor *Sensor::get(int n){ Sensor *tt; for(tt=firstSensor;tt!=NULL && tt->data.snum!=n;tt=tt->nextSensor); return(tt); } + /////////////////////////////////////////////////////////////////////////////// void Sensor::remove(int n){ diff --git a/DCCpp_Uno/Sensor.h b/DCCpp/Sensor.h similarity index 97% rename from DCCpp_Uno/Sensor.h rename to DCCpp/Sensor.h index aed60ee..c685515 100644 --- a/DCCpp_Uno/Sensor.h +++ b/DCCpp/Sensor.h @@ -24,6 +24,7 @@ struct Sensor{ static Sensor *firstSensor; SensorData data; boolean active; + boolean uploaded; float signal; Sensor *nextSensor; static void load(); diff --git a/DCCpp_Uno/SerialCommand.cpp b/DCCpp/SerialCommand.cpp similarity index 94% rename from DCCpp_Uno/SerialCommand.cpp rename to DCCpp/SerialCommand.cpp index 4d3f9b2..7717629 100644 --- a/DCCpp_Uno/SerialCommand.cpp +++ b/DCCpp/SerialCommand.cpp @@ -15,12 +15,13 @@ Part of DCC++ BASE STATION for the Arduino // See SerialCommand::parse() below for defined text commands. #include "SerialCommand.h" -#include "DCCpp_Uno.h" +#include "DCCpp.h" #include "Accessories.h" #include "Sensor.h" #include "Outputs.h" #include "EEStore.h" #include "Comm.h" +#include "DccServer.h" extern int __heap_start, *__brkval; @@ -216,6 +217,47 @@ void SerialCommand::parse(char *com){ * returns: the status of each sensor ID in the form (active) or (not active) */ Sensor::status(); + RemoteSensor::status(); + break; + +/***** SHOW STATUS OF ALL OUTPUTS ****/ + + case 'Y': // +/* + * returns: the status of each output ID in the form (active) or (not active) + */ + Output::show(); + RemoteOutput::status(); + break; + +/***** REFRESH DCC++ SERVER DATA ****/ + + case 'G': // +/* + * broadcasts a status request to all DCC++ SERVERS + * causing them to re-send the status of each of their + * local outputs and sensors. + * + */ + DccServer::refresh(); + break; + +/***** SET/SHOW DCC++ SERVER ID ****/ + + case 'J': // +/* + * : sets the SERVER ID of this board to ID + * + * returns: on success, on failure + * + * : shows the SERVER ID of this board + * + * returns: + * + * ID: the SERVER ID of this board (0=DCC++ MASTER, 1-119=DCC++ BOOSTER) + * + */ + DccServer::parse(com+1); break; /***** WRITE CONFIGURATION VARIABLE BYTE TO ENGINE DECODER ON MAIN OPERATIONS TRACK ****/ @@ -401,7 +443,7 @@ void SerialCommand::parse(char *com){ /* * stores settings for turnouts and sensors EEPROM * - * returns: + * returns: */ EEStore::store(); @@ -411,6 +453,8 @@ void SerialCommand::parse(char *com){ INTERFACE.print(EEStore::eeStore->data.nSensors); INTERFACE.print(" "); INTERFACE.print(EEStore::eeStore->data.nOutputs); + INTERFACE.print(" "); + INTERFACE.print(EEStore::eeStore->data.serverID); INTERFACE.print(">"); break; @@ -431,7 +475,7 @@ void SerialCommand::parse(char *com){ case ' ': // < > /* - * simply prints a carriage return - useful when interacting with Ardiuno through serial monitor window + * simply prints a carriage return - useful when interacting with Arduino through serial monitor window * * returns: a carriage return */ diff --git a/DCCpp_Uno/SerialCommand.h b/DCCpp/SerialCommand.h similarity index 100% rename from DCCpp_Uno/SerialCommand.h rename to DCCpp/SerialCommand.h