Introducing DCC++ ---a complete open-source DCC station and interface

Gregg Aug 25, 2015

  1. esfeld

    esfeld TrainBoard Member

    442
    382
    17
    DJ79 ...... Yes DT is Android ... only offered it as an alternative not realizing how far you are all taking the DCC++ environment........ NOW, since you all seem to be proficient programmers: I am trying to extend the Controller Java code to include an input box in Throttle A so that one can enter a cab number ...... my Java code is:
    public class CN
    {
    public static void main(Int[] args)
    {
    int CabNum; // Define variable
    Scanner in = new Scanner(System.in);

    }
    System.out.print("Enter Cab Number = "); // ******* Prompt message
    CabNum = in.nextInt(); // Read in Cab number and store in CabNum
    }

    cab622 = new CabButton(tAx-125,tAy-100,50,30,150,15,CabNum,throttleA);
    cab622.setThrottleDefaults(53,30,-20,-13);
    cab622.functionButtonWindow(220,59,70,340,backgroundColor,backgroundColor);
    cab622.setFunction(35,15,60,22,60,10,0,"Headlight",ButtonType.NORMAL,CabFunction.F_LIGHT);
    cab622.setFunction(35,45,60,22,60,10,1,"Tailight",ButtonType.NORMAL,CabFunction.R_LIGHT);
    I keep getting an error: unexpected token (
    Should be a simple error to find, but for the life of me I'm not finding it ......... anyone care to jump in?
    BTW I love the fact that we are all trying to take Greggs monumental work even farther.
    Steve
     
  2. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    I could also use a quick primer on the concept of "Registers" ... are these treated similar to Digitrax "Slots"? Who (Base Station vs. control code -- e.g. JMRI) controls the allocation, assignment and deletion of registers?

    I'm guessing it's done on the JMRI (host) side... that it would keep an array of registers, assigning a throttle to an available register as it is created, then releasing that register when the throttle is deleted... and passing the register number to the Base Station as a reference...

    Yes? No? What?
     
  3. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Looks like you have a closing bracket in the wrong place. Your last two statements (System.out.print... and CabNumb = ...) are outside of the main() method.
     
  4. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Also... Predefined Turnout #s... who owns the assignment of these? How are they mapped to the DCC address of the turnout(s) itself?
     
  5. DJ79

    DJ79 TrainBoard Member

    36
    25
    14
    Since JMRI keeps track of turnouts and their states, we don't need to rely on predefined turnouts in DCC++. Instead of the <T ID THROW> command, which works only on predefined turnouts, we would need to use the <a ADDRESS SUBADDRESS ACTIVATE> command, which sends accessory packets to the track directly, essentially bypassing predefined turnouts functionality.
     
  6. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Cool. That makes things a good deal easier. So basically all accessory decoders are the same.
     
  7. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    TwinDad, you are correct that the programming track is essentially always in service mode from the point of view of the DCC++ base station. The base station code implements just one sequential packet register for the programming track channel and that register is pre-loaded with a DCC idle packet (the main ops channel has 12 sequential packet registers, and each can contain a separate cab throttle setting). Thus the programming track receives idle packets over and over. When you send a DCC++ command to the base station asking for a programming track read or write, the required series of packets is stored in a "one-time" register that temporarily interrupts the idle packets being sent from the sequential register. Once the read and write packets for any given CV read or write are sent, the sequential register kicks back in and the cycle of sending idle packets resumes. All of the read and write packets use the DCC Direct Configuration method for Service Mode calls.
     
    TwinDad likes this.
  8. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    That's correct - there is nothing special about the turnout IDs stored in the DCC++ Base Station. It's really just a shortcut to the <a> accessory command with a predefined address/sub address, with the one exception that the turnout method stores current status in the Arduino EEPROM. This status was originally stored in the Java controller interface, but then I started writing autopilot routines for the Arduino itself and half the time I would run the trains without any computer control. The interface would therefore get out of sync. Since all accessory commands must go through the base station regardless of which system or interface generates the request, I figured I would store the turnout status within the Arduino so multiple interfaces can be used and always be in sync.
     
    Last edited: Nov 4, 2015
    KC Smith and TwinDad like this.
  9. esfeld

    esfeld TrainBoard Member

    442
    382
    17
    TwinDad ... thanks, that was the solution to that problem but try as I might I am not succeeding in my projected goal of creating an input box to add a cab on the fly: ie: an input cab box so that one can enter a new cab on the fly without going into the code. I see that Gregg has accounted for InputBox functionality in the "controllerConfig" tab but evidently I am not skilled enough to call it ..... I think it should be under the "// CREATE THROTTLE, DEFINE CAB BUTTONS, and SET FUNCTIONS FOR EACH CAB" section. Care to give it a try?
     
  10. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    I would, but implementing the JMRI "driver" has already drawn down all of my available time. I've actually set aside a couple of modeling projects to "strike while the iron is hot." Sorry...
     
  11. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Quick progress update...

    I'm most of the way there with the JMRI interface. I have code for the throttle and programmer interfaces, and track power control, that connects to the larger JMRI system. There is a simulator and a serial/USB connection, and they both appear to generate and send properly formatted commands.

    I am testing out the port monitor, and preparing to publish the branch with the code changes. Next up is to grab my Arduino and test the serial interface with an actual, working base station. I do not have a motor shield, so for now I can at best make sure the comms work.

    It will need to be tested and vetted out a bit before being included in the main branch. I am quite confident that I will have something with basic function by the next development release of JMRI.
     
  12. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Hello TwinDad,

    Very good to hear! I would love to test this out.....as I have a working base station and motor shield....and I do have the complete JMRI program I use quite often. Let me know when you need to start testing.
     
    TwinDad likes this.
  13. DJ79

    DJ79 TrainBoard Member

    36
    25
    14
    TwinDad, that is fantastic. Could you please commit what you've done so far to the repository (non-main branch)? I would also like to test it, and perhaps even to contribute. I've been playing with this the last couple of evenings (about an hour is all I can spare), but so far I only managed to get it to show up in connection configuration. I was working on basic communication, but I spend a lot of time exploring how the whole source code base is organized. To me this is a learning experience, but at some point I'd prefer to implement some missing functionality rather than just duplicate what you've done long ago. Unless, of course, you're done with it in the next few days. :)
     
  14. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    I'm unfamiliar with JMRI (apart from knowing genererally what it is), but this sounds like a great project. If you run into any difficulties due to the DCC++ command structure please let me know. There may alternatives that I can adjust in the base station code. Two changes I was thinking of making was to add new commands that would let you create turnout and sensor identifiers so that you would not need to change the code. Anything defined would be stored in EEPROM so it would only need to be done once or when changes are made to the layout itself.

    I've also been thinking about changes to the controller interface so that you can change cabs and function buttons without needing to change the Java code (per Steve's request)
     
  15. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Good news: I plugged in my Arduino, and with a few minor adjustments had no trouble sending and receiving commands.

    @DJ79 Give me a few more days... I'm surprisingly close to having the basic functions (throttle and programmer) complete, including integration with the GUI. And the rest won't take much longer. I will have it available in a branch, as per JMRI policy...

    Right now I'm "in the zone" and I want to get it to a certain level of completeness before opening it up to collaboration. I'm sure you'll understand.

    @Gregg, yes, being able to set/clear the registers and turnout IDs through the interface would be very helpful.

    Also, an "OK" or "ACK" for the messages that don't have real feedback would be good. Just to make sure the Arduino received the command.
     
    Last edited: Nov 6, 2015
    Gregg likes this.
  16. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Oh, one more thing... I realize that you may not be able to query the actual stationary decoder for its state, but if you could cache the stationary decoder commands and send their value back in the command station status (along with the throttles and predefined turnouts), that would help with updating state. It may be memory prohibitive, but perhaps a linked list storing only the ones you've seen, plus commands for clearing the list or releasing/deleting a specific address...

    Just a thought... sleep on it... no hurry.
     
  17. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Actually, belay that... sort of... at least for turnouts...

    It appears that the Turnout ID number is a direct match for the (abstract, user defined) Turnout Number/Address used within JMRI. With some ability to create/assign/delete/release Turnout IDs over the serial interface, I can pretty much directly use the T command for turnout control.

    Actually, even with the predefined Turnouts as-is, with the DCC addresses hard coded in the Base Station, it is still usable, as long as the user manually assigns the Turnout ID as specified in the Base Station code when setting up Turnouts in JMRI.

    This is looking pretty good. More news to come soon.
     
  18. DJ79

    DJ79 TrainBoard Member

    36
    25
    14
    This turnout state caching may not be necessary for DCC++, where we have either a single instance of GUI connected to it, or just a single JMRI connection (unlike in a system like Digitrax, where there can be multiple throttles and other things, including possibly multiple instances of JMRI). In its current implementation, there is nothing that the DCC++ base station is aware of (other than the sensors, of course) that the JMRI driver wouldn't be aware of first. That may change in the future, but for now, it appears that this functionality rather belongs in the JMRI driver, where it would also much easier to implement, if it's needed at all. My Digitrax system doesn't keep track of turnout states, and it's really a non-issue, at least for my small home layout (I use servos for turnout control). JMRI always sends the turnout commands, whether they are needed or not, and the servo controller ignores them if they are not needed. Our club's layout is mostly manual (Peco), with some mix of Tortoise and snap switches that can be manually overridden, so a turnout could be in a different state, and the system would have no way of knowing it other than having additional sensors. In other words, I think this would be a lot of work for Gregg with little benefit.
     
    Last edited: Nov 7, 2015
  19. DJ79

    DJ79 TrainBoard Member

    36
    25
    14
    Scott, how would you compare the Pololu shield with the output stage of say Digitrax CS100 or the Zephyr?
     
  20. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Are you referring to the voltage output? I'm using the power supply from Digitrax listed earlier in this thread that I had connected to the Super Chief....so far its working good....I've had a few sound equipped locos on the track and drawing very little amps.....is that what you were asking? The Pololu motor shield can handle up to 26 volts.....they make a higher voltage motor shield also.
     

Share This Page