Semaphore Control Commands

{From the laptop (4) to the Raspberry Pi (3)}

The interface to the Base Station is not standardized. NMRA defines the DCC standards between a Base Station and the hardware NOT the controllers to the Base Station. The following added commands from the laptop to the Raspberry Pi need to be coordinated only with the DCC++ commands going from the laptop to the Base Station (Arduino) through the same channel.

Command summary

    • < -- Start of added command
    • A|G|K|N|n -- command character
    • Zero, 2, 3, 4, 5 or 6 data bytes
      • Pole -- There are 16 sections of track with a semaphore signal pole at each end (1-32) and 4 staging yard tri-color dwarf LED signals (33-36)
      • Top -- There may be two semaphore signal arms on a pole, true = 1 (top) or false = 0 (bottom). For the LEDs, Top must be true.
      • Row -- Each servo to control the aspect of a semaphore is attached to a 16-channel PWM Raspberry HAT or Bonnet numbered 0 - 3
      • Column -- Each servo to control the aspect of a semaphore is further address by channel numbers 0 - 15 on each HAT/Bonnet (Row).
      • X -- The aspect of each signal (Pole/Top) can also be displayed by an LED on the Unicorn display(s) at horizontal location 0 - 31
      • Y -- The y, vertical, coordinate of the Unicorn display 0 - 15.
      • RED, YELLOW, GREEN -- The servo setting for the red, yellow or green aspect of the identified (Pole/Top) semaphore; 0 - 180°
      • Aspect -- The setting of the identified semaphore or tri-color LED: 0=off (LED only), 1=red, 2=yellow or 3= green.
      • angle -- The angle to set the identified (Row/Column) servo; 0 - 180°
    • > -- End of added command

Added command response summary

    • < -- Start of response
    • G|K|n|U|V -- Response character
    • Zero, 1, 2, 9 data bytes
      • (see above)
      • nsignals -- The number of signal (Pole/Top) definitions saved to EPPROM
      • nservos -- the number of servos (Row/Column) signals are assigned too.
    • > -- End of response

  • Define Signal

Associate a signal (semaphore/LED), with a servo and unicorn location. 

<K Pole Top Row Column X Y > 6 data bytes

Returns: <U> OK or <V> not good - out of range, (pole, Top) or (row, column) or (x, y) in use

       IF OK:        Set RAM only new entry - Pole, Top, Row, Column, X, Y, 90 ,90, 90, 1

Set servo Row/Column to 90 (YELLOW)

(See <N> below)

  • Calibrate Semaphore

       Set the servo angle (0 - 180°) for each semaphore aspect.

<K Pole Top RED YELLOW GREEN >         5 data bytes

       Returns: <U> OK or <V> not good - not found, not associated or out of range

       IF OK:        Set RAM only entries for Pole/Top to RED, YELLOW, GREEN and aspect to 2 (GREEN)

Set the servo pointed to by Pole/Top to RED, YELLOW then GREEN

(See <N> below)

  • Add Servo to Signal

Add servo Row, Column to a previously defined signal.

<K Pole Top Row Column> 4 data bytes

Returns: <U> OK or <V> Pole < 33, 0 <= Row <= 3, 0 <= Column <= 15, Row/Column NOT 0/0, Row/Column in use.

IF OK Set RAM only (See <N> below)

  • Delete Signal

       Remove the association between a signal and a servo & unicorn location

<K Pole Top> 2 data bytes

         Returns: <U> OK or <V> if not found or out of range

       IF OK:        remove from RAM only entry for Pole/Top.

               (See <N> below)

  • Change Aspect of a Signal

       Change a signal to a new aspect 

<K Pole Top Aspect> 3 data bytes

       Returns: <K Pole Top Aspect> or <V> not changed - not found, out of range

       IF OK:        Set RAM only entry for Pole/Top - Aspect to Aspect

Set servo pointed to by Pole/Top to Aspect or tri-color LED aspect.

  • List All Defined Semaphores

       Return all associations between semaphores, servos and unicorn locations currently in RAM 

<K> zero data bytes

       Returns: <G Pole Top Row Column X Y RED YELLOW GREEN> for each semaphore or 

 <G Pole Top 0 0 X Y 0 0 0> for each tri-color LED or <V> if none

  • Return Aspect of semaphore

Return the current aspect of all defined semaphores.

<G> zero data bytes

Returns: <K pole Top Aspect> for each defined semaphore or <V> if none.

       Return the current aspect of the given semaphore.

<G Pole Top> 2 data bytes

         Returns: <K pole Top Aspect> or <V> of not found

  • Store Pi RAM to EPPROM

       Store semaphore data in Pi RAM into Pi EPPROM

<N> zero data bytes

       Returns: <n nsignals nservos>

  • Erase all Pi EPPROM

       Erase all semaphore association data from Pi EPPROM

<n> zero data bytes

       Returns: <U> Done

               Erase all EPPROM data. Read EPROM into RAM

  • Adjust servo angle (Maintenance)

       Move semaphore arm by changing servo angle

       <A Row Column angle> 3 data bytes

       Returns: <U> OK or <V> not good - out of range

       IF OK:        Set servo Row/Column to angle

               (Results to be used in "Calibrate Semaphore" above)

Data Range

    • Pole 1-36 (Semaphore poles 1-32, or tri-color LED signals 33-36) 
    • Top 1 (true) or Bottom 0 (false) (33-36 Top = 1 only)
    • Row 0-3 (16-channel PWM HAT/Bonnet address)
    • Column 0-15 (channel on each HAT/Bonnet), except Row/Column (0,0) is unassigned.
    • X 0-31, Y 0-15 Unicorn location, except (0,0) is unassigned
    • RED, YELLOW, GREEN, angle 0-180° 
    • Aspect 0-OFF, 1-RED, 2-YELLOW, 3-GREEN
    • nsignals 0-64, nservos 0-60 (60, 56 expected max)

Invalid Data

    • Define - Pole, Top already in RAM
    • Calibrate/Delete/Change/Return - Pole, Top NOT in RAM
    • Calibrate - Pole, Top NOT associated with a servo (Row/Column 0/0)
    • Change - Aspect 0-OFF invalid if Pole, Top point to Row, Column not 0/0 
    • Define - Row, Column, not 0/0 AND already assigned
    • Define - X, Y not 0/0 AND already assigned
    • Define - Row, Column OR X, Y must not be 0/0

Data Base






















On initializing Pi:

  1. Set all servos (1-63) to 90° (YELLOW) (Whether servo attached or not)
  2. Read EPPROM to RAM setting each aspect to 0 (RED)
  3. For each defined Pole/Top, set each defined servo (Row/Column not 0/0) to aspect (RED) 
  4. For each defined Pole/Top, set Unicorn (X/Y not 0/0) to aspect (RED)

The initialization sequence is mostly for testing.

(1) identifies all attached servos/semaphores

(3) identifies which semaphores (Row/Column) are associated with a signal (Pole/Top) in EPPROM

(4) identifies unicorn locations (X/Y) associated with a signal (Pole/Top).