DCC++ EX Software Thread

David Cutting Apr 8, 2020

  1. FlightRisk

    FlightRisk TrainBoard Member

    407
    126
    5
    Yes, we default to looking for a little less than the 60mA that the NMRA specifies a decoder can send. But some engines, especially at a smaller scale can send less. What is doing your current sense? Are you using the Arduino Motor Board R3?
     
  2. RBTKraisee

    RBTKraisee New Member

    5
    0
    1
    I'm currently using a Kuman Uno with a Deek-Robot Motor Shield. Although the Uno is Kuman branded, not Arduino original, it seems to work well with the original DCC++ code and I haven't found any other incompatibilities compared to a 'real' Uno.

    I have three Dapol N gauge steam loco's, all fitted with the Zimo MX622N's. And my coach lighting is an 11-LED ESU 50709 (note that I have *never* seen any kind of ACK back from the ESU unit, regardless of which DCC++ codebase I use, but it still programs and operates correctly - The Zimo's do ACK correctly under DCC++ Classic).

    When I try to read CV's on the prog track the Track Current Meter in JMRI only twitches by around 0.1%. When I run one of the loco's on the main track, it shows around 2.0% to 2.5%, dependent on speed.


    I've been experimenting with ACK_SAMPLE_THRESHOLD values between 20 to 50 and haven't seen any difference. I've also experimented by removing the comment from the ACK_SAMPLE_SMOOTHING line, again with no difference observed with a variety of different THRESHOLD numbers.

    Ross.
     
  3. FlightRisk

    FlightRisk TrainBoard Member

    407
    126
    5
    Let's compare the packet sequence in the CV read and write routines from classic and EX and see if that is where the problem lies for that decoder. In packetregister.cpp, look for ::ReadCV and ::WriteCV. In each of these routines there are 2 groups of 3 lines that send packets. They look like this:

    loadPacket(0,resetPacket,2,3); // NMRA recommends starting with 3 reset packets
    loadPacket(0,bWrite,3,5); // NMRA recommends 5 verify packets
    loadPacket(0,bWrite,3,6); // NMRA recommends 6 write or reset packets for decoder recovery time

    There may be a difference that we can put into EX. There is the packet type (resetPacket, bWrite, Idle, etc.) and the bytes in the packet then the number of times we repeat it. So we care about any differences in those 6 lines. Shortening the 6 above in the last bWrite packet will have it come back quicker if it is missing the ACK rather than just not sensing it because the sample threshold is too high.
     
  4. RBTKraisee

    RBTKraisee New Member

    5
    0
    1
    First, thanks for helping me out with all of this Flight, I really appreciate you taking so much of your time to help! And my apologies for the tardiness in responding - I had a lot going on!

    Here is what I've got for DCC++ EX, which currently does ***NOT**** read or ACK any of my Zimo/ESU CV's (these settings are all 'straight out of the box'):


    DCCppEx - PacketRegister.cpp - ::ReadCV

    ...
    loadPacket(0,resetPacket,2,3); // NMRA recommends starting with 3 reset packets
    loadPacket(0,bRead,3,5); // NMRA recommends 5 verify packets
    loadPacket(0,bRead,3,1); // Line for D&H decoders
    loadPacket(0,idlePacket,2,6); // NMRA recommends 6 idle or reset packets for decoder recovery time
    ...


    DCCppEx - PacketRegister.cpp - ::WriteCVByte

    ...
    loadPacket(0,resetPacket,2,1); // NMRA recommends starting with 3 reset packets
    loadPacket(0,bWrite,3,4); // NMRA recommends 5 write packets
    //loadPacket(0,bWrite,2,6); // NMRA recommends 6 write or reset packets for decoder recovery time
    loadPacket(0,idlePacket,2,10);
    ...


    DCCppEx - PacketRegister.cpp - ::WriteCVBit

    ...
    loadPacket(0,resetPacket,2,3); // NMRA recommends starting with 3 reset packets
    loadPacket(0,bWrite,3,5); // NMRA recommends 5 verify packets
    // loadPacket(0,bWrite,3,6); // NMRA recommends 6 write or reset packets for decoder recovery time
    loadPacket(0,idlePacket,2,6); // TODO remove old line after testing
    ...


    ----====----

    And for the setup that ***DOES*** read my Zimo decoders, but still gets no response from my ESU ones, I've been using the original DCC++ codebase: (again, all values 'straight out of the box')


    DCCpp_Uno - PacketRegister.cpp - ::ReadCV

    ...
    loadPacket(0,resetPacket,2,3); // NMRA recommends starting with 3 reset packets
    loadPacket(0,bRead,3,5); // NMRA recommends 5 verify packets
    loadPacket(0,bRead,3,1); // forces code to wait until all repeats of bRead are completed (and decoder begins to respond)
    ...


    DCCpp_Uno - PacketRegister.cpp - ::WriteCVByte

    ...
    loadPacket(0,resetPacket,2,1);
    loadPacket(0,bWrite,3,4);
    // loadPacket(0,resetPacket,2,1);
    loadPacket(0,idlePacket,2,10);
    ...


    DCCpp_Uno - PacketRegister.cpp - ::WriteCVBit

    ...
    loadPacket(0,resetPacket,2,1);
    loadPacket(0,bWrite,3,4);
    //l oadPacket(0,resetPacket,2,1);
    loadPacket(0,idlePacket,2,10);
    ...


    Does this help?

    Ross.
    (Edit: Corrected)
     
    Last edited: Aug 1, 2020
  5. FlightRisk

    FlightRisk TrainBoard Member

    407
    126
    5
    Yes, it does! First, your version is older than the current release. If you used the installer, I need to make sure the installer is pointing to the correct version. Here is the zip. You can just unzip this into the folder where your DCCppEX is located. If you have made other changes that you are afraid of being overwritten, let me know. In particular backup or remember what is in your config.h file. Then give this a try.

    https://github.com/DCC-EX/BaseStation-EX/archive/master.zip

    This version has ACK_SAMPLE_SMOOTHING disabled. I would set it to .1 If these changes don't work, we still have two more thing to try. The first is reduce ACK_SAMPLE_THRESHOLD down to a ridiculous number ;) We can try 20, then 10, then 5. I hope that gets us good with both decoders. If not, we can try one more thing with the packets that are being sent.

    Fred
    DCC-EX Team
     
  6. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    For the ACK_SAMPLE_THRESHOLD stuff - is it a possible idea to add in coding so that, say, A0 (0r some spare analogue pin) can be used to have a potentiometer on it to alter that threshold value in realtime? If not used (floating) it goes to the normal default(50), for people not using it.
    But for problem decoders it means altering that threshold in real-time MIGHT get them through that decoder. And even someone using it (potentiometer) could then disable/disconnect that to achieve the assured default value again (50).
    Of course there are many ways someone could wire it up.... just a pot, or a switched pot.... to make it easier to utilise. Or if 'floating' is not good enough to assure that input (or lack of input pot) is known as not being used, another digital pin could be used as a 'switch' and only people wiring it up to utilise the whole functionality would need to do anything. Anyone else that did 'nothing' extra just has it default to the 50 as per normal.
     
    Last edited: Aug 2, 2020
  7. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    To use an LCD display, do you only need to uncomment "//#define ENABLE_LCD" in config.h, and set the library type?
    Or are there other places that need changes?
    In BaseStationInstaller it seems to hang at the LCD library area and uploading is never reached.
    So if I enable LCD it wont complete, but if it is commented out (disabled) it will complete fine. Some bug??

    To verify this I upload some other random sketch to the Arduino (Mega), so that I can see it is not DCC++EX anymore, and then run the BaseStationInstaller(BSI) again to see DCC++EX is back. Even with the LCD disabled, BSI never really tells you it completed anyway - you mainly tell as the Compile and Upload button is active again, and the last line in the console is (??) an AVRdude line. Plus you have seen the high level of TX/RX traffic.
    But with LCD enabled the last line is "Using wire library version at......". And no TX/RX traffic.
     
    Last edited: Aug 2, 2020
  8. PeterV

    PeterV TrainBoard Member

    10
    0
    2
  9. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    BaseStationInstaller - LCD issue 'circumvented'.
    To get the LCD Enabled version of DCC++EX going I just ran the ArduinoIDE and manually compiled/uploaded the program. I only needed to download and add the LiquidCrystal_PCF8574.h library to the IDE. That made me think that the BSI probably is not finding, or getting, that library and then stalls/fails at that point.
     
  10. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    Real-Time ACK_SAMPLE_THRESHOLD addition:
    I added code to run a Pot for the ACK_SAMPLE_THRESHOLD in real-time. A15 used for that, and 'gated' via D22 to enable it or not.
    I gave it a range of 10 to 60 from Pot end to end.
    I have a few decoders that do not read reliably, or sometimes at all (out of about 15 in total). I have not had time to go and test those with the new adjustable system.

    Oh.... I also send the ACK_SAMPLE_THRESHOLD value to my 20x4 LCD display so I can see what it is. As far as I can see, this ackThreshold code (in PacketRegister.cpp) only gets changed/called on a CV Read or Write. So once that is triggered, the LCD shows the change. (The LCD Display write is done in the PacketRegister areas along with the Pot reading etc).

    EDIT: Test1. The first 'unreliable' decoder reads fully reliably with ACK_SAMPLE_THRESHOLD 36
    It is an ESU LokSound5, which I have other installations of that type working fine. I suspect this Loco acts differently due to its motor and/or friction/resistance which will alter the load a motor pulse will create. I am pretty sure this is why we have this decoder acknowlegement 'random' issue.
    And if so, that is why a 'variable' ackThreshold value will be needed sometimes.
    Actually, even the Motor Shields used could have variations in the Current Sense value they 'read', so some setups might just need a value other than 50 all of the time anyway. Still plus a need to be able to alter it in real-time for 'problem' locos/decoder pairings.
     
    Last edited: Aug 2, 2020
  11. RBTKraisee

    RBTKraisee New Member

    5
    0
    1
    Hi Fred,
    Thanks for pointing me towards the latest copy, I was previously using the link Harald had posted upthread on July 11th :)

    With this new version, straight out of the box the Zimo decoders are responding now! Woo hoo!

    The ESU light kit is still not responding though. It never has ACK'd using any codebase, but I do wonder if playing with some of these alternative settings might encourage it to ACK properly. As time allows over the next day or so I'll experiment with a variety of the ACK_SAMPLE_SMOOTHING and ACK_SAMPLE_THRESHOLD figures you mention and see what happens. I'll report back ASAP.

    Thank you so much for getting me back up and operating with the Zimo's!

    BTW, I've done a little beta testing in the past, so if I can help with anything, I'd really like to help you guys!

    Ross.
     
  12. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    This zip includes updated V2.1.3 files (5) to include real-time AST adjustment on a Mega. With a text file to outline the changes.
    They are all #ifdef controlled, and thus totally non-intrusive if those defines are commented out.
    It is set up for a 20x4 LCD diplay, but can easily be modded to a 16x2
    Also easily modded to run on a UNO/NANO instead of Mega. (if you know at least a little bit of Arduino coding).

    The LCD addition would allow for all kinds of 'internal' info to be set up to be reported, and thus seen by the user in real-time. Great for fault finding etc. Or even just info you might find of use.

    It is quite possible that the manner I use to add the coding is not optimal, or 'strictly legal', in terms of the structure used as a standard in DCCpp. Though it seems to look OK to me.

    I have found that AST 36 works for all my decoders - they can all read extremely long 'pages' of CV data without any hiccup of any CV (eg a JMRI full sheet read of 100+ CVs). A few used to have issue at the default 50 value. But it is still best to have a real-time control (Pot) of that, because the range of possible other users loco/decoder and motor shield variations means each case could have a different optimal AT value anyway. Or even be the case that some of their loco/decoders need AST value X and others need AST value Y.
    At the moment - from my cases tested and resolved - it seems the CV Ack issue is all due to that AST value (not other values). So I am happy that I now can reliably read/write all loco/decoder CVs with total reliability.
     

    Attached Files:

  13. FlightRisk

    FlightRisk TrainBoard Member

    407
    126
    5
    Whew, lots of stuff! I will check the installer. It must not be finding the LCD library.

    You must have done some work to change the Ack threshold since that is a a constant. I'll see if you made it a variable or what. That is a nice experiment to see the value each decoder likes!

    So a value of 30 should work for all your decoders, correct?

    ESU should still write and accept the command on the programming track or main even if is does not acknowledge it. Does it?

    We would love the help! We can use a few people to test the next beta release. Join us on Discord.
     
  14. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    I left the ACK_SAMPLE_THRESHOLD define as per normal. (50)
    This define is used to set the AckThreshold variable, and I still leave that alone at first.
    AFTER that code area, I use my added #ifdef AST_POT to then alter that AckThreshold variable - if you do have the Pot set up. Otherwise the normal coding, AckThreshold, just continues on anyway.
    Thus it is an easily configurable addition - just like tons of other #ifdef stuff has been done in the DCC++EX coding anyway. (a great way to make it flexible and easily configurable).

    eg: The first line is the standard code. My added stuff is done if the Pot has been added, and if so it replaces that AckThreshold (its last line).
    ----------

    ackThreshold = ACK_SAMPLE_THRESHOLD/CURRENT_CONVERSION_FACTOR;

    #ifdef AST_POT
    if(digitalRead(22)==0)
    {
    int PotVal=analogRead(A15);
    ackThreshold=map(PotVal,0,1023,10,60);
    #ifdef ENABLE_LCD
    lcdDisplay.setCursor(0, 3);
    lcdDisplay.print("AckTHP: ");
    lcdDisplay.print(ackThreshold);
    lcdDisplay.setCursor(10, 3);
    lcdDisplay.print("PotEN: ");
    lcdDisplay.setCursor(17, 3);
    lcdDisplay.print(digitalRead(22));
    #endif
    ackThreshold=ackThreshold/CURRENT_CONVERSION_FACTOR;
    }
    #endif
     
  15. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    I used 36(mA?) and that has worked for me.
    But it is a reasonably variable case per loco/decoder setup. And motor shield.
    36 on mine might truly be 40mA...and different for someone elses setup too.
    A loco that has lights coming on will have some low level current value as a base. And if it has a sound decoder that auto starts up some sounds, that will have an even higher base current. If that ended up higher than '36' then the sense level has been exceeded/swamped already.
    Or various motors will have different load levels per pulse they have sent to them. Some locos move a bit for each pulse... some don't. etc.
    So whilst it would be nice to find a good value that worked for all cases, it is always possible to have a loco that is a 'special case' - thus having control to alter that Ack_Sample_Threshold is of use.
    The Digikeijs DR5000 gives that as a programmable value (you can alter it in their PC interface).... for that reason.

    I think the decoders DO receive the CV programming in all cases. This issue is only the RESPONSE (acknowledge) being missed, because of how they had to shonky up this "pulse the motor" method to even have any way to get a signal back out of the loco/decoder.
    And then JMRI etc use that acknowledge as proof of reply - and list a failure if they do not get it. eg an unreliable CV read as they cannot prove it was successful (seeing no acknowledge received).
    It is quite likely that any WRITE on the program track, or main track, is really always successful (highly likely at least). But having some acknowledge system is always better to know it was successful for sure, so you do want a reliable working Ack system really (if you can).

    Oh... so note it is NOT the Decoder involved at all. It is the MOTOR and what load/current it draws on the pulse it was sent. Plus after that, what sense level/accuracy the motor shield had.
    These are variable and the motor per loco will differ too.
    Hmmmm.... I guess it is possible that some decoders send a bit longer pulse, which then causes a higher current spike/pulse(??). Or some a shorter pulse that then has lower current.

    I think the NRMA 'tested'(??) and came up with the idea that 60mA will work for all cases. But in reality it does not. Plus it is even possible that newer better motors have even less load result when pulsed. So it is just not a constant playing field.

    Someone writing Decoder code could never write it to guarantee the motor caused a 60mA load - because every loco/motor is different. Or maybe the NRMA said "cause a 100mA spike", and we will be looking for at least 60mA....
    Whatever is actually being done, it is obviously a pretty coarse and variable case result. Still meaning we need to be able to ADJUST for any given loco that is a problem.
     
    Last edited: Aug 3, 2020
  16. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    Discord etc. I am happy to help out. I probably know 1/100th of what others here do! lol
    I am just learning all this DCC stuff on the fly - reading what I can find etc. Doing some simple tests.
    And a very mediocore 'arduino' programmer - but I have made tons of devices/code etc for them.

    I think the threshold Pot, and even the LCD display (20x4 to be of more use), are things that DCC++EX should have - and that users should add in for pretty well every case. (the displays are very cheap)
     
  17. PeterV

    PeterV TrainBoard Member

    10
    0
    2
    I had to change a few things to tidy up the display.
    1. Update the Pot change of AST to be 'all the time' - via the main ino <loop> (it used to be only done on a CV Read/Write call)
    2. Fix a 'rogue' ON/OFF text message that was in the display (I had not noticed the standard code sent a Track ON/OFF message on line 4 already)
    3. Added the Pot and Enable pins as defines - to make it easy to change it to UNO/Nano. I want to find pins for those that work for all board types, if possible. eg A3(?), D7(?). I have not worked out yet which are free on all boards used for DCC++EX. Otherwise I would probably add Defines set up to account for all the board types and which pinouts each can use.

    A Mega allows a lot more train layout stuff to be done (Accessories/Turnouts etc) so I would think most people should choose to use one of those(!).
    I am also trying to work out the best way to have ESP8266 on the DCC++EX setup, as it is far better to have a controller linked via your home Wifi than a USB cable. (as a Wifi Client... not an AP). There are a few reasons it is nicer to have the DCC++EX unit able to be standalone, at the train layout itself, and any JMRI system to be also standalone and probably elsewhere - using Wifi as their link, not the added mess and distance limitations of USB/LAN cables.
    Optimal cost/value, and neatness, is via a Mega unit with ESP8266 included. (or at worst, an UNO of that same type).
    I have just not got up to that stage of working out how to get the ESP8266 portion of that working, so far.... (I have an UNO/ESP8266 unit to work that out on).
     

    Attached Files:

    Last edited: Aug 3, 2020
  18. David Cutting

    David Cutting TrainBoard Member

    62
    29
    3
    @PeterV very nice work! We are having similar discussions in our discord channels, please come join us. https://discord.gg/3W5pKm9

    Sent from my Pixel 3 using Tapatalk
     
  19. Ash

    Ash TrainBoard Member

    20
    4
    2
    @PeterV I appreciate the notes. I got the 4-line LCD and used it to fine tune AST. I was able to detect a loco on the programming track from current sensing of BTS7960 / IBT-2, and also had success with Pololu ACHS-7121 current sensor (connected in line on the +15v power supply to IBT-2 and IRF3205).

    LCD was quite useful in monitoring a few other variables, such as current and base. Attached 2-page file with some notes and code changes -- the unsigned int data type resulted in some math anomalies, and the other readBaseCurrent() changes facilitate the 512 zero-base ACHS-7121.

    I also tried this, similar to what was in DCCpp. It could enable better precision; might not be too inefficient. (Perhaps starting value for current could be set to ackThreshold*.9).
    Code:
    for(int j=0;j<ACK_SAMPLE_COUNT;j++){
         current=(analogRead(CURRENT_MONITOR_PIN_PROG) - base + current*9)/10;
         if(current > ackThreshold) {
             d=1;
             j=ACK_SAMPLE_COUNT;            // break out once we get an ACK
            }
         }
     

    Attached Files:

  20. RonB

    RonB New Member

    1
    0
    1
    Hi Huub

    If you are using this circuit to read the DCC packets, I think you need to fit a 271pF capacitor across the inputs of the opto-coupler (pins 2&3).
    330pF also works.

    upload_2020-8-21_15-54-31.png
    I built an accessory decoder, using this circuit and the Mynabay library.
    upload_2020-8-21_15-54-46.png

    Did not work at all initially.
    Fitting the capacitor, as above, sorted the problem - now works perfectly.

    Regards
    Ron
     

    Attached Files:

Share This Page