Introduction: Arduino - Points/turnout/accessory Control V2

Updated 19 Oct 2021: new PCB v3 (Jun 2021) available with added memory push button to set the first turnout address.

PCB v3 version Jun 2021 also has a push button to store the accessory address. To use this on the finished assembly, hold this button while you select the required address from your DCC controller.


Updated 20 Jan 2021: On v2 version of the PCB (Oct 2019) Arduino Nano pin A6 may not work as designed (analog pin used to switch 5v)

I now provide the PCB for this project with a modification to make pin A5 feed the LED and to switch 5v to the h-bridge ICs.

[If you already have a V2 version (Oct 2019), please Modify the PCB as above]


Updated 13 Nov 2019: Added a new sketch to control 8 servos, 6 LED's and 2 flashing LED's

Updated 30 Oct 2019: I have added a new step for a servo points controller.


I now have a new PCB designed for this application - available from eBay from 19 Sep 2019.

PCB is identified as 'DCC turnouts / points Oct 2019' on the top surface of the PCB.

An Arduino Nano module provides 8 turnouts each configurable for momentary surface (or under base) mount or tortoise slow motion motor types, or for on/off switches (signals, station lighting, sounds etc)

Step 1: Arduino Sketches:

NB: In the Arduino Nano sketch, the NmraDCC library files must be version NmraDcc-1.2.1.zip - later versions will not work. Download here nmrdcc

Attached sketches for:

T1-T6 twin coil turnouts plus T7 T8 as switches
T1 - T8 twin coil turnouts
T9 - T16 twin coil turnouts


From an excellent tutorial by Geoff Bunza in the Model Railroad Hobbyist Magazine forum. It described how an Arduino Pro Mini (a low cost Arduino board) could be wired and programmed to respond to function keys on a DCC controller. This opens up a wide world of control options for animations, sound and other options on a DCC equipped model railroad.

I have made use of this circuit to capture DCC packets from my Arduino based Command Station (see DCC Command Station). The Command station may control up to 16 turnouts.

Basic Accessory decoder packet is : 0 10AAAAAA 0 1AAACDDD 0 EEEEEEEE 1

From analysing the packet used by Lenz (Compact / Atlas) for points control, I have used the following binary packet format for bytes 1 and 2 :
tunAddr = 1 //Accessory decoder address
Turnout 1a : 1000 0001 1111 1000
Turnout 1b : 1000 0001 1111 1001
Turnout 2a : 1000 0001 1111 1010
Turnout 2b : 1000 0001 1111 1011
Turnout 3a : 1000 0001 1111 1100
Turnout 3b : 1000 0001 1111 1101
Turnout 4a : 1000 0001 1111 1110
Turnout 4b : 1000 0001 1111 1111

tunAddr = 2
Turnout 5a : 1000 0010 1111 1000
Turnout 5b : 1000 0010 1111 1001
Turnout 6a : 1000 0010 1111 1010
Turnout 6b : 1000 0010 1111 1011
Turnout 7a : 1000 0010 1111 1100
Turnout 7b : 1000 0010 1111 1101
Turnout 8a : 1000 0010 1111 1110
Turnout 8b : 1000 0010 1111 1111

tunAddr = 3
Turnout 9a : 1000 0011 1111 1000
Turnout 9b : 1000 0011 1111 1001

etc

By manipulation of the binary packet, we can extract the turnouts required and send a pulse (t_on) of variable duration.

if (tunAddr == 1){
if ((((Msg->Data[1]) - 0xf8>>1) + 1) == 1 && (Msg->Data[1] & 0x01) == 1){ // f1a on
// pin 3
digitalWrite(FunctionPin1a, 1);
pulse = true;
t_on = 50; }

if ((((Msg->Data[1]) - 0xf8>>1) + 1) == 1 && (Msg->Data[1] & 0x01) == 0){ // f1b on
// pin 4
digitalWrite(FunctionPin1b, 1);
pulse = true;
t_on = 50; }

Step 2: Turnout Control - PCB and Components

Bill of Materials:

All components including PCB are available from eBay.

NB: Please use a on/off switch to supply power to the board. Plug in power supply first before switching on. This helps to protect sensitive points/turnouts e.g. side mounting with coils that are prone to burn out if an applied current is extended beyond normal pulse times.

1 off v2 PCB (no longer available on eBay)

Or, 1 off v3 PCB eBay item number 234244550455 (with memory function)

6 off Ceramic Capacitor; capacitance 100 nF; package 200 mil

1 off Capacitor Polarized variant pth1; package cpol-radial-100uf-25v

2 off Screw terminal - 2 pins pins 2; hole size 1.0mm,0.508mm; pin spacing 0.197in (5.0mm);

1 off 1kΩ Resistor bands 5; tolerance ±5%; pin spacing 400 mil;

1 off 1.5kΩ Resistor bands 5; tolerance ±5%; pin spacing 400 mil;

1 off 10kΩ Resistor bands 5; tolerance ±5%; pin spacing 400 mil;

2 off 4.7kΩ Resistor bands 5; tolerance ±5%; pin spacing 400 mil;

1 off Diode variant 1n4148;

8 off Screw terminal - 3 pins pins 3; hole size 1.0mm,0.508mm; pin spacing 0.137in (3.5mm);

1 off 5v reg Voltage Switching Regulator RECOM 5v 500mA;

1 off 0.1Ω 2W Metal Film Resistor; tolerance ±5%; pin spacing 11.5 mm;

1 off 6N137 IC chip label IC; pins 8; hole size 1.0mm,0.508mm; true; pin spacing 300mil; package DIP

2 off Generic female header - 15 pins; hole size 1.0mm,0.508mm; pin spacing 0.1in (2.54mm);; row single

17 off Diode variant pth; package diode-1n4001

4 off H-Bridge SN754410

1 off 3mm LED (any colour)

1 off Arduino Nano module (5v)

On v3 version of PCB Jan 2021, there is are 2 additional components:

1 off momentary TACT PCB Mount Switch Push Button 6x6x5mm

1 off 4.7kΩ Resistor

NB: For the memory function on this version V3 of the PCB (Jan 2021) , use Arduino sketch 'DCC_turnout_control_v2_t1_t8_momentary_jan_2021_memory.ino'

Step 3: Current Limit Control

Current sense circuit detects >2 amps. This triggers all outputs to off state and disables the sketch.
The LED will switch off.
You must clear the fault and reset the Arduino Nano before resuming points operations.

void current()
delay(2);
amp = 10.8 * analogRead(currentSense);
if (amp > 150){
Serial.print("current (mA) = ");
Serial.println(amp); //milli amps }

if (amp > 2000){ // approx 2 amps
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 1.1V) = 1.08mv per division
// 0.1 ohm resistor on current sense gives 200mv at 2 Amps or, 100mv per Amp
// 1.08 mv per div for Internal Ref of 1.1v : 100/1.08 = 92.6 divisions per 1000mA or 1 div = 10.8mA
// current = 10.8 * currentSense ; // mA

digitalWrite(enable, LOW); // disable the h-bridge IC's
digitalWrite(led, LOW); // turn LED off
Serial.println("Over current - Power off");
Serial.println(amp); //Amps
shut_down(); } //close all outputs
}

Step 4: Accessory Control

The Arduino sketch may be modified to include on/off switching or timed switching for control of lights, signals, etc. The SN544110 h-bridge can supply at least 250mA per output.
For configuration of on/off switches, remove the pulse logic and t_on :

if ((((Msg->Data[1]) - 0xf8>>1) + 1) == 4 && (Msg->Data[1] & 0x01) == 1){
// f8a on ; f8b off
// pin A3
digitalWrite(FunctionPin8a, 1);
digitalWrite(FunctionPin8b, 0); }
if ((((Msg->Data[1]) - 0xf8>>1) + 1) == 4 && (Msg->Data[1] & 0x01) == 0){
// f8b on ; f8a off
// pin A4
digitalWrite(FunctionPin8b, 1);
digitalWrite(FunctionPin8a, 0); }


The signal common wire is connected to the middle pin of connector f8a / f8b.
Remember, turnout / point motors are designed to activate on momentary applied voltage for around 25 milli-seconds.
Always be careful NOT to connect a turnout / point motor to this on / off pin as it will over heat and probably burn out.

Step 5: Tortoise Points/turnouts

The Arduino sketch may be modified to operate Tortoise slow motion motorised points.

The DC power connections are made to f1a and f1b (or any other output required)
The common middle pin connection is not required.
Alter the code for the output pin required to be on or off, for example for f1a (pin3) and f1b (pin 4):

if ((((Msg->Data[1]) - 0xf8>>1) + 1) == 1 && (Msg->Data[1] & 0x01) == 1){
digitalWrite(FunctionPin1a, 1); // motor on
digitalWrite(FunctionPin1b, 0); }

if ((((Msg->Data[1]) - 0xf8>>1) + 1) == 1 && (Msg->Data[1] & 0x01) == 0){
digitalWrite(FunctionPin1a, 0);
digitalWrite(FunctionPin1b, 1); // motor on (reversed)
}

If the stall current is <100 mA, there is no need to switch the motor off.

Step 6: Servo Points

I have attached a sketch for 8 servo points control, 6 LED's and 2 flashing LED's.
You will need to edit the variables etc to suit your application - e.g. angle of rotation and speed of operation

In the setup void of the sketch:

min_pos[3] = 35; max_pos[3] = 82; //D3 servo 1
min_pos[4] = 56; max_pos[4] = 90; // D4 servo 2
min_pos[5] = 35; max_pos[5] = 82; // D5 servo 3
min_pos[6] = 36; max_pos[6] = 100; // D6 servo 4
min_pos[7] = 55; max_pos[7] = 135; // D7 servo 5
min_pos[8] = 40; max_pos[8] = 110; // D8 servo 6
min_pos[9] = 55; max_pos[9] = 88; // D9 servo 7
min_pos[10] = 30; max_pos[10] = 84; // D10 servo 8

This sketch requires a simpler circuit with no need for h-bridge IC's - see diagram above.

The 5 volt regulator may need to be upgraded to a 1 amp version to handle the total servo current.