DCC++ Update Project 2020

FlightRisk Feb 16, 2020

  1. RoadRailer

    RoadRailer TrainBoard Member

    34
    11
    2
    Yeah, for readability it perhaps also might have been nice for more of the code to have been implemented in C, but some of that was likely done for performance reasons, to help ensure the integrity of the signal timing.

    The dcc_packet assembly method basically entails the following
    • Parameters
      • Preamble: Number of preamble bits
      • Packet: The DCC packet data, in bytes
      • Length: The number of bytes comprising the DCC packet data in the preceding parameter
    • Actions
      • Output the number of preamble bits specified (1s)
      • Output the packet start bit (a 0)
      • Reset checksum to 0
      • For each packet byte
        • XOR for the checksum
        • Output the packet byte
        • Output the data byte start bit (a 0)
      • Output the checksum byte
      • Output the packet end bit (a 1)

    That dcc_packet method was typically called from dcc_ops_packet (a C method), and that dcc_ops_packet method just did the following:
    • Parameters
      • Packet: The DCC packet data, in bytes
      • Length: The number of bytes comprising the DCC packet data in the preceding parameter
    • Actions
      • Call dcc_packet, specifying a standard preamble size
      • Call dcc_flip to flip the polarity

    Because the stored values were not bit-shifted to accommodate the various start/end bits of the DCC protocol, a byte in the packet data structure always matches a DCC byte (which can be handy for debugging/troubleshooting).


    Back to DCC++, there is still the "invalid" flag to track, but even if that ends up taking its own byte (as a result of not bit-shifting in the various start/end bits), it still represents an overall reduction in size.
     
  2. haba

    haba TrainBoard Member

    28
    17
    5
    > Back to DCC++, there is still the "invalid" flag to track,...

    With start- and stopbits the 6 DCC bytes take up 55 bits and 7 bytes in the buf have 56 so I had exactly the last bit to spare for the invalid flag.
    That was luck.

    Regards,
    Harald.
     
  3. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    @haba, @road I used to code assembly way back when (z80, 8088). Nothing like bare bones economy of function. But I'm not sure I'm up to the task either. I love speed, but like readability ;) Still, if might be worth a look sometime if there is someone who could handle looking at that.

    @haba, How are you handling the sending of idle packets? When do you send them? And what did you gain from the <#> command you couldn't get from <s>?

    Also to anyone, without me trying to do the math, when do we run out of bandwidth? In other words, when do we have too much going on that the time is off or it takes 3 seconds for a loco to receive a command? Has anyone figured out what realistic limits we have on the number of trains/amount of packets that can be sent before we run into problems?
     
    Last edited: Mar 21, 2020
  4. haba

    haba TrainBoard Member

    28
    17
    5
    Idle packets are only sent when nothing else is. So until a <t 1 ... > command overwrites that slot. If something else is sent, we don;t need idle any more and so far we never purge.

    The <#> gives the number of locos this particular instance of DCC++ can take. I did send patches to JMRI and they use info from <#> if available. <s> does not give that.

    And the output from <s> is difficult to parse. Yuck!

    On timing I can comment after sleep period.

    Regards,
    Harald.
     
  5. haba

    haba TrainBoard Member

    28
    17
    5
    DCC commands are variable length and therefore you can not give 100% exact times. But I try to do an estimate.
    I estimate the packet payload time for each packet as 200microseconds (for a 0 bit) times 37 bits (128 speed step short adress) plus präamble-time 1600microseconds. That's approx 9 ms per packet. For 46 bits (128 speed step long adress) you and up at 10,8ms. Now say we have 100 packets in the refresh loop that will give us a worst case refresh time of approx 1s. (Did I do that right?)

    But that does not mean that it takes 1s until a command reaches the loco as new changed commands are sent directly as they come in to DCC++. (That was so in Greggs code and I think I preserved that property). Here it works to our advantage that we do not refresh function commands (which is say in the standard that one should) because that would double the amont of time for the refresh loop if all locos have one function on.

    If you run JMRI it tries to take care of the refresh of the functions and we have currently a discussion how that could be done better because as it is now it will never ever stop to refresh a function group if it has started once and the interval is not configurable. That discussion is here: https://jmri-developers.groups.io/g/jmri/topic/dcc_dccpp_loco_decoder/71567076

    Then you will never get any refesh loop of 3 seconds on a Arduino UNO as it does not have the amount of RAM to keep a that big reftesh table ;-)
    I don't think we need to prioritize that we for example would refresh locos which are at speed=0 more seldom.

    What you can do for a test is to take my code and fill all the 100 slots with locos by opening a serial terminal and cutpaste 100 <t ...> commands. Then disconnect from the terminal and connect with JMRI which will assume that the slots are empty and overwrite those (I think). Then you can feel how everything behaves with 99 other "ghost" locos.

    That said we should think as well whose job it is to purge locos. I think only the overlying program has enough intelligence to see that a loco needs to be purged so one approach is that we say that's someone elses job but then we need to offer a purge/remove throttle command. But that should not be that difficult as I think the invalid
    flag would handle that if the code in RegisterList::loadPacket() would use that. Today it uses the recycleReg which just for simplicity points to the onlt Reg that can have the invalid flag set.

    Regards,
    Harald.
     
    Sumner likes this.
  6. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    That's a great idea. It may take a week with my schedule at the moment, but I'll use a logic analyzer on it and see. I can read a pin going high at the start of a packet and going low when it is finished and see exactly how long it takes. I am also building a DCC Packet Analyzer. I am waiting for some parts like some opto-isolators I ordered. I tested the code, so just need to solder things together.

    Since we are settling on a Mega for DCC++ EX, we can worry less about available memory.

    As for JMRI, I look forward to making some of the decisions as to who is responsible for purging locos, JMRI or us. Hopefully, we can agree of a "best" course of action if we can have enough engineers to discuss it and vote. I don't want to dilute our resources, so for now posting here is working, but do you like the idea of also having a groups.io discussion board? I suppose I could monitor both places
     
    Last edited: Mar 22, 2020
    Sumner likes this.
  7. haba

    haba TrainBoard Member

    28
    17
    5
    As on the UNO the TIMER0 is used for the DCC-signal, the micros() function only returns crap. But we need to time the ack pulses on the programming track. So I did create a tickcounter that is incremented the right amount at each DCC 1/0 that goes out on the main track. With that we have a course timer again (ok, it jumps 200/116us each increment but good enough to time if the ack is within 6ms +- 1ms). The code is at https://github.com/habazut/dcc-ardu/tree/tickcounter and yes how I use INCTICKCOUNT in DCC_SIGNAL is gross. Currently not documented yet.

    Regards,
    Harald.
     
    FlightRisk likes this.
  8. haba

    haba TrainBoard Member

    28
    17
    5
    > I can read a pin going high at the start of a packet and going low when it is finished and see exactly how long it takes.

    I just wanted to generate a sync pulse on a pin to be able to see how long DCC_SIGNAL takes but upon startup my Tek TDS 520 scope did show "FAIL++Processor". So no scope until this is fixed :-( The Net tells me that if I am lucky that means broken NVRAM data which can be fixed but it not I need a "new" scope. The day could have started better.

    Regards,
    Harald.
     
  9. RoadRailer

    RoadRailer TrainBoard Member

    34
    11
    2
    For specific, individual topic discussions, I would suggest just using the "Issue"-tracking capabilities in GitHub (e.g. here for Classic) and then let the discussion flow from there. It's one less place to track, and then after a decision is made, the code change are completed, and the pull request is merged in, the record of that discussion can be associated with the commit (making it handy for future reference).
     
  10. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    @RoadRailer I agree. Since trainboard sends emails in a similar way to groups.io, I think that may answer folks who don't want to have to log into a forum. Between that and using issues, that can be the plan for now. @haba Do you have the expression; "when it rains, it pours"? Sorry about your scope. :(

    I'm working on combining code from different sources that started with rudysmodelrailway for a DCC packet analyzer/sniffer, but for an esp8266 dev board. I may fork it into our repo. The version I had works, but I made a few changes and have to test. There are at least 2 libraries out there that read DCC code, but I liked the idea of having just one file with no dependencies like Bjorn had.
     
  11. Walt Scrivens

    Walt Scrivens New Member

    8
    1
    4
    Forgive me if I'm missing something. I've read from pages 15 onward and found the DCC-EX repository. My question is, "Where is a zip file with all the code?" I can only find an HTML file that has links to each individual file.

    Some background: I've been running the original (2015) version of DCCpp_Uno as compiled with the Mac Arduino IDE version 1.6 or so. Lately, I wanted to change some speed tables, so I got out my secondary set-up which I use for programming. (I don't have a convenient programming track on the layout, and "Program-on-main" has never worked.) So I compiled and loaded the sketch with Arduino 1.8.12, and got no errors, but the programming track just doesn't work. Using raw text input to DCC++ and all the programming track commands return a -1 error code, but when I re-connect the track to Operations, all works fine. I've tried different permutations of hardware without success, so I can only assume that something in the support libraries has changed, and when I saw that an updated version of Classic was available, I decided to try it, but I can't find the file to download. (Since I'm on a Mac, the Windows installer is no use to me.)

    Can someone provide a link to the complete package with the latest updates?

    Thanks,
    Walt
     
  12. RoadRailer

    RoadRailer TrainBoard Member

    34
    11
    2
    Yes, it can be a challenge trying to jump into a long-running thread and get up to speed! :-O

    If you're looking for BaseStation-Classic, which has largely been the main focus right now, head to the GitHub project page for BaseStation-Classic.

    Once there, you can click the "Releases" link to view the releases that have been created thus far, or you can click the "Clone or Download" button (which is the current code and might or might not be stable). If you are familiar with Git and/or GitHub, you can also fork or clone the repository for yourself.

    I don't think any actual release updates have been posted yet for this restarted BaseStation-Classic effort, so I would probably go with the Download or Fork options.

    To help with "forking" projects, there is the GitHub Desktop client, which does include a Mac OS version.

    upload_2020-3-25_12-26-11.png
     
    Last edited: Mar 25, 2020
  13. Mani

    Mani TrainBoard Member

    51
    13
    3
    Hello All,

    Some questions from end user perspective:

    1. The release versioning will continue from current version for classic and for the EX, will the version number will be reset?
    2. Any date on first (or next) stable release?

    Suggestions:

    Can we have 2 different threads
    (1) For release updates
    (2) For support forum for end-users to discuss.

    This way users can easily access material etc..




    Sent from my GM1901 using Tapatalk
     
    Sumner likes this.
  14. RoadRailer

    RoadRailer TrainBoard Member

    34
    11
    2
    Good question. At least for Classic, I would lean towards continuing the current version. In fact, with the way the GitHub repository for Classic was setup, it includes the DccPlusPlus releases in the DCC-EX/BaseStation-Classic repository, up through v1.2.1 (c.f. "Releases" link here).

    For DCC++ EX, since it is intended as a different product (i.e. it won't do away with Classic), I would anticipate its versioning to be independent of Classic, unless we are absolutely certain that Classic would be put in a "deep freeze" mode.

    In the case of putting Classic in a "deep freeze" mode, we could perhaps starting DCC++ EX versioning at 2.0. (That would also allow for additional minor updates to Classic's version, if perchance any issues are discovered that might necessitate an update to Classic.)
     
  15. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    @Atani , @RoadRailer , @haba and other developers, how can we solve @Walt Scrivens issue since that is on the issues list. We need an easy way to be able to develop in PlatformIO and maintain compatibility with the Arduino IDE. I *believe* I have one way to do this working with Classic now. We make sure the folder name matches the main sketch file. So the folder there is "DCCpp" and the main file is "DCCpp.ino". Another way it to create an automation like Mike did with the build process happening when we do a PR. That would do whatever is necessary to copy and rename things into a folder that looks more like what the Arduino IDE looks like.

    Has anyone tested any of this? Does renaming DCCpp.cpp to DCCpp.ino affect PlatformIO? Is the separate folder easier or cleaner for non-coders? They would have just one folder and it would look like any of the example projects, though many users may just be following directions to get a sketch uploaded and don't want or need to learn anything else. I don't think we are using any external libraries that would cause a compile issue. If arduino.h is defaulted in both environments, won't that cover that part?
     
  16. RoadRailer

    RoadRailer TrainBoard Member

    34
    11
    2
    I guess I interpreted @Walt Scrivens’s issue as being related to Mac OS and the current installer being more Windows-focused at the present.

    Since PlatformIO is available for Windows, Mac, and Linux, I didn't interpret PlatformIO vs. Arduino IDE as being the issue but instead of more of "where do I find the latest code?" (Hence my earlier post in response.)

    Perhaps @Walt Scrivens might be able to chime back in and clarify?
     
  17. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    @Walt Scrivens, @RoadRailer gave you great help. The releases will get you to the last version that Gregg worked on. If you just click the "clone or download" button, that will give you that latest version that does have changes to it. It has not been tested enough to guarantee it is stable. If you use that version, you just copy the DCCpp folder to where you have your Arduino projects and open the Dccpp.ino file in the Arduino IDE.

    Are you using the standard Arduino UNO and Arduino Motor Control Board Rev 3? Usually errors there are related to current sense not detecting the acknowledgement back from the decoder. What voltage are you running? If you watch closely, do you see the motor twitch when you try to program the decoder? That will at least let you know if the command registered and that it it the acknowledgement that is not being detected.
     
  18. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    Yes, we need to start a new threat for support. People can also post issued on GitHub. That will leave this thread for developing.

    Yes as to versioning with Classic maintaining its "1.x.x" scheme and DCC++ EX starting with 2.0.

    I'm trying to catch up ;) I really want to merge in current monitoring and motor board support additions and look at what @haba has been working on. We have to reorganize the repo, figure out the Arduino IDE/PlatformIO compatibility, and rename things like we have done with Classic to get rid of the _Uno in the project name and files.
     
  19. FlightRisk

    FlightRisk TrainBoard Member

    196
    63
    4
    I guess there are several issues then. ;) First, like a lot of folks, he is using the Arduino IDE and trying to find a simple way to just copy files from a zip and open them. That doesn't work in the DCC-EX repo unless you know what you are doing. We need to trace how people might find us and see that the WEB page might be the most valuable resource because it is the simplest way to download a zip.

    I think he, like others, would land on the main repo page where there is no help text. Maybe there is a way to add some. Then you have to know what BaseStation Classic and BaseStation is. I believe he clicked on one of them, probably dcc-ex.github.io since he mentioned finding "html pages". From there he probably saw the old README.md text that asked him to "download the zip file". From that screen, there is no access to the zip. Even if he found the BaseStation Classic repo, I think "clone or download" may not be intuitive enough. You would then have to figure that is your only option, click on it and then on "download" in the lower right corner. This is all good stuff for our documentation lead and tells me we need to quickly get some more text on the web page and put download links here: https://dcc-ex.github.io/. It would be great if anyone has time to add a menu to the left or right where we could put a download option and then point to zips.
     
  20. haba

    haba TrainBoard Member

    28
    17
    5
    When I look at the code of "Classic", it is not astonishing that it only works sometimes in respect to reading stuff back from the decoder. For example if the decoder is too fast it will fail. If there are any other current spikes than the ack pulses it will fail. If your decoder is a little slow at reset it may fail.

    Test my version from https://github.com/habazut/dcc-ardu/ and tell me if that works better for you. It's configured for the Uno as I happen to have Uno and uses the Arduino IDE. I habe read out all CV of Kühn (old and slow) and Zimo decoders (quite recent and faster) with success. JMRI DecoderPro (latest and greatest) as the user interface.

    Regards,
    Harald.
     

Share This Page