DCC++ vs NMRA (accessory commands)

schufti Apr 6, 2021

  1. schufti

    schufti TrainBoard Member

    30
    3
    2
    Hi,
    looking at NMRA standard s-9.2.1_2012_07 I see

    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.

    in the source of DCC++EX I see

    b[0] = address % 64 + 128;
    // first byte is of the form 10AAAAAA, where AAAAAA represent 6 least signifcant bits of accessory address
    b[1] = ((((address / 64) % 8) << 4) + (number % 4 << 1) + activate % 2) ^ 0xF8;
    // second byte is of the form 1AAACDDD, where C should be 1, and the least significant D represent activate/deactivate

    where function of bits 3 and 0 of the 2nd command byte are contradictory (underlined parts).
    I have verified with sniffers that output complies with source code
    Acc 9 3:0 1 On 10000011 11111001
    Acc 9 3:0 1 Off 10000011 11111000
    Acc 9 3:0 0 On 10000011 11110001
    Acc 9 3:0 0 Off 10000011 11110000
    and decoders do work with this signal (allthough "C" didn't have any effect on my decoder, it might depend on CVs?).
    But why? Is the NMRA document outdated? Did the specification change? Is it documented somewherer?

    any hint much appreciated,
    schufti
     
  2. schufti

    schufti TrainBoard Member

    30
    3
    2
    ok, this seems to work due to weird premises:
    1) accessory only being turnouts (or treating all other accessory as such)
    2) decoder automatically switching off the output

    why?
    for a turnout with the decoder automatically switching off the output it is sufficient to power on either of the coils via DCC to switch between straight/diverge. So in DCC one only needs "power on" command (bit 3 in byte 2 can be fixed to "on") for either of the usually paired outputs. So bit 0, indicating which of the paired outputs to use, translates the on/off to straight/diverge.

    problem (as I see it):
    since there is no actual DCC++ command to send "switch off" for a specific decoder output, all accessories need to be treated as turnouts, using one address to switch on and another to switch off, reducing the useable addresses to 50%.

    this is my analysis of the source code. please prove me wrong, I would like to gain more insight on hidden gems in the code.
    Right now I cannot see how to control single decoder outputs (e.g. lights) as foreseen in s-9.2.1_2012_07 with DCC++.
     
    Last edited: Apr 7, 2021
  3. schufti

    schufti TrainBoard Member

    30
    3
    2
    please don't get me wrong. I am not criticizing DCC++, just want to know why it is implemented this way.
    If there are true NMRA compatible accessory decoders for e.g. lights, how to control them with DCC++?
    Do all the "base stations" implement the "nonNMRA" version of accessory commands?
    Then what is the meaning of NMRA standard? How do manufacturers get approved (nmra id) if they implement non NMRA compatible command? Is the behaviour selectable on "professional" decoders?

    I really would appreciate your comment.
     
  4. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    If you ask me, there is no NMRA standard. There is a just a bunch of confusing and poorly followed "suggestions" ;) I don't mean to slight the NMRA, it is a hobby, not the defense department and it is a bunch of volunteers (for the most part) who come and go. And because there aren't millions of dollars of profit potential for many of these manufacturers (some of who are very small companies), they tend to interpret the spec as best they can, or to try to advance it to get some functionality they want to implement. And then, of course there is politics. Maybe @Atani can jump in and comment on questions like "is the behavior selectable"

    I spent weeks researching this and talking to many experts. Geoff Bunza and 2 of the head developers at JMRI provided me with some good information. It might help to start at the beginning. Lenz developed the Marklin system that the NMRA specification was based on. If you read the "LS100/110 Accessory DCC Decoder Manual", that might help explain things if you haven't already. As Geoff explained his take on the source of the confusion to me:

    "The LS100 was designed to operate twin coil switch machines and had added "features" for stall motors and LEDs. The pulse output was inherent in the LS100 and could be programmed. The so-called activation bit was unnecessary for a pulse output as it effectively turned itself off (deactivated) after the pulse duration. But LEDs still needed a way to be shut off -- hence the deactivation bit. The LS100 could control 4 twin coils hence the 2 bit 1,2 sub address. One solenoid in the twin coil set was selected by bit 0."

    When technology evolved, some decoder manufacturers did not want the complexity of the Lenz LS100 or to adopt the "twin-coil concept", so they went a different way. There are not just 2 interpretations, for example there are decoders that use the last 3 bits together to be able to address 8 bits of data. As Geoff also mentioned, if you bought from a Vendor who made both the CS and the decoders, the "standard" was self-enforced. The rest of the CS creators had to choose a path. Since JMRI is THE standard with the largest user base, their default method is the path we chose. It made the most sense and ensured the most compatibility. We have plans to take a look again soon and see if it makes sense to have a switchable option, but so far not a single person has said their decoder does not work with the "Twin-Coil" accessory packet method.

    If you have any input, we are always happy to hear it. We literally improve DCC++EX every single day. You can see all the commits in GitHub ;) We did add "linear addressing". So we can accept a command that uses the address, subaddress pair OR just the equivalent integer value. So instead of <a ADDRESS SUBADDRESS ACTIVATE> where ADDR is 0-511 and subaddress is 0-3 you can just enter <a LINEARADDR ACTIVATE> where LINEARADDR is 0-2047. We did the same thing with Function commands. Instead of the convoluted function groups and having to do math, we now have <F CAB FUNC ON|OFF> where FUNC is 0-68 (we support the RCN-212 spec for extended functions instead of just F0-F28.

    Fred
    N4IXL
    DCC-EX
     
  5. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    What are you using to control accessories? If it is JMRI or Engine Driver, then it just works. If you are trying to program something yourself, the command is <a ADDRESS ON> and OFF to turn them off. (0 and 1) work too for off and on. We haven't had any reports yet of a decoder that didn't respond to the packet that turns bit 0 of the second packet on and off instead of the "C" bit. Most decoders that can use these old switch machines, have a way internally to handle the pairs. Let us know if you find something that doesn't work as you expected.
     
  6. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    The 9.2.2 spec shows the two address modes for accessory decoders:

    CV29, Bit 6 = Addressing Method
    ‘0’= Decoder Address method
    ‘1’ = Output Address method

    Decoder Address Method is the 4 turnout "switch machine" addressing with Address/SubAddress pair
    Output Address Method combines the two into one accessory address and the turnouts are numbered in a linear fashion. This is supposed to use CV512 and CV521 (1 and 9) to hold the address of the first accessory.

    In either case, our packet is the same, this is just how a user would enter or see the address and output.

    If you look at the code the NMRA has in it's repository here: https://github.com/mrrwa/NmraDcc/blob/master/NmraDcc.h

    It defaults to Output Address Method so puts the 2 parts of the address into one 11 bit address. Then it populates these:

    Direction - Turnout direction. It has a value of 0 or 1. From bit 0 of the 3 DDD bits in the accessory packet.
    OutputPower - Output On/Off. From Packet "C" bit. 0 - Output pair is off, 1 - Output pair is on.

    Power makes no sense for a switch or signal, so that is always on for us and "direction" controls the accessory just as if it was a turnout or a relay or a light switch.

    If you look at any of the example programs where they use the callback routine "notifyDccAccTurnoutOutput()", you will see that the "direction" (bit 0, not the C bit) is always used. If you look here, you can see how they use it to turn on an LED: Geoff Bunza's 17 Function Decoder AccDec_17LED_1Ftn.ino and you can see here how they are using the "C" bit to check if power is on to Set a Turntable Position, but still using bit 0 (direction) to move the turntable. In this case, it is a real direction, "front" or "back". Then they give it the steps to move.
     
  7. schufti

    schufti TrainBoard Member

    30
    3
    2
    Hello Fred,
    thank you very much for your elaborate answer. Things now make much more sense to me (apart from NMRA providing compliance test certificates, IDs, but ignoring the actual facts and hiding their compatibility with reality in some source instead of the documentation).

    Some background: a nephew of mine got a ~20sqm model train layout that had to be cut to pieces for moving to his home. As you can see from the picture schalttafel.jpg (only showing 1/3 of the wiring harness), it was not feasible to restore the wiring and I (the electronics guy in the family) was asked to "help out". So for a first step I decided to modernise the accessory control only as the boy insists on the "hands on" feeling of analog operation (and full digitalisation is way over budget). The diy accessory controller is allready finalised dekoder.jpg , now I am busy with the design of a layout based switchboard (pushbuttons and leds on track graphics STafel_modern.jpg ). So I tried to get all this most compatible for later expansion. As reference I used DCC++EX with RockRail (which to me looked more intuitive to setup and operate). Then I discovered some discrepancies between the options selectable for trains/decoders with the DCC++EX commands, so I tried to get the loose ends connected... not really helped by the fact that DCC sniffers did not agree on command analysis, showing allmost all combinations possible and most decoder examples being in line with the DCC++ implementation (despite some using the NMRA codebase you mentioned). Maybe I should have gone for sth like loconet or BiDiB but DCC looked very tempting, not even needing seperate wiring.

    I see that in the git there now is some compile time option for switching from 128 to 28 speed step mode. So my first "rants" got somehow ack'ed but in a way that might not be usefull to most (who wants to abstain from 128 mode for some/few old 28 mode loco). My comments on the current sensing on the l298 or pololu shield (switch voltage reference, calculation of conversion factor) didn't get any attention yet.

    Unfortunately the devs decided not to discuss in the forum but somewhere "online" (another platform to register) where the time difference is a drawback for people from different continents.

    thanks for your time,
    schufti
     
    Last edited: Apr 10, 2021
  8. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    The NMRA standard for accessory decoders covers both use cases (eight on/off outputs or four paired outputs). However, from a manufacturer perspective the only implemented option is paired outputs. The eight output pin option has not been implemented by any manufacturer that I'm aware of, likely due to the original implementation being to control dual coil switch motors. This also plays into the C bit (activate bit) usage, originally this was needed for the dual coil switch motors so they were not left "ON" for longer than necessary. But with the more modern alternatives almost all CS will always send the C bit as 1 (On) and never send it as 0 (Off), those that do will typically send it after a configurable delay. Note that many of the Arduino DCC accessory decoders ignore the C bit entirely which could lead to unintended consequences.
     
    FlightRisk likes this.

Share This Page