DCCpp
This is the library version of a program for Arduino to control railroading DCC devices.
DCCpp.cpp
1 /*************************************************************
2 project: <DCCpp library>
3 author: <Thierry PARIS>
4 description: <DCCpp class>
5 *************************************************************/
6 
7 #include "Arduino.h"
8 #include "DCCpp.h"
9 
10 // NEXT DECLARE GLOBAL OBJECTS TO PROCESS AND STORE DCC PACKETS AND MONITOR TRACK CURRENTS.
11 // NOTE REGISTER LISTS MUST BE DECLARED WITH "VOLATILE" QUALIFIER TO ENSURE THEY ARE PROPERLY UPDATED BY INTERRUPT ROUTINES
12 
13 volatile RegisterList DCCpp::mainRegs(MAX_MAIN_REGISTERS); // create list of registers for MAX_MAIN_REGISTER Main Track Packets
14 volatile RegisterList DCCpp::progRegs(3); // create a shorter list of only two registers for Program Track Packets
15 
16 CurrentMonitor DCCpp::mainMonitor; // create monitor for current on Main Track
17 CurrentMonitor DCCpp::progMonitor; // create monitor for current on Program Track
18 
19 bool DCCpp::programMode;
20 bool DCCpp::panicStopped;
21 bool DCCpp::IsPowerOnMain = false;
22 bool DCCpp::IsPowerOnProg = false;
23 byte DCCpp::ackThreshold = 0;
24 
25 // *********************************************************** FunctionsState
26 
28 {
29  this->clear();
30 }
31 
33 {
34  // Clear all functions
35  this->activeFlags[0] = 0;
36  this->activeFlags[1] = 0;
37  this->activeFlags[2] = 0;
38  this->activeFlags[3] = 0;
39 
40  this->statesSent();
41 }
42 
43 void FunctionsState::activate(byte inFunctionNumber)
44 {
45  bitSet(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
46 }
47 
48 void FunctionsState::inactivate(byte inFunctionNumber)
49 {
50  bitClear(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
51 }
52 
53 bool FunctionsState::isActivated(byte inFunctionNumber)
54 {
55  return bitRead(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
56 }
57 
58 bool FunctionsState::isActivationChanged(byte inFunctionNumber)
59 {
60  return bitRead(this->activeFlagsSent[inFunctionNumber / 8], inFunctionNumber % 8) != isActivated(inFunctionNumber);
61 }
62 
64 {
65  for (int i = 0; i < 4; i++)
66  this->activeFlagsSent[i] = this->activeFlags[i];
67 }
68 
69 #ifdef DCCPP_DEBUG_MODE
70 void FunctionsState::printActivated()
71 {
72  for (int i = 0; i < 32; i++)
73  {
74  if (this->isActivated(i))
75  {
76  Serial.print(i);
77  Serial.print(" ");
78  }
79  }
80 
81  Serial.println("");
82 }
83 #endif
84 
85 // *********************************************************** end of FunctionsState
86 
87 // *********************************************************** DCCpp class
88 
89 static bool first = true;
90 
92 // MAIN ARDUINO LOOP
94 
96 {
97 #ifdef USE_TEXTCOMMAND
98  TextCommand::process(); // check for, and process, and new serial commands
99 #endif
100 
101  if (first)
102  {
103  first = false;
104 #if defined(DCCPP_DEBUG_MODE) && defined(DCCPP_PRINT_DCCPP)
106 #endif
107  }
108 
110  { // if sufficient time has elapsed since last update, check current draw on Main and Program Tracks
111  mainMonitor.check();
112  progMonitor.check();
113  }
114 
115 #ifdef USE_SENSOR
116  Sensor::check(); // check sensors for activated or not
117 #endif
118 }
119 
120 #ifndef USE_ONLY1_INTERRUPT
121 void DCCpp::beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
122 {
123  DCCppConfig::DirectionMotorA = inOptionalDirectionMotor;
124 #else
125 void DCCpp::beginMain(uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
126 {
127 #endif
128 
129 #ifdef DCCPP_DEBUG_MODE
130 // CheckPowerConnectionsWithLeds(inSignalPin, 1000);
131 #endif
132 
133  DCCppConfig::SignalEnablePinMain = inSignalEnable; // PWM
134  DCCppConfig::CurrentMonitorMain = inCurrentMonitor;
135 
136  // If no main line, exit.
137  if (inSignalPin == UNDEFINED_PIN)
138  {
139 #ifdef DCCPP_DEBUG_MODE
140  Serial.println("No main track");
141 #endif
142  return;
143  }
144 
145  mainMonitor.begin(DCCppConfig::CurrentMonitorMain, DCCppConfig::SignalEnablePinMain, (char *) "<p2>");
146 
147  DCCpp::beginMainDccSignal(inSignalPin);
148 
149  if (DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
150  digitalWrite(DCCppConfig::SignalEnablePinMain, LOW);
151 
152 #ifdef DCCPP_DEBUG_MODE
153  Serial.print(F("beginMain achivied with pin "));
154  Serial.println(inSignalPin);
155 #endif
156 }
157 
158 #ifndef USE_ONLY1_INTERRUPT
159 void DCCpp::beginProg(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
160 {
161  DCCppConfig::DirectionMotorB = inOptionalDirectionMotor;
162 #else
163 void DCCpp::beginProg(uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
164 {
165 #endif
166  DCCppConfig::SignalEnablePinProg = inSignalEnable;
167  DCCppConfig::CurrentMonitorProg = inCurrentMonitor;
168 
169  // If no programming line, exit.
170  if (inSignalPin == UNDEFINED_PIN)
171  {
172 #ifdef DCCPP_DEBUG_MODE
173  Serial.println("No prog track");
174 #endif
175  return;
176  }
177 
178  progMonitor.begin(DCCppConfig::CurrentMonitorProg, DCCppConfig::SignalEnablePinProg, (char *) "<p3>");
179 
180  DCCpp::beginProgDccSignal(inSignalPin);
181 
182 #ifdef DCCPP_DEBUG_MODE
183  Serial.print(F("beginProg achivied with pin "));
184  Serial.println(inSignalPin);
185 #endif
186 }
187 
189 {
190  DCCpp::programMode = false;
191  DCCpp::panicStopped = false;
192  DCCpp::ackThreshold = 30;
193 
194  DCCppConfig::SignalEnablePinMain = UNDEFINED_PIN;
195  DCCppConfig::CurrentMonitorMain = UNDEFINED_PIN;
196 
197  DCCppConfig::SignalEnablePinProg = UNDEFINED_PIN;
198  DCCppConfig::CurrentMonitorProg = UNDEFINED_PIN;
199 
200 #ifndef USE_ONLY1_INTERRUPT
201  DCCppConfig::DirectionMotorA = UNDEFINED_PIN;
202  DCCppConfig::DirectionMotorB = UNDEFINED_PIN;
203 #else
204  DCCppConfig::SignalPortMaskMain = 0;
205  DCCppConfig::SignalPortMaskProg = 0;
206 #endif
207 
208  mainMonitor.begin(UNDEFINED_PIN, UNDEFINED_PIN, "");
209  progMonitor.begin(UNDEFINED_PIN, UNDEFINED_PIN, "");
210 
211 #ifdef SDCARD_CS
212  pinMode(SDCARD_CS, OUTPUT);
213  digitalWrite(SDCARD_CS, HIGH); // De-select the SD card
214 #endif
215 
216 #ifdef USE_EEPROM
217  EEStore::init(); // initialize and load Turnout and Sensor definitions stored in EEPROM
219  EEStore::store();
220 #endif
221 
222 #ifdef DCCPP_DEBUG_MODE
223  //pinMode(LED_BUILTIN, OUTPUT);
224  Serial.println(F("begin achieved"));
225 #endif
226 
227 } // begin
228 
229 #ifdef USE_ETHERNET
230 void DCCpp::beginEthernet(uint8_t *inMac, uint8_t *inIp, EthernetProtocol inProtocol)
231 {
232  if (inIp != NULL)
233  for (int i = 0; i < 4; i++)
234  DCCppConfig::EthernetIp[i] = inIp[i];
235 
236  for (int i = 0; i < 6; i++)
237  DCCppConfig::EthernetMac[i] = inMac[i];
238 
239  DCCppConfig::Protocol = inProtocol;
240 
241  if (inIp == NULL)
242  Ethernet.begin(inMac); // Start networking using DHCP to get an IP Address
243  else
244  Ethernet.begin(inMac, inIp); // Start networking using STATIC IP Address
245 
246  DCCPP_INTERFACE.begin();
247 #ifdef DCCPP_DEBUG_MODE
248  //pinMode(LED_BUILTIN, OUTPUT);
250  Serial.println(F("beginEthernet achieved"));
251 #endif
252 } // beginEthernet
253 #endif
254 
255 #ifdef DCCPP_PRINT_DCCPP
256 // PRINT CONFIGURATION INFO TO SERIAL PORT REGARDLESS OF INTERFACE TYPE
258 // - ACTIVATED ON STARTUP IF SHOW_CONFIG_PIN IS TIED HIGH
259 
261 {
262  Serial.println(F("*** DCCpp LIBRARY ***"));
263 
264 // Serial.print(F("VERSION DCCpp: "));
265 // Serial.println(VERSION);
266  Serial.println(F(DCCPP_LIBRARY_VERSION));
267  Serial.print(F("COMPILED: "));
268  Serial.print(__DATE__);
269  Serial.print(F(" "));
270  Serial.println(__TIME__);
271 
272  //Serial.print(F("\nARDUINO: "));
273  //Serial.print(ARDUINO_TYPE);
274 
275  //Serial.print(F("\n\nMOTOR SHIELD: "));
276  //Serial.print(MOTOR_SHIELD_NAME);
277 
278 #ifdef ARDUINO_ARCH_AVR
279  Serial.print(F("\n\nDCC SIG MAIN(DIR): "));
280  Serial.println(DCC_SIGNAL_PIN_MAIN);
281 #endif
282 
283 #ifndef USE_ONLY1_INTERRUPT
284  if (DCCppConfig::DirectionMotorA != UNDEFINED_PIN)
285  {
286  Serial.print(F(" DIRECTION: "));
287  Serial.println(DCCppConfig::DirectionMotorA);
288  }
289 #endif
290 
291  if (DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
292  {
293  Serial.print(F(" ENABLE(PWM): "));
294  Serial.println(DCCppConfig::SignalEnablePinMain);
295  }
296 
297  if (DCCppConfig::CurrentMonitorMain != UNDEFINED_PIN)
298  {
299  Serial.print(F(" CURRENT: "));
300  Serial.println(DCCppConfig::CurrentMonitorMain);
301  }
302 
303 #ifdef ARDUINO_ARCH_AVR
304  Serial.print(F("\n\nDCC SIG PROG(DIR): "));
305  Serial.println(DCC_SIGNAL_PIN_PROG);
306 #endif
307 
308 #ifndef USE_ONLY1_INTERRUPT
309  if (DCCppConfig::DirectionMotorB != UNDEFINED_PIN)
310  {
311  Serial.print(F(" DIRECTION: "));
312  Serial.println(DCCppConfig::DirectionMotorB);
313  }
314 #endif
315  if (DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
316  {
317  Serial.print(F(" ENABLE(PWM): "));
318  Serial.println(DCCppConfig::SignalEnablePinProg);
319  }
320  if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
321  {
322  Serial.print(F(" CURRENT: "));
323  Serial.println(DCCppConfig::CurrentMonitorProg);
324  }
325 
326 #if defined(USE_EEPROM)
327 #if defined(USE_TURNOUT)
328  Serial.print(F("\n\nNUM TURNOUTS: "));
329  Serial.println(EEStore::data.nTurnouts);
330 #endif
331 #if defined(USE_SENSOR)
332  Serial.print(F(" SENSORS: "));
333  Serial.println(EEStore::data.nSensors);
334 #endif
335 #if defined(USE_OUTPUT)
336  Serial.print(F(" OUTPUTS: "));
337  Serial.println(EEStore::data.nOutputs);
338 #endif
339 #endif
340 
341 #ifdef USE_TEXTCOMMAND
342  Serial.print(F("\n\nINTERFACE: "));
343 #ifdef USE_ETHERNET
344  Serial.println(F("ETHERNET "));
345  Serial.print(F("MAC ADDRESS: "));
346  for (int i = 0; i<5; i++) {
347  Serial.print(DCCppConfig::EthernetMac[i], HEX);
348  Serial.print(F(":"));
349  }
350  Serial.println(DCCppConfig::EthernetMac[5], HEX);
351 // Serial.print(F("PORT: "));
352 // Serial.println(DCCppConfig::EthernetPort);
353  Serial.print(F("IP ADDRESS: "));
354  Serial.println(Ethernet.localIP());
355 
356 /*#ifdef IP_ADDRESS
357  Serial.println(F(" (STATIC)"));
358 #else
359  Serial.println(F(" (DHCP)"));
360 #endif*/
361 
362 #else
363  Serial.println(F("SERIAL"));
364 #endif
365 
366 #endif
367 // Serial.print(F("\n\nPROGRAM HALTED - PLEASE RESTART ARDUINO"));
368 
369 // while (true);
370 // Serial.println("");
371 }
372 #endif
373 
374 void DCCpp::panicStop(bool inStop)
375 {
376  panicStopped = inStop;
377 
378 #ifdef DCCPP_DEBUG_MODE
379  Serial.print(F("DCCpp PanicStop "));
380  Serial.println(inStop ? F("pressed"):F("canceled"));
381 #endif
382 
383  /* activate or not the power on rails */
384 
385  if (inStop)
386  powerOff();
387  else
388  powerOn();
389 }
390 
391 void DCCpp::powerOn(bool inMain, bool inProg)
392 {
393  bool done = false;
394  if (inProg && DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
395  {
396  digitalWrite(DCCppConfig::SignalEnablePinProg, HIGH);
397  done = true;
398  IsPowerOnProg = true;
399  }
400 
401  if (inMain && DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
402  {
403  digitalWrite(DCCppConfig::SignalEnablePinMain, HIGH);
404  done = true;
405  IsPowerOnMain = true;
406  }
407 
408  if (done)
409  {
410  DCCPP_INTERFACE.print("<p1>");
411 #if !defined(USE_ETHERNET)
412  DCCPP_INTERFACE.println("");
413 #endif
414  }
415 }
416 
417 void DCCpp::powerOff(bool inMain, bool inProg)
418 {
419  bool done = false;
420  if (inProg && DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
421  {
422  digitalWrite(DCCppConfig::SignalEnablePinProg, LOW);
423  done = true;
424  IsPowerOnProg = false;
425  }
426  if (inMain && DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
427  {
428  digitalWrite(DCCppConfig::SignalEnablePinMain, LOW);
429  done = true;
430  IsPowerOnMain = false;
431  }
432 
433  if (done)
434  {
435  DCCPP_INTERFACE.print("<p0>");
436 #if !defined(USE_ETHERNET)
437  DCCPP_INTERFACE.println("");
438 #endif
439  }
440 }
441 
442 byte DCCpp::setAckThreshold(byte inNewValue)
443 {
444  byte old = DCCpp::ackThreshold;
445  DCCpp::ackThreshold = inNewValue;
446  return old;
447 }
448 
449 /***************************** Driving functions */
450 
451 bool DCCpp::setThrottle(volatile RegisterList *inpRegs, int nReg, int inLocoId, int inStepsNumber, int inNewSpeed, bool inForward)
452 {
453 #ifdef DCCPP_DEBUG_MODE
454  Serial.print(F("DCCpp SetSpeed for loco "));
455  Serial.print(inLocoId);
456  Serial.print(F(" : "));
457  Serial.print(inForward ? inNewSpeed : -inNewSpeed);
458  Serial.print(F("/"));
459  Serial.print(inStepsNumber);
460  Serial.println(F(" )"));
461 #endif
462 
463  inpRegs->setThrottle(nReg, inLocoId, inNewSpeed, inForward);
464 
465  return true;
466 }
467 
468 void DCCpp::setFunctions(volatile RegisterList *inpRegs, int nReg, int inLocoId, FunctionsState &inStates)
469 {
470 #ifdef DCCPP_DEBUG_MODE
471  if (inpRegs == &mainRegs)
472  {
473  if (nReg > MAX_MAIN_REGISTERS)
474  Serial.println(F("Invalid register number on main track."));
475  }
476  else
477  {
478  if (nReg > MAX_PROG_REGISTERS)
479  Serial.println(F("Invalid register number on programming track."));
480  }
481 #endif
482  byte flags = 0;
483 
484  byte oneByte1 = 128; // Group one functions F0-F4
485  byte twoByte1 = 176; // Group two F5-F8
486  byte threeByte1 = 160; // Group three F9-F12
487  byte fourByte2 = 0; // Group four F13-F20
488  byte fiveByte2 = 0; // Group five F21-F28
489 
490  for (byte func = 0; func <= 28; func++)
491  {
492  if (func <= 4)
493  {
494  /*
495  * To set functions F0 - F4 on(= 1) or off(= 0) :
496  *
497  * BYTE1 : 128 + F1 * 1 + F2 * 2 + F3 * 4 + F4 * 8 + F0 * 16
498  * BYTE2 : omitted
499  */
500 
501  if (inStates.isActivationChanged(func))
502  flags |= 1;
503  if (inStates.isActivated(func))
504  {
505  if (func == 0)
506  oneByte1 += 16;
507  else
508  oneByte1 += (1 << (func - 1));
509  }
510  }
511  else if (func <= 8)
512  {
513  /*
514  * To set functions F5 - F8 on(= 1) or off(= 0) :
515  *
516  * BYTE1 : 176 + F5 * 1 + F6 * 2 + F7 * 4 + F8 * 8
517  * BYTE2 : omitted
518  */
519 
520  if (inStates.isActivationChanged(func))
521  flags |= 2;
522  if (inStates.isActivated(func))
523  twoByte1 += (1 << (func - 5));
524  }
525  else if (func <= 12)
526  {
527  /*
528  * To set functions F9 - F12 on(= 1) or off(= 0) :
529  *
530  * BYTE1 : 160 + F9 * 1 + F10 * 2 + F11 * 4 + F12 * 8
531  * BYTE2 : omitted
532  */
533 
534  if (inStates.isActivationChanged(func))
535  flags |= 4;
536  if (inStates.isActivated(func))
537  threeByte1 += (1 << (func - 9));
538  }
539  else if (func <= 20)
540  {
541  /*
542  * To set functions F13 - F20 on(= 1) or off(= 0) :
543  *
544  * BYTE1 : 222
545  * BYTE2 : F13 * 1 + F14 * 2 + F15 * 4 + F16 * 8 + F17 * 16 + F18 * 32 + F19 * 64 + F20 * 128
546  */
547 
548  if (inStates.isActivationChanged(func))
549  flags |= 8;
550  if (inStates.isActivated(func))
551  fourByte2 += (1 << (func - 13));
552  }
553  else if (func <= 28)
554  {
555  /*
556  * To set functions F21 - F28 on(= 1) of off(= 0) :
557  *
558  * BYTE1 : 223
559  * BYTE2 : F21 * 1 + F22 * 2 + F23 * 4 + F24 * 8 + F25 * 16 + F26 * 32 + F27 * 64 + F28 * 128
560  */
561 
562  if (inStates.isActivationChanged(func))
563  flags |= 16;
564  if (inStates.isActivated(func))
565  fiveByte2 += (1 << (func - 21));
566  }
567  }
568 
569  int b1 = 0, b2 = -1;
570 
571  if (flags & 1)
572  b1 = oneByte1;
573  if (flags & 2)
574  b1 = twoByte1;
575  if (flags & 4)
576  b1 = threeByte1;
577  if (flags & 8)
578  {
579  b1 = 222;
580  b2 = fourByte2;
581  }
582  if (flags & 16)
583  {
584  b1 = 223;
585  b2 = fiveByte2;
586  }
587 
588  inpRegs->setFunction(nReg, inLocoId, b1, b2);
589 
590  inStates.statesSent();
591 
592 #ifdef DCCPP_DEBUG_MODE
593  Serial.print(F("DCCpp SetFunctions for loco"));
594  Serial.print(inLocoId);
595  Serial.print(" / Activated : ");
596  inStates.printActivated();
597 #endif
598 }
599 
600 int DCCpp::identifyLocoId(volatile RegisterList *inReg)
601 {
602  int id = -1;
603  int temp;
604  temp = inReg->readCV(29, 100, 200);
605  if ((temp != -1) && (bitRead(temp, 5))) {
606  // long address : get CV#17 and CV#18
607  id = inReg->readCV(18, 100, 200);
608  if (id != -1) {
609  temp = inReg->readCV(17, 100, 200);
610  if (temp != -1) {
611  id = id + ((temp - 192) << 8);
612  }
613  }
614  }
615  else {
616  // short address: read only CV#1
617  id = inReg->readCV(1, 100, 200);
618  }
619  return(id);
620 }
621 
622 bool DCCpp::writeCv(volatile RegisterList *inReg, int inCv, byte inValue, int callBack, int callBackSub)
623 {
624 #ifdef DCCPP_DEBUG_MODE
625  Serial.print(F("DCCpp WriteCv "));
626  Serial.print(inCv);
627  Serial.print(F(" : "));
628  Serial.println(inValue);
629 #endif
630 
631  return inReg->writeCVByte(inCv, inValue, callBack, callBackSub);
632 }
633 
634 void DCCpp::setAccessory(int inAddress, byte inSubAddress, byte inActivate)
635 {
636 #ifdef DCCPP_DEBUG_MODE
637  Serial.print(F("DCCpp AccessoryOperation "));
638  Serial.print(inAddress);
639  Serial.print(F(" / "));
640  Serial.print(inSubAddress);
641  Serial.print(F(" : "));
642  Serial.println(inActivate);
643 #endif
644 
645  mainRegs.setAccessory(inAddress, inSubAddress, inActivate);
646 }
647 
648 #ifdef DCCPP_DEBUG_MODE
649 void DCCpp::CheckPowerConnectionsWithLeds(uint8_t aDirPin, unsigned int inDelay)
650 {
651  if (DCCppConfig::SignalEnablePinMain != 255 || DCCppConfig::SignalEnablePinProg != 255)
652  {
653  Serial.print(F("DCC signal is started, this function cannot operates."));
654  return;
655  }
656 
657  pinMode(aDirPin, OUTPUT);
658  digitalWrite(aDirPin, HIGH);
659  delay(inDelay);
660 
661  digitalWrite(aDirPin, LOW);
662  delay(inDelay);
663 }
664 #endif
665 
666 
static void setAccessory(int inAddress, byte inSubAddress, byte inActivate)
Definition: DCCpp.cpp:634
static byte setAckThreshold(byte inNewValue)
Definition: DCCpp.cpp:442
static void powerOn(bool inMain=true, bool inProg=true)
Definition: DCCpp.cpp:391
static void powerOff(bool inMain=true, bool inProg=true)
Definition: DCCpp.cpp:417
static void panicStop(bool inStop)
Definition: DCCpp.cpp:374
static bool needsRefreshing()
Definition: EEStore.cpp:112
static void beginProgDccSignal(uint8_t inSignalPin)
static EEStoreData data
Definition: EEStore.h:45
static void beginProg(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnablePin, uint8_t inCurrentMonitor)
Definition: DCCpp.cpp:159
void begin(int pin, int inSignalPin, const char *msg, float inSampleMax=300)
void statesSent()
Definition: DCCpp.cpp:63
static void beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnablePin, uint8_t inCurrentMonitor)
Definition: DCCpp.cpp:121
bool isActivated(byte inFunctionNumber)
Definition: DCCpp.cpp:53
static boolean checkTime()
static void begin()
Definition: DCCpp.cpp:188
FunctionsState()
Definition: DCCpp.cpp:27
static void check()
Definition: Sensor.cpp:123
static void init()
Definition: EEStore.cpp:26
void inactivate(byte inFunctionNumber)
Definition: DCCpp.cpp:48
bool isActivationChanged(byte inFunctionNumber)
Definition: DCCpp.cpp:58
static void loop()
Definition: DCCpp.cpp:95
static void store()
Definition: EEStore.cpp:92
void activate(byte inFunctionNumber)
Definition: DCCpp.cpp:43
static void process()
Definition: TextCommand.cpp:37
static void beginMainDccSignal(uint8_t inSignalPin)
void clear()
Definition: DCCpp.cpp:32
static void showConfiguration()
Definition: DCCpp.cpp:260