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
        }
    }

Test Track Blog Posts