Skip to main content

A new generation of Node.JS powered control of your TMCC/Legacy/ERR engines is here! Layout Bridge Control (LBC) brings the power of different control systems under a common control schema and provides extendable methods via a REST API that you can directly interface with!

LBC is now available at the Github link below!

Github Repo link: https://github.com/SirCaptainT...ayout-Bridge-Control

Setup Guide: https://github.com/SirCaptainT...l/blob/main/SETUP.md

Current Control Systems in progress:

  • TMCC (Partial)
  • Legacy (Partial)
  • ERR - 0% Complete

Current Controller Methods (Documentation pending for API's):

  • Dualsense 5 (Playstation 5 Controller)
  • HTTP Web API

Additional Support needed:

I need another CAB-2 Base for testing, if anyone would like to help support this very much still in alpha development project, and has one they wouldn't mind parting with for a fair price: https://ogrforum.com/...-1l-base-legacy-base for more info. (I've had to rip the legacy base out of my layout to start doing CAB-2 development since I couldn't find one that wasn't wildly overpriced)

Last edited by SirCaptain
Original Post

Replies sorted oldest to newest

@SirCaptain,

This is certainly one creative way to solve the wireless-handheld-going-out-of-production problem.

I'm looking forward to trying out your solution, however not having any experience with JavaScript, I'll have to leave the final integration to others.

Thanks for the effort.  We're cheering you on.

Mike

Last edited by Mellow Hudson Mike

Yep, it's relative steps, so it just sends the step up or step down command.  That's also why there's an R100 engine type in the CAB2, it's specifically for the ERR 100 step mode, though it's also used for TAS and K-Line cruise.

Awesome thanks! I'll have to add the TMCC1 & 2 increment and decrement commands in to the serial interface (was using abs up till now as the app was keeping track of speed), after that should be drop and run into the controllers. Would be nice if Lionel implemented a native abs speed for ERR 100 steps (TMCC 1.5?), But I can live with desync on ERR if it occurs. (ERR engine owners may not agree with that statement though!)

LBC v0.0.2-alpha released

  • Updated Controller UI - Added dividers, added extended power/on options, added speed step/abs step controller (disabled right now), added whistle slider / toggle depending on Legacy/TMCC status
  • Updated whistle handling on controller, now resets to 0 rather than waiting for a full horn interval to play if the whistle analog thumbstick is released.
  • Fix controller causing crash on invalid engine index
  • Fix skipped steps in router handling
  • Other bug fixes / etc

A setup/run guide will be coming soon for those who want to help break things with me. Additionally, persistent serial / engines are coming soon, once I decide on using a DB or flatfile for config storage.

Post #2 will be updated with the new image for the Web UI, video coming shortly (hopefully?)

Last edited by SirCaptain

In EngineUtil.ts, you have the Legacy max speed set to 127.  That value should be 199.

The Highball button on the Cab2 brings the absolute speed step to 199.  See the attached log for Engine 56.  I pressed Startup, then pressed Highball.  The Cab2 adjusts the absolute speed step at regular intervals (typically less than 300 milliseconds) and adjusts the engine labor periodically.

Log format (three columns):
Milliseconds since previous command, WiFi packet (hexadecimal chars), Text description of the command
00021896    D128F871FC73DF    Engine 56 StartUpSequence2(ImmediateStartUp)
00022532    D128F8700070DF    Engine 56 Set Absolute Speed Step 0
00000056    D128F871A7C8DF    Engine 56 RPM level 7
00000010    D128F870F080DF    Engine 56 Train Brake Level 0
00000034    D128F870F080DF    Engine 56 Train Brake Level 0
00000042    D128F870CCA4DF    Engine 56 Set Momentum 4
00000124    D128F870016FDF    Engine 56 Set Absolute Speed Step 1

The actual bytes transmitted as the TMCC signal are encapsulated within the packet framing.  For a Legacy engine, they begin with F8.
D128F870016FDF  packet (Engine 56 Set Absolute Speed Step 1) contains the three hex bytes F8,70,01 that are transmitted by the base.

The Cab2 finishes acceleration with D128F870C7A9DF (Engine 56 Set Absolute Speed Step 199) , F8,, 70, C7 where 0xC7 == 199 decimal.

The log illustrates, in part, why developing a 3rd party Legacy remote is non-trivial.  The acceleration is punctuated by engine labor levels and is governed by the momentum assigned to the engine. The remote exchanges an engine profile from the base's tables.  Absolute speed acceleration/deceleration is performed by the Cab2 remote.  The context of the buttons shown in the Cab2 is governed by the base record for the engine.  The more I play with the Cab2 remote features and look at the logs showing how it controls engine behavior, the more I appreciate the logic within the device.

Looking forward to testing your software.

Attachments

Last edited by Tracker John

I am definitely seeing some complexity in the way they handle operations as speed increase/decreases/etc. As I continue to develop the serial interface side it will likely require non-trivial refactoring to support more complex operations down the road.

And yea, just getting to this point has taken hours upon hours of work, and it's only at the basic level of speed control, direction, bell/whistle, and power. Good news is the more I work with it the easier it gets. Still many revisions away from what I would consider a proper piece of software.

Thanks for a capture from the wifi LCS module! I don't have a wifi module, and Lionel is still ghosting me on the LCS Dev API so it's always helpful to get more captures. (Aside from what I can read from the CAB-1 base / SER2 & BASE-2)

Will update to 199 speed steps on 0.0.3 (or someone can make a PR and update it)

You need a WiFi module (or wait for the Base3) to understand the the data stored in the base and communications with LCS modules such as sensor tracks.  Wireshark and the LCS WiFi Monitor are your tools for that.  For engine/train/switch/acc/route control, the serial interface and the Legacy Protocol Specification is fine.

Yep I was hoping to pull engine info from the base, but have to put that on the backlog for now

Ended up ordering a Wifi LCS module, figure in the long run it will make debugging serial much easier. (I REALLY wish there was an ethernet equivalent module, but so be it). Next week when it gets in I can start doing deeper inspections into the Base communications between LCS modules, unless Lionel gets back to me quicker.

v0.0.3 should release sometime later today with the updated changes and more fixes

LBC v0.1.0-alpha released (First minor version increment!!!)

Many Web UI improvements relating to the engine controller - it now supports most common functions (engine power / direction / speed / whistle / bell). Post #2 will be updated with the latest screenshots

  • Update Web UI: Speed commands added, better labeling, whistle steps display added
  • Update API: Added more routes for serial control, engine control
  • Bug fixes in Web + App to improve reliability
  • Updated halt command to scale slowdown by current engine speed, rather than decrementing by 1
  • Created serial utils file and moved common functions out of serial interfaces
  • Add support for running via other devices outside localhost (currently a hacky local IP solution)

A setup guide will be coming soon for those that want an easier path to startup. I've also been able to get in touch with Dave Olson regarding the LCS API, more  to come on that soon.

This is a more modular setup.

At the core is a Node.JS app (think of this as the "brain"). This app communicates back to the serial coms for legacy/tmcc. (Legacy via the SER2 LCS module). The core communicates internally to an Engine controller that houses the logic for serial commands / keeping track of engines. This logic is then exposed via friendly-er-ish methods to "controllers" that tell the engines what to do via these exposed methods.

You then have modular controllers.

I currently have built 2 so far:

  • Dualsense 5 (Playstation 5) <- the one you're probably interested in
  • HTTP Web (REST API)

Setup wise here's the hardware requirements:

  • TMCC: USB-RS232 Cable, TMCC Command Base
  • Legacy: USB-RS232 Cable, LCS SER2 module, Legacy Command Base (Not sure if CAB-1L base provides same API as Legacy Base), PDI power cable
  • Dualsense 5 Controller: PS5 Controller / USB-C Cable (Or bluetooth - although I ran into some bluetooth problems untethered, may just be me)

Software wise requires the following:

  • Git (Git bash as well for running)
  • Node.JS v16
  • yarn (Alternative to npm)
  • Serial drivers for your RS-232 cable (If your OS doesn't install them by default)


I'll write up a proper explanation / setup guide after I get off work to go more in depth. But for the most part you can get up and running within minutes (unless you're on dial up - gonna be a while to download things). My main goal was to make this as "Plug and Play" as possible, and I'm exploring ways to make it more portable so you could run on a SFF / SBC in case the space near your layout/Command base doesn't allow for a bulky tower / laptop to sit connected.

@SirCaptain posted:

At the core is a Node.JS app (think of this as the "brain").

So this is a Java application? or like a smart phone app?

@SirCaptain posted:

This app communicates back to the serial coms for legacy/tmcc. (Legacy via the SER2 LCS module). The core communicates internally to an Engine controller that houses the logic for serial commands / keeping track of engines. This logic is then exposed via friendly-er-ish methods to "controllers" that tell the engines what to do via these exposed methods.



So Node.JS communicates with the Dualsense 5/ HTTP web page and commands (such a whistle or accelerate) are discussed between the two, then Node.JS sends that back to CAB2, which broadcasts the command?

I am more interested in the Dualsense 5 but that's mostly because non-model railroader people are going to be more confident running trains for the first time because most people my age (30ish) have held a video game controller at some point. The CAB2 is intimidating at first. But most of us had a video game console by the time we were 5 years old. But I figure an HTTP web page will have massive benefits if it means JMRI or Raspberry Pi/Arduino integration. I could achieve my own dream of delivering/picking up virtual cargo haha

I've added a setup guide for those brave explorers who wish to become alpha testers: https://github.com/SirCaptainT...l/blob/main/SETUP.md . - Note: I am not super-great at documentation (insert self-documenting code joke here). If something isn't clear, feel free to let me know / or create a PR and update the documentation. I'll make a video soon of a basic setup guide

@BillYo414 -

The core Node.JS app controls the following:

  • Engine internal control (serial, engine management)
  • Serial Communication with the command bases/LCS modules
  • REST API Routes
  • Dualsense 5 API (Dualsense will -very- likely get moved out of here soon, but it's tucked in nicely for now)

The web Node.JS app controls the following

  • Frontend for the app: Exposes user-friendly menu options for configuring the engines/serial/controller
  • Communicates with the REST API Routes exposed in the core app

The lifecycle for a request looks like the following:

  1. web: req submitted (ie: /engine/control -> setSpeed -> 2)
  2. app: REST API receives request, sends to middleware
  3. app: middleware figures out what the request is trying to do (ie: "setSpeed", "2"), sends to API controller
  4. app: API Controller in turn parses it further / error checks (ie: "setSpeed": "ludicrous" is invalid), then retrieves the active serial interface for the engine in question
  5. app: After retrieving the serial interface, call the appropriate interface command (ie: interface.setSpeed(engineId, 2))
  6. app: Interface then converts the data from human readable to machine readable using a blood sacrifice made to the serial gods ("2" is converted to a *******ized binary, back to number, then bitshifted into the speed command)
  7. app: Interface adds the command bytes to the interface command queue
  8. app: Interface serial queue loops every x ms (usually 50ms), retrieves 1 entry from command queue at a time
  9. app: Interface sends the buffers 1 by 1 every x ms write interval to the serial connection
  10. app: Interface removes the item from the queue and re-loops

All that an end user needs to worry about is Step 1: Which is sending the right data to the right REST endpoint. Right now the web app currently does this for you, so looking through that can give you an idea of how it can be used. So if you were interested in Arduino/JMRI control - you would just need to make the appropriate HTTP calls as needed. However more work would need done to ensure you "know" what engines are available, keeping track of their state, etc. (REST Endpoint exposes this data now)

A tidbit on the Dualsense 5 controller support, since you were interested in it: The dualsense API is console-only right now (so you stare at the screen to make sure things aren't hitting bumps in the road, but I'm looking to flex that out into another seperate app to make it a proper "external controller", but for now it lives in the core app. Think of it as living rent-free there for now but it's getting ready to get evicted to it's own house soon.

Last edited by SirCaptain

LBC v0.2.1-alpha released - LET THERE BE PERSISTENCE

  • (BREAKING CHANGE): API Routes now require the engine UUID passed as part of the req body, the API controller no longer contains knowledge of the active engine
  • Database Persistence added in the form of an SQLite DB. Engines / Serial interfaces will be stored here so when the program restarts, it will automagically pull applicable serial ports / engines and load them into running mode. Still haven't implemented the delete button, so if something breaks delete the "lbc.db" file in the /packages/app directory
  • Minor cleanup / bug fixes / code changes
Last edited by SirCaptain

LBC v0.3.0-alpha released

  • Dualsense migrated from core app to own package (@lbc/dualsense), uses REST API for communication back to core
  • Refactor apps to /core and /controllers workspaces
  • Change package naming to @lbc/<app>
  • Fix serial interface mismatch on serial reconnect
  • Add bell toggle to legacy interface / REST API
  • Under the hood fixes/improvements for com

Setup Guide updated for new package structure

Last edited by SirCaptain
@rplst8 posted:

P.S. TMCC-1 does support absolute steps in 32 step mode. This makes running MU consists with older locomotives much more reliable.

Yep I developed the TMCC interface with abs steps in mind. now I need to go back through and correctly set up relative steps so ERR-engines can work correctly (I don't have an ERR-based engine to test, but in theory if a relative step works in TMCC1 mode, then the ERR internally handles all that other magic for 33 - 100 "relative" steps, so I shouldn't have much work around that).

Odds are that will be part of the next minor version increment. I've started work on the DCS side which is an absolute behemoth to even try and understand, so brainpower is stretched thin right now. (Parsing through Mark's documentation @ http://www.silogic.com/trains/...tream%20Decoding.pdf & http://www.silogic.com/trains/...%20Command%20Set.pdf from http://www.silogic.com/trains/RTC_Running.html)

Last edited by SirCaptain

Add Reply

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