DCC shield for Arduino

luca 25/09/2017 2

In addition to the love for electronics, in my (little) spare time I’m working with my friend Davide on a model railway in H0 scale; in particular my main task is to take care of the digital control of locos, turnouts and accessories.

Davide’s main job is to create architectural and railway models. You can see his projects and follow the updates to our model railway on the dedicated Facebook page and website.

The de facto standard to digitally control a model railway is named DCC (Digital Command Control); it is a communication protocol defined by the american National Model Railroad Association. The specs of the protocol are available on NMRA’s website.

Using DCC, you control a loco sending commands through the rails to modules (decoders) installed within the loco itself: based on the commands it receives, the decoder controls motor, lights and in some cases also sounds and smoke generators…


DCC decoder installed in a locomotive

Specific decoders are also available to control turnouts and accessories:


turnout DCC decoder DCC by Esu

Thanks to Alex Shepherd and other developers, an Arduino library is available to receive and parse DCC commands.

You can install the library using the IDE’s Library Manager:


I designed in Eagle a simple shield to have an optocoupled connection between Arduino and the DCC bus:


The NmraDcc library requires that you connect the DCC signal to an Arduino pin which supports interrupts. Because of Arduino Uno has pin 2 and 3 with that feature, I added a jumper to the shield you can use to choose the pin:


The Eagle files for the shield are available on Github; in the same repository you can also find an example program, which changes color and brightness of an led based on speed and direction of the loco with id 10:

The use of the library is quite straightforward. First specify the pin for the DCC signal:

Dcc.pin(0, 2, 1);

The first parameter is the interrupt number, the second is the pin number and the third is the status of the internal pullup resistor (1 means enabled). You can find the link between pin and interrupt number in the official documentation:


Then initialize the library:

Dcc.init(MAN_ID_DIY, 10, 0, 0);

The first two parameters are the manufacturer and the version of the decoder. NMRA keeps a list of manufacturers and reserved the value 0x0D (constant MAN_ID_DIY) for opensource and DIY decoders:


With the third parameter you can change the default behaviour of the library:


while the last one is the EEPROM address from which the library stores its values.

To let the library process incoming packets, you have to call the process() method as frequently as possible in the loop:


If the library receives a command to change the speed/direction of a loco, it executes the callback function notifyDccSpeed:

void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, 

in this function I implemented the code that controls the led.

dccshield-02 dccshield-01


  1. mario 17/10/2017 at 16:36 - Reply

Leave A Response »

This website uses cookies to ensure you get the best experience on our website maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.