-
-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle Turnout vs. Accessory Packet format once and for all #141
Comments
Reading the NMRA spec, there are 9 bits allocated to the decoder address (0-511). And there are three bits allocated DDD (0-7) to specify the output to be set or reset. So it seems rather strange that most documentation refers to address and subaddress, with subaddress only being in the range of 0-3 or 1-4. There seem to be a few possibilities:
Surely the accessory command should be able to address all 8 outputs (4 pairs) on a decoder? |
This is one thing I've become an expert on ;) And once again, there are multiple standards. Most decoders use the address/subaddress method with bit 0 controlling closed/throw and bits 1 and 2 controlling the port (0-3). Maybe I'll write a paper on it with a pretty graphic, but it all comes down to twin coil switch machines which is before a lot of modelers time. and how they worked with 2 solenoids. And then a lot of the decoder manufacturers created decoders with 4 outputs to control 4 turnouts. Depending on the decoder or it's mode selection, you can control 4 turnouts or 8 single outputs. Controlling 8 means you use all three lower order bits and the C bit is activate/deactivate. According to the Wiki, "C activates/deactivates the addressed decoder as needed. The three data bits allow control of up to 8 functions (0-7), split into 2 pairs of 4 outputs." The question I have is how the 8 functions are supported by us. We don't currently touch the C bit. So how can we support a decoder with 8 outputs? |
By 'don't currently touch the C bit' I assume you mean it's 1 in every packet. So on receipt of the command, the decoder sets one or the other of the pair of outputs identified by bit zero, and then de-energises it after a time. |
Very few (if any) modern decoders reference this bit for their runtime usage. It was intended to be used to activate/deactivate dual coil switch machines. However, this functionality has been replaced over time with CDU or alternative switch machines. It does not pertain to selecting an output (0-7) on the decoder.
It is already being supported (indirectly). DCC++ currently supports the board:address (0-511 : 0-3) address format, when converting this to the on-the-wire DCC address the address selects which dcc output pair is selected to be acted upon and the least significant bit in the address selects which output of the pair is "active". |
Assume we continue to use the address/subaddress parameters as is. Then for a specific address/subaddress there are two outputs that can each be set to either of two states, by specifying a 0 or 1 in the LSB of the DDD field and a 0 or 1 in the C bit.
(The latter two commands being unnecessary when the decoder automatically resets the output). One possible way of doing this would seem, to me, to add a command which allows the D bit to be treated as a sub-sub-address and the C bit as the output state. This would allow each of the eight outputs to be set on or off independently. A separate command form would be retained to address a pair of outputs. For example,
A command in the form Note: I've used zero base for address, subaddress, and output number above for simplicity. They can equally well be 1 based where convention dictates (e.g. subaddress 1-4). |
The C bit is not used by any commercial decoders that I'm aware of and is always sent as "1" by virtually all DCC Command Stations (including the upcoming TCS one from my understanding). Additionally, all eight outputs are already controlled via the available commands using the least significant bit by DCC++ as a direction bit. Virtually all decoders on the market today use paired output mode with only one output active at any time. In the case of DIY decoders (arduino based) it is possible to control individual outputs BUT it is an optional configuration on the decoder, see the NmraDcc library code. However, the current board:index addressing scheme used in DCC++ has caused a lot of confusion and complications for users and switching to using the DCC address for a decoder (individual output or direction based output) can simplify this considerably for the users. |
I heared that there are CS (Roco Maus2 for example) which when you operate a turnout first send the command with C=1 (coil on) and then some ms later to the same address but with C=0 (coil off). But as I do not have the HW I can not verify this. Regards, |
I'm not an expert on accessory decoders, I don't own one of any brand. I'm relying on the manuals to understand what you can do with the various types on the market. The first manual I find on Google is the Hornby R8247. This has the ability to drive four output pairs, or eight independent outputs. Each of the outputs can be placed in 'continuous' mode where, once turned on, they stay on (rather than pulsing a fixed number of times). Can you explain how the output is turned off? Looks like a candidate for a packet with C=0? |
If it is "continuous" then yes the "C" bit could in theory be being used by the decoder when configured to use independent outputs mode. |
I may have found the answer myself. It looks like the decoder is able to take up eight consecutive sub addresses, i.e. sub addresses 0-3 (1-4) on two consecutive addresses. The manual doesn't go into details of the DCC commands but could feasibly be set on/off by toggling D bit 0. If other decoders all operate the same way then, as @atanisoft says, all eight outputs can be driven independently without changing the CS. The addressing style is a separate issue .. |
It would be very strange if any NMRA compliant decoders ignored the C-bit, as it is a requirement of the standard. Likewise, command stations that were not capable of generating packets with C=0 would surely be non-compliant too? So perhaps we still need to change the CS code to cover all bases. |
After a while I would like to bring up this issue again. (Please excuse my English in case of mistakes.) |
Add v4.0 announcement notes
The NMRA spec says that "C" below is activate/deactivate and the X in DDX handles which pair of outputs and the DD specifies which of the 4 outputs is being controlled. But... some decoders can allow DDX to be DDD so you can control 3 things or 2^3 thing (8)
Here is another wording of how acc. packets are being used in practice, despite how I read the specification:
Accessory decoder packet format:
UKBloke (AKA Chris) — 01/02/2021
But that's not an "accessory" its a "turnout"... and that's where we have so many issues when it comes to non-turnout accessories or non-dcc turnouts!
... and does that mean that to switch this turnout you need to send an "on" and an "off" with some delay between?
FlightRisk — 01/02/2021
True, thanks for making the distinction
But they don't make the distinction in the spec. So I'm not sure if a light or a servo is handled differently. You have 2 bytes and you fill them with 1s and 0s. So a light can be on/off which corresponds to throw/close. What are you seeing with non turnout accessories?
UKBloke (AKA Chris) — 01/02/2021
I'm not even looking........ I'm just trying to imagine the mess....
I'm presuming these accessory messages are coming from JMRI... so why do we have a command at all?
FlightRisk — 01/02/2021
Well the spec briefly mentions this: "Note if the duration the device is intended to be on is less than
or equal the set duration, no deactivation is necessary"
And the "duration" is what is set in CVs515-518 of the decoder
I think our command came from making an artificial distinction between turnouts and other accessories to make it easier to address and save them in EEPROM. We can assign an ID to turnouts internally. It may have also come from how Gregg wanted to code his throttle software.
UKBloke (AKA Chris) — 01/02/2021
I can understand that... we need it similar for ED and RMFT without JMRI..
FlightRisk — 01/02/2021
Honestly, what is the purpose of have 3 bits of the address be in 1s complement form??? Just to make it more difficult to program? I think that came from Lenz in a closed door political thing where the general group was not consulted. But, it is what we have to work with 😉
UKBloke (AKA Chris) — 01/02/2021
We have the accessory command which generates the packet you describe...
FlightRisk — 01/02/2021
Yes, you are right. Well, now is a good time to think it through and do it right.
Happy New Year, BTW 😉
It is still the new year on the other side of the ocean, isn't it?
haha
UKBloke (AKA Chris) — 01/02/2021
I'm not sure what you have in mind... we can't change the packet format because the decoders read that
FlightRisk — 01/02/2021
No, just how we implement our scheme and what has to go in ED, JMRI and RMFT. It plays into my desire to be able to use the JMRI linear addressing directly with one of our commands. It is much easier to say turn whatever responds to address 2045 to ON, than compute an address and subaddress.
UKBloke (AKA Chris) — 01/02/2021
How do you expect to get from address 2045 to addr/subaddr? (obviously the code can do all the bit twiddling but you still need the numbers)
FlightRisk — 01/02/2021
Right. I'll look again at my notes, but if we are just putting bits into a packet, it doesn't matter whether the user inputs a long linear address and on/off or addr/subaddr/on. The packet is created by us. Maybe I am misunderstanding
Shufti:
ok, this seems to work due to weird premises:
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%.
Don_Willsmer — 02/06/2021
For an example with the Lenz 110 you can isssue a command to operate 9 and it will also set 10,11 and 12 the four outputs. However you couldn't set the addresses as 11,12,13 and 14 because they cross two blocks of four. If you set the address to 11 it will assume you are setting the third output . So although you are using a linear address the system knows it is dealing with an address and sub addresses.
From analysing the packet used by Lenz (Compact / Atlas) for points control:
tunAddr = 1 //Accessory decoder address
Turnout 1a : 1000 0001 1111 1000
Turnout 1b : 1000 0001 1111 1001
Turnout 2a : 1000 0001 1111 1010
Turnout 2b : 1000 0001 1111 1011
Turnout 3a : 1000 0001 1111 1100
Turnout 3b : 1000 0001 1111 1101
Turnout 4a : 1000 0001 1111 1110
Turnout 4b : 1000 0001 1111 1111
tunAddr = 2
Turnout 5a : 1000 0010 1111 1000
Turnout 5b : 1000 0010 1111 1001
Turnout 6a : 1000 0010 1111 1010
Turnout 6b : 1000 0010 1111 1011
Turnout 7a : 1000 0010 1111 1100
Turnout 7b : 1000 0010 1111 1101
Turnout 8a : 1000 0010 1111 1110
Turnout 8b : 1000 0010 1111 1111
tunAddr = 3
Turnout 9a : 1000 0011 1111 1000
Turnout 9b : 1000 0011 1111 1001
etc
NMRA Specification:
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.
The text was updated successfully, but these errors were encountered: