CommandStation-EX icon indicating copy to clipboard operation
CommandStation-EX copied to clipboard

Potential Decoder Tolerance/Compatibility Improvement when not in High Accuracy Waveform Mode

Open mesheets opened this issue 3 years ago • 7 comments

Synopsis

Reduce DCC-EX's half-bit transmit duration for "1" to 54 µSec (or at least 55 µSec).

Background

As described in the High Accuracy Waveform Mode documentation and defined in the code in DCCTimer.cpp, the half-bit transmit duration for "1" is 58 µSec. This aligns with the nominal value defined in the NMRA S-9.1 DCC Electrical Standard document (see Table 2.1, "DCC Bit Timing").

The specification is tighter for transmission, with receiving having (for "1") an additional 3 µSec of tolerance added at either end.

Thresholds

Defined Minimum Half-Bit Durations for "1" (nominal 58 µSec)

  • Transmit: 55 µSec [-3 µSec offset]
  • Receive: 52 µSec [-6 µSec offset]

Defined Minimum Half-Bit Durations for "0" (nominal 100 µSec)

  • Transmit: 95 µSec [-5 µSec offset]
  • Receive: 90 µSec [-10 µSec offset]

For "1" (as defined), the half-bit maximum durations simply mirror the offsets for the minimum threshold.

  • Transmit: 61 µSec [+3 µSec offset]
  • Receive: 64 µSec [+6 µSec offset]

However, it seems possible that in some cases where there have been decoder tolerance/compatibility issues, the implementers perhaps also defined the maximum half-bit duration threshold for "0" to follow—in at least some cases—the same pattern as for the "1" maximum half-bit transmit/receive durations. Hypothetically, these maximum half-bit durations for "0" might then have been implemented as follows:

  • Transmit (hypothetical): 105 µSec [+5 µSec offset]
  • Receive (hypothetical): 110 µSec [+10 µSec offset]

DCC-EX Implementation and Potential Implications

The above would potentially explain why some decoders don't work unless High Accuracy Waveform Mode is enabled—DCC-EX's half-bit "0" duration of 116 µSec is longer than the 110 µSec that would be the theoretical receive cutoff in an implementation that followed the same duration timing pattern for both "0" and "1".

Mitigating

Particularly when running on something such as Arduinos, efforts to simplify and conserve resources—such as by reusing timers—is understandable. While still facilitating reuse of timers, compatibility could perhaps potentially be improved by reducing DCC-EX's half-bit transmit duration for "1" to 54 µSec (or at least 55 µSec).

  • Reducing the half-bit transmit duration for "1" brings the duration for "0" closer to the defined nominal value
    • At 55 µSec, DCC-Ex's half-bit duration for "0" would be right at the maximum theoretical receive cutoff of 110 µSec
    • At 54 µSec, DCC-Ex's half-bit duration for "0" would—at 108 µSec—offer a 2 µSec buffer against the maximum theoretical receive cutoff of 110 µSec
      • While 54 µSec is below the minimum transmit threshold, it is still within the defined receive threshold, with a 2 µSec buffer here as well
      • Jitter during the course of execution is more likely to cause a duration to be long than to be short, so defining a lower half-bit transmit duration provides a better buffer against such stretched durations

If nothing else, defining the half-bit duration for "1" at a value below the spec-defined nominal value should provide better buffer protection against jitter-induced timing delays

mesheets avatar Nov 13 '21 19:11 mesheets

Can you give more information on what decoders you are referring to that are incompatible with DCC++EX? I've seen some Arduino decoder libraries that are non-compliant with NMRA, but DCC+EX is fully compliant with NMRA pulse length requirements in the high accuracy mode. I would be surprised if there is a commercial decoder that cannot handle 116us pulses.

The bottom line is, if a decoder rejects 116us pulses for '0' bits, it is non-compliant with NMRA standards. The standard has narrow requirements for '1' bits, but for '0' bits decoders are required to accept a wide range of pulse lengths up to 10,000us half-length. So it would seem inadvisable to reduce our leeway on the '1' bit in order to adjust the '0' bit unnecessarily.

Bear in mind also, that if an interrupt is delayed, the preceding half-pulse will be extended as you say, but the following one will be shortened. And moving the '1' bit half-length away from 58us will increase the number of packets that are out-of-spec due to jitter significantly.

Neil-McK avatar Nov 13 '21 23:11 Neil-McK

DCC+EX is fully compliant with NMRA in the high accuracy mode

Not disagreeing; as intended by the subject line, this thread does not pertain to behavior when running in the High Accuracy Mode of DCC++EX.


Can you give a hint on what decoders you are referring to that are incompatible with DCC++EX?

From the High Accuracy Waveform Mode documentation

We have found that some older decoders do not adhere to the NMRA specification tolerances.


The bottom line is, if a decoder rejects 116us pulses for '0' bits, it is non-compliant with NMRA standards.

Correct, as per the initial post, I don't think there is any debate about that here; this is simply with respect to the aforementioned caveat noted in the documentation for DCC++EX.


if an interrupt is delayed, the preceding half-pulse will be extended as you say, but the following one will be shortened

Agree regarding High Accuracy Mode, but this thread is not with respect to the use of hardware timers in High Accuracy Mode; with software routines (such as are used when not in High Accuracy mode), the interval can be additive (instead of fixed), eliminating the potential risk of a shortened interval.

mesheets avatar Nov 14 '21 00:11 mesheets

I should explain my comments above. As I said, in HA mode there is no jitter. However, when pulses are generated through software in interrupt code, interrupts such as the serial port handler, clock and others may delay the generation of the DCC pulse transition. Observations show that the pulse is delayed by up to 6us every clock interrupt, for example. So the preceding half pulse will be extended, potentially to 64us. However, the next interrupt transition is very likely to be back on schedule, so the next half pulse will be 52us (116us total cycle time). These variations can be seen on a logic analyser. No such variations exist in HA mode, it is accurate to within 100 nanoseconds (at the Arduino pin output), which is why we encourage its use. A characteristic of the DCC protocol is that retransmissions occur for, I think, all packets. Consequently, this jitter in the pulse lengths may result in the rejection in the decoder of some packets but will not cause loss of functionality or maloperation. In fact, the NMRA spec identifies the pulse lengths that MUST BE ACCEPTED by the decoder, but does not prevent the decoder from accepting a wider range. So even with jitter, this may be a non-issue. We have certainly seen problems with programming older decoders, mostly because of the length and magnitude of the acknowledgement generated by the decoder. The team have done a lot of work on finding what works for each decoder. I'm not aware of any decoders that may be problematic with DCC signal jitter in non-HA mode, other than the above-mentioned Arduino libraries, but if you know of any, please let us know!

Neil-McK avatar Nov 14 '21 01:11 Neil-McK

Thank you; perhaps some clarification with respect to the documentation might be in order?

While jitter is a potential concern when not in High Accuracy Mode, it has seemed that deviation from the specified nominal transmit duration is also of concern. Per the documentation [emphasis mine]:

The High Accuracy mode makes the waveform, the pulse train of 1’s and 0’s, even tighter to the nominal values in the specification.

For non-HA setups, then, the intent was to bring the overall deviation closer to the specified nominal values—specifically reducing the larger variance of "0" from the specified nominal—by slightly deviating from the nominal for "1".

High Accuracy would certainly improve timing consistency, but bringing "tighter to the nominal values" would imply reducing DCC++EX's target half-bit duration for "0" from 116 µSec to something closer to the specified nominal of 100 µSec. (Grammatically, making a 116 µSec interval more consistent does not bring that interval it closer to the "nominal value"; it simply has eliminated potential timing variance while maintaining a target duration of 116 µSec.)

Stated another way, the documentation currently reads that bringing timings closer to the specified nominal durations (which in the case of the "0" half-bit duration is deviates from the specified nominal by 16 µSec) can help improve compatibility. The next paragraph then also states that High Accuracy Mode helps "to tighten up any jitter."

So, is High Accuracy Mode really only "tighten[ing] up any jitter," or—as the first paragraph on that documentation page implies—is it also changing the target durations so that they more closely match with the specified nominal values? If the target timings in High Accuracy Mode are not substantively closer to the specified nominal durations than when not in High Accuracy Mode, then the "The High Accuracy mode makes the waveform…even tighter to the nominal values in the specification" verbiage should be struck (while retaining the verbiage about reducing jitter).

mesheets avatar Nov 14 '21 02:11 mesheets

Thanks for your complete report. We don't often get such detail. It has been difficult keeping the documentation up with developmemt and recruiting others to help me write everything on the web page. Proofreaders and Documenters are in high demand, and suggestions as you have offered are appreciated. I am always looking for ways to make the documentation more clear and accurate. When you find something, please continue to report it.

Fred

FrightRisk avatar Nov 14 '21 04:11 FrightRisk

While jitter is a potential concern when not in High Accuracy Mode, it has seemed that deviation from the specified nominal transmit duration is also of concern.

The jitter is symmetrical as explained above. For '1' bits, being close to the nominal value also gives the greatest margin to the limits (3us either way for a CS). For '0' bits the limits are not symmetrical and the margin is higher (5us at 100us half-pulse length, or 21us at 116us). So it's the 1 bit that merits closer alignment. With a nominal 58us value, we have margin for 3us jitter before the CS goes beyond the NMRA spec. If we change the value to 56us we have a margin of only 1us.

But your points about the documentation are understood and welcomed. Some issues are described in a simplified way in order to make them easier for a non-expert to appreciate!

PS I tested a commercial loco decoder today and found that it responds to a much wider range of pulse lengths than the standards require, so immunity to jitter, for that decoder, is fairly high. But one decoder library in particular will start rejecting packets if the jitter exceeds 2us.

Neil-McK avatar Nov 14 '21 14:11 Neil-McK

I appreciate the feedback. Particularly on Open Source projects, documentation can be an underappreciated (and even neglected) aspect, so my hat's off to those who have invested the time and effort.

I'm familiar with some past discussion on the TrainBoard forum, so that background might factor into a few suggestions here.

Personas

I like the personas concept (Conductor, Tinkerer, Engineer) and would suggest introducing the personas at the very outset, on the "Getting Started" landing page. From there, it could then advance to "Components" and "What You Need."

The Conductor Persona

At the risk of perhaps creating too many personas, the Conductor persona could potentially be split into three personas—specifically, splitting off two simple use cases from the current Conductor persona and leaving the remainder under the existing Conductor persona.

Feel free to come up with other persona names (in fact, I'm sure someone can probably come up with better names, lol); the idea is more the role.

  1. Passenger: Stand-alone DCC++EX command station with WiThrottle control (no connected computers, JMRI, RocRail, etc.)
    • For simplicity, don't list choices; just state the most-recommended/best-supported option for each need (e.g. Arduino Mega, Arduino Motor Shield, and a specific, easy-to-use power supply)
  2. First-Class Passenger: DCC++EX command station with application (e.g. JMRI, RocRail) control
    • A superset of "Passenger"
    • For simplicity, don't list choices; just state the most-recommended/best-supported option for each need (e.g. Arduino Mega, Arduino Motor Shield, and a specific, easy-to-use power supply)
    • State the additional requirements/needs for connecting to an application, again not listing choices but just stating the most-recommended-best-supported option for each need
  3. Conductor: Apart from the proposed new personas added above, essentially remains the same as it is as the present, with the Conductor's distinguishing characteristic being provided a menu

OK, but I thought this issue was about setups that don't support High Availability Mode?

Yes, it was, lol. :-) From the documentation, it appears use of Arduino Mega and the Arduino Motor Shields would automatically enable "High Accuracy Mode"; however, that tidbit of information doesn't seem to be noted until very deep into the advanced setup on a page that is tagged for Tinkerers or Engineers.

We might be able to help steer less-experienced users away from potential pitfalls and caveats like this by essentially providing "Recommended Starter Packs" for the "Passenger" and "First-Class Passenger" personas.

So about the "High Accuracy Waveform Mode" page…

Based on my current understanding, might the following rewording of the first two paragraphs be appropriate:

Do you need it? Most likely, you don’t, and if you are running on the hardware specified in the "Recommended Starter Pack" for either the "Passenger" or "First-Class Passenger" personas, you already have it. However, if you are running DCC++EX on a different hardware setup and encounter a problem with a particular decoder and all the usual settings don’t help, you might want to try this mode. We have found that some older decoders do not adhere to the NMRA specification tolerances, failing to read bits that are within the proper range. While rare, this could occur. The High Accuracy mode increases the precision of the waveform timings—the pulse train of 1’s and 0’s that comprise a DCC signal.

The nominal spec asks for 58us ‘1’ bits and 100us ‘0’ bits, with a few microseconds leeway in either direction. We opted to use 116us ‘0’ bits since it is exactly twice a ‘1’ bit, and made it easy for us to use one timer to generate both bits. On occasion, with all the other things going on inside the command station, and the way we use timers and interrupts in normal accuracy mode, it is possible for there also to be a little jitter. That’s when the bit durations from bit to bit can vary a few microseconds. High Accuracy Mode uses the hardware timers instead of just our software routine, to tighten up any jitter and increase the precision of the DCC waveform timings.

mesheets avatar Nov 15 '21 17:11 mesheets