By combining an Arduino and a DCC Interface you can easily produce your own DCC Accessory Decoder.
Here is a simple sketch showing how to create an accessory decoder that has 2 LEDs driven by 2 accessory addresses.
An example can be seen on YouTube here : DCC Accessory Decoder Example
Using the MynaBay DCC Library, create the following sketch…..
// Accessory Decoder - www.dccinterface.com
#include <NmraDcc.h>
#include <Wire.h>
typedef struct
{
int address;
uint8_t arduinoPin;
}
DCCAccessoryAddress;
// this is designed for 2 addresses, if you want more decoder functions, increase this to 3 for 3, 5 for 5, etc etc etc
DCCAccessoryAddress gAddresses[2];
NmraDcc Dcc;
uint16_t lastAddr = 0xFFFF;
uint8_t lastDirection = 0xFF;
//
// Decoder Init
//
void ConfigureDecoder()
{
// this is address number 1
gAddresses[0].address = 200;
gAddresses[0].arduinoPin = A6;
// this is address number 2
gAddresses[1].address = 201;
gAddresses[1].arduinoPin = A7;
// if you wanted more, make sure the array on line 13 is bigger, and start adding lines as follows
//gAddresses[2].address = 202;
//gAddresses[2].arduinoPin = A8;
//gAddresses[3].address = 203;
//gAddresses[3].arduinoPin = A9;
// the above are commented out, and just for example only
// set the pin for output
for (int i = 0; i<(int)(sizeof(gAddresses) / sizeof(gAddresses[0])); i++)
{
pinMode(gAddresses[i].arduinoPin, OUTPUT);
}
}
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput(uint16_t Addr, uint8_t Direction, uint8_t OutputPower)
{
Serial.print("notifyDccAccTurnoutOutput: ");
Serial.print(Addr, DEC);
Serial.print(',');
Serial.print(Direction, DEC);
Serial.print(',');
Serial.println(OutputPower, HEX);
for (int i = 0; i < (sizeof(gAddresses) / sizeof(DCCAccessoryAddress)); i++)
{
if ((Addr == gAddresses[i].address) && ((Addr != lastAddr) || (Direction != lastDirection)) && OutputPower)
{
lastAddr = Addr;
lastDirection = Direction;
Serial.print(F("Activating Decoder Address "));
Serial.println(i, DEC);
if (Direction)
{
Serial.print(F("Turning Accessory On : "));
Serial.println(gAddresses[i].arduinoPin, DEC);
digitalWrite(gAddresses[i].arduinoPin, HIGH);
break;
}
else
{
Serial.print(F("Turning Accessory Off : "));
Serial.println(gAddresses[i].arduinoPin, DEC);
digitalWrite(gAddresses[i].arduinoPin, LOW);
break;
}
}
}
}
void setupDCCDecoder()
{
Serial.println(F("Setting up DCC Decorder..."));
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(0, 2, 1);
// Call the main DCC Init function to enable the DCC Receiver
Dcc.init(MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0);
// Configure the Decoder
ConfigureDecoder();
}
void setup()
{
Serial.begin(9600);
Serial.println(F("Accessory Decoder - www.dccinterface.com"));
Serial.println(F("Initializing...."));
setupDCCDecoder();
}
void loop()
{
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
}
The DCC Library reads the DCC Input via the D2 ( Digital Pin 2 ) external interrupt pin on the Arduino – if you are using the DCC Interface standalone board – connect the “ARD” pin to D2 as shown here…
The sketch turns on 2 LEDs, which are connected to A4 and A3.
As you operate accessory addresses on your DCC handset, you will see the addresses and the enabled status ( point open or closed ) appear on the serial monitor ( Open Serial Monitor from Tools ) and depending on if you turn on or turn off the accessory decoder, the LED will turn on or turn off.