Arduino + DCC Interface = Accessory Decoder

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…..

// DCC Accessory Decoder Example Sketc v1.1 - www.dccinterface.com

#include <DCC_Decoder.h>
#include <Wire.h>

// Defines and structures
//
#define cDCC_INTERRUPT 0

typedef struct
{
	int address;
	uint8_t arduinoPin;
	//int stationBack;
}
DCCAccessoryAddress;
DCCAccessoryAddress gAddresses[2];

//
// Decoder Init
//
void ConfigureDecoder()
{
	// this is home
	gAddresses[0].address = 200;
	gAddresses[0].arduinoPin = A3;

	gAddresses[1].address = 201;
	gAddresses[1].arduinoPin = A4;

	// set the pin for output
	for (int i = 0; i<(int)(sizeof(gAddresses) / sizeof(gAddresses[0])); i++)
	{
		pinMode(gAddresses[i].arduinoPin, OUTPUT);
	}
}

//
// Accessory packet handler - This is where we react to DCC Addresses
//
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;

	Serial.print(F("Basic addr: "));
	Serial.print(address, DEC);
	Serial.print(F(" activate: "));
	Serial.println(enable, DEC);

	performAction(address, enable);
}

void performAction(int address, bool enabled)
{
	for (int i = 0; i<(int)(sizeof(gAddresses) / sizeof(gAddresses[0])); i++)
	{
		if (address == gAddresses[i].address)
		{
			Serial.print(F("Activating Decoder Address "));
			Serial.println(i, DEC);

			if (enabled)
			{
				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..."));
	DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
	ConfigureDecoder();
	DCC.SetupDecoder(0x00, 0x00, cDCC_INTERRUPT);
}

void setup()
{
	Serial.begin(9600);

	Serial.println(F("Accessory Decoder - www.dccinterface.com"));

	Serial.println(F("Initializing...."));

	setupDCCDecoder();
}

void loop()
{
	
	DCC.loop();
}

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.