DCC++ EX Software Thread

David Cutting Apr 8, 2020

  1. haba

    haba TrainBoard Member

    78
    32
    10
    The "turn on again after short" feature is something that people will want different for differnt situations. Think of layouts from Z to G scale with very differnet current limit situatons and very differt sizes and levels of attention by the driver. Automatic run layouts.

    So I think we can do in 3 ways:

    1. Turn always track off after short detection and say it's SEP (Someone Elses Problem) and let JMRI or Rocrail or whatever Program or human operator deal with it. Well, DCC++ reported <p2 xxxx> in that case and no problem for the higher level program to handle the delay and make the decision to to it automatically or ask the user to press a button.

    2. Do it in DCC++ and have a configurable delay or manual depending on compile options.

    3. As 2. for default but add a runtime configurable delay (that means a command to set the delay or "infinity").

    On the electrical side...
    I think the detection time vs auto-on time should be at least 1:100 to minimize the energy which goes into whatever created the short. The wipers at the wheels in N-scale engines are quite flimsy. That means that if you detect a short in 20ms then you are off at least 20ms*100 = 2s before trying again. One can even say after 10 tries (that would be 20s) we give up and always want a manuel power on.

    I had one user reporting that he had problems with auto reversing units for loops (2 rails H0) which triggered the short protection. Some extra code showed that all his shorts when entering such a section were < 20ms so I added code to my fork to ignore the first short on the MAIN (but not on the PROG) track and turn off at the second test. That seems to work well.

    The CURENT_SAMPLE_SMOOTHING was a big ball and chain to do shutoff accurately and fast so it put it down the drain in my code. Why? When you think about how the calculation of the smoothed value works, you will see that it is flawed when the current value where you want to detect the short is very near the top value of what the motor board can report. Example: Motor board with max capacity of 3000mA and can report a max of 3100mA on the current pin.So we set a trigger of 2900mA. If now the real current is 5000mA when a short occurs, the board will still only report 3100mA and the smoothing will make current shutoff slow as that calculation takes into account the ratio 3100/2900 which is only ~ 7% over current reported. But it is much more in reality.

    Regards,
    Harald.
     
    Atani, KC Smith and FlightRisk like this.
  2. Mani

    Mani TrainBoard Member

    76
    15
    4
    Today I tested EX with clone UNO& Deek robot & JMRI. The important finding is that, in Decoder Pro, CVs are getting READ properly but WRITE is failing..
    MAIN seems working fine..

    Sent from my GM1901 using Tapatalk
     
  3. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    Ok, I'll check that tonight. Is this the development build? I'll check on the Mega too. And when you say the MAIN track is ok, do you mean it writes? EX: You can change a bell or a horn and it saves it? Which of course points to not getting the ACK.
     
    Last edited: May 7, 2020
  4. Mani

    Mani TrainBoard Member

    76
    15
    4
    Yes it is development build. I have not checked MAIN for programming. Generally I always use PROG to write CV. What I meant is operations on MAIN. But I will try this today.

    Sent from my GM1901 using Tapatalk
     
  5. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    I can see what is happening. The programming does work, even on the prog track. All CVs get written and you can read them. The problem is it does not sense the ACK. Going to have to think through support for all the different motor boards we support and the (at least) 3 Aduinos. Changing to internal reading of current in milliAmps is a start since we would have to have a table for all the pin readings and what they mean for each combination. We just want to read a 60mA pulse. But what is happening now is the smoothing value is incorrect. I put in some debug code and on my test track with an N scale logo with an MRC sound decoder, the pin reading with the loco sitting there and making noise varies between 15-20. The ACK pulse is 100-102. So that is 44-59mA with a pulse up to around 300mA. So that is a difference of about 240mA. Interesting since the programming track is supposed to be only 250mA. But technically, this pulse doesn't last the 100ms the spec states should cut off the power. I'll measure actual track current and see how close this is. I imagine is a pretty close. Then adjust the parameters.
     
    Mani likes this.
  6. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    Well, I tried everything until 3am. At one point, I did a write with logging and saw the current jump for the right amount of time. Now I can't read a pulse. I tried the mega and the UNO. I don't know if my train is broken, the current sense is broken or if the code has a timing issue and misses it... I will load classic and if that doesn't work, test the pins with another sketch.
     
  7. Mani

    Mani TrainBoard Member

    76
    15
    4
    Classic is working fine for me..

    Sent from my GM1901 using Tapatalk
     
  8. David Cutting

    David Cutting TrainBoard Member

    62
    29
    3
    If it is any help, I was having trouble reading a pulse on the programming track tonight in my SAMD21 branch, and I think it was the current smoothing and threshold values that were killing things. I ended up blowing away the smoothing code and now it works... I do need to go back in at some point and put it back in, but for now it works.

    Adding an external trigger for when the base station thinks it is getting a pulse and looking at that plus the current sense pin on the o-scope seems like the best way I know of to tune the system.

    Edit: this was om my fork from the development branch, less than a week ago.
     
  9. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    I was thinking of getting rid of the smoothing anyway. Not sure why Gregg thought he needed it here. I thought of taking the same number of readings and just having a counter that increments every time it gets a value over the threshold. So right now, it takes 500 quick readings after writing a CV. Then we can check for 3 readings over that value which would eliminate a bad reading. I was trying this code when I realized I am not getting any change in current back from the loco. So need to check if pin A1 is working and if the motorboard is sending out a signal.
     
  10. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    @ardsuppi , @Mani , et. al. The development branch now has all the fixes and some major changes. Feel free to download and test. I really want to push this to the master branch quickly since that is what the installer points to and what most people will find.

    I'll clean a few things up after more testing and adding more comments. The big change (after fixing the Uno memory issue from the other day) is that the ACK detection for reading and writing CVs is also handled in milliAmps now. Since we also now track what board you are using, DCC++ EX should automatically adjust to how your board generates current sense. It will get a base reading, since your train scale, decoder, etc. can all affect the initial current on the PROG track, and then read/write your CVs and look for the NMRA spec of a short 60mA increase in current.

    The old smoothing routine is gone for now, instead we take less readings (they were unnecessary and the byproduct is a little bit more speed) and then when we get a current spike, make sure it wasn't a fluke and that we have 3 readings over the ACK threshold. If so, we stop (before we kept going even after the ACK until 500 current checks in a loop completed), issue a decoder reset packet and are done. I haven't notice the decoder needing all those wasted milliseconds to settle before it gets its reset command. Your tests will help verify that.

    I was playing on a short PROG track with only 9V on it and an N scale sound loco. Sitting there purring, it was using about 60mA. The ACK spike went up to 300mA. So that is a 240mA difference. My short circuit detection is set to 250mA on that track, but the pulse is so short (under the NMRA 100ms) it doesn't trip. So looking good. Will try it with 12V and more tests later.
     
  11. haba

    haba TrainBoard Member

    78
    32
    10
    I have a finger injury so I will keep it short.
    For the current sensing the orig code is nonsense, because if you do nor immidiately sense after the command that triggers the ack you might miss it depending on decoder speed. that's why I use slot 1 which repeats and not slot 0.
    Code:
     loadPacket(1,bRead,3,1);  // Start transmitting verify packets (according to NMRA at least 5)
                               // but we do it continiously until Ack or timeout
    
    then when the ack is found I change back.
    H.
     
    FlightRisk likes this.
  12. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    So the question about the short circuit protection does the user have any responsibility for knowing the limitations of the hardware
    and not changing any settings without reading the manual? Here is a graph of such a short, the current is greater than this peak. This is pin readings, not actual current. So you don't want to set a 3A board to 3000mA, but that seems to be an issue with that board and building it into the software. This graph is using a smoothing value in the exponential smoothing routine (a common routine) of ".9" out of 0 to 1. So the response is fairly quick and you get some smoothing. You could make this value smaller and get a little lag and more smoothing. So it depends on how fast a response you need. Even with no smoothing, you are still going to run into the issue of the current is much more than one the device can report.

    upload_2020-5-9_20-38-54.png
     

    Attached Files:

  13. haba

    haba TrainBoard Member

    78
    32
    10
    I guess we are on ms and mA on the axis. Why are there 2 series and both series look smoothed. Can you plot pin reading and smoothed value?

    I found smoothing to hide the real numbers. I rather have a history of say 10 readings and then decide based on that if I cut the power. In addition to that I don't like floating point math where I feel that I can do it with simpler and faster integer math and compare operations. You can plot c and smoothed c and the point of time you cut the power. Then look at these graphs and how fast the shutoff is for limits set at 1.5, 2 and 2.5A. I don't want users to the the limit at 3A for a 3A board which can only report at max 3.1A and then they get a very slow shutoff because of smoothing, Enough rant against smoothig.

    This is from my tests of my code. I might be able to produce a better picture if I make myself some current sensing equipment, but this is the voltage over a resistor in series. First there is only a small current/voltage (decoder idle current) and then when the short happens it raises to the DCC volatage (all voltage drop over measuring resistor) and then when the shield cuts the power you see it's zero. https://habazut.github.io/dcc-ardu/SDS-short11.png In that way I can measure how long it takes to shut down and with my tests I've had times t which are 22ms < t < 37ms. My code ignores a spike that only shows in one sample (every 20ms) when the next sample is OK again.

    Regards,
    Harald.
     
  14. Mani

    Mani TrainBoard Member

    76
    15
    4
    Some times READ still having problems... I used Serial monitor & JMRI to Read the values..
    The ones that I am not able to READ also returns -1 (error) after WRITE.

    With Classic, it's reading fine.
     
  15. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    @Mani. Is it the same CV or just random reads and writes giving the issue? What decoder?

    @haba I understand what you are saying. Those reading were using a high value for the constant. I then used a c++ online server to run tests and look at the results. I'll post the code. You can comment and uncomment different kinds of routines and see the numbers. The data is real data.

    Ultimately I like the integer math anyway. But I was experimenting with one change at a time. With .9 smoothing, the smoothed values track very close to the actual values. These were a few milliseconds apart and raw pin readings.

    Thanks for a great discussion. Simpler is better. The one thing I can't easily do without a scope is see the packets AND the ACK pulse at the same time directly from the track. That would be nice to have.
     
  16. Mani

    Mani TrainBoard Member

    76
    15
    4
    It's random. Decoder is BLI paragon 3. May be I will try with Digitrax decoder and let you know my findings.



    Sent from my GM1901 using Tapatalk
     
  17. huub

    huub New Member

    6
    2
    1
    Goodmorning

    I am new to trainboard (member for 10 minutes) and I am not sure if this is the correct place for the question underneath, but ......

    My name is Huub en I live in Belgium, running a lay out with 14 locomotives, with Rocrail as software and the opendcc command station,
    As the opendcc command station broke down I ordered a Mega and motor-shield (original) and loaded the sketch, the last experimental one!!
    I can drive my loco's, POM works, and programming on the programming track is also perfect,

    The only problem I have are the servo's (I have 40 of them) they don't work at all

    The hardware is the Mardec solution from Arcomora, based on a arduino uno,

    As I have received the parts I needed to repair the Opendcc command station, I could (by using a dccmonitor based on a uno) analyze the signal on the rails.

    Below the difference between the two systems,
    (dcc address 229 or in mada 58:0)

    Values with opendcc (lenz implementation P50x)
    19:05:52.417 -> Acc 229 58:0 1 Off 10111010 11111000
    19:05:52.604 -> Acc 229 58:0 0 Off 10111010 11110000

    values with dcc++
    19:21:33.756 -> Acc 229 58:0 1 Off 10111010 11111000

    There are a lot of treads on this topic on the Rocrail forum, as well on the page of the developer of arcomora, and also on beneluxspoor, but nobody seems to be able to find an answer,
    I am hoping you understand the why and how, and perhaps can ad a choice in the config,h

    I am more than willing to help testing, if a solution is found, dozens of enthusiasts here would be very happy

    best regards
    Huub
     
  18. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    How are you activating the turnout in DCC++? Based on the above it would seem that only the activate command is being sent to DCC++ and it only generates the first packet, the command being <a 58 0 1>
     
  19. FlightRisk

    FlightRisk TrainBoard Member

    548
    237
    14
    Hello @huub and welcome! Can you give us more information? By not working at all do you mean that DCC++ EX does not turn the accessory on or off? And openDCC does? What are you using to turn things on and off? JMRI?

    @Atani There may be two standards for how to do this. I did find two competing pieces of documentation. NMRA 9.2.1 and 9.3.2 contradict themselves. In reading it seems there is the usual NMRA "standards" confusion and that the 9.3 is mostly ignored despite it being more clear about the packet format and Rocrail cutout spec. This is from 9.2.1:

    10AAAAAA 1AAACDDD

    First byte is correct for either standard. An accessory decoder packet starts with "10". The next 6 bits are are the least significant bits of the address .

    The second byte always starts with a one and then the next 3 bits are the most significant bits of the address. We are XOR'ing that byte with 0xF8, so the first 5 bits are ALWAYS going to be 1s! Gregg made a note that "C" as in the above example should always be 1. The least significant bit (the last D) is where Gregg is putting a 0 or 1 for on and off. Discussion? There may be confusion between an accessory decoder and a signal decoder.

    And since any front ends that have been written are working like that, we would break things like JMRI if we change it. Now I see why Huub may have been asking for something in config.h. A setting there could change how this is reported.

    Doing a lot of detecting work, I think I see how this came about. There are different methods in JMRI, one is ackDecoderpkt and another is ackDecoderPktOpsMode. The JMRI code is HERE.

    I have no idea how this could have ever worked unless there are decoders following the way DCC++ is doing it.
     
  20. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    Both DCC++ and JMRI are implementing the spec as written.

    accDecoderPkt is used to interact with an accessory decoder (throw/close/etc), accDecoderPktOpsMode is strictly for POM for accessory decoders.

    They do not contradict, 9.2.1 is the basic DCC command extension for accessory decoders (and other extensions to the base format). 9.3.2 is for RailCom and introduces an extension to a couple packets defined in 9.2.1. DCC++ doesn't implement RailCom nor the extensions for that (at this time).

    second byte is stored in 1s complement so it will not always be 1s (see 9.2.1 line 431). So the 0xF8 will flip bits accordingly for 1s complement.

    9.2.1 line 428. I agree it could be a config option to not flip the least significant bit, but it would be a change applied to all accessories and not on a per-accessory basis which would require changes to the flags that DCC++ persists for turnouts (probably not a bad idea anyway).

    Correct but it doesn't necessarily need to be as the activate flag is passed in as part of the text protocol to support flipping it from 1 to 0 as needed. This is typically only needed for decoders connected to dual coil machines or similar that want to "power down" the outputs, many decoders implement some form of "power down" based on a timer.
     

Share This Page