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
From the Bachmann web site it seems there are DCC enabled turnouts as well as traditional AC-powered turnouts. Which do you have?
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.
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++.
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
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.
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!
You can get the 8 relay boards for $5us or so like this one. http://www.ebay.com/itm/351561705400?_trksid=p2060353.m1438.l2649&ssPageName=STRK:MEBIDX:IT 8 relays would control 4 switches. As long at the coil on the relay is 5v a Arduino will be able to control it.
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); }
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?
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.
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.
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.
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).