Skip to main content

I have read through the 2015 Lionel  LCS  Partner  Documentation Legacy  Command  Protocol document and understand how to throw routes via the TMCC1 protocol (and even did so from Python on a Raspberry Pi). But by my read, the TMCC1 route command only provides 5 bits to specify a route number, which limits me to routes 1 - 31 (2**5 - 1).

I  cant find information on how to throw routes via the Legacy/TMCC2 syntax. I am assuming that command would support all routes (1-99/100). I could write a serial port sniffer and try to figure it out, but is this information documented somewhere?

BTW, I am planing to develop a Python package to control my layout, based on PySerial to talk with the serial port. I can make this code public, if there is interest (I’ll be setting up the GitHub project next week). Eventually, I’ll use buttons connected to the Raspberry to throw routes, activate accessories, etc (think control panel), but that is phase 2.

Any pointers are appreciated.

Thanks,

  — Dave

Last edited by cdswindell
Original Post

Replies sorted oldest to newest

The RTE info (SW ##s, through/out) is stored in the Base logic.   When a RTE is fired, the SW command are sent with the programmed delay.  The TMCC1 Route Commands [1-9] will fire whatever is in the Base's table when used from the Cab1, Cab2, and Cab3.

I see that firing RTE 1 (and through 9) triggers the TMCC1 Route command:

7232.37 <-- D1 28 FE D0 9F 6B DF
   TMCC data: FED09F - (S) FED09F RTE 1 Fire!
47232.63 <-- D1 28 FE 4A 80 10 DF
   TMCC data: FE4A80 - (S) FE4A80 SW  21 Through
etc.

Firing RTE 10 (and through 99) triggers an undocumented TMCC extended command:

47434.58 <-- D1 28 FA 6C FD 75 DF
   TMCC data: FA6CFD - Extended block 'FA'6CFD 110110011111101
47434.71 <-- D1 28 FE 4C 00 8E DF
   TMCC data: FE4C00 - (S) FE4C00 SW  24 Through
etc.

I guess you will have to maintain RTE table is your device for route IDs > 9, or explore the extended commands.

The RTE info (SW ##s, through/out) is stored in the Base logic.   When a RTE is fired, the SW command are sent with the programmed delay.  The TMCC1 Route Commands [1-9] will fire whatever is in the Base's table when used from the Cab1, Cab2, and Cab3.

I see that firing RTE 1 (and through 9) triggers the TMCC1 Route command:

7232.37 <-- D1 28 FE D0 9F 6B DF
   TMCC data: FED09F - (S) FED09F RTE 1 Fire!
47232.63 <-- D1 28 FE 4A 80 10 DF
   TMCC data: FE4A80 - (S) FE4A80 SW  21 Through
etc.

Firing RTE 10 (and through 99) triggers an undocumented TMCC extended command:

47434.58 <-- D1 28 FA 6C FD 75 DF
   TMCC data: FA6CFD - Extended block 'FA'6CFD 110110011111101
47434.71 <-- D1 28 FE 4C 00 8E DF
   TMCC data: FE4C00 - (S) FE4C00 SW  24 Through
etc.

I guess you will have to maintain RTE table is your device for route IDs > 9, or explore the extended commands.

Thanks John. I was able to fire Rte 10 via the TMCC1 syntax. As that syntax provides 5 bits to specify route, I’m assuming I can use it to fire routes 1 - 31.

Did you capture these byte sequences by looking at the traffic out of the LCS SER module? I’m going to have to figure out where the 7 bits to specify address are in these values.

You say this command is undocumented? Bummer. I wonder if I asked Lionel support.

Thanks,

  — Dave

@cdswindell posted:

Thanks John. I was able to fire Rte 10 via the TMCC1 syntax. As that syntax provides 5 bits to specify route, I’m assuming I can use it to fire routes 1 - 31.

Did you capture these byte sequences by looking at the traffic out of the LCS SER module? I’m going to have to figure out where the 7 bits to specify address are in these values.

This is the explanation of the extended route command

  TMCC data: FA6CFD - Extended block 'FA'6CFD 110110011111101

The route address is the first 7 bits of the middle byte.  The sequence always starts with 0xFA, and ends with 0xFD.

The LSB of the middle byte is zero(0).  If you try a few sequences with the Cab2, you can see this.  (parenthesis bit is always 0 as indicated in examples below).

Examples:       

..................................---0xFD---

RTE10:  0001010(0)  11111101   => 0x14   => 8+2 = 10

RTE99:  1100011(0)  11111101   => 0xC6   => 64+32+2+1 = 99

This should get you going..  Not sure a route fire command injected into the serial port will cause the Base3 to fire the route, that probably works, but not a guarantee without me digging deeper.  LMK your results, my email is in profile.



Last edited by SantaFeFan

Re: I was able to fire Rte 10 via the TMCC1 syntax. As that syntax provides 5 bits to specify route, I’m assuming I can use it to fire routes 1 - 31.

I was using the Cab1 while looking at the ouput captured by the LCS WiFi Monitor.  The Cab1 doesn't allow 2-digit routes so my limit was 9.

Jon, thanks for the tip on decoding the route number.  Am I correct assuming that the Base is responsible for converting a Route Fire command to a series of SW throw commands?

Re: I was able to fire Rte 10 via the TMCC1 syntax. As that syntax provides 5 bits to specify route, I’m assuming I can use it to fire routes 1 - 31.

I was using the Cab1 while looking at the ouput captured by the LCS WiFi Monitor.  The Cab1 doesn't allow 2-digit routes so my limit was 9.

Jon, thanks for the tip on decoding the route number.  Am I correct assuming that the Base is responsible for converting a Route Fire command to a series of SW throw commands?

Some more information:  Prior to Legacy, Routes were stored in the switch controller(ie ASC1 or TMCC Fastrack SW).  Much like a Train address represents a multiple of engines and stores the train address in the engine; routes did the same storing a route address and a switch address in the controller, not the Base1.  So Legacy had to address this in some way, and it was decided to use single digit addressing as before for routes 0-9, where the route is saved in the controlling device, not the base2 or base3.

I am not 100% sure if the switch array is saved in the base2/3 route addresses from 0-9 (the Cab2 would control that anyways).  I think for Route 10 to 99 the switch array *is* stored in the base2/3; and that is why there is an extended route command sent out (0xFA) so the controlling devices of the past don't interpret this command.  I would suggest using the 0xFA command on routes 10+ as I am not sure if the devices in the field will also interpret a 0xFE route command in addition to the Base3 firing the switches from its route record.

Wow, so complicated....

@kwilliamm posted:

@cdswindell I'm very interested in your python code to read and write the commands via the SER2.

Sharing code is always a humbling experience

FYI, the following code was actually generated by the AI assistant in PyCharm! So far we have traveled since I started programming for a living in 1979...

So, with that caveat, here is the code to fire Route 10:

import serial

def write_byte_sequence_to_serial_port(port, baudrate, byte_sequence):

    # Open the serial port

    with serial.Serial(port, baudrate) as ser:

        # Write the byte sequence

        ser.write(byte_sequence)

byte_sequence = bytes.fromhex("FED51F")

write_byte_sequence_to_serial_port("/dev/ttyUSB0", 9600, byte_sequence)

So some explanation. This code relies upon the PyThon package PySerial to do the output over the RS232 port of my Pi (which in my case is a USB - RS232 dongle). The helper method write_byte_sequence_to_serial_port writes a specified byte sequence out to the specified serial port on my Pi.

The line:

byte_sequence = bytes.fromhex("FED51F")

encodes the TMCC 1 command into a byte sequence that is sent to the serial port and read by the LCS SER2 device (and forwarded to my Base 3).

From the Lionel Legacy Command Protocol document, we can understand the 6 character hexadecimal value passed into the Python bytes.fromhex function (and in case others are reading this, a byte is comprised of 8 bits; 4 bits can be expressed by a single Hexadecimal (base 16) digit; 0 - F, so one byte can be expressed as 2 Hex digits; the string of 6 Hex digits above ("FED51F") thus represents the 3 byte TMCC1 command sequence; the route number, 10 in my case is expressed as 5 binary digits (0, 1), or 01010, and, as may make sense below, the first 4 of these 5 bits. 0101, are represented by the hex digit "5" ( 0*16 + 1*8 + 0*4 + 1*2 + 0*1)):

Byte 1: 0xFE - specifies the start of a TMCC1 command (page 3 of the document)

Byte 2: 0xD5 - the first 4 bits (0xD) specify the command is a route fire command; the 2nd 4 bits (0x5) are the 4 most significant bits of the 5 bit encoded route number.

Byte 3: 0x1F - this byte has the last bit of the route number, and a 2 bit command field, and a 5 bit data field (refer to page 4 of the Lionel documentation for an explanation of these bits...)

I hope this helps. The code isn't pretty and as the route number is "hard coded", is minimally reusable. But, when ran from my Pi connected to my LCS SER2, it did fire Route 10

My ultimate goal over the next sever months is to build a python package that:

  • exposes command line tools to flip switches, fire routes, and maybe fire accessories
  • provides classes that a developer could use to send Legacy commands via serial
  • sense button clicks and fire Legacy commands in response
  • provide a configuration language to specify the binding of a button press to the command to fire and the required parameters (route number, switch number and through/out, etc)

My goal is to be able to build a physical control panel, such as one I built for a DCC-controlled Z-scale layout I built with discrete hardware during the pandemic. Once I set up the GitHub project, I will post it's link.

  -- Dave



IMG_0038

Attachments

Images (1)
  • IMG_0038
Last edited by cdswindell

The RTE info (SW ##s, through/out) is stored in the Base logic.   When a RTE is fired, the SW command are sent with the programmed delay.  The TMCC1 Route Commands [1-9] will fire whatever is in the Base's table when used from the Cab1, Cab2, and Cab3.

I see that firing RTE 1 (and through 9) triggers the TMCC1 Route command:

7232.37 <-- D1 28 FE D0 9F 6B DF
   TMCC data: FED09F - (S) FED09F RTE 1 Fire!
47232.63 <-- D1 28 FE 4A 80 10 DF
   TMCC data: FE4A80 - (S) FE4A80 SW  21 Through
etc.

Firing RTE 10 (and through 99) triggers an undocumented TMCC extended command:

47434.58 <-- D1 28 FA 6C FD 75 DF
   TMCC data: FA6CFD - Extended block 'FA'6CFD 110110011111101
47434.71 <-- D1 28 FE 4C 00 8E DF
   TMCC data: FE4C00 - (S) FE4C00 SW  24 Through
etc.

I guess you will have to maintain RTE table is your device for route IDs > 9, or explore the extended commands.



John, I can confirm the extended route command did work and I was able to throw routes >= 10 via the LCS Ser2 connected to my base 3.

I could also throw routes 1 - 9 using the TMCC1 syntax. I defined these routes via my Base 3, so I am guessing Lionel allows you to throw routes 1 - 31 through either syntax.

  — Dave

Add Reply

Post
×
×
×
×
Link copied to your clipboard.
×
×