13 volatile RegisterList DCCpp::mainRegs(MAX_MAIN_REGISTERS);
19 bool DCCpp::programMode;
20 bool DCCpp::panicStopped;
21 bool DCCpp::IsPowerOnMain =
false;
22 bool DCCpp::IsPowerOnProg =
false;
23 byte DCCpp::ackThreshold = 0;
35 this->activeFlags[0] = 0;
36 this->activeFlags[1] = 0;
37 this->activeFlags[2] = 0;
38 this->activeFlags[3] = 0;
45 bitSet(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
50 bitClear(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
55 return bitRead(this->activeFlags[inFunctionNumber / 8], inFunctionNumber % 8);
60 return bitRead(this->activeFlagsSent[inFunctionNumber / 8], inFunctionNumber % 8) !=
isActivated(inFunctionNumber);
65 for (
int i = 0; i < 4; i++)
66 this->activeFlagsSent[i] = this->activeFlags[i];
69 #ifdef DCCPP_DEBUG_MODE 70 void FunctionsState::printActivated()
72 for (
int i = 0; i < 32; i++)
89 static bool first =
true;
97 #ifdef USE_TEXTCOMMAND 104 #if defined(DCCPP_DEBUG_MODE) && defined(DCCPP_PRINT_DCCPP) 120 #ifndef USE_ONLY1_INTERRUPT 121 void DCCpp::beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
123 DCCppConfig::DirectionMotorA = inOptionalDirectionMotor;
125 void DCCpp::beginMain(uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
129 #ifdef DCCPP_DEBUG_MODE 133 DCCppConfig::SignalEnablePinMain = inSignalEnable;
134 DCCppConfig::CurrentMonitorMain = inCurrentMonitor;
137 if (inSignalPin == UNDEFINED_PIN)
139 #ifdef DCCPP_DEBUG_MODE 140 Serial.println(
"No main track");
145 mainMonitor.
begin(DCCppConfig::CurrentMonitorMain, DCCppConfig::SignalEnablePinMain, (
char *)
"<p2>");
149 if (DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
150 digitalWrite(DCCppConfig::SignalEnablePinMain, LOW);
152 #ifdef DCCPP_DEBUG_MODE 153 Serial.print(F(
"beginMain achivied with pin "));
154 Serial.println(inSignalPin);
158 #ifndef USE_ONLY1_INTERRUPT 159 void DCCpp::beginProg(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
161 DCCppConfig::DirectionMotorB = inOptionalDirectionMotor;
163 void DCCpp::beginProg(uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
166 DCCppConfig::SignalEnablePinProg = inSignalEnable;
167 DCCppConfig::CurrentMonitorProg = inCurrentMonitor;
170 if (inSignalPin == UNDEFINED_PIN)
172 #ifdef DCCPP_DEBUG_MODE 173 Serial.println(
"No prog track");
178 progMonitor.
begin(DCCppConfig::CurrentMonitorProg, DCCppConfig::SignalEnablePinProg, (
char *)
"<p3>");
182 #ifdef DCCPP_DEBUG_MODE 183 Serial.print(F(
"beginProg achivied with pin "));
184 Serial.println(inSignalPin);
190 DCCpp::programMode =
false;
191 DCCpp::panicStopped =
false;
192 DCCpp::ackThreshold = 30;
194 DCCppConfig::SignalEnablePinMain = UNDEFINED_PIN;
195 DCCppConfig::CurrentMonitorMain = UNDEFINED_PIN;
197 DCCppConfig::SignalEnablePinProg = UNDEFINED_PIN;
198 DCCppConfig::CurrentMonitorProg = UNDEFINED_PIN;
200 #ifndef USE_ONLY1_INTERRUPT 201 DCCppConfig::DirectionMotorA = UNDEFINED_PIN;
202 DCCppConfig::DirectionMotorB = UNDEFINED_PIN;
204 DCCppConfig::SignalPortMaskMain = 0;
205 DCCppConfig::SignalPortMaskProg = 0;
208 mainMonitor.
begin(UNDEFINED_PIN, UNDEFINED_PIN,
"");
209 progMonitor.
begin(UNDEFINED_PIN, UNDEFINED_PIN,
"");
212 pinMode(SDCARD_CS, OUTPUT);
213 digitalWrite(SDCARD_CS, HIGH);
222 #ifdef DCCPP_DEBUG_MODE 224 Serial.println(F(
"begin achieved"));
230 void DCCpp::beginEthernet(uint8_t *inMac, uint8_t *inIp, EthernetProtocol inProtocol)
233 for (
int i = 0; i < 4; i++)
234 DCCppConfig::EthernetIp[i] = inIp[i];
236 for (
int i = 0; i < 6; i++)
237 DCCppConfig::EthernetMac[i] = inMac[i];
239 DCCppConfig::Protocol = inProtocol;
242 Ethernet.begin(inMac);
244 Ethernet.begin(inMac, inIp);
246 DCCPP_INTERFACE.begin();
247 #ifdef DCCPP_DEBUG_MODE 250 Serial.println(F(
"beginEthernet achieved"));
255 #ifdef DCCPP_PRINT_DCCPP 262 Serial.println(F(
"*** DCCpp LIBRARY ***"));
266 Serial.println(F(DCCPP_LIBRARY_VERSION));
267 Serial.print(F(
"COMPILED: "));
268 Serial.print(__DATE__);
269 Serial.print(F(
" "));
270 Serial.println(__TIME__);
278 #ifdef ARDUINO_ARCH_AVR 279 Serial.print(F(
"\n\nDCC SIG MAIN(DIR): "));
280 Serial.println(DCC_SIGNAL_PIN_MAIN);
283 #ifndef USE_ONLY1_INTERRUPT 284 if (DCCppConfig::DirectionMotorA != UNDEFINED_PIN)
286 Serial.print(F(
" DIRECTION: "));
287 Serial.println(DCCppConfig::DirectionMotorA);
291 if (DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
293 Serial.print(F(
" ENABLE(PWM): "));
294 Serial.println(DCCppConfig::SignalEnablePinMain);
297 if (DCCppConfig::CurrentMonitorMain != UNDEFINED_PIN)
299 Serial.print(F(
" CURRENT: "));
300 Serial.println(DCCppConfig::CurrentMonitorMain);
303 #ifdef ARDUINO_ARCH_AVR 304 Serial.print(F(
"\n\nDCC SIG PROG(DIR): "));
305 Serial.println(DCC_SIGNAL_PIN_PROG);
308 #ifndef USE_ONLY1_INTERRUPT 309 if (DCCppConfig::DirectionMotorB != UNDEFINED_PIN)
311 Serial.print(F(
" DIRECTION: "));
312 Serial.println(DCCppConfig::DirectionMotorB);
315 if (DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
317 Serial.print(F(
" ENABLE(PWM): "));
318 Serial.println(DCCppConfig::SignalEnablePinProg);
320 if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN)
322 Serial.print(F(
" CURRENT: "));
323 Serial.println(DCCppConfig::CurrentMonitorProg);
326 #if defined(USE_EEPROM) 327 #if defined(USE_TURNOUT) 328 Serial.print(F(
"\n\nNUM TURNOUTS: "));
331 #if defined(USE_SENSOR) 332 Serial.print(F(
" SENSORS: "));
335 #if defined(USE_OUTPUT) 336 Serial.print(F(
" OUTPUTS: "));
341 #ifdef USE_TEXTCOMMAND 342 Serial.print(F(
"\n\nINTERFACE: "));
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(
":"));
350 Serial.println(DCCppConfig::EthernetMac[5], HEX);
353 Serial.print(F(
"IP ADDRESS: "));
354 Serial.println(Ethernet.localIP());
363 Serial.println(F(
"SERIAL"));
376 panicStopped = inStop;
378 #ifdef DCCPP_DEBUG_MODE 379 Serial.print(F(
"DCCpp PanicStop "));
380 Serial.println(inStop ? F(
"pressed"):F(
"canceled"));
394 if (inProg && DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
396 digitalWrite(DCCppConfig::SignalEnablePinProg, HIGH);
398 IsPowerOnProg =
true;
401 if (inMain && DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
403 digitalWrite(DCCppConfig::SignalEnablePinMain, HIGH);
405 IsPowerOnMain =
true;
410 DCCPP_INTERFACE.print(
"<p1>");
411 #if !defined(USE_ETHERNET) 412 DCCPP_INTERFACE.println(
"");
420 if (inProg && DCCppConfig::SignalEnablePinProg != UNDEFINED_PIN)
422 digitalWrite(DCCppConfig::SignalEnablePinProg, LOW);
424 IsPowerOnProg =
false;
426 if (inMain && DCCppConfig::SignalEnablePinMain != UNDEFINED_PIN)
428 digitalWrite(DCCppConfig::SignalEnablePinMain, LOW);
430 IsPowerOnMain =
false;
435 DCCPP_INTERFACE.print(
"<p0>");
436 #if !defined(USE_ETHERNET) 437 DCCPP_INTERFACE.println(
"");
444 byte old = DCCpp::ackThreshold;
445 DCCpp::ackThreshold = inNewValue;
451 bool DCCpp::setThrottle(
volatile RegisterList *inpRegs,
int nReg,
int inLocoId,
int inStepsNumber,
int inNewSpeed,
bool inForward)
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(
" )"));
463 inpRegs->setThrottle(nReg, inLocoId, inNewSpeed, inForward);
470 #ifdef DCCPP_DEBUG_MODE 471 if (inpRegs == &mainRegs)
473 if (nReg > MAX_MAIN_REGISTERS)
474 Serial.println(F(
"Invalid register number on main track."));
478 if (nReg > MAX_PROG_REGISTERS)
479 Serial.println(F(
"Invalid register number on programming track."));
486 byte threeByte1 = 160;
490 for (byte func = 0; func <= 28; func++)
508 oneByte1 += (1 << (func - 1));
523 twoByte1 += (1 << (func - 5));
537 threeByte1 += (1 << (func - 9));
551 fourByte2 += (1 << (func - 13));
565 fiveByte2 += (1 << (func - 21));
588 inpRegs->setFunction(nReg, inLocoId, b1, b2);
592 #ifdef DCCPP_DEBUG_MODE 593 Serial.print(F(
"DCCpp SetFunctions for loco"));
594 Serial.print(inLocoId);
595 Serial.print(
" / Activated : ");
596 inStates.printActivated();
604 temp = inReg->readCV(29, 100, 200);
605 if ((temp != -1) && (bitRead(temp, 5))) {
607 id = inReg->readCV(18, 100, 200);
609 temp = inReg->readCV(17, 100, 200);
611 id =
id + ((temp - 192) << 8);
617 id = inReg->readCV(1, 100, 200);
622 bool DCCpp::writeCv(
volatile RegisterList *inReg,
int inCv, byte inValue,
int callBack,
int callBackSub)
624 #ifdef DCCPP_DEBUG_MODE 625 Serial.print(F(
"DCCpp WriteCv "));
627 Serial.print(F(
" : "));
628 Serial.println(inValue);
631 return inReg->writeCVByte(inCv, inValue, callBack, callBackSub);
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);
645 mainRegs.setAccessory(inAddress, inSubAddress, inActivate);
648 #ifdef DCCPP_DEBUG_MODE 649 void DCCpp::CheckPowerConnectionsWithLeds(uint8_t aDirPin,
unsigned int inDelay)
651 if (DCCppConfig::SignalEnablePinMain != 255 || DCCppConfig::SignalEnablePinProg != 255)
653 Serial.print(F(
"DCC signal is started, this function cannot operates."));
657 pinMode(aDirPin, OUTPUT);
658 digitalWrite(aDirPin, HIGH);
661 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 panicStop(bool inStop)
static bool needsRefreshing()
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)
bool isActivated(byte inFunctionNumber)
static boolean checkTime()
void inactivate(byte inFunctionNumber)
bool isActivationChanged(byte inFunctionNumber)
void activate(byte inFunctionNumber)
static void beginMainDccSignal(uint8_t inSignalPin)
static void showConfiguration()