DCC shield for Arduino

by luca
13 comments

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-01

DCC decoder installed in a locomotive

Specific decoders are also available to control turnouts and accessories:

dcc-02

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:

dcc-03

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

dcc-04

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:

dcc-05

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:

[youtube id=”9P8VJvbLKmE” width=”600″ height=”350″]

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:

dcc-06

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:

dcc-07

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

dcc-08

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:

Dcc.process();

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, 
 DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps ) {

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

dccshield-02 dccshield-01

Related Posts

13 comments

mario Tuesday October 17th, 2017 - 04:36 PM Reply
lucadentella.it – DCC, decoder accessori per led Saturday November 25th, 2017 - 02:32 PM

[…] aver realizzato uno shield per interfacciare Arduino ad un bus DCC, vediamo oggi come realizzare un semplice decoder […]

Reply
Gianni Barbotti Sunday February 4th, 2018 - 03:55 PM

Ciao Luca, mi piacerebbe far azionare i servo da programmi quali RocRail o TrainController i quali gestiscono i protocolli di molte centrali digitali. Per fissare le idee ti chiedo se può essere possibile che dallo schema del tracciato visualizzato dal software tipo TrainController (o RocRail), modificando lo stato di un deviatoio col classico click del mouse, questo comando possa essere trasmesso, per mezzo della tua interfaccia qupresentata, ad Arduino e quindi alla scheda scheda 16-Channel 12 bit PWM Servo che azionerà il servo. Sono già in possesso dei seguenti sistemi DCC : Lenz LZV100+LI101F e Digitrax DCS 100 + PR3. Sono settimane che cerco di dare una risposta a questo quesito e mi pare di essere arrivato a bussare alla porta giusta per avere una risposta definitiva. Grazie in anticipo se avrai il tempo di rispondermi.
Nel caso di risposta affermativa, come posso reperire la shield già montata od in kit e con quali protocolli funziona?

Reply
luca Tuesday February 6th, 2018 - 08:51 AM

ciao Gianni. Si, ti confermo che quello che vuoi fare è proprio realizzare un “decoder accessori” che, rispondendo ai comandi DCC ricevuti dalla centrale (eventualmente “prodotti” da un software quale TC o Rocrail), esegua azioni quali muovere un servocomando. Non ho in vendita lo shield ma ho qualche avanzo del primo batch quindi posso mandarti il PCB… contattami dal sito!

Reply
Simon Friday February 16th, 2018 - 03:04 PM

these guys sell them either as a board, a kit or fully assembled

https://www.dccinterface.com/product/arduino-uno-model-railway-dcc-interface-shield/

Reply
luca Friday February 16th, 2018 - 04:20 PM

thanks, they don’t publish the schematics but from the photos it seems very similar to my design

Reply
Riccardo Friday March 9th, 2018 - 11:11 PM

Ma poi lo shield va collegato al booster?

Reply
luca Monday March 12th, 2018 - 09:07 AM

ciao riccardo, lo shield funziona come un “dispositivo” DCC, quindi va collegato al segnale DCC. Questo può provenire da un booster, direttamente dalla centrale, preso dalle rotaie… dipende dal layout del tuo plastico.

Reply
Andrea Saturday August 25th, 2018 - 03:42 PM

Ciao Luca,
complimenti per il bel lavoro.
Vorrei sapere se hai portato ancora avanti il progetto.
Mi piacerebbe capire se pensi sia possibile creare una specie di dialogo bidirezionale per sapere dove è il convoglio.
grazie

Andrea

Reply
luca Monday August 27th, 2018 - 08:39 AM

ciao Andrea, lo shield funziona e l’ho utilizzato in diversi altri progetti. Sto per pubblicare la versione nuova che consente anche di leggere le CV. Per conoscere la posizione dei treni, normalmente si utilizzando sensori di “feedback” appositi su un bus diverso (S88, XpressNet, Loconet…) a seconda poi della centralina/software che vuoi utilizzare. Esiste effettivamente anche il DCC “bidirezionale” ma richiede l’utilizzo di booster e centraline appositi.

Reply
Fiorenzo Friday December 28th, 2018 - 07:46 AM

Ciao Luca,

Complimenti per lavoro e descrizione.
E’ possibile acquistare il PCB?

Ciao
Fiorenzo

Reply
luca Friday December 28th, 2018 - 02:11 PM

Ciao Fiorenzo, ti scrivo via mail…

Reply
Eugenio Depaulis Thursday February 21st, 2019 - 09:03 AM

Ciao Luca, avrei la stessa richiesta di Fiorenzo.
Mi sai dire qualcosa?
Grazie

Eugenio

Reply

Leave a Comment