Adding Servo-Controlled Turnouts to Your Model Railway with DCC-EX and EXRAIL

Adding Servo-Controlled Turnouts to Your Model Railway with DCC-EX and EXRAIL

Introduction

You can add reliable, low-cost servo turnout control to a running DCC-EX system using a PCA9685 (I²C) 16-channel servo driver and EXRAIL. This guide covers wiring, HAL setup, turnout definition, and calibration.


Hardware You Need

  • PCA9685 16-channel I²C servo board
  • Servos (one per turnout)
  • Regulated 5 V power supply for servos (separate from CommandStation)
  • I²C connection to your CommandStation (Qwiic on CSB1/EX8874 or SDA/SCL pins)
  • Cables and common ground (CS GND ↔ PCA9685 GND ↔ 5 V PSU GND)

⚠️ Power warning: Do not power servos from the CommandStation. Use a separate 5 V supply to the PCA9685’s servo power input and share ground with the CommandStation.


Wiring & Bring-Up

  1. Connect PCA9685 SDA→SDA, SCL→SCL, VCC (logic 3.3/5 V) and GND to the CommandStation.
  2. Feed the servos from the separate 5 V supply connected to the PCA9685’s servo power rail; share GND with the CommandStation.
  3. Power up and watch the serial log; it will list detected I²C devices and the PCA9685’s I²C address (commonly 0x40, but verify).
      Note: If you see
    < No I2C Devices found >
    check the SDA/SCL wiring and ensure correct orientation.

HAL Configuration (PCA9685)

Declare the PCA9685 in myAutomation.h using the HAL(...) macro.

// start vPin, count, I2C address
HAL(PCA9685, 100, 16, 0x40)

vPin → Channel Map

  • vPin 100 → PCA9685 ch 0
  • vPin 101 → ch 1
  • vPin 115 → ch 15

Adding another PCA9685? Give it a new address (e.g., 0x41) and a new vPin block:

HAL(PCA9685, 116, 16, 0x41)  // vPins 116–131

Defining Servo Turnouts in myAutomation.h

After registering the PCA9685, define each servo turnout using SERVO_TURNOUT.

Syntax

SERVO_TURNOUT(id, vPin, active_angle, inactive_angle, profile, description)

Parameters

  • id → Turnout ID number (referenced in throttles/automation)
  • vPin → Virtual pin assigned to servo (from PCA9685 block)
  • active_angle → Servo position for "thrown"
  • inactive_angle → Servo position for "closed"
  • profile → Motion profile (e.g., "Fast", "Slow")
  • description → Label for turnout

Example

// First servo (channel 0, vPin 100)
SERVO_TURNOUT(1, 100, 250, 250, "Fast", "Turnout 1")

// Second servo (channel 1, vPin 101)
SERVO_TURNOUT(2, 101, 250, 250, "Fast", "Turnout 2")

Both active and inactive angles are initially set to the same value (250) so the servo has a safe starting point. You can later fine-tune these.

Important: After adding or editing HAL(...) or SERVO_TURNOUT() entries, you must recompile and upload the sketch to the CommandStation. This ensures the PCA9685 is properly detected and initialised at startup.


Calibrating Servo Angles

  1. Start with both angles equal (e.g., 250, 250).
  2. Use the EX-Toolbox Android application to make incremental adjustments to the servo position. This allows you to carefully move the servo until the turnout aligns correctly without stressing the mechanism.
  3. Once you have found the correct active and inactive angles with EX-Toolbox, update your SERVO_TURNOUT() command in myAutomation.h with these values.
  4. After updating the SERVO_TURNOUT() command with your new angles, you must recompile and upload the sketch again to the CommandStation before testing.
  5. Test turnout via throttle or EXRAIL commands:
    • Closed → <T 1 C>
    • Thrown → <T 1 T>
  6. Repeat for each turnout until all are calibrated.

Note: Many throttles and consoles require angle brackets < > around the turnout commands. Do not omit them.

Example After Tuning

SERVO_TURNOUT(1, 100, 120, 400, "Fast", "Turnout 1")

Example Block: Four Servos (vPins 100–103)

// PCA9685 mapped at vPins 100–115
HAL(PCA9685, 100, 16, 0x40)

// Define four turnouts
SERVO_TURNOUT(1, 100, 250, 250, "Fast", "Turnout 1")
SERVO_TURNOUT(2, 101, 250, 250, "Fast", "Turnout 2")
SERVO_TURNOUT(3, 102, 250, 250, "Fast", "Turnout 3")
SERVO_TURNOUT(4, 103, 250, 250, "Fast", "Turnout 4")

Using EngineDriver or Other Throttle Apps

When using EngineDriver (an Android application) to control turnouts:

  1. See EngineDriver First Connection to DCC for how to connect EngineDriver to your DCC-EX system.
  2. Once connected, EngineDriver will briefly display "Points Loaded".
  3. Click the three dots in the top-right corner and select Turnouts/Points.
  4. You will see the turnouts you have configured.
  5. Tap Throw to throw the turnout or Close to close it.

It really is that simple — once set up, your turnouts can be operated directly from the Android throttle app.


Troubleshooting

Problem Cause Solution
PCA9685 not detected Wrong wiring/I²C addr Check SDA/SCL wiring, verify address in log
Servo not moving Power issue Confirm 5 V supply + common ground
Chatter/jitter Over-travel / weak PSU Adjust angles, use stable 5 V supply
Wrong channel moves Wrong vPin mapping Recheck vPin ↔ channel mapping

✅ With HAL configured, turnouts defined, and servos calibrated (using EX-Toolbox for precise adjustments), your DCC-EX system now supports servo-controlled turnouts through EXRAIL!

Back to blog