Test Track – OO – N – O – HO
Arduino Code – Analogue to Digital switching

Wire as above
// GMRC Test Track Control System 2022 - Version 1.0
// Written on Arduino UNO - can be used on all pin based Arduino's
// Written by Giles W - GMRC 05/2022
// Improved by Albert M - GMRC 06/2022
/* ***** WIRING NOTES *****
RELAY 1
- Connect CAB A(+) to relay 1 normally closed
- Connect relay 1 center to track A(+)
- Connect DCC(+) to relay 1 normally open from relay 5 center out
RELAY 2
- Connect CAB A(-) to relay 2 normally closed
- Connect relay 1 center to track A(-)
- Connect DCC(-) to relay 1 normally open from relay 6 center out
RELAY 3
- Connect CAB B(+) to relay 3 normally closed
- Connect relay 1 center to track B(+)
- Connect DCC(+) to relay 3 normally open from relay 5 center out
RELAY 4
- Connect CAB B(-) to relay 4 normally closed
- Connect relay 1 center to track B(-)
- Connect DCC(-) to relay 4 normally open from relay 6 center out
RELAY 5
- DO NOT Connect normally closed
- Connect relay 5 center to DCC(+) on relay 1 and relay 3 normally open
- Connect relay 5 normally open to DCC controller(+) output
RELAY 6
- DO NOT Connect normally closed
- Connect relay 6 center to DCC(-) on relay 2 and relay 4 normally open
- Connect relay 6 normally closed TO DCC controller(-) output
RELAY 7
- Connect (+) DC LED to relay 7 normally closed
- Connect (+) from Arduino 5V
- Connect (+) DCC LED to relay 7 normally open
RELAY 8
- Connect (-) DC LED to relay 8 normally closed
- Connect (-) from Arduino GND
- Connect (-) DCC LED to relay 8 normally open
*/
// ***** Define constants and variables *****
const int interval = 100; // Set for pause period in microseconds (1000 = 1 SECOND)
// Store switch position
byte switchStateOld = HIGH; // Stored from last time the switch was changed.
byte switchStateNew; // Latest reading
// User interface pins
const byte pinSwitch = 3; // Attach the toggle switch to pin 3 and ground(GND)
const byte pinLed = 13; // Attach the onboard LED to pin 13, not for LED output just for testing
// Relay control pins - See ***** WIRING NOTES ***** above
const byte pinR1 = 4; // Relay 1
const byte pinR2 = 5; // Relay 2
const byte pinR3 = 6; // Relay 3
const byte pinR4 = 7; // Relay 4
const byte pinR5 = 8; // Relay 5
const byte pinR6 = 9; // Relay 6
const byte pinR7 = 10; // Relay 7
const byte pinR8 = 11; // Relay 8
void setup()
{
// ***** put your Setup code here, to run once: *****
// pins setup
pinMode(pinSwitch, INPUT_PULLUP);// Set pin as INPUT_PULLUP to high
pinMode(pinR1, OUTPUT); // Set pin as output
pinMode(pinR2, OUTPUT); // Set pin as output
pinMode(pinR3, OUTPUT); // Set pin as output
pinMode(pinR4, OUTPUT); // Set pin as output
pinMode(pinR5, OUTPUT); // Set pin as output
pinMode(pinR6, OUTPUT); // Set pin as output
pinMode(pinR7, OUTPUT); // Set pin as output
pinMode(pinR8, OUTPUT); // Set pin as output
// Relays set to OFF on first start
digitalWrite(pinR1, HIGH); // Set pin to off state
digitalWrite(pinR2, HIGH); // Set pin to off state
digitalWrite(pinR3, HIGH); // Set pin to off state
digitalWrite(pinR4, HIGH); // Set pin to off state
digitalWrite(pinR5, HIGH); // Set pin to off state
digitalWrite(pinR6, HIGH); // Set pin to off state
digitalWrite(pinR7, HIGH); // Set pin to off state
digitalWrite(pinR8, HIGH); // Set pin to off state
// test LED setup
pinMode(pinLed, OUTPUT); // Set pin as output
digitalWrite(pinLed, LOW); // Set pin to off state
}
void loop()
{
// ***** put your main code here, to run repeatedly: *****
// Monitor controller switch - NB defaults to CAB on when no power.
switchStateNew = digitalRead(pinSwitch); // Read the switch and put its value into switchStateNew
if (switchStateNew != switchStateOld) // Switch has changed if switchStateNew is different from switchStateOld
{
if (switchStateNew == LOW) // Activate DCC - NB toggle switch is pulled down to ground(GND)
{
dccOn(); // CAB off - DCC on - DCC LED on
}
else // Activate CAB - NB toggle switch is internally pulled to 5V or power is off
{
cabOn(); // DCC OFF - CAB on - CAB LED on
}
}
}
// ***** Procedures called from Loop() *****
void relayOn(byte pinNumber) // Turns on the relay referenced by the pin number
{
digitalWrite(pinNumber, LOW); // Set relay state to ON
}
void relayOff(byte pinNumber) // Turns off the relay referenced by the pin number
{
digitalWrite(pinNumber, HIGH); // Set relay state to OFF
}
void cabOn() // DCC off - CAB on - CAB LED on
{
static unsigned long int waitEnd; // Holds the time in millis at the end of the wait
if (waitEnd == 0) // It's the first loop thru this process since the switch changed
{
relayOff(pinR5); // turn off DCC
relayOff(pinR6);
waitEnd = millis() + interval; // Set the wait end time
}
else if (waitEnd < millis()) // Wait for interval until millis goes past the wait end value
{
relayOff(pinR1); // Turn on DC CABs
relayOff(pinR2); // Turn on DC CABs
relayOff(pinR3); // Turn on DC CABs
relayOff(pinR4); // Turn on DC CABs
relayOff(pinR7); // CAB indicator on, DCC indicator off
relayOff(pinR8); // CAB indicator on, DCC indicator off
digitalWrite(pinLed, LOW); // Set arduino LED
waitEnd = 0; // waitEnd reset to 0
switchStateOld = switchStateNew; // switchState Old is changed to match switchStateNew
}
}
void dccOn() // CAB off - DCC on - DCC LED on
{
static unsigned long int waitEnd; // the time (in millis) when the wait interval expires
if (waitEnd == 0) // It's the first loop thru this process since the switch changed
{
relayOn(pinR1); // Turn off DC CABs
relayOn(pinR2); // Turn off DC CABs
relayOn(pinR3); // Turn off DC CABs
relayOn(pinR4); // Turn off DC CABs
waitEnd = millis() + interval; // Set the wait end time
}
else if (waitEnd < millis()) // Wait for interval until millis goes past the wait end value
{
relayOn(pinR5); // Turn on DCC
relayOn(pinR6); // Turn on DCC
relayOn(pinR7); // CAB indicator off, DCC indicator on
relayOn(pinR8); // CAB indicator off, DCC indicator on
digitalWrite(pinLed, HIGH); // Set arduino LED
waitEnd = 0; // waitEnd reset to 0
switchStateOld = switchStateNew; // switchState Old is changed to match switchStateNew
}
}
