Strekdambaan, Arduino en Fotografie
/

 

DCC protocollen.

Voor de aansturing van de treinen, wissels, seinen en eventuele andere modules wordt gebruik gemaakt van het DCC protocol.
Je hebt een DCC centrale nodig. Deze genereert de DCC berichten voor de bediening van de treinen en wissels.

Ik maak gebruik van van de de Intellibox I van Uhlenbrock, zie ook desbetreffende pagina.

Waarom meer uitleg over het DCC protocol.

Maak je alleen gebruik van koop producten voor de aansturing van wissels, seinpalen en eventueel andere devices dan heb je geen verdere kennis van het protocol nodig. Omdat ik met Arduino projecten aan het uitvoeren ben voor de aansturing van mijn seinpalen op basis van door Koploper gestuurde commando's en o.a. de standen van wissels moet wel inzicht hebben in de commando structuur. Ik heb tot nu toe mijn wisseldecoders gekocht (Littfinski Data Technik), type SA-DEC-4_DC. Deze decoder kan 4 wissels aansturen. Ze zijn niet goedkoop. Nu ik de Arduino tot mijn beschikking heb en een goede Arduino software bibliotheek heb om DCC commando's te decoderen kan ik zowel voor de wissels als de seinen goedkope aanstuurmodules maken. Voor de aansturing van seinen gebruikt Koploper ook 'wissel commando's'. Voor meer informatie zie de pagina's wissels aansturen en seinen aansturen.

De DCC protocollen zijn gestandaardiseerd door de DCC werkgroep van de NMRA organisatie. De specificaties zijn veel omvattend maar de aansturing van wissels en seinen wordt slechts een klein gedeelte van de berichten (commando's) gebruikt. Alle specificaties zijn vastgelegd in NMRA Standards and Recommended Practices.

Op de site Learn about Digital Command (Engels) is veel informatie over DCC en aanverwante items te vinden.

Voorbeeld van het DCC protocol:







Ik ben alleen geïnteresseerd in het document S-9.2.1 dat de Extended Packet Formats beschrijft. Hieronder een uittreksel van het relevante gedeelte:

Format Definitions

Within this Standard, bits within the address and data bytes will be defined using the following abbreviations.
Individual bytes within a specific packet format are separated by spaces. Bytes which are within square [] brackets
can occur one or more times as necessary. Bits are numbered from right to left with bit 0 (the right most bit) being
the least significant bit (LSB) and bit 7 (the left most bit) being the most significant bit (MSB).


A = Address bit
0 = Bit with the value of "0"
1 = Bit with the value of "1"
U = bit with undefined value either a "1" or a "0" is acceptable
B = Bit Position / Address
C = Instruction Type field
F = Flag to determine Instruction Implementation
L = Low Order Binary State Control Address
H = High Order Binary State Control Address
S = Decoder Sub Address
V = CV Address Bit
D = Data
X = Signal Head Aspect Data Bit
E = Error Detection Bit

D: Accessory Digital Decoder Packet Formats

Accessory Digital Decoders are intended for control of a number of simple functions such as switch machine
control or turning on and off lights. It is permissible to develop Digital Decoders that respond to multiple addresses
so that more devices can be controlled by a single Digital Decoder.

Basic Accessory Decoder Packet Format

The format for packets intended for Accessory Digital Decoders is:

               {preamble} 0   10AAAAAA   0  1AAACDDD   0   EEEEEEEE  1

Accessory Digital Decoders can be designed to control momentary or constant-on devices, the duration of time each
output is active being controlled by configuration variables CVs #515 through 518. Bit 3 of the second byte "C" is
used to activate or deactivate the addressed device. (Note if the duration the device is intended to be on is less than
or equal the set duration, no deactivation is necessary.) Since most devices are paired, the convention is that bit "0"
of the second byte is used to distinguish between which of a pair of outputs the accessory decoder is activating or
deactivating. Bits 1 and 2 of byte two are used to indicate which of 4 pairs of outputs the packet is controlling. The
most significant bits of the 9-bit address are bits 4-6 of the second data byte. By convention these bits (bits 4-6 of
the second data byte) are in ones complement.
If operations-mode acknowledgement is enabled, receipt of a basic accessory decoder packet must be acknowledged
with an operations-mode acknowledgement.

Uitleg

Het meest rechtse bit (minst significant of LSB) van een (8 bit) byte is bit-0, het meest linkse bit (meest significant of MSB) is bit-7.
Je ziet er 3 bytes in het bericht zijn waarvan het derde byte EEEEEEEE voor de controle is (Error Detection Bits).

Het eerste byte begint met 10 en het tweede byte begint met 1. Dit geeft aan dat dit het Basic Accessory Decoder Packet is.

Het adres van de module bestaat uit 9 bits en is verdeeld over de twee bytes: AAAAAA en AAA. De 3 bits AAA (bit 4-6) bevatten de meest significante bits van het 9-bits adres, genoteerd in 2-complement.
Bit C (bit 3) van het tweede byte wordt gebruikt om het geadresseerde module te activeren of deactiveren.
Bit-1 en bit-2 van het tweede byte (de linkse twee DD's) zijn bedoeld voor de selectie van welke van mogelijk 4 paren uitgangen wordt aangestuurd.
Bit-0 van het tweede byte (de rechtse D) geeft aan welk van paar van de uitgangen van de decoder wordt geactiveerd of gedeactiveerd.

Hoe maken de Intellibox centrale en Koploper hier gebruik van

Aangezien in deze hobby wereld niet of nauwelijks specificaties worden gegeven hen ik dit zelf moeten uitzoeken.
Mijn vermoeden is dat alleen bit-0 van het tweede byte van belang is. Dit bit wordt ook in de voorbeeld code afgevangen.

Ik maak gebruik van wisseldecoders met 4 uitgangen (Littfinsky). Deze uitgangen krijgen elk een eigen DCC adres. Het adres van de eerste uitgang wordt met behulp van de Koploper of direct vanuit de DCC centrale geprogrammeerd. De andere 3 uitgangen krijgen dan de eerst volgende 3 adressen. Dus altijd groepjes van 4. Koploper stuurt het wisselcommando meerdere keren uit afhankelijk van de gekozen bekrachtigingstijd die per wissel instelbaar is. Standaard is deze ingesteld op 250ms en dus wordt er 10x om de ca. 25ms een (hetzelfde) commando uitgezonden. 

Bit-1 en bit-2 van het tweede byte (de linkse twee DD's) bevatten het nummer van de uitgang 00, 01, 10, 11. Bij het aansturen van het eerste adres van de decoder hoort DD = 00, enzovoort. Deze informatie is verder niet van belang omdat toch elke uitgang zijn eigen adres heeft.
Bit-0, de rechtse D bevat de wisselstand informatie: D = 0 is afbuigend, D = 1 is rechtdoor.

Gebruiken we een schakelaar (ook via een wisseldecoder) dan is D = 0 Aan en D = 1 Uit.

Voor een 2 standen sein is D = 0 Rood en D = 1 Groen

 Conclusie

Voor het gebruik van de informatie voor mijn eigen seinaansturingsproject is slechts één commando van belang. De andere worden genegeerd.

Voor de nog te ontwerpen eigen wisseldecoders is ook het aantal commando's ook van belang omdat deze de bekrachtigingstijd bepalen.
Opmerking: alle wissels hebben geen automatische eindafschakeling meer (was te onbetrouwbaar). Dit betekent dat de decoder moet garanderen dat de aanstuurpuls nooit te lang is omdat anders de wisselspoel door kan branden.

Ter illustratie hoe de relevante informatie uit het packet wordt gedecodeerd hier onder een deel van de DCC-decoder software (DCC_Decoder.cpp - Arduino library for NMRA DCC Decoding) . De vet gemaakte regel is de aan roep van de afhandelende routine in mijn programma.    

       ///////////////////////////////////////////////////////////
            // Handle as a basic accessory decoder packet
        if( ((gPacket[0] & 0xC0) == 0x80)  &&  ((gPacket[1] & 0x80) == 0x80) )
        {
            address = ~gPacket[1] & 0x70;
            address = (address<<2) + (gPacket[0] & 0x3F);
            gLastPacketToThisAddress = (address==DCC.Address());
            if( gLastPacketToThisAddress || address == 0x003F || func_BasicAccPacket_All_Packets )    // 0x003F is broadcast packet
            {
                if( !gHandledAsRawPacket && func_BasicAccPacket )
                {
                        // Call BasicAccHandler           Activate bit                         data bits
                    (func_BasicAccPacket)( address, ((gPacket[1] & 0x08) ? true : false), (gPacket[1] & 0x07));
                }
            }
            GOTO_DecoderReset( kDCC_OK_BASIC_ACCESSORY );
        }

Mijn afhandelende functie:

void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
    // Converteer NMRA packet address format to human address
    address -= 1;
    address *= 4;
    address += 1;
    address += (data & 0x06) >> 1;
    address = address + DCC_AdresCorrectie;

    bool enable = (data & 0x01) ? true : false;

... etc verwerking ....