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

Gregg Aug 25, 2015

  1. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    W8ONE - have you tried the suggested circuit with this shield: http://www.ebay.com/itm/221937117597?_trksid=p2059210.m2749.l2649&ssPageName=STRK:MEBIDX:IT or a similar one?
    I have been experimenting with this project and can't get the shield to put out voltage to the track even though I have both the INA1 and INB1 pins connected as you suggest - my scope shows that the appropriate signals are being applied - I also have the PWM1 pin pulled high.
    Any suggestions?
    thanks to you and all of the others who have worked so hard to get this working!

    dave
     
    Scott Eric Catalano likes this.
  2. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Dave, I think the Pololu VHN5019 could be used but there are a few caveats. First, you'll need to add some additional, though simple, logic circuity or a few transistors to drive the IN1A and IN1B (IN2A and IN2B for the second channel) pins. This is because DCC++ (presently) only creates one DCC signal per channel.

    Second, you'll probably need to re-map some of the pins (cut a few traces and solder a few wires) to avoid conflicts with DCC++ functionality.

    Third, since this is high-current board, according to the Pololu spec the current sensing scaling is set to 140mV per Amp. On the Arduino Motor Shield this scaling is 1.65 V per Amp (more than 10x greater). DCC++ uses current sensing to read decoder CVs from the programming track --- NMRA standards require a decoder to consume at least 60 mA to send an acknowledgement. I find my locos typically use 3-4 times that when sending an acknowledgment, but let's assume a minimum of 60mA.

    The ADC on the Arduino has a resolution of 1024 over a 5-volt range (the default), which yields a return value from the ADC of 0.060A * 1.65V/A * 1024/5V = 20 units. This is readily detectable within a background current draw of 20 units (which is what I typically observe). But at the scaling of 140mV per Amp on the Pololu VHN5019, the return value could be less than 2 units, and this likely not distinguishable from background current and ADC noise.

    If your trains draw a higher current when acknowledging a CV read, this may not be an issue. One possible solution is to utilize the Arduino's internal reference options for the analog-to-digital conversion. We can programmatically select an internal voltage for ADC reference of only 1.1V. This would give us about 5X the sensitivity and hopefully would be sufficient to accurately read CV acknowledgments.

    -Gregg
     
    NormHal and Scott Eric Catalano like this.
  3. w8one

    w8one TrainBoard Member

    89
    109
    5
    Dave

    This shield has the Current sense pins on A2 & A3 not A0 & A1 . Side 1 should be inA1 (shield d7) and inB1 (shield d8) with the transistor not circuit hooked to them the input to the circuit to (on uno) d10 or (on mega) d12. The pwm1 (shield pin d5) would hook to (on uno or mega) d3. Don't forget to hook up the power and ground for the tracks to the shield and out 1A & 1B to the tracks. It looks as if it only used the Arduino's +5v to enable the en/dia pins and vcc to do the rest.
    These settings are with config.h set for the arduino motor shield, and you must use arduino ide 1.6.6 or higher to upload the code.
     
    Last edited: Dec 30, 2015
    Scott Eric Catalano likes this.
  4. w8one

    w8one TrainBoard Member

    89
    109
    5
    You won't need 2 i2c buses they all share 1 bus each component on the buss will have its own address base address + the address you configure The MCP23017 is base address of (0100) 0,1,0,0,a2,a1.a0 .
    You set the a2,a1,a0 address by +5v or ground to each pin. So if the first chip you set all to ground the address will be 0100000. The PCA9685 as a base of 1 + a5-a0 you configure so if the first 1 were all address pins are grounded its address will be 1000000. 74hc595 is a shift register it wont be on the i2c bus.
    For the current sensors you can use 74hc4051 to give you more analog inputs. See http://playground.arduino.cc/Learning/4051 for more info. Oh someone maks a shield for that using i2c http://blueberryde.com/shop/24-channel-analog-expander-shield/#!prettyPhoto
     
    Last edited: Dec 30, 2015
    Scott Eric Catalano likes this.
  5. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    W8ONE - I have what I think is a good test configuration which puts the appropriate signals to the A1 and B1 pins on the shield - I also have pulled the PWM pin high - I have put my notes on my web page here:
    http://trainelectronics.com/DCC_Arduino/DCC++/
    Please have a look at the part titled Monster Moto Shield and let me know what you think - I feel that the signal that I am providing should get me something on the output but it does not -
    I do have DCC++ working well with the Arduino Motor Shield and the one from DFRobot (also shown on the web page)
    Your help is appreciated!
    dave
     
    Scott Eric Catalano likes this.
  6. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    Gregg - thanks for the tips - My first goal it to get it to respond to the JMRI commands and put power to the track (see email above to w8one) -
    thanks again!
    dave
     
    Scott Eric Catalano likes this.
  7. w8one

    w8one TrainBoard Member

    89
    109
    5
    What voltage are you feeding to the hhd led connector? The data sheet shows 5.5v min input on the power going to the input on the shield. The not circuit looks to be working properly according to the scope.
    Have you tried the sketch on the ebay page?
    It may be that h side1 and side2 both have to be hooked up for the chip to work.?
    It looks as you have everything right.
     
    Last edited: Dec 31, 2015
    Scott Eric Catalano likes this.
  8. w8one

    w8one TrainBoard Member

    89
    109
    5
    I was looking at the datasheet and may have found the problem. Table 9. Switching, tDEL Delay time during change of operating mode (see Figure 4) 300µs min, 600µs typical, 1800µs max
    DCC standard for a "1" bit is 116µs (58µs+ then 58µs-), DCC++ may be to fast for it.
    The VHN5019 is faster but not fast enough at 200µs min, 400µs typical, 1800µs max
    The L298 longest delay is 2.2µs.
     
    Last edited: Dec 31, 2015
    Scott Eric Catalano likes this.
  9. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    I agree that the timing may be the issue - Thanks for your research - I think I'll set this shield aside and concentrate on the others.

    At least it may save some others from going down the same road!

    dave
     
    Scott Eric Catalano likes this.
  10. Bill Jones

    Bill Jones New Member

    3
    3
    6
    I have this excellent project from Greg up and running on the bench. I would like to get a turnout working, but my programming skills are zero. Could someone guide me with an example of just what code needs editing to get just one turnout working. Hopefully armed with this I can go forward from there. Are the edits needed in dTurnouts and Accessories.cpp? Many thanks.
     
    Scott Eric Catalano likes this.
  11. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Hi Bill,

    To begin, I would recommend first ensuring the DCC++ signals are being generated correctly. Though you have the system on a bench, have you tried running a loco? If you can use the <t> command from within the Arduino Serial Monitor to start and stop a loco then you have DCC++ running correctly.

    Next, you need to have a stationary decoder connected to a turnout (in future versions of DCC++ you will likely be able to drive a servo directly without needing to utilize a stationary decoder). You do not need to change any of the code on the Arduino to operate a turnout. Rather, first you define the Turnout ID and DCC address/subaddress using the <T> command from within the Serial Monitor, and then you can test it using a different form of the <T> command. The Accessories.cpp file shows the different formats of the <T> command and how it is used.

    Once you've been able to verify that you can operate the turnout from within the Serial Monitor, the next step is to create the turnout graphically in the Controller. This will require changing some of the code on the controllerConfig.pde file to define the turnouts, but no changes are needed in dTurnouts.pde (which provides for the generic handling of turnout controls). I can step you through the code-change process when ready.

    -Gregg
     
    Scott Eric Catalano likes this.
  12. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    Dave (HVT),

    I've been thinking more about your requirements above and it might be cost-effective to use the IC2 bus to daisy-chain a bunch of Megas together. Though the Mega itself is more expensive than a multiplexer, there are a few advantages. First, you have a lot of pins --- digital inputs, digital outputs, PWM outputs, and analog inputs. You would be able to connect current sensors directly to the analog inputs, servos directly to the digital output pins (Arduino has a robust servo library), panel buttons to pins configured as digital inputs, and probably LEDs to the pins configured as digital outputs, though you may be limited by the total power draw of the Arduino in supporting lots of LEDs (in which case an additional circuit or driver card may be needed). The other advantage of using Megas to serve all of these accessories is that you can utilize each Mega's separate processing abilities. For example, DCC++ current-sensing uses exponential weighting to smooth out current spikes, and the sensor input routine uses exponential weighting as a virtual switch/signal de-bouncer. Also, the remote Megas can perform all of the polling of sensors to look for changes, and then send back a message to the Master Mega only when needed. This distributes the polling across as many Megas as you need and doesn't bog down the Master that's generating the DCC signals and, presumably, maintaining ultimate control of all the accessories.

    As present, DCC++ Base Station allows you to add/edit/delete/control generic digital outputs through the <Z> command and generic digital inputs (e.g. sensors) through the <S> command. Polling of the sensors is automatic and the Base Station generates <Q> and <q> commands whenever the state of a sensor is triggered. I'll experiment a bit this weekend and add some code to extend the <Z> and <S> commands to utilize the IC2 bus for remote operation of additional Arduinos. The idea I have is to create a small, standalone piece of "serving" code that would run on each additional Mega or Uno that contains basically just a small subset of the main DCC++ code --- the parts used for sensor and output control --- plus support for listening to the Master over the IC2 bus. Then, on the Master, I'll add some code to the <S> and <Z> definitions that inspects the pin number you specify in the definition, and, based on some logic, decides if the pin is local, or is on the Ic2 bus (and if so, where). One possibility is to simply cascade the pin numbers. On the Mega, pin numbers range from 0-69. If you specify pin 70, DCC++ can treat that as pin 0 on IC2 bus address 1, pin 71 as pin 1 on IC2 bus address 1, pin 145 as pin 5 on IC2 address 2, etc. And since the <S> and <Z> commands both utilize 2-byte integers as ID's, once you define a sensor or input, the rest of the code won't know or care if the input or output was generated locally or remotely (or course I'll need to add an Ic2 handler for this within DCC++). Also since the switch debouncing and other polling will occur separately on each remote Mega, the Ic2 bus will only be busy with traffic when an event is actually occurring. The Master Mega would simply "poll" each remote Mega in general to see if there is anything to report on the I2C bus, which should create very little overhead.

    I'll give it a try and see how well it scales. If it works well, we can then add in specific commands to control Servos (using the servo library) as well as read current sensors. And it gives me a good excuse to go to the hobby store this weekend and buy a servo (I use snap-switches on my layout but wished I used servos).

    -Gregg
     
    KC Smith and Scott Eric Catalano like this.
  13. HVT

    HVT TrainBoard Member

    74
    93
    15
    Gregg,
    Thank you so much for the latest explanation. I sure feel much more comfortable with the daisy chained Megas sharing the work load. I don't yet understand what is meant by the <S> <Z> <Q> stuff but I do understand the concept of polling and your proposed address scheme. I would expect that there would be no problem distributing the Mega boards around the layout with each board handling the local switching/sensing/signaling. A local 5 volt power bus at each Mega with the grounds all tied together should handle the current load for the servos and LEDs.

    Concerning your previous response to the Pololu VHN5019 the higher sensitivity threshold makes sense for the larger H-bridges. Today I'll order the Pololu MC33926, a few Mega boards and some ACS712 current sensors to get started with. The plan is to connect it to a PC laptop running JMRI.

    Thank you for all the effort and time that you have invested in this wonderful project.

    Regards,
    Dave (HVT)
     
    Scott Eric Catalano likes this.
  14. HVT

    HVT TrainBoard Member

    74
    93
    15
    Gregg,

    One other question, can another Pololu MC33926 be added to the system to form a second power district?

    Dave (HVT)
     
    Scott Eric Catalano likes this.
  15. HVT

    HVT TrainBoard Member

    74
    93
    15
    Gregg, et al,

    One other advantage to multiple Mega boards besides distributing the workload is that I am building the layout in sections and each section can have its own Mega/sensors/signals/servos and only a track power bus and an i2c bus will need to be connected between sections.

    Dave (HVT)
     
    Scott Eric Catalano likes this.
  16. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    I think so. To allow continuous operability between power districts you would need to ensure the DCC signal is the same. I don't see why a single DCC logic signal coming from pin 12 of the Mega could not simultaneously drive the direction channel of 2, 3, or 4 Pololus. And since you probably only needs one programming track, each additional Pololu could serve two districts (one on channel A, one on Channel B). However, you would need to map the enable/PWM pins of each Pololu to distinct pins on the Arduino so that you can separately turn on/off each power district. We'd also need to map the current sensing outputs which are normally connected to A0 and A1, to A2 and A3, A4 and A5, etc. for each Pololu. This would provide for short-circuit protection for each separate channel.

    -Gregg
     
    Scott Eric Catalano likes this.
  17. esfeld

    esfeld TrainBoard Member

    442
    382
    17
    TwinDad
    I see that you are taking a break from software writing .... does that mean that development has stopped on the wireless shield/WiThrottle code?
    Steve
     
    Scott Eric Catalano likes this.
  18. w8one

    w8one TrainBoard Member

    89
    109
    5
    Would it be better / easier to give each arduino a i2c address and sync them over i2c and have a shield on each one? Could you also use the current sense of each additional shield as a "district occupancy detection" as well as current limiter?
     
    Scott Eric Catalano likes this.
  19. markwr

    markwr TrainBoard Member

    339
    6
    11
    One thing you might want to consider adding to the board would be a regulator to take the input voltage for the motor driver circuit to a voltage appropriate for the Uno or Mega board and feed the output to the Vin connection. This way the main board could be safely powered by the power connection to the shield and eliminate the need for two power connections to the stack of boards.
     
    Scott Eric Catalano likes this.
  20. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    I don't think we can sync the DCC signals on separate Arduinos --- we need a "master" DCC logic signal if a train is to pass seamlessly from one district to another (if the districts are completely separate then we can use separate systems since it's basically separate layouts). However, it may be that a master DCC signal can be distributed to other Arduinos that each have their own motor shield. Each Arduino would be responsible for monitoring current for its district, and would have control over the enable pins to turn on and off current from its motor shield.
     
    Scott Eric Catalano likes this.

Share This Page