DCC++ Turnout Control

Scott Eric Catalano Jan 30, 2016

  1. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Hello All,

    Ok I have several of the Bachmann Ez-Track Turnouts and I was wondering what would be the best way to go about controlling them with the Arduino? Any suggestions? Thanks - Scott
     
  2. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    From the Bachmann web site it seems there are DCC enabled turnouts as well as traditional AC-powered turnouts. Which do you have?
     
    Scott Eric Catalano likes this.
  3. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    I have the standard AC versions...I used them during the Christmas show while Demoing the DCC++ base station which everyone liked....they were connected to a separate AC power supply...I will be using a separate Arduino to control the turnouts along with the Signal system on the demo layout for this coming christmas show. I am a firm believer in keeping things separate as if one system goes down it will not interfere with the other system and vice versa.
     
  4. Gregg

    Gregg TrainBoard Member

    237
    311
    18
    If you control them via a DCC stationary decoder (I use the 6-channel ones from Lenz on my own layout) you can control them directly with DCC++.
     
    Scott Eric Catalano likes this.
  5. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Right....I was going to use my second arduino which controls my signals and crossing flashers already to control the turnouts and not using DCC to do it.... this way the layout itself can be controlled via DCC++ or conventional DC...no decoders needed
     
  6. w8one

    w8one TrainBoard Member

    89
    109
    5
    I don't have any of these but i will guess what the 3 wires do. There looks to be a Left, Middle, and Right. Someone that has one will have to measure with a meter or light which one is common, for now i'll ASSUME the middle is common and left switches to the left, right switches to right. You could use 2 relays and 2 Arduino pins to control them them. Each relay has a N/C (normally closed), Com or C (common), and N/O (normally open) on the contact side, and 2 wires to the coil side. 1st relay will choose direction: Attach left wire to N/C and right wire to N/O going to the turnout and 1 of the ac wires (from power pack) to Com. The second relay will engage the coils: Attach the middle wire from the turnout to N/O, attach the Com to the other ac wire (from power pack). The coil side of the relays has to attach 2 different arduino pins (1 to each relay) the other 2 relay coil wire both go to ground.
    RelaysToControlSnapSwitchAC_schem.jpg
     
    Last edited: Jan 31, 2016
    Scott Eric Catalano likes this.
  7. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Yes...the middle wire is common....will any 5V relay do or should I use the relay modules that work with the arduino? and I assume I can use any digital read out pin on the arduino to accomplish this? This is new territory for me. Thanks for the drawing as a reference and any idea where I should start with a sketch on this? Thanks in advance!
     
  8. mikegillow

    mikegillow TrainBoard Member

    116
    117
    13
    You might want to start with one of Dave Bodnar's DCC Decoder projects. This one includes a relay.
     
    Scott Eric Catalano likes this.
  9. w8one

    w8one TrainBoard Member

    89
    109
    5
    Scott Eric Catalano likes this.
  10. w8one

    w8one TrainBoard Member

    89
    109
    5
    Here is a example sketch to try now warranties either expressed or implied that it will work, but its a starting point.

    Code:
    // A example of using 8 relays to control 4 AC turnouts
    // using 4 DPST ( double pole single throw) switches named input a-d
    // give pins names direction A-D and Go A-D
    // there are probally better ways to do this.
    // this may or may not work :) w8one
    
    // initalize pins your using
    
    int DirA = 1;
    int GoA  = 2;
    int DirB = 3;
    int GoB  = 4;
    int DirC = 5;
    int GoC  = 6;
    int DirD = 7;
    int GoD  = 8;
    
    int Pulse = 500;  // how long to pulse the coil 500 is 1/2 a second
    
    //Asuming your useing switches to run turnouts
    int InputA = 9;       // Attach center wire of a double pole single throw switch to pins 9 - 12
    int InputB = 10;      // Attach one side of each switch to ground and the other side to +5v
    int InputC = 11;
    int InputD = 12;
    
    // set up the 4 current input states
    int SwitchAState = LOW;
    int SwitchBState = LOW;
    int SwitchCState = LOW;
    int SwitchDState = LOW;
    
    // set 4 input state variables to check against
    int LastAState = LOW;     // previous state of the Switch A
    int LastBState = LOW;     // previous state of the Switch B
    int LastCState = LOW;     // previous state of the Switch C
    int LastDState = LOW;     // previous state of the Switch D
    
    
    void setup() {
      // set pin mode(s) as outputs
      pinMode(DirA, OUTPUT);
      pinMode(DirB, OUTPUT);
      pinMode(DirC, OUTPUT);
      pinMode(DirD, OUTPUT);
      pinMode(GoA, OUTPUT);
      pinMode(GoB, OUTPUT);
      pinMode(GoC, OUTPUT);
      pinMode(GoD, OUTPUT);
      // set them all to low to start
      digitalWrite(DirA, LOW);
      digitalWrite(DirB, LOW);
      digitalWrite(DirC, LOW);
      digitalWrite(DirD, LOW);
      digitalWrite(GoA, LOW);
      digitalWrite(GoB, LOW);
      digitalWrite(GoC, LOW);
      digitalWrite(GoD, LOW);
      // Set Pin mode for inputs as a input
      pinMode(InputA, INPUT);
      pinMode(InputB, INPUT);
      pinMode(InputC, INPUT);
      pinMode(InputD, INPUT);
    
    } //End setup
    
    void loop() {
      // put your main code here, to run repeatedly:
      // check the inputs and set the outputs
    
      SwitchAState = digitalRead(InputA);          // read the switch input A, if it is the same as last time goto the next swich
       if (SwitchAState != LastAState) {           // if the state is not the same as last time then
        if (LastAState == LOW) TurnoutTurnA();    // if it was LOW it will now be high goto TurnoutTurnA
          LastAState = HIGH;                       // Set LastAState to HIGH
        if (LastAState == HIGH) TurnoutStraitA(); // if it was HIGH it will now be LOW
        LastAState = LOW;                          // Set LastAState to LOW
       } // end SwitchAState
    
       SwitchBState = digitalRead(InputB);          // read the switch input B, if it is the same as last time goto the next swich
       if (SwitchBState != LastBState) {           // if the state is not the same as last time then
        if (LastBState == LOW) TurnoutTurnB();    // if it was LOW it will now be high goto TurnoutTurnB
          LastBState = HIGH;                       // Set LastBState to HIGH
        if (LastBState == HIGH) TurnoutStraitB(); // if it was HIGH it will now be LOW
        LastBState = LOW;                          // Set LastBState to LOW
       } // end SwitchBState
    
       SwitchCState = digitalRead(InputC);          // read the switch input C, if it is the same as last time goto the next swich
       if (SwitchCState != LastCState) {           // if the state is not the same as last time then
        if (LastCState == LOW) TurnoutTurnC();    // if it was LOW it will now be high goto TurnoutTurnC
          LastCState = HIGH;                       // Set LastCState to HIGH
        if (LastCState == HIGH) TurnoutStraitC(); // if it was HIGH it will now be LOW
        LastCState = LOW;                          // Set LastCState to LOW
       } // end SwitchCState
    
       SwitchDState = digitalRead(InputD);          // read the switch input D, if it is the same as last time goto the next swich
       if (SwitchDState != LastDState) {           // if the state is not the same as last time then
        if (LastDState == LOW) TurnoutTurnD();    // if it was LOW it will now be high goto TurnoutTurnD
          LastDState = HIGH;                       // Set LastDState to HIGH
        if (LastDState == HIGH) TurnoutStraitD(); // if it was HIGH it will now be LOW
        LastDState = LOW;                          // Set LastDState to LOW
       } // end SwitchDState
    } // end loop
    
    // Turnout behaviors
    
    void TurnoutStraitA() { // Turnout A goes strait
      digitalWrite(DirA, LOW);
      digitalWrite(GoA, HIGH);
      delay (Pulse);
      digitalWrite(GoA, LOW);
      digitalWrite(DirA, LOW);
      }
    
    void TurnoutTurnA() { // Turnout A turns
      digitalWrite(DirA, HIGH);
      digitalWrite(GoA, HIGH);
      delay (Pulse);
      digitalWrite(GoA, LOW);
      digitalWrite(DirA, LOW);
      }
    
    void TurnoutStraitB() { // Turnout B goes strait
      digitalWrite(DirB, LOW);
      digitalWrite(GoB, HIGH);
      delay (Pulse);
      digitalWrite(GoB, LOW);
      digitalWrite(DirB, LOW);
      }
    
    void TurnoutTurnB() { // Turnout B turns
      digitalWrite(DirB, HIGH);
      digitalWrite(GoB, HIGH);
      delay (Pulse);
      digitalWrite(GoB, LOW);
      digitalWrite(DirB, LOW);
      }
    
    void TurnoutStraitC() { // Turnout C goes strait
      digitalWrite(DirC, LOW);
      digitalWrite(GoC, HIGH);
      delay (Pulse);
      digitalWrite(GoC, LOW);
      digitalWrite(DirC, LOW);
      }
    
    void TurnoutTurnC() { // Turnout C turns
      digitalWrite(DirC, HIGH);
      digitalWrite(GoC, HIGH);
      delay (Pulse);
      digitalWrite(GoC, LOW);
      digitalWrite(DirC, LOW);
      }
    
    void TurnoutStraitD() { // Turnout D goes strait
      digitalWrite(DirD, LOW);
      digitalWrite(GoD, HIGH);
      delay (Pulse);
      digitalWrite(GoD, LOW);
      digitalWrite(DirD, LOW);
      }
    
    void TurnoutTurnD() { // Turnout D turns
      digitalWrite(DirD, HIGH);
      digitalWrite(GoD, HIGH);
      delay (Pulse);
      digitalWrite(GoD, LOW);
      digitalWrite(DirD, LOW);
      }
    
     
    Scott Eric Catalano likes this.
  11. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Thanks w8one...I do plan on using switches, momentary buttons etc on a small control panel...at this point in time since I am using my GUI throttle via computer I will be using a GUI control panel to control the switches and signals. This will be a good starting point....so 5v DPDT relays is the key then?
     
  12. w8one

    w8one TrainBoard Member

    89
    109
    5
    Yes, relays have to sets of numbers the coil voltage and the contact ratings. 5v-6A@120v would mean the coil uses 5vDC to close and the contacts can handle 6A at 120 volts AC or 6A at 30 volts DC. You will find that unless you have relays laying around, it will cost more for 10 relays alone than it will for two 8 channel (relay) board for a arduino. If using over serial you can have 16 relays (8 turnouts) from 1 arduino just call analog 0 pin 14 and so on.
     
  13. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    I just ordered 2 of the 8 channel relay boards and should be here by the end of the week and I will test it out..theoretically I could hook up signal lights directly to the relays and it should change aspects automatically with out using the arduino.
     
  14. w8one

    w8one TrainBoard Member

    89
    109
    5
    If you do not reset the direction pin to the relay you could hook lights to the direction relay. To have a GUI run them you will need the arduino or something similar.
     
    Scott Eric Catalano likes this.
  15. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    My relay boards just showed up in the mail and I will see how things go later and report back
     
  16. 67vettefan

    67vettefan New Member

    4
    5
    1
    Hey all - first post!

    I monkeyed around with the following and got solenoid turnouts to work with DCC++. First, got some two 5V relay boards (one relay to toggle open and one closed) from banggood.com. I've gotten a number of parts from them and as long as you are patient (takes weeks to get stuff), they've been good for me and are very cheap (Arduino Megas for $9...). Here is part:

    http://www.banggood.com/10Pcs-2-Cha...o-AVR-Raspberry-Pi-ARM-PIC-DSP-p-1068107.html

    Hooked it up to a Mega with the common on both relays going to power from an external 12V, 1A supply (N scale turnouts from Atlas). NO is the supply line to the turnout for open and closed for each relay.

    I also modified the DCC++ code so you can switch the type of turnout you want to use from DCC to DC. Trying to keep things simple, I used the address and subAddress variables to represent the open and closed digital pins on the Mega that are controlling the relays. I've uploaded the files that I modified (Accessories.cpp and Config.h) if anyone wants to tinker with them. This should in theory work with JMRI, which I'm going to try as soon as I can get past a bug there that keeps it from sending commands to setup turnouts.

    I also considered using servo motors for under table control, but already had a lot of money invested in the solenoid switches. I would think if someone wanted to do this, they could do something similar using the address as the pin for the servo motor control and the subAddress as the angle for open, normalizing close at 0 degrees. While the modified sketch initializes the pins from memory, it currently doesn't set the turnout to where it should be on startup - I'm working on that next...but should be simple code change. (okay, got that done, new files should initialize turnout to memory position).
     

    Attached Files:

    Last edited: Sep 3, 2016
    Scott Eric Catalano likes this.
  17. Texas Tim

    Texas Tim TrainBoard Member

    53
    52
    9
    Can this be used to control the Kato Turnouts? particularly the Double Cross over? Thanks!
     
    Scott Eric Catalano likes this.

Share This Page