This is only a preview of the October 2018 issue of Silicon Chip. You can view 40 of the 112 pages in the full issue, including the advertisments. For full access, purchase the issue for $10.00 or subscribe for access to the latest issues. Items relevant to "GPS-synched Frequency Reference Pt.1":
Items relevant to "Arduino-based programmer for DCC Decoders":
Items relevant to "Low-voltage, high-current DC Motor Speed Controller":
Items relevant to "Opto-Isolated Mains Relay":
Items relevant to "Intro to programming: Cypress' System on a Chip (SoC)":
Purchase a printed copy of this issue for $10.00. |
Here’s one for all the model railway enthusiasts . . .
DIGITAL
D
IGITAL
COMMAND
C
OMMAND
CONTROL
C
ONTROL
PROGRAMMER
for DECODERS
DCC – Digital Command Control – is a widely-used method for
controlling model railways, especially when running multiple locos/
trains on the same track(s). This DCC programmer is simple, cheap and
easy to build – and operates from a computer’s USB port.
by Tim Blythman
DCC
is a great innovation,
allowing many model
locomotives to be addressed and operated independently
on the same track at the same time
It has been embraced as a standard
by the NMRA (National Model Railroad Association, based in the USA),
so equipment from different manufacturers can inter-operate without issue.
And since the standards are public,
anybody can create DCC-compatible
devices.
But the big downside to DCC (especially for beginners) is the cost of a
base station. Even the cheapest base
stations cost several hundred dollars
and each locomotive also needs a decoder. Usually, even the simplest base
38
Silicon Chip
stations include the option to program
decoders but this can be a bit fiddly to
use and can interfere with the operation of other trains on the “main line”.
In this article, we describe how to
build a standalone programmer based
using an Arduino microcontroller
module with a custom shield.
It connects to a computer USB port
to provide a convenient interface for
programming. It allows you to read
and write the Configuration Variables
(CVs) on DCC rolling stock, customising their operation and performance.
We have also designed the shield to
be compatible with the DCC++ Arduino software. DCC++ is an open-source
hardware and software system for the
operation of DCC-equipped model
Australia’s electronics magazine
railroads; see https://github.com/DccPlusPlus/
When programmed with the DCC++
software, the programmer can be used
with the Java Model Railroad Interface
(JMRI), which provides a way to control DCC-based model trains from a
computer. Its most relevant functions
for this project are the ability to load
and save locomotive (decoder) configurations.
There is also another graphical user
interface (GUI) which is compatible
with DCC++, written in the “Processing” language. See the DCC++ web
page for details.
As well as being able to use the
DCC++ software, we have written a
small Arduino program which allows
siliconchip.com.au
CVs to be read and written via commands on the Arduino Serial Monitor.
You don’t need JMRI or DCC++ to use
it in this mode.
By the way, we have previously published two other DCC system related
designs: a 10A DCC Booster in the July
2012 issue (siliconchip.com.au/Article/614) and a Reverse Loop Controller
in the October 2012 issue (siliconchip.
com.au/Article/494).
DCC hardware interface
A typical DCC system requires 1215V to operate (see the panel below
for an explanation of how DCC works).
You can power the Arduino from a
voltage in this range but it isn’t necessary; we’re using a small boost regulator module so that you can also run
it off a 5V USB supply. In this case,
the boost regulator provides the 1215V DC to power the tracks and DCC
decoder(s).
The DCC signal is a square wave at
several kilohertz and the locomotive/
decoder could draw a few hundred
milliamps, so our programmer needs
to be capable of rapidly switching the
track voltage and supplying sufficient
current. Luckily, this can be achieved
using a low-cost, bog-standard 556
dual timer IC. This IC is basically two
555 timers glued together in a 14-pin
package.
The outputs on the 556 can deliver
up to 200mA at 500kHz, so it is perfectly suitable for this project.
The Arduino module generates the
DCC signals with the correct timing,
which the 556 converts into the correct voltage levels. We’re also using a
current sense (shunt) resistor so that
the Arduino can detect how much
current the attached locomotive is
drawing.
The DCC decoder can send data back
to the programmer by varying its current draw. It sends a response by briefly
drawing at least 60mA from the tracks.
This is important as it is the only way
to read data back from the decoder.
Circuit description
Fig.1 shows the circuit of the DCC
Programmer. It’s based around dual
Why DCC?
If you’re running more than one loco/
train on a layout, the only logical way to do
it is with DCC, which gives control to each
one without affecting any other(s). And
because the power and control signals
are separate, the locos are still powered
even when not moving, so their lights and
any sound effects can still be operated.
The downsides of DCC are mostly to do
with cost and there is the added complexity of adding decoders to your locomotive.
DCC allows manual control over each
train, just as you normally have with a
normal controller – but DCC has the big
advantage of being able to take its operating commands from a computer, allowing completely automated model layouts,
if you wish.
This is especially useful in larger layouts; DCC also allows automatic point
switching, level crossing boom gates and
so on, obviously with suitable motors.
The JMRI software mentioned in the
text allows control over all these functions.
Fig.1: besides the Arduino
itself, the other components
are mounted on a plug-in
shield. It’s based around
dual timer IC1, which acts
as two power inverters with
some built-in logic circuitry,
forming a basic low-power
full-bridge driver under the
control of the Arduino. DC/
DC boost converter MOD1
provides the ~13V DC
supply for IC1 when
the Arduino is running
from a 5V USB supply.
siliconchip.com.au
Australia’s electronics magazine
October 2018 39
556 timer IC1 and boost converter
MOD1.
Pins 4 and 10 of IC1 are the reset inputs of the two timers and the timer
outputs are disabled if these pins are
low. They are held low initially by the
1kΩ resistor from pin 10 to ground,
so output pins 5 and 9 are low. These
pins connect to either side of the track,
either via CON6 (a header socket) or
CON7 (terminal block), depending on
which suits you best.
So when both timers are in reset and
both outputs are low, there is no voltage across the track. The enable signal
from the Arduino is fed to CON3 so
when this goes high, the reset input
at pin 10 is pulled high via the 100Ω
series resistor.
Schottky diode D1 is then reversebiased, so the other reset input at pin 4
can also be driven high by the Arduino,
via CON2 and its 10kΩ series resistor.
The trigger input of the first timer
(pin 6) is pulled to ground while the
threshold input of that same timer (pin
2) is tied to VCC (pin 14), so its output at pin 5 is high by default. However, if the pin 4 reset input is held
low by the Arduino (via CON2), then
this timer is in its reset state, so output
pin 5 is low. Therefore, during operation, the output at pin 5 follows the
signal at pin 4.
Output pin 5 is also connected to
the trigger input of the second timer,
at pin 8, while that timer’s threshold
input (pin 12) is also tied to VCC. So
output pin 9 is low when output pin
5 is high and vice versa, and thus the
second timer operates as an inverter
once it is enabled.
Thus, when IC1 is enabled, there is
always a voltage across the track, with
the magnitude being close to VCC and
the polarity depending on the signal
from CON2.
A 2.2Ω resistor between IC1’s ground
pin and the main circuit ground is used
to sense the current flowing between
the track connections.
Regardless of the direction of current flow through the track connections, that current must ultimately
flow back through IC1 and to the power
supply ground. The result is a voltage
across that 2.2Ω resistor.
That voltage is fed to CON5 via a
1kΩ series resistor and on to one of the
Arduino’s analog pins where it feeds
the internal 10-bit analog-to-digital
converter (ADC) and is converted into
a digital value in the range of 0-1023
by the software. The combination of
the 10-bit ADC and the 2.2Ω current
sense resistor means the resolution of
this reading is around 2mA.
JP1 is a three-pin header which allows you to choose whether the voltage fed to the 556 IC is from the Arduino’s DC input socket (via the VIN
pin) or from MOD1, an MT3608 2A
boost DC/DC converter module. If you
are powering the Arduino from a 12V
plugpack, then you can put JP1 in the
VIN position, so the plugpack provides
the track voltage.
But if you are powering the Arduino
from a computer or a 5V USB charger,
this voltage is not sufficient to power
the tracks. In this case, you can place
JP1 in the VOUT+ position and adjust
the trimpot on the MT3608 module to
provide 13V to IC1.
The stand-alone Arduino program has a very simple
interface, and allows direct reading and writing of CVs.
This is sufficient to fully manipulate any parameters, but
may not be as intuitive as the advanced roster settings
available with DecoderPro.
40
Silicon Chip
While not vital, as MOD1 has onboard bypass capacitors, the shield
has provision for 100µF input bypass
and output filter capacitors. We recommend that you fit the input bypass
capacitor but leave the output filter
capacitor off (as described in the Construction section).
There is also an onboard 6.8Ω resistor between the 5V supply and the
module’s VIN+ terminal, to reduce
the inrush current from the 5V supply
when it is first connected and to limit
the maximum current drawn during
operation (eg, if the tracks are accidentally shorted).
The shield is driven using two of the
Arduino’s digital pins and feeds the
current sense voltage back to one of the
analog pins. Rather than make these
fixed, and risk interfering with the
function of any other shields plugged
into the Arduino, all three pins can
be selected using jumper shunts for
maximum flexibility.
The digital pins are selected by placing one jumper between CON1 and
CON2 (for the polarity signal) and another between CON1 and CON3 (for
the enable signal). By default, our software is set up to use digital output D5
for the polarity signal and D11 for the
enable signal but you can change the
software if you place the jumpers in
other locations.
Similarly, the analog pin is selected
by connecting a pin on CON4 to the associated pin on CON5 and by default,
we’re using analog input A1.
The software
The primary job of the software is
This is the Simple CV Programmer interface in
DecoderPro, and it allows CVs to be directly written and
read. Using the Roster feature allows the locomotive to be
given a name, and CVs to be saved to a configuration file,
as well as grouping the CVs into logical groups.
Australia’s electronics magazine
siliconchip.com.au
Fig.2: use this PCB overlay
diagram and the photo at
right as a guide when
building the shield.
Make sure that MOD1 is
orientated correctly, with
its VIN pins towards the
electrolytic capacitor. IC1,
D1 and the electrolytic
capacitor are also polarised.
The jumper locations shown
here suit our sketch as well
as the DCC++ code, when
being used as a DCC
programmer.
to produce a signal across the tracks
which carries the required DCC packets. It does this using an interrupt software routine (ISR) which is triggered
every 58µs by a timer. 58µs is the halfperiod of a ‘1’ bit.
To send a ‘1’ bit, we toggle the DIR
pin each time the interrupt fires. To
send a ‘0’, we should ideally have a
half-period of 100µs but 116µs (2 x
58µs) is within the limits that are recognised by the decoder. So we merely
wait for two timer interrupts to occur
before toggling the DIR pin to transmit a zero bit.
The interrupt handler steps through
the DCC data array as each bit is transmitted, then sets a flag to indicate that
the complete packet has been sent and
moves onto the next packet. Thus,
most of the real work is done inside
the interrupt routine.
During most programming sequences, the programmer sends several reset packets to the loco, followed by
multiple ‘write’ packets and this is
accomplished by placing the appropriate commands in the array to be
transmitted.
The detection of acknowledgement
pulses from the loco is done by continually sampling the voltage across the
current sense resistor, at the selected
Arduino analog input. The quiescent
sample value is used as a baseline value. If an acknowledgement is expected, the current sample is compared
with the baseline and if the threshold
is reached, a flag is set indicating an
acknowledgement has been received.
As well as being able to use the
DCC++ software, we provide a basic
serial terminal interface. This allows
you to send DCC commands straight
to the locomotive, assuming that you
know what is required. These are inserted into the array of packets to be
sent, but they are not transmitted until
siliconchip.com.au
you indicate that they are ready. The
software then sets a flag to start the
transmission.
MOD1 is optional
We are using boost regulator MOD1
for convenience, so that you can run
the programmer off a 5V USB supply.
However, if you plan to power the
Arduino from a 12-15V DC supply,
you could omit MOD1. In this case,
you would need to place JP1 in the
“VIN” position.
Keep that in mind as you assemble
the shield.
Construction
The DCC Programmer Shield is built
on a PCB measuring 68.5 x 53.5mm
(the size and shape of a standard Arduino shield) and coded 09107181.
Use the overlay diagram, Fig.2, as a
guide during construction.
Fit the smaller resistors first, confirming the values with a DMM before
soldering each in place. Follow with
diode D1, taking care to orientate it as
shown in Fig.2. Then install the two
larger 1W resistors.
You can now fit the 100µF input bypass capacitor for MOD1. This should
be laid over on the PCB so that you
can later stack another shield on top
if you need to. Make sure its positive
(longer) lead goes in the pad nearest
the adjacent edge of the PCB.
Next, solder in pin headers CON1CON6 and JP1 where shown. You
can then fit MOD1, by first soldering
four component lead off-cuts to the
pads so that they stick out the top of
the board, then lowering MOD1 over
those leads and soldering them to the
pads on the top of the module. You
can then trim off the excess lead length
on top of MOD1 and on the underside
of the PCB.
Now solder CON7 to the board,
making sure it has been pushed down
so it is sitting correctly on top of the
Parts list –
Arduino DCC Decoder Programmer
1 double-sided PCB, code 09107181, 68.5 x 53.5m
1 set of Arduino stackable headers (1 x 6-pin, 2 x 8-pin, 1 x 10-pin)
1 Arduino Uno or equivalent
1 MT3608 2A boost module [SILICON CHIP Online Shop Cat SC4437]
3 14-pin headers (CON1-CON3)
2 6-pin headers (CON4,CON5)
1 2-pin female header socket (CON6)
1 2-way terminal block, 5/5.08mm pin spacing (CON7)
1 3-way pin header (JP1)
4 jumper shunts/shorting blocks
Semiconductors
1 556 dual timer IC (IC1)
1 1N5819 1A schottky diode (D1)
Capacitors
1 100µF 25V electrolytic
Resistors (all 0.25W, 1% unless otherwise stated)
1 10kΩ
3 1kΩ
1 100Ω
1 6.8Ω 1W 5%
Australia’s electronics magazine
1 2.2Ω 1W 5%
October 2018 41
PCB and its wire entry holes
are facing towards the outside
edge of the board.
Fit the Arduino headers
next. We’ve specified stackable headers but you could potentially use standard headers
if you don’t plan to attach any
shields on top of this board. Either way, make sure the long
pins project out the bottom of
the board. You need to solder
the stackable headers carefully to avoid getting solder
on the pins except near where
they connect to the pads.
Note that the stackable
headers give more clearance
for the components on the board underneath (eg, the Arduino).
If you use standard headers, you
may find that CON7’s pads short to
the shield of the USB connector below, which is connected to ground.
Adjusting MOD1’s output
voltage
Before installing IC1, you must adjust MOD1’s output voltage. Plug the
shield into your Arduino board and
then apply power.
Use a DMM set to measure DC volts
to probe the VOUT+ and VOUT- pads
on MOD1. Adjust its onboard trimpot screw to get a reading just below
15V; counter-intuitively, the voltage is
decreased by turning the adjustment
screw clockwise. We set our track voltage to 13V and it works well.
You can then remove power, unplug
the shield and fit IC1, ensuring that its
pin 1 notch faces into the middle of the
board, as shown in Fig.2. You could
potentially use a socket but given that
the IC is supplying significant current
to the tracks, it’s better to avoid that.
Now fit the jumpers to select your
desired track voltage source and to
configure which Arduino pins are
used for control. If you are unsure,
insert the jumpers in the positions
shown in Fig.2. The shield assembly
is then complete.
Software setup and testing
Now you need to upload the Arduino sketch code to the board. This is
done using the free Arduino IDE (integrated development environment).
It is available for Windows, macOS
and Linux and you can download it
from www.arduino.cc/en/Main/Software The IDE is used to compile and
42
Silicon Chip
Monitor indicating the locomotive’s short address (CV
1). Other CVs can be written
to and read from with simple
commands like this. To write
a CV, use the format “w1:3”
That command writes the value 3 to CV 1.
Using it with DCC++
and JMRI DecoderPro
If you want to run DCC
trains from a computer, you
can use the open-source JMRI
The DCC software. It comes with Deprogrammer shield coderPro, which has a commounts on top of the Arduino prehensive “Roster” feature
UNO board, as seen here. which that be used to save
and restore locomotive programming
upload the software to the Arduino.
Now download the software pack- parameters.
If you have a fleet of similar locomoage from the SILICON CHIP website.
This contains a “standalone” Ardui- tives, this is a convenient way of manno sketch called “DCC_Programmer_ aging their various performance CVs.
So that our Programmer can operShield_V2”, which is the easiest way
to test your shield. Before you can ate with JMRI, we can use the openuse this sketch, you need to install a source DCC++ Arduino sketch. This
was designed to work with other hardlibrary called TimerOne.
TimerOne can be installed from the ware but our shield has been designed
IDE’s Library Manager (Sketch menu to be compatible with that hardware,
→ Include Library → Manage Librar- so you can run DCC++ on it without
ies…). Open the Library Manager and any modifications.
Our software download package for
search for “TimerOne” and then when
you find it, select it and click the “In- this project includes the DCC++ software. To use it, extract and open the
stall” button.
In case you have trouble with that DCCpp_uno sketch. Then check the
method, we also include a zipped “Config.h” tab and make sure that this
copy of the library in the sketch down- line is set correctly:
load package. This can be installed us#define MOTOR_SHIELD_TYPE 0
ing the Sketch → Include Library →
You need to set up the jumpers on
Add .ZIP Library menu option.
Now extract and open the DCC_Pro- CON1-CON5 for your shield to match
grammer_Shield_V2 sketch from the those shown in the overlay diagram,
download package, eg, using the IDE’s Fig.2. This configuration is required
File → Open menu option. Connect to emulate this motor shield type. Upthe Uno to your computer and select load the sketch to the Uno board, as
the “Uno/Genuino” option from the described above.
The DCC++ software also uses a seTools → Board menu.
Also, check that the correct COM rial interface, so you can use the serial
port listed under the Tools → Port monitor to examine its output.
The DecoderPro program has the
menu matches the one assigned to
option to use a DCC++ programmed
your Uno board.
Select the Upload option under Uno, so our reprogrammed board can
the Sketch menu and then open the now be used with DecoderPro. JMRI
serial monitor (Tools → Serial Moni- is available for Windows, Mac and
tor) at 115,200 baud. You should get Linux (including a Raspberry Pi vera message describing how to use the sion). However, note that you need to
sketch. If you have a DCC locomotive, have Java installed to use it.
Get JMRI from http://jmri.sourceplace it on a length of track wired to
either CON6 or CON7 and type “r1” forge.net/download/index.shtml and
in the Serial Monitor, followed by the open the DecoderPro program. Go
to the Edit → Preferences menu and
Enter key.
If everything is working, you should under Connections, choose DCC++
see some text appear on the Serial as System Manufacturer and DCC++
Australia’s electronics magazine
siliconchip.com.au
Serial Port as System connection. Ensure the Serial port matches that of
the Uno.
Save the configuration and close
DecoderPro so that it can re-load the
new settings. Open DecoderPro again
and under Edit → Preferences choose
defaults, and ensure that DCC++ is selected for Service Programmer. Unless
you have other hardware, you should
select DCC++ for all options.
Save, close and re-open DecoderPro again. Click the red power button
and ensure that it turns green. You
should see “Service Mode Programmer DCC++ Is Online” in the bottom
left corner of the screen.
Now use the Actions → Single CV
Programmer menu option to open the
Simple Programmer window. This
window allows you to read and write
single CVs via a basic interface.
If you find you are getting the “No
acknowledge from locomotive” error
then the threshold that DCC++ uses
for detecting acknowledge pulses from
the track may need to be adjusted.
This is a parameter in the DCCpp_
uno sketch.
Close DecoderPro (so that it no longer has control over the Arduino) and
navigate to the “PacketRegister.h” tab
in the DCCpp_uno sketch. Near line
20, there is a value called ACK_SAMPLE_THRESHOLD which is 30 by default. We found that reducing this to
12 gave consistent results with three
different decoders.
Save the sketch with the changes,
then upload it to the Arduino board
again. Ensure that the Serial Monitor
is closed before reopening DecoderPro and try the Single CV Programmer option again.
siliconchip.com.au
While the default value of 30 corresponds to the specified value of 60mA
for the acknowledge pulse, the DCC++
sketch also applies some smoothing to
the sensed current, so this may change
the actual detected current threshold.
To use the Roster feature, click the
“New Loco” button in the top left corner of the main DecoderPro window.
Click “Read type from decoder” and
DecoderPro will read a number of the
CVs to identify parameters such as the
manufacturer.
If this does not work, you can also
choose Roster → Create entry to enter
this manually.
Once a Roster entry has been created, double-click it to open the Comprehensive Programmer, allowing
more detailed and complex programming to occur.
JMRI is a vast program with many
features and we can’t pretend that
we’ve covered a fraction of them here.
There is comprehensive documentation online.
The article at siliconchip.com.au/
link/aal3 introduces DecoderPro and
is a good place to start.
JMRI also has a layout editor (PanelPro) so that you can create track
diagrams and these can be animated
with information from the layout if
you have the correct sensors installed.
Other uses for this project
You may not think that having a
DCC Programmer is all that useful
but this device can also be used as a
minimal DCC base station. With the
DCC++ software, the Programmer can
act as a low-power booster.
If you set the board jumpers for EN
on pin D3, DIR on pin D10 and Current
Australia’s electronics magazine
Sense on A0 then the DCC++ sketch
can use the Programmer as its “main
line” output.
This means that the output can be
connected to some track and DecoderPro’s throttle window can be used
to control a DCC decoder-equipped
locomotive.
Because its current capacity is limited, you’re not going to be running a
fleet of trains but it could be handy for
testing and experimentation.
In our trials, we found a small H0
scale locomotive was able to be driven at low speed, including operating
the lights.
What about driving a small
motor?
Another possible use for this shield
is as a small 12V motor driver board.
If you need to drive a small 6-15V
DC motor using USB power or some
other source of 5V then this shield can
be used as a reversible motor driver,
without the need for an external power source.
It’s suitable for motors drawing up
to about 2W. Note that your 5V supply must be able to deliver enough
current.
Useful links
Setting up DCC++ with JMRI DecoderPro: https://github.com/DccPlusPlus/BaseStation
DCC Standards Page: www.nmra.org/
index-nmra-standards-and-recommended-practices
OVERLEAF: I I I I I I I I I I I I I I I
HOW DCC WORKS
October 2018 43
How DCC works
We published an article in the February 2012 issue
explaining how DCC works and showed some typical
DCC decoders (see siliconchip.com.au/Article/769).
But that article didn’t go into much detail regarding the DCC protocol, so read on for a more detailed
explanation.
If you aren’t into model railways then the advantages of DCC may not be obvious. To understand why
it is so useful, we’ll explain how model railway systems worked before DCC.
For a standard DC model railway, a single locomotive is fed power through the tracks, with one rail being negative and the other positive. Varying the average voltage between the rails changes the loco’s speed
while swapping the rail polarities reverses its direction of travel. A typical H0 scale locomotive (1:87
scale) runs from 12V DC, drawing
from a few hundred milliamps up to
an amp or so.
Such a system only allows a single locomotive to be controlled as
multiple locomotives would receive
the same track voltage. And direct
control of accessories such as headlights, steam or sound effects is not
possible. With clever use of diodes,
it’s possible to have directional headlights, but a battery is still needed for
lights if the locomotive is stopped as there is no voltage on the track.
The most common way to allow multiple locomotives to operate is to divide the track into individual
“blocks” or sub-circuits which can be switched between controllers. As you can imagine, the switching
rapidly becomes very complicated as the track layout
expands or more controllers are added.
DCC transmits both power and control signals using the tracks. The locomotive’s onboard decoder interprets the control signals and commands the motors, lights and other accessories. Power is supplied
continuously, allowing accessories to operate even while
the locomotive is stationary. Beyond lights, features such
as smoke generators and sound effects modules are quite
common (if not especially cheap).
The DCC signal is a square wave with a 50% duty cycle
and varying pulse width. The data is encoded in the pulse
widths while the square wave, once rectified, provides DC
power for the decoder, motor, lights etc.
The track voltage is typically 30V peak-to-peak, with
cycle times of around 100µs. A typical DCC base station
consists of a microcontroller feeding an H-bridge of some
sort, usually with some form of current detection to shut it
down in the event of a short circuit. With exposed conductors in the form of rails, it’s bound to happen sooner or later.
A simplified circuit diagram of a typical DCC decoder is
shown in Fig.3. This shows some of the circuitry to drive
two lamps (eg, headlight and marker LEDs)
as well as the motor.
The DCC protocol encodes a binary 1
as a pulse that is nominally 58µs high
and 58µs low, with a binary 0 having high
and low periods that are 100µs or longer
(see Fig.4). Because the locomotive can
be placed on the track either forwards or
backwards, the absolute polarity cannot be
determined, so the high pulse may come
before or after the low pulse.
Fig.5 shows what these ‘0’ and ‘1’ bit pulses look like when they are arranged back-to-back, forming
a continuous AC waveform.
While the standards are specific as to what should and
should not be accepted as valid data, merely sampling the
“high” period of adjacent bits is sufficient to decode the
bitstream and in any case, each command has a checksum
byte, so errors caused by timing inaccuracies can be detected and the corrupt command ignored.
The peak frequency of this signal is around 8kHz, which
is higher than the 5kHz that the widely-used L293 fullbridge motor driver IC can deliver. So DCC base stations
designed around the L293 IC probably won’t work reliably.
®: Registered DCC trademark of the
National Model Railroad Association (USA).
Fig.3: a simplified version of a
typical DCC decoder circuit,
showing the bridge rectifier and
filter capacitor used to convert
the AC voltage on the tracks to a
DC voltage, with the raw track
signal also being fed to the micro
so it can be decoded. The micro
then controls the H-bridge motor
driver transistors, lamps, sound
effects module etc.
44
Silicon Chip
Australia’s electronics magazine
siliconchip.com.au
Fig.4: in a DCC system, the voltage across the tracks has
a more-or-less constant magnitude but its polarity is
continuously reversing, creating a 5-8kHz square wave.
This is rectified by the DCC decoder(s) and is used as a
power source for their logic circuitry as well as driving
motors, lights, audio amplifiers etc. But the frequency
modulation also encodes digital commands, addressed to
individual locos.
DCC protocol
The bitstream is broken up into packets, with each packet containing one command, for tasks such as setting the
motor to a particular speed or turning a light on and off.
The loco’s state is stored by the decoder and kept consistent until it is updated by a future packet.
There are also dedicated programming commands, which
set configuration values (CVs) in non-volatile EEPROM.
These values are used to determine which address the locomotive responds to, how the speed changes with throttle position, how lights and other accessories react to inputs etc. It’s these CVs that our programmer is designed to
read and modify.
Each valid packet starts with at least 14 sequential ‘1’
bits. This is referred to as the preamble and allows the decoder to synchronise itself with the start of the data packet,
which is indicated by the first following ‘0’ bit. The data
for the first byte of the command (which is an address) follows this, with all bytes sent most-significant-bit (MSB)
first (see Fig.6).
Subsequent bytes are prefixed with a zero bit so each
byte transfer requires nine bits to be sent. The last byte to
be transmitted is the aforementioned checksum byte.
After this, a ‘1’ bit is sent, indicating that the packet is
complete. The final ‘1’ can also count as the start of the
next preamble if packets are sent back-to-back.
Since each byte in the packet is separated by a ‘0’ bit,
the only place that more than eight ‘1’ bits can appear
in a row in a valid DCC sequence in is the preamble, so
decoders can’t be fooled into thinking a new packet is
starting in the middle of a valid packet.
Each packet is a minimum of three bytes so the minimum packet transmission length is 40 bits, giving a
minimum packet time of just over 5ms. So it’s possible
to send close to 200 commands per second using DCC.
Once the decoder has received a packet and the checksum is correct, it checks the address byte. If it matches
the address stored in the decoder’s EEPROM, it can act
on the command and if necessary, send a response. That
is generally only necessary for programming commands
as the programmer needs a way to read the configuration from the decoder.
In this case, the packet sent by the base station is
equivalent to asking “is this bit of this configuration
variable set?”, to which the decoder replies either with
an acknowledgement or not. The acknowledgement is
performed by the decoder by placing a load of 60mA or
more across the tracks for 6ms.
In practice, this is usually done by the decoder briefly
powering the motor, often resulting in the locomotive
inching forwards during programming.
The acknowledgement is one of two reasons why programming usually occurs on a dedicated programming
track. Firstly, it would be difficult to accurately detect the
acknowledgement pulse in the presence of other loads
(such as other locomotives) on the rails.
Secondly, many programming packets are broadcast to
all decoders on the track. So the only way to guarantee
that only the correct locomotive receives the programming packets is to have a dedicated section of track for
programming.
The DCC standards are very detailed and make for interesting reading. It could potentially be used in situations
other than model railways, where power and commands
SC
need to be sent and received over two wires.
Fig.6 (right): the structure of the shortest possible valid
DCC command, containing one address and one data
(command) byte. The preamble always consists of at least
fourteen sequential ‘1’ bits and each
byte is separated by a ‘0’ bit, with the
command being terminated by a
checksum byte (to detect errors) and
then a final ‘1’ bit to indicate that there
is no further data in this command.
siliconchip.com.au
Australia’s electronics magazine
Fig.5 (left):the sequences of ‘0’ and ‘1’
bit pulses are strung together to create
a continuous AC waveform across the
tracks, effectively forming a frequencymodulated square wave. The RMS
voltage is very close to the peak voltage,
providing a similar voltage and current
to the motors in the locos, while the
average voltage is effectively zero since
the waveform is symmetrical.
October 2018 45
|