Overview
To
show OpenVMS V9.2 X86_64 processing in an edge environment, a
multi-threaded ‘C’ application was developed.
The program uses serial connected RFID readers to identify and
track model railroad cars (rolling stock) on a G-scale model railroad
loop. The railroad loop
is divided into five sections (blocks).
The same program uses GPIO output signals to control track signals
for those blocks and maintain train (consist) separation.
RabbitMQ message broker is employed to distribute (publish)
block and consist information and to accept commands for loop
operation.
Rolling Stock Detection and Identification
RFID
readers are used to detect movement and identify rolling stock on the
model railroad loop. Each
block has an RFID reader mounted beneath the track at the start of
that block. The readers
are each connected to the OpenVMS serial ports provided by
SYS$YPDRIVER (devices TTA through TTE).
A dedicated process thread is created, one for each reader
device (train block). Each
of these block threads assigns a channel to the reader port,
initializes the reader and prepares the reader to read/detect an RFID
tag. The RFID readers
used initialize and communicate at 115,200 baud.
Each piece of model railroad rolling stock has an RFID tag
mounted on its underside. As
each piece of rolling stock enters a train block, the RFID tag passes
over that block’s RFID reader and the tag’s value is read.
An in memory database of tag values is queried and the
rolling stock identified. The
rolling stock database contains a description for each piece of
rolling stock as well as other attributes (locomotive, car type, end
of train car, etc.).
RFID
reader mounted under track at block entrances. |
RFID
tags mounted on rolling stock undersides. |
When an RFID tag is read for the first time, an inventory
operation is begun. The
first, and successive, tags are read and assembled into a running set
of train cars (rolling stock) called a consist.
Once completed, the consist is tracked as it travels from
block to block and the RFID tags are scanned.
RFID tags being read as consist enters a train block and each rolling stock RFID tag passes over RFID reader. |
Train Block Control
Two
blocks on the train layout have block signals.
One block also has an entry and approach signal.
When a block’s block signal is set to STOP, a consist
entering that block will pause. When
a block’s block signal is set to PROCEED, a consist entering that
block will continue through that block or resume forward movement is
paused. A
block’s signal state (STOP or PROCEED) is set based on whether or not
the next block in the model railroad loop is occupied or vacant.
The
signals on this layout are controlled using Direct Current (DC)
pulses. Using an
Alternating Current (AC) voltage source, an AC relay board and diodes,
a block’s control voltage can be selected using GPIO output signals.
Publishing Block Status and Train (Consist) Position using
RabbitMQ
Two
publishing threads are created by the loop control application.
Each thread uses a RabbitMQ Exchange to dynamically distribute loop information.
The Exchange names are based on the name of
name of the railroad loop being controlled, South
Main1.
The first exchange is named South
Main1 Blocks and distributes running state and occupancy
information for the loop.
The second exchange is named South
Main1 Consists and publishes consist position
information. The name of
a consist, taken from the lead locomotive description, is used as a
RabbitMQ exchange routing key. This
allows individual consist updates to be subscribed to.
Receiving Loop Commands using RabbitMQ
Also
included in the application is a command processing thread.
That thread subscribes to the RabbitMQ queue South
Main1 Commands. Publishing
a text string command to this queue wakes up the command processing
thread which receives, parses and processes the sent command.
The commands PROCEED, HOLD and STOP can be used to set
individual loop blocks to a proceed, manual pause or momentary pause
(one cycle pause), respectively.
A SHUTDOWN command is also recognized to perform an orderly
shutdown of the train loop.