[code] ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Arduino DCC Solenoid Switch Decoder. // Author: Ruud Boer - January 2015 // This sketch turns an Arduino into a DCC decoder to drive max 8 dual coil solenoid switches. // The DCC signal is optically separated and fed to pin 2 (=Interrupt 0). Schematics: www.mynabay.com // Many thanks to www.mynabay.com for publishing their DCC monitor and -decoder code. // Aggiornamento Fabio 13/03/16 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTANT: GOTO lines 17 and 40 to configure some data! ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #define kDCC_INTERRUPT 0 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FILL IN ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const byte maxaccessories=8 ; //The number of switches you want to control with this Arduino ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct { int address; // Address to respond to byte output; // State of accessory: 1=on, 0=off (for internal use only) int outputPin; // Arduino output pin int outputPin2; // Arduino output pin2, used for solenoid junctions byte highlow; // State of outputpin: 1=HIGH, 0=LOW byte highlow2; // State of outputpin2: 1=HIGH, 0=LOW boolean finished; // Memory location that says the oneshot is finished boolean finished2; // Memory location that says the second oneshot (for solenoid) is finished int durationMilli; // ms flash time unsigned long onMilli; // for internal use unsigned long offMilli; // for internal use } DCCAccessoryAddress; DCCAccessoryAddress accessory[maxaccessories]; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Initialization: COPY - PASTE the structure as many times as you have switches and fill in the values you want. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void ConfigureDecoderFunctions() // The amount of accessories must be same as in line 26 above! { accessory[0].address = 10; accessory[0].durationMilli = 1000; accessory[0].outputPin = 6;//5 accessory[0].outputPin2 = 5;//6 accessory[0].highlow = 0; // Do not change this value accessory[0].highlow2 = 0; // Do not change this value accessory[0].finished = false; // Do not change this value accessory[0].finished2 = true; // Do not change this value accessory[0].output = 0; // Do not change this value accessory[1].address = 11; accessory[1].durationMilli = 1000; accessory[1].outputPin = 7;//8 accessory[1].outputPin2 = 8;//7 accessory[1].highlow = 0; // Do not change this value accessory[1].highlow2 = 0; // Do not change this value accessory[1].finished = false; // Do not change this value accessory[1].finished2 = true; // Do not change this value accessory[1].output = 0; // Do not change this value accessory[2].address = 12; accessory[2].durationMilli = 1000; accessory[2].outputPin = 10;//9 accessory[2].outputPin2 = 9;//10 accessory[2].highlow = 0; // Do not change this value accessory[2].highlow2 = 0; // Do not change this value accessory[2].finished = false; // Do not change this value accessory[2].finished2 = true; // Do not change this value accessory[2].output = 0; // Do not change this value accessory[3].address = 13; accessory[3].durationMilli = 1000; accessory[3].outputPin = 18; accessory[3].outputPin2 = 19; accessory[3].highlow = 0; // Do not change this value accessory[3].highlow2 = 0; // Do not change this value accessory[3].finished = false; // Do not change this value accessory[3].finished2 = true; // Do not change this value accessory[3].output = 0; // Do not change this value accessory[4].address = 14; accessory[4].durationMilli = 1000; accessory[4].outputPin = 16; accessory[4].outputPin2 = 17; accessory[4].highlow = 0; // Do not change this value accessory[4].highlow2 = 0; // Do not change this value accessory[4].finished = false; // Do not change this value accessory[4].finished2 = true; // Do not change this value accessory[4].output = 0; // Do not change this value accessory[5].address = 15; accessory[5].durationMilli = 1000; accessory[5].outputPin = 15;//14 accessory[5].outputPin2 = 14;//15 accessory[5].highlow = 0; // Do not change this value accessory[5].highlow2 = 0; // Do not change this value accessory[5].finished = false; // Do not change this value accessory[5].finished2 = true; // Do not change this value accessory[5].output = 0; // Do not change this value accessory[6].address = 16; accessory[6].durationMilli = 1000; accessory[6].outputPin = 4;//3 accessory[6].outputPin2 = 3;//4 accessory[6].highlow = 0; // Do not change this value accessory[6].highlow2 = 0; // Do not change this value accessory[6].finished = false; // Do not change this value accessory[6].finished2 = true; // Do not change this value accessory[6].output = 0; // Do not change this value //DISP. accessory[7].address = 9; accessory[7].durationMilli = 1000; accessory[7].outputPin = 11; accessory[7].outputPin2 = 12; accessory[7].highlow = 0; // Do not change this value accessory[7].highlow2 = 0; // Do not change this value accessory[7].finished = false; // Do not change this value accessory[7].finished2 = true; // Do not change this value accessory[7].output = 0; // Do not change this value // Setup output pins for(int i=0; i> 1; boolean enable = (data & 0x01) ? 1 : 0; for(int i=0; i= maxaccessories ) addr = 0; // Bump to next address to test if (accessory[addr].output == 1) { if (!accessory[addr].highlow && !accessory[addr].finished) { accessory[addr].highlow = 1; accessory[addr].offMilli = millis() + accessory[addr].durationMilli; } if (accessory[addr].highlow && millis() > accessory[addr].offMilli) { accessory[addr].highlow = 0; accessory[addr].finished = true; } accessory[addr].finished2 = false; } else // output==0 { accessory[addr].highlow=0; accessory[addr].finished = false; if (!accessory[addr].highlow2 && !accessory[addr].finished2) { accessory[addr].highlow2 = 1; accessory[addr].offMilli = millis() + accessory[addr].durationMilli; } if (accessory[addr].highlow2 && millis() > accessory[addr].offMilli) { accessory[addr].highlow2 = 0; accessory[addr].finished2 = true; } } if (accessory[addr].highlow) digitalWrite( accessory[addr].outputPin, HIGH); else digitalWrite( accessory[addr].outputPin, LOW); if (accessory[addr].highlow2) digitalWrite( accessory[addr].outputPin2, HIGH); else digitalWrite( accessory[addr].outputPin2, LOW); } //END loop ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [/code]