13 volatile RegisterList DCCpp::mainRegs(MAX_MAIN_REGISTERS);
19 bool DCCpp::programMode;
20 bool DCCpp::panicStopped;
21 byte DCCpp::ackThreshold = 0;
33 this->activeFlags[0] = 0;
34 this->activeFlags[1] = 0;
35 this->activeFlags[2] = 0;
36 this->activeFlags[3] = 0;
43 bitSet(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
48 bitClear(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
53 return bitRead(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
58 return bitRead(this->activeFlagsSent[inFunctionNumber / 8], inFunctionNumber % 8) !=
isActivated(inFunctionNumber);
63 for (
int i = 0; i < 4; i++)
64 this->activeFlagsSent[i] = this->activeFlags[i];
67 #ifdef DCCPP_DEBUG_MODE 68 void FunctionsState::printActivated()
70 for (
int i = 0; i < 32; i++)
87 static bool first =
true;
95 #ifdef USE_TEXTCOMMAND 96 TextCommand::process();
102 #if defined(DCCPP_DEBUG_MODE) && defined(DCCPP_PRINT_DCCPP) 118 #ifndef USE_ONLY1_INTERRUPT 119 void DCCpp::beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
121 DCCppConfig::DirectionMotorA = inOptionalDirectionMotor;
123 void DCCpp::beginMain(uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
127 #ifdef DCCPP_DEBUG_MODE 131 DCCppConfig::SignalEnablePinMain = inSignalEnable;
132 DCCppConfig::CurrentMonitorMain = inCurrentMonitor;
135 if (inSignalPin == UNDEFINED_PIN)
137 #ifdef DCCPP_DEBUG_MODE 138 Serial.println(
"No main track");
143 mainMonitor.
begin(DCCppConfig::CurrentMonitorMain, DCCppConfig::SignalEnablePinMain, (
char *)
"<p2>");
147 if (DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
148 digitalWrite(DCCppConfig::SignalEnablePinMain, LOW);
150 #ifdef DCCPP_DEBUG_MODE 151 Serial.print(F(
"beginMain achivied with pin "));
152 Serial.println(inSignalPin);
156 #ifndef USE_ONLY1_INTERRUPT 157 void DCCpp::beginProg(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
159 DCCppConfig::DirectionMotorB = inOptionalDirectionMotor;
161 void DCCpp::beginProg(uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
164 DCCppConfig::SignalEnablePinProg = inSignalEnable;
165 DCCppConfig::CurrentMonitorProg = inCurrentMonitor;
168 if (inSignalPin == UNDEFINED_PIN)
170 #ifdef DCCPP_DEBUG_MODE 171 Serial.println(
"No prog track");
176 progMonitor.
begin(DCCppConfig::CurrentMonitorProg, DCCppConfig::SignalEnablePinProg, (
char *)
"<p3>");
180 #ifdef DCCPP_DEBUG_MODE 181 Serial.print(F(
"beginProg achivied with pin "));
182 Serial.println(inSignalPin);
188 DCCpp::programMode =
false;
189 DCCpp::panicStopped =
false;
190 DCCpp::ackThreshold = 30;
192 DCCppConfig::SignalEnablePinMain = UNDEFINED_PIN;
193 DCCppConfig::CurrentMonitorMain = UNDEFINED_PIN;
195 DCCppConfig::SignalEnablePinProg = UNDEFINED_PIN;
196 DCCppConfig::CurrentMonitorProg = UNDEFINED_PIN;
198 #ifndef USE_ONLY1_INTERRUPT 199 DCCppConfig::DirectionMotorA = UNDEFINED_PIN;
200 DCCppConfig::DirectionMotorB = UNDEFINED_PIN;
202 DCCppConfig::SignalPortMaskMain = 0;
203 DCCppConfig::SignalPortMaskProg = 0;
206 mainMonitor.
begin(UNDEFINED_PIN, UNDEFINED_PIN,
"");
207 progMonitor.
begin(UNDEFINED_PIN, UNDEFINED_PIN,
"");
210 pinMode(SDCARD_CS, OUTPUT);
211 digitalWrite(SDCARD_CS, HIGH);
216 if (EEStore::needsRefreshing())
220 #ifdef DCCPP_DEBUG_MODE 222 Serial.println(F(
"begin achieved"));
228 void DCCpp::beginEthernet(uint8_t *inMac, uint8_t *inIp, EthernetProtocol inProtocol)
231 for (
int i = 0; i < 4; i++)
232 DCCppConfig::EthernetIp[i] = inIp[i];
234 for (
int i = 0; i < 6; i++)
235 DCCppConfig::EthernetMac[i] = inMac[i];
237 DCCppConfig::Protocol = inProtocol;
240 Ethernet.begin(inMac);
242 Ethernet.begin(inMac, inIp);
244 DCCPP_INTERFACE.begin();
245 #ifdef DCCPP_DEBUG_MODE 248 Serial.println(F(
"beginEthernet achieved"));
253 #ifdef DCCPP_PRINT_DCCPP 258 void DCCpp::showConfiguration()
260 Serial.println(F(
"*** DCCpp LIBRARY ***"));
262 Serial.print(F(
"VERSION DCC++: "));
263 Serial.println(VERSION);
264 Serial.println(F(DCCPP_LIBRARY_VERSION));
265 Serial.print(F(
"COMPILED: "));
266 Serial.print(__DATE__);
267 Serial.print(F(
" "));
268 Serial.println(__TIME__);
276 #ifdef ARDUINO_ARCH_AVR 277 Serial.print(F(
"\n\nDCC SIG MAIN(DIR): "));
278 Serial.println(DCC_SIGNAL_PIN_MAIN);
281 #ifndef USE_ONLY1_INTERRUPT 282 if (DCCppConfig::DirectionMotorA != UNDEFINED_PIN)
284 Serial.print(F(
" DIRECTION: "));
285 Serial.println(DCCppConfig::DirectionMotorA);
289 if (DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
291 Serial.print(F(
" ENABLE(PWM): "));
292 Serial.println(DCCppConfig::SignalEnablePinMain);
295 if (DCCppConfig::CurrentMonitorMain != UNDEFINED_PIN)
297 Serial.print(F(
" CURRENT: "));
298 Serial.println(DCCppConfig::CurrentMonitorMain);
301 #ifdef ARDUINO_ARCH_AVR 302 Serial.print(F(
"\n\nDCC SIG PROG(DIR): "));
303 Serial.println(DCC_SIGNAL_PIN_PROG);
306 #ifndef USE_ONLY1_INTERRUPT 307 if (DCCppConfig::DirectionMotorB != UNDEFINED_PIN)
309 Serial.print(F(
" DIRECTION: "));
310 Serial.println(DCCppConfig::DirectionMotorB);
313 if (DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
315 Serial.print(F(
" ENABLE(PWM): "));
316 Serial.println(DCCppConfig::SignalEnablePinProg);
318 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
320 Serial.print(F(
" CURRENT: "));
321 Serial.println(DCCppConfig::CurrentMonitorProg);
324 #if defined(USE_EEPROM) 325 #if defined(USE_TURNOUT) 326 Serial.print(F(
"\n\nNUM TURNOUTS: "));
327 Serial.println(EEStore::data.nTurnouts);
329 #if defined(USE_SENSOR) 330 Serial.print(F(
" SENSORS: "));
331 Serial.println(EEStore::data.nSensors);
333 #if defined(USE_OUTPUT) 334 Serial.print(F(
" OUTPUTS: "));
335 Serial.println(EEStore::data.nOutputs);
339 #ifdef USE_TEXTCOMMAND 340 Serial.print(F(
"\n\nINTERFACE: "));
342 Serial.println(F(
"ETHERNET "));
343 Serial.print(F(
"MAC ADDRESS: "));
344 for (
int i = 0; i<5; i++) {
345 Serial.print(DCCppConfig::EthernetMac[i], HEX);
346 Serial.print(F(
":"));
348 Serial.println(DCCppConfig::EthernetMac[5], HEX);
351 Serial.print(F(
"IP ADDRESS: "));
352 Serial.println(Ethernet.localIP());
361 Serial.println(F(
"SERIAL"));
374 panicStopped = inStop;
376 #ifdef DCCPP_DEBUG_MODE 377 Serial.print(F(
"DCCpp PanicStop "));
378 Serial.println(inStop ? F(
"pressed"):F(
"canceled"));
392 if (inProg && DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
394 digitalWrite(DCCppConfig::SignalEnablePinProg, HIGH);
398 if (inMain && DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
400 digitalWrite(DCCppConfig::SignalEnablePinMain, HIGH);
406 DCCPP_INTERFACE.print(
"<p1>");
407 #if !defined(USE_ETHERNET) 408 DCCPP_INTERFACE.println(
"");
416 if (inProg && DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
418 digitalWrite(DCCppConfig::SignalEnablePinProg, LOW);
421 if (inMain && DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
423 digitalWrite(DCCppConfig::SignalEnablePinMain, LOW);
429 DCCPP_INTERFACE.print(
"<p0>");
430 #if !defined(USE_ETHERNET) 431 DCCPP_INTERFACE.println(
"");
438 byte old = DCCpp::ackThreshold;
439 DCCpp::ackThreshold = inNewValue;
445 bool DCCpp::setThrottle(
volatile RegisterList *inpRegs,
int nReg,
int inLocoId,
int inStepsNumber,
int inNewSpeed,
bool inForward)
453 val = map(inNewSpeed, 0, inStepsNumber, 2, 127);
455 #ifdef DCCPP_DEBUG_MODE 456 Serial.print(F(
"DCCpp SetSpeed "));
457 Serial.print(inForward?inNewSpeed:-inNewSpeed);
458 Serial.print(F(
"/"));
459 Serial.print(inStepsNumber);
460 Serial.print(F(
" (in Dcc "));
462 Serial.println(F(
" )"));
465 inpRegs->setThrottle(nReg, inLocoId, val, inForward);
472 #ifdef DCCPP_DEBUG_MODE 473 if (inpRegs == &mainRegs)
475 if (nReg > MAX_MAIN_REGISTERS)
476 Serial.println(F(
"Invalid register number on main track."));
480 if (nReg > MAX_PROG_REGISTERS)
481 Serial.println(F(
"Invalid register number on programming track."));
488 byte threeByte1 = 160;
492 for (byte func = 0; func <= 28; func++)
510 oneByte1 += (1 << (func - 1));
525 twoByte1 += (1 << (func - 5));
539 threeByte1 += (1 << (func - 9));
553 fourByte2 += (1 << (func - 13));
567 fiveByte2 += (1 << (func - 21));
572 inpRegs->setFunction(nReg, inLocoId, oneByte1, -1);
574 inpRegs->setFunction(nReg, inLocoId, twoByte1, -1);
576 inpRegs->setFunction(nReg, inLocoId, threeByte1, -1);
578 inpRegs->setFunction(nReg, inLocoId, 222, fourByte2);
580 inpRegs->setFunction(nReg, inLocoId, 223, fiveByte2);
584 #ifdef DCCPP_DEBUG_MODE 585 Serial.print(F(
"DCCpp SetFunctions for loco"));
586 Serial.print(inLocoId);
587 Serial.print(
" / Activated : ");
588 inStates.printActivated();
596 temp = inReg->readCV(29, 100, 200);
597 if ((temp != -1) && (bitRead(temp, 5))) {
599 id = inReg->readCV(18, 100, 200);
601 temp = inReg->readCV(17, 100, 200);
603 id =
id + ((temp - 192) << 8);
609 id = inReg->readCV(1, 100, 200);
614 void DCCpp::writeCv(
volatile RegisterList *inReg,
int inCv, byte inValue,
int callBack,
int callBackSub)
616 inReg->writeCVByte(inCv, inValue, callBack, callBackSub);
618 #ifdef DCCPP_DEBUG_MODE 619 Serial.print(F(
"DCCpp WriteCv "));
621 Serial.print(F(
" : "));
622 Serial.println(inValue);
628 mainRegs.setAccessory(inAddress, inSubAddress, inActivate);
630 #ifdef DCCPP_DEBUG_MODE 631 Serial.print(F(
"DCCpp AccessoryOperation "));
632 Serial.print(inAddress);
633 Serial.print(F(
" / "));
634 Serial.print(inSubAddress);
635 Serial.print(F(
" : "));
636 Serial.println(inActivate);
640 #ifdef DCCPP_DEBUG_MODE 641 void DCCpp::CheckPowerConnectionsWithLeds(uint8_t aDirPin,
unsigned int inDelay)
643 if (DCCppConfig::SignalEnablePinMain != 255 || DCCppConfig::SignalEnablePinProg != 255)
645 Serial.print(F(
"DCC signal is started, this function cannot operates."));
649 pinMode(aDirPin, OUTPUT);
650 digitalWrite(aDirPin, HIGH);
653 digitalWrite(aDirPin, LOW);
static void setAccessory(int inAddress, byte inSubAddress, byte inActivate)
-
static byte setAckThreshold(byte inNewValue)
static void powerOn(bool inMain=true, bool inProg=true)
+
static void powerOff(bool inMain=true, bool inProg=true)
+
static void beginProgDccSignal(uint8_t inSignalPin)
static void beginProg(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnablePin, uint8_t inCurrentMonitor)
-
-
void begin(int pin, int inSignalPin, const char *msg, float inSampleMax=300)
+
-
-
-
+
+
static void beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnablePin, uint8_t inCurrentMonitor)
+
static void panicStop(bool inStop)
-
static void beginProgDccSignal(uint8_t inSignalPin)
-
-
void activate(byte inFunctionNumber)
-
static void powerOff(bool inMain=true, bool inProg=true)
+
static byte setAckThreshold(byte inNewValue)
void inactivate(byte inFunctionNumber)
-
+
static void beginMainDccSignal(uint8_t inSignalPin)
bool isActivated(byte inFunctionNumber)
bool isActivationChanged(byte inFunctionNumber)
-
static void beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnablePin, uint8_t inCurrentMonitor)
-
static void panicStop(bool inStop)
+
+
+
static boolean checkTime()
-
static void beginMainDccSignal(uint8_t inSignalPin)
+
+
void activate(byte inFunctionNumber)
+
void begin(int pin, int inSignalPin, const char *msg, float inSampleMax=300)