Le 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. pins 14 to 19 for A0 to A5
// 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.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// msport version for Locoduino paper 27 03 2022 and dilc3 pcb
//
https://www.locoduino.org/spip.php?article318//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: GOTO lines 22 and 47 to configure some data! <---- je ne sais pas ce qu'il faut faire!!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <DCC_Decoder.h>
#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 19 above!
{
accessory[0].address = 1; // K1 connector
accessory[0].durationMilli = 250;
accessory[0].outputPin = 4;
accessory[0].outputPin2 = 3;
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 = 2; // K2 connector
accessory[1].durationMilli = 250;
accessory[1].outputPin = 6;
accessory[1].outputPin2 = 5;
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 = 3; // K3 connector
accessory[2].durationMilli = 250;
accessory[2].outputPin = 8;
accessory[2].outputPin2 = 7;
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 = 4; // K4 connector
accessory[3].durationMilli = 250;
accessory[3].outputPin = 10;
accessory[3].outputPin2 = 9;
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 = 5; // K5 connector
accessory[4].durationMilli = 250;
accessory[4].outputPin = 12;
accessory[4].outputPin2 = 11;
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 = 6; // K6 connector
accessory[5].durationMilli = 250;
accessory[5].outputPin = 15; // A1
accessory[5].outputPin2 = 14; // A0
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 = 7; // K7 connector
accessory[6].durationMilli = 250;
accessory[6].outputPin = 17; // A3
accessory[6].outputPin2 = 16; // A2
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
accessory[7].address = 8; // K8 connector
accessory[7].durationMilli = 250;
accessory[7].outputPin = 19; // A5
accessory[7].outputPin2 = 18; // A4
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<maxaccessories; i++)
{
if( accessory
.outputPin )
{
pinMode( accessory.outputPin, OUTPUT );
digitalWrite( accessory.outputPin, LOW);
}
if( accessory.outputPin2 )
{
pinMode( accessory.outputPin2, OUTPUT );
digitalWrite( accessory.outputPin2, LOW);
}
}
} // END ConfigureDecoderFunctions
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DCC packet handler
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
// Convert NMRA packet address format to human address
address -= 1;
address *= 4;
address += 1;
address += (data & 0x06) >> 1;
boolean enable = (data & 0x01) ? 1 : 0;
for(int i=0; i<maxaccessories; i++)
{
if( address == accessory.address )
{
if( enable ) accessory.output = 1;
else accessory.output = 0;
}
}
} // END BasicAccDecoderPacket_Handler
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Setup (run once)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
ConfigureDecoderFunctions();
DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
pinMode(2,INPUT_PULLUP); //Interrupt 0 with internal pull up resistor (can get rid of external 10k)
pinMode(13,OUTPUT);
digitalWrite(13,LOW); //turn off Arduino led at startup
for (int n=0; n<maxaccessories; n++) accessory[n].output = 0; //all servo's to min angle and functions to 0
} //END setup
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main loop (run continuous)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
static int addr = 0;
DCC.loop(); // Loop DCC library
if( ++addr >= 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
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////