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

Gregg Aug 25, 2015

  1. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Though the problem could be the voltage getting to the WiFi, many shields are designed explicitly for the Arduino. It would seem strange if the Arduino regulator was a limiting factor, else what's the point of manufacturers making the Wifi into a "shield." My guess is that the Wifi board is either bad, or there is something else going on.

    Though I have two different Ethernet boards (one from Arduino.org and one from Seeed Studio), I don't currently have a WiFi to test directly and try to debug the issue. Spent almost an hour at MicroCenter today trying to buy an Adafruit Wifi Shield (using the HUZZAH chip). According to the store they had 3 in stock, but no one could find them. They have giant bins filled with shields, parts, wires, breakout boards. The folks working there decided it was too difficult to find one in all the mess, so I left empty-handed! Will order one directly from Adafruit -- should take a week or so to arrive.
     
    Scott Eric Catalano likes this.
  2. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    It does seem like the short circuit protection on the Pololu might just be more sensitive and faster than any external circuit or software detection. I'm going to order a Pololu and test out reading the SF signal that indicates a fault. This will allow the Base Station to better manage the process. Just to double-check, in the test where you got the current up to 200mA and a <c> command returned an 11/1024, can you try this with the CURRENT_SAMPLE_MAX set to 10 (or even 6). Once the current gets to <11/1024> this should definitely trigger the short-circuit routine in the software (since 11 > 6 :)).
     
    Scott Eric Catalano likes this.
  3. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    I'm not sure a 1A 5V would be enough, but 1.5 or 2 should be. I have not tested that, though.

    The core problem seems to be that the Mega's onboard 5V regulator cannot supply enough current to power the WiFi board, which requires at least 1A.

    I'm testing a Mega with a Huzzah WiFi board, by itself. The "buildtest" demo program that comes with the (Huzzah) WiFi library crashes during startup. This is apparently a symptom of insufficient current supply to the board.

    I have a 5V 2A supply on its way. When it gets here I will be able to bypass the Mega's onboard regulator and test the theory.

    Assuming it works (it could just be my horribly bad luck with getting things to work), my hope would be to convince Jason to include a hefty 5v regulator circuit (1-2A) on his DCC++ shield, so that the whole stack (Mega + WiFi + Motors) can be powered from a single 15-18V supply, simplifying even more the installation.
     
    Scott Eric Catalano likes this.
  4. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Interpretation of the <a CURRENT> response:

    The Arduino contains an internal 10-bit analog-to-digital converter (ADC) connected to the analog pins at the "bottom" of the board, usually label A0-A5 (or A0-A15 on the Mega). This 10-bit converter provides for responses ranging from a minimum of 0 to a max of 1023. When the voltage applied to one of the analog pins is 0, the response from that pin is zero. That's the easy part.

    When the voltage is at its MAX, the response is 1023. By default, the Arduino uses 5V as the max for 5V-Arduino boards, and 3.3V as the max for 3.3V Arduino boards, meaning that either 5V or 3.3V at the A0 pin (depending on the board) will result in a response of 1023. A voltage of 2.5V would thus result in a response of about 511 on a 5V board.

    There are two ways of changing the MAX value. Within the software, you can change the MAX value to 1.1V (for both the Uno and the Mega) or 2.56V (Mega only). Changing the MAX to these lower values allows you to better measure smaller voltages. You can also apply your own voltage (anything from 0-5V) to the pin labeled AREF on the Arduino, and let the Arduino know (via the software) that it should use this voltage as the MAX.

    DCC++ uses the default, which for 5V boards is simply 5V.

    So what does that have to do with monitoring track current?

    For motor shields that have current-sensing circuity, they set certain pins to a voltage that is proportional to whatever current they are measuring (usually separate signals for each motor channel). The Arduino Motor Shield uses a scale of 1.65V per Amp. So if it senses a current of 1A, the voltage applied to pin A0 is 1.65V. If it senses only 500mA, the voltage would be 0.825V, and so on. I think the reason they picked this scale is because at 2 Amps (which is the max for this Motor Shield), the voltage would be 3.3V, which is the same as the max for a 3.3V Arduino board.

    To determine the value of the <a CURRENT> response, we would first convert the current to a voltage using the scale specified for the Motor Shield, and then multiple that by the ratio of 1023 to the MAX voltage used for the ADC. If the MAX is 5V, then on the Motor Shield a 1 Amp current would be 1.65v * 1023/5V = ~338. If we maxed out the Shield at 2 Amps, the value would be ~675. So we can never get to the full 1023 when the MAX is 5V.

    Different shields would respond differently. The specs for the Pololu MC33926, indicate a scaling of 0.525V per Amp. This means that the same 1 Amp current sensed with this Pololu would yield an <a> response of only 0.525V * 1023/5V = ~107. This is why I needed to re-write the current-sensing routines to read the CVs -- -different boards produce different values for the same current.

    It would be possible to build this scaling logic into Base Station, but since I wanted to minimize the number of floating-point calculations (which takes a LOT of clock cycles in the Arduino since it does not have native floating point support), I decided to do the translations in DCC++ Controller. Of course this means the Controller needs to be aware of the scale factors for the Motor Shield, and the MAX voltage used for the ADC.

    Sorry for the long-winded email on this -- wanted to make sure I captured all the details for those programming their own systems.

    -Gregg
     
  5. Gregg

    Gregg TrainBoard Member

    237
    311
    18

    Hmm.. Something still doesn't make sense to me. The on-board regulator on the Arduino is for the Arduino, not necessarily the shield. Shields that need more power will read the VIN pin and use their own on-board regulator. For example, the Adafruit Huzzah Shield (https://www.adafruit.com/products/1491) indicates it has an on-board 3.3V regulator that itself handles 350mA. This board should not draw any current from the Arduino regulator.
     
    Davemil and Scott Eric Catalano like this.
  6. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    All,

    I just posted a small, but important, update of DCC++ Base Station to GitHub.

    The good folks at Arduino recently updated the IDE to verison 1.6.7. I downloaded it today and was surprised to find that the logic I included in Base Station that allows you to easily specify different libraries for different Ethernet Shields no longer compiles!

    A check through the Arduino release notes reveals that the library inclusion routines were optimized for faster loading, and a lot of other logic was changed. I think this would have no impact on most programs, but I was trying to be a bit clever in Base Station and was specifying library files in a #define statement which was then used in a #include statement. This did not work in 1.6.5, but did in 1.6.6. Now it does not work again :(

    So... I re-did the logic so that it no longer utilizes a #define in #include. Instead, the COMM_TYPE parameter in Config.h has been replaced by a COMM_INTERFACE parameter that specifies NOT just whether you are using Serial or Ethernet, but WHICH Ethernet card you are using. Then, in Comm.h it determines which library to include. You still need to have downloaded and installed the library into the Arduino IDE, but based on which Shield you specify using the COMM_INTERFACE parameter, the program will pull in the correct library.

    While I was at it, I also made some minor changes based on your feedback over the past few weeks.

    First, I added a method to specify a static IP address insted of always using DHCP. You’ll now find a line in Config.h that has a 4-byte array defined as IP_ADDRESS. If the line is un-commented, Base Station uses that as the IP address. If the line is commented-out, it will use DHCP. Of course, if you have specified Serial as the COMM_INTERFACE, the IP_ADDRESS is ignored.

    Second, to avoid some of the uncertainties associated with which pins are mapped to what on any given Shield, I created a new function in Base Station that prints to the serial window a detailed list of all Base Station parameters, settings, the IP address, etc. It’s meant to be read by a human, not a computer, so I did not want to simply include it in some expanded <s> response. Instead, it’s meant to be used standalone and invoked only when needed.

    But how? If you are using an Ethernet Shield or Wifi Shield, you can’t type commands into the Arduino Serial Window (well, you can, but they are ignored). Which made me realize that if you just pick up an Arduino, there really is no way of knowing what’s on the board if you don’t remember what version of the code you used (or any changes you made to the code).

    So I added a feature that utilizes a “reserved pin” to change the start-up behavior of Base Station. Pin A5 (which is unlikely to have been used by anyone yet) is now set to an INPUT with its PULL_UP resistor activated. If Pin A5 is left open (or tied to 5V - HIGH), Base Station will start-up as normal. But if Pin A5 is set LOW, by jumpering to ground, Base Station will start up by showing a list of its configuration parameters and other settings. The program then halts. Simply remove the jumper and reset for normal operations. This way, if (like me) you have a lot of different boards with slightly different configurations, you can quickly identify the settings.

    More so, you can use this to confirm that the settings are what you think they are supposed to be. Very helpful when deugging pin-mapping problems, especially if you made changes to the DCCpp_Uno.h file.

    The final change I made to Base Station was to add a VERSION number to the software (which is echoed in the <s> command as well as the new configuration mode). The format of the VERSION number is designed to help make a distinction between official releases (that are numbered in GitHub) and simply the latest version of the master branch (which is updated much more frequently before a new release is “stamped”).

    The VERSION number within the Base Station code will always match the version number of the latest official release. However, if it includes changes from updates to the master branch, a “+” is added. This way you will know when a version is based on a particular release, but has new updates that have not yet been stamped with a new release number. The code I just uploaded to GiHub has a version number of “1.2.1+” since it is based on the the last official release (which is 1.2.1) and has the new modifications listed above.

    Please give the new update a try, and make sure you have the latest 1.6.7 version of the Arduino IDE. Let me know if you have any problems compiling (I’ve tested the code on an Uno and also on a Mega with and without an Ethernet Shield). Also, curious as to what you think about the new “configuration” mode.
     
  7. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Ah. OK. So the value sent back in the <a value> response is the raw ADC "click" value.

    That's fine. I'll just have to think about what needs to go into JMRI to allow the user to properly scale the value and provide a meaningful output. Since there could be a variety of hardware (and voltages) involved, that's not so clear right away. But I'll sleep on it... :)
     
    Scott Eric Catalano likes this.
  8. HVT

    HVT TrainBoard Member

    74
    93
    15
    Feature request for consideration, auto-reversing. Since the Pololu has such a fast, sensitive short circuit protection how can an auto-reversing be implemented? Would it require a separate motor shield running the opposite phase with some way to detect and switch phase? Should make for an interesting discussion.
    Dave
     
    Scott Eric Catalano likes this.
  9. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    https://learn.adafruit.com/system/a...nal/adafruit_products_ccshield.png?1379351866

    The Huzzah CC3000 board draws its 5V power from the VCC pin, not from the VIN pin, so it is powered through the Arduino's 5V regulator. And that regulator, without some major heat sinking (which isn't present and there isn't much room for) is not going to supply much more than 750mA without going into thermal shutdown.

    Beats me why they did it that way, but the schematic doesn't lie. Maybe some of the other WiFi boards work differently, but this is the one I bought :(

    The Huzzah board itself apparently only needs about 350mA, leaving... 400mA for the Arduino itself, and that is operating the Arduino's regulator at maximum power.

    Of course, I could be fighting some completely unrelated problem and only *think* the power supply is the problem... we'll see in a few days...
     
    Scott Eric Catalano likes this.
  10. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Should be able to just quickly flip the polarity of the Arduino outputs driving the motor shield...
     
    Scott Eric Catalano likes this.
  11. KE4NYV

    KE4NYV TrainBoard Member

    219
    281
    17
    I was trying to wrap my head around the problem and now I think I have it. I didn't realize the ON BOARD 5V regulator was the problem. I was under the impression that the on-board was handling the current requirements, everyone just wanted a way to power everything from the single supply input, thus the 9V regulator I put on the board. I did that to just knock it down to a reasonable voltage, before sending it to the Arduino.

    If I was to switch up (which I can), I would go to a 2A 5V regulator and instead of taking that to the Vin pin, I would take it to the 5V pin, thus backfeeding voltage to the 5V bus of the Arduino. I'll have to check and see if feeding 5V to the output of the Arduino's on-board regulator will damage it. This is partially why my originally design was feeding 5V to the bus through a common anode diode network, to avoid "colliding voltages".
     
    Scott Eric Catalano likes this.
  12. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    Yeah... that's what I had in mind. I'm a bit concerned abut backfeeding the onboard 5V regulator as well... that would probably require some looking into first...
     
    Scott Eric Catalano likes this.
  13. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Wow! The schematic does show the VIN pin unused and the +5V being pulled from the Arduino. Not sure why they did it that way. I was just looking at the Arduino.org version of their WiFi shield and it's hard to tell from the schematics if they are using VIN or +5V (they are tied together with a diode, but it seems the VIN is driving the on-board regulators). Good catch TD!

    For now, I think I'll stick with the Ethernet Shield and an external WiFi router (I'm actually using a spare Sonos music controller).

    However, if you do get the WiFi shield working, I have some ideas regarding where to store the password for your WiFi. Probably not a good idea to store in the code, since then you have copies of your WiFi password everywhere. But it can be stored in EEPROM on the Arduino along with all the other "saved" settings. You would type it in through a new command via the Serial Window. Though it would not be encrypted and thus not particularly secure, at least it would only be stored on the board, and you can continue developing and sharing code without having to worry about your password being embedded in the program itself.
     
  14. KE4NYV

    KE4NYV TrainBoard Member

    219
    281
    17
    On a side subject, while I wait for the first DCC++ interface boards to come in I have been working on a handheld cab design. I have a basic PCB designed, but was trying to work out the physical hardware. I found this handheld case from Hammond (who I use regularly for other products) and I think it could fit the bill. I'm doing a mock up now. So far it just has a membrane keypad, rotary encoder w/ push switch and a 128x64 graphical LCD display. Only took a few minutes on the CNC to cut out the LCD window.

    [​IMG]
     
    KC Smith, HVT, lnxlnx and 1 other person like this.
  15. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    All,

    On a totally different subject (though very apropos of the post that I just saw above!) I have given more thought to the issues related to using multiple controllers, either programs or HHTs, and the need to be able to sync up registers. I think I have a solution, but before coding, I wanted to get everyone’s feedback.

    Currently, the throttle command looks like this:

    <t REGISTER CAB SPEED DIRECTION>

    where both REGISTER and CAB are required, and both are always non-zero.

    I’d like to change this so that one or the other can be zero:

    <t REGISTER 0 SPEED DIRECTION> or <t 0 CAB SPEED DIRECTION>

    In the first case, the throttle will be set for the register you specify. Also, each register will store its CAB value. So if you leave out the CAB number (by setting it to zero), the throttle command will use whatever CAB was already associated with the specified register. If you select a register number that has never been used and has no associated CAB, the command will do nothing and respond with an <X>.

    In the second case, where the REGISTER is not specified, the throttle command will first search all the existing registers to see if any of them are associated with the CAB you specified. If yes, it will use that register. If not, it will initialize a new register, associate the CAB, and set its SPEED and DIRECTION.

    Currently, the <t> command returns <T REGISTER SPEED DIRECTION>. This needs to be updated so that it also includes the CAB. However, adding a new field will likley mess up existing DCC++ Contoller logic, JMRI, and other programs. So to aid in the transition I would create a second version of the response: <G REGISTER CAB SPEED DIRECTION>. Base Station will have an option to use either the <T> or <G> response. Then at some point in the future I would deprecate the <T> version.

    By parsing the <G> version you can instantly see what REGISTER is associated with what CAB.

    A few other bells and whistles:

    If you try to set the throttle of a new CAB, and you are out of register slots, the code will look for the first slot that has a cab with zero throttle speed, and replace that. The only purpose of a register in DCC++ is to keep sending speed commands to each cab. If a cab speed is zero, there is no reason to keep sending zero-speed requests.

    This way, you can simply use the <t 0 CAB SPEED DIRECTION> verison of the command and never have to think about registers or even know they exist. Also, no need to “release slots.” So what happens if you are at the maximum number of slots and you try to set the throttle of a new cab? You get the response <G 0 CAB SPEED DIRECTION>, which tells you the command was unsuccessful. The solution is then to set the speed of any other cab to zero, and send the command for the new cab a second time. This effectively swaps your new cab for the old one without you needing to manage the registers.

    Also, the options for DIRECTION would be expanded. Instead of just 0 for reverse and 1 for forward, we’ll also have 2 for increase, and 3 for decrease. These options will not set the throttle to the value of SPEED, but rather would increase or decrease the current speed by the value SPEED. This would allow you to create an HHT using a rotary encoding knob that just kept sending <t 0 CAB 1 2> commands to ramp up the speed and <t 0 CAB 1 3> commands to decrease the speed. It would never have to bother reading the <G> response. And of course the code would make sure the speed never went out of bounds (below zero or above 126).

    This feature would also allow you to “query” a given register or cab. For example:

    <t REGISTER 0 0 2> would increase the speed of the cab in REGISTER by zeo — e.g. do nothing.
    <t 0 CAB 0 2> would similarly do nothing to the speed of whatever register was associated with CAB (or it would create a new register if needed).

    BUT… both of these command would return <G REGISTER CAB SPEED DIRECTION>. You can parse this and learn what register is associated with what cab (as well as its speed and direction).

    Thoughts?

    -Gregg
     
    HVT and Scott Eric Catalano like this.
  16. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Very good description and here is my 2 cents:

    Easy DCC: each throttle has to be added to its own base station as in registered...no slot max
    NCE/MRC: all you have to do is pick the loco address...no slot max
    Digitrax: Utilizes cab addresses and slots feature.....and 9 out of 10 times we get slot max because after you're done using the throttle and loco you are suppose to dispatch out the address to make room for another slot.....this is very annoying.

    Your idea that you're proposing is very "dynamic" when a throttle isn't used that register is open...all you should be able to do is select a cab number and be on your way...thats all you need....the registers and everything else needs to be hidden...when a HHT is in use behind the scenes the register number is assigned from a "pool" of available numbers...built on the same principal as DHCP....HHT in use register assigned.....HHT not in use register released. Simple
     
  17. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Scott, thanks for the feedback and info.

    Note that using my proposed format, one could build an entire system with different software and hardware throttles, and never implement the concept of a "register". All throttle commands would specify the Cab and leave the register field as 0; and any throttle that wanted to be aware of the speed would read the <G> command and note the Cab number (ignoring the first field which is the register). However, I kept the register concept as a parallel method for two reasons -- backwards compatibility, and other-system limitations. I'm not concerned about DCC++ Controller. I can change that to utilize cab addresses and dump the concept of a register. But I'm not sure if getting rid of the register concept would break other existing implementations, such as those who created JMRI and WiThrottle interfaces. More so, I'm not sure if any of these other control system require the concept of a register slot, in which case if I dump it all together, those systems could never be used with DCC++.

    Any ideas on this? If JMRI etc, do not actually need the concept of a register, does it make sense to eliminate registers from the <t> command and <G> response? This would certainly simplify things (of course the registers would still be there, just hidden within Base Station structures). - Gregg
     
    KC Smith and Scott Eric Catalano like this.
  18. esfeld

    esfeld TrainBoard Member

    442
    382
    17
    Gregg
    Can not determine from your post but would like to ensure that upon changing direction, speed setting does not revert to zero. Those of us that use magnetic uncoupling prefer the ability to reverse direction without having to input a speed setting. I helped Balazas Gyori include this in DigiTrains and it has been well received.
    Steve
     
    Scott Eric Catalano likes this.
  19. mikegillow

    mikegillow TrainBoard Member

    116
    117
    13
    This concept works if you are building an AR from from an Arduino+Pololu, but I don't think so if the question is "how do you use a commercial AR if your base station uses a Pololu?" I borrowed an AR1 from the club and will be trying to figure that out since I will have a turntable on my layout and was intending to use an AR1 on the bridge. I'm hoping that putting a tail light bulb in the mix will allow it to work - I've seen posts where there have been similar issues with some commercial base stations.
     
    Scott Eric Catalano likes this.
  20. conrailandrew

    conrailandrew TrainBoard Member

    18
    29
    11
    Wonder if that could be an option the user could set to the user's preference, I myself prefer that the train be stopped before reversing.

    Good work on everything though, guys! It's rare to find folks that are willing to donate so much of their time and expertise to the good of the community, we really appreciate it, keep up the good work!

    Andrew
     
    Scott Eric Catalano and HVT like this.

Share This Page