Arduino - Points/turnout/accessory Control V2




Introduction: Arduino - Points/turnout/accessory Control V2

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 Sketch (for T1 - T8 and T9 - T16)

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


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 PCB eBay item number 233264617488

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)

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()
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.

Be the First to Share


    • Make it Glow Contest

      Make it Glow Contest
    • First Time Author Contest

      First Time Author Contest
    • PCB Challenge

      PCB Challenge

    19 Discussions


    Question 18 days ago on Introduction

    Good Morning:
    first of all congratulate him for the excellent work done.
    My question is: How can I connect a second arduino with address 17?
    I understand that you are using the first 16 addresses, but I need to connect a second arduino to control another 10 more turnouts and I don't know how to do it.
    I would appreciate a little help.
    Thanks a lot.


    Answer 17 days ago

    Buenos días Bill:
    Con la última modificación todo está funcionando bien.
    Es el decodificador mas rápido que he encontrado en Internet y he probado unos pocos.
    Muchas gracias por su atención y su tiempo.
    Muy feliz año nuevo


    Answer 18 days ago

    Thanks for your interest in my project.
    To control address 17 onwards change lines in the code:
    addr1 = 1; // gives decoder address of 1 to 4
    addr2 = 2; // gives decoder address of 5 to 8
    addr3 = 3; // gives decoder address of 9 to 12
    addr4 = 4; // gives decoder address of 13 to 16
    addr5 = 1; // gives decoder address of 17 to 20
    addr6 = 2; // gives decoder address of 21 to 24
    addr7 = 3; // gives decoder address of 25 to 28
    addr8 = 4; // gives decoder address of 29 to 32

    if( (Msg->Data[0] == 0x81) || (Msg->Data[0] == 0x82) || (Msg->Data[0] == 0x83) ||(Msg->Data[0] == 0x84)){ //for Addr1 = 1, Addr2 = 2, Addr3 = 3, Addr4 = 4
    if( (Msg->Data[0] == 0x85) || (Msg->Data[0] == 0x86) || (Msg->Data[0] == 0x87) ||(Msg->Data[0] == 0x88)){ //for Addr5 = 5, Addr6 = 6, Addr7 = 7, Addr8 = 8

    Then amend each segment of code :
    if (MainAddr == addr1){ // T1 to T4
    if (MainAddr == addr5){ // T17 to T20
    if (MainAddr == addr2){ // T5 to T8
    if (MainAddr == addr6){ // T21 to T24
    if (MainAddr == addr7){ // T25 to T28
    if (MainAddr == addr8){ // T29 to T32

    Otherwise, the rest of the code remains the same.



    Reply 17 days ago

    Hi Rafael,

    Sorry I also had a senior moment in giving you the wrong instructions !
    Please change this part of the code:

    addr5 = 1; // gives decoder address of 17 to 20
    addr6 = 2; // gives decoder address of 21 to 24
    addr7 = 3; // gives decoder address of 25 to 28
    addr8 = 4; // gives decoder address of 29 to 32
    addr5 = 5; // gives decoder address of 17 to 20
    addr6 = 6; // gives decoder address of 21 to 24
    addr7 = 7; // gives decoder address of 25 to 28
    addr8 = 8; // gives decoder address of 29 to 32



    Answer 18 days ago

    Good night Bill:
    Thank you very much for your quick response, but unfortunately my servos are not working.
    apart from changing the lines of code that you told me, I have taken the liberty of also changing the following line to
    int addr5; int addr6; int addr7; int addr8; because there were errors when compiling, (addr5 not declared in this scope) etc.
    With the serial monitor, when giving a status change order to servo 17, I can see the following:
    Main Addr = 5
    DccMsg 3 133 249 124
    turnout = 17
    tun = 1 (this value changes to 0 when I press again)
    Sorry to bother you, but at my age (68 years old), I've been a bit late to this technology and I hope I don't make it too difficult for you.
    Many thanks.


    7 months ago

    Bi Bill,
    I see you've used part of my NmraDcc library (I'm the original author) in your project, but you seem to have reinvented much of the wheel in decoding the DCC packets yourself, rather than letting the library do it for you.
    I'd be interested in adding an example DCC Accessory Decoder sketch that supports your hardware, however the schematic you've posted is _very_ blurry and difficult to read, making software development rather difficult.
    Can you post a clearer version please?
    Perhaps print it to PDF of something that is scaleable as opposed to the screen shot or image dump that you appear to have done?
    Alex Shepherd


    Reply 7 months ago

    Hi Alex, yes I did start with your great idea on this, thanks for all your efforts.
    I decided to keep options open to users to allow for variations in use of the circuit. For example in my own loft railway, I use 6 turnouts using solenoids plus 2 on/off switches for lights and station announcement (switches on an Arduino based sound circuit).
    I did not want to turn the circuit into a decoder and preferred to keep options within the Arduino code.

    As you know, other users require different pulse widths, use of tortoise and servos, etc. The servo example by passes the h-bridge IC's.

    Please find attached circuit diagram - hopefully fully readable and printable.
    Thanks for your interest and if you want a PCB let me know - I have only 1 left.
    I plan to get more manufactured later this month.

    Take care and stay safe.



    Reply 7 months ago

    Hi Bill,
    This image isn't much better than the original. I expect the Instructables platform is resizing it, so perhaps can you email the original to me on: please.


    Question 10 months ago on Step 2

    Thanks for all your information, Bill, but I checked on ebay and found no results for 233264617488 or 233461778549. Do you have a new item number to search? Thanks for all your efforts... very much appreciated. Ed in Ohio


    Answer 10 months ago

    Hi Ed in Ohio
    I have run out of PCB's for the moment (been popular) and should have 10 more to sell on eBay within a few days. I will let you know when they are available.
    Bill from Falkland in Scotland.


    Question 1 year ago on Step 6

    Good day Bill, I ordered 2 of your original boards a few months ago and I am beginning to work on them. I see that you have a version 2 out now and was wondering, should I re-order this later version or continue with the ones I have? My final goal is to operate solenoid type turnouts and maybe a few lights/relay controls. I am good with the boards I have unless you suggest I upgrade to version 2. Thanks for your work I'm very excited about making this an addition to my layout. Also, one quick question, when you list items needed your list first the number needed followed by the word "off". I'm sure this is just a, you live in a different place than me but, could you offer some insight.
    Thanks again for all your work, I'm enjoying your efforts. Bill from Oklahoma.


    Answer 1 year ago

    Hi Bill, The v2 has improved protection of the h-bridge when outputs are shorted or overloaded. Also, all of my sketches now relate to the new design. If you have not assembled the boards you have, I would recommend you re-order the new ones.
    I am waiting a delivery of these and should be on eBay by the end of this week.
    If you decide to order 1, I shall give the second one free.
    The boards you have already (v1) may be safely used for driving relays and LED lights.
    where the risk of over load or shorts is lower
    The use of 'off' is just the same as 'x' i.e. 2 off resistors = 2 x resistors
    Thanks for your support.
    Bill from Falkland, Scotland


    Reply 1 year ago

    Thank you for you quick response. I will be ordering 2 of the V2 boards, since there is LED lights in my future the boards I have will not be lost, please allow me to pay for both boards, Your offer is very kind but, I wish to continue to support your efforts. This will also give me a chance to order some parts I will need to complete to assembly of both V1 and V2 boards.
    Again, thank you for your great work.


    Reply 1 year ago

    Hi, Bill
    I now have another 10 PCB's for sale on eBay (for V2 of DCC Digital Model rail 8 o/p for points, turnout, accessories)


    Reply 1 year ago

    Hi, could you include an item number. I made several searches using your name, item name several ways and even the old item number with no luck. Thanks for the note and put me down for 2 boards and I will paypal you the funds soon as I know and amount. Also, are you stocking any of the componets for the boards, I'm having a little problem finding some of the caps. Thanks again, Bill.


    Reply 1 year ago

    Hi Bill
    item num is 233461778549 on eBay


    Reply 10 months ago

    Thank you Bill, I did receive two updated boards and have built one, finally. Now, I am ready for testing and installing on my layout. Currently I am using a Digi Traxx controller to run trains and will soon be changing to DCCpp. I have read all I can find on interfacing with my DCC to send commands to the arduino V2 with no success. Do you have any prepared documents that cover this part of the process? I will be more than happy to research the internet I just need some help with where to start my search. I have read Geoff's information which brings me to a question, do I need to assign and ID to the Arduino Nano and if so where in the code do I do that. And, can commands be sent to the Nano from the monitor screen in Arduino IDE?
    Thank you very much for your time and patients, I'm very willing to learn I just think I need a place to start.
    Thank you and have a great day.