MERG CBUS/VLCB hardware support

Hi All,

I’m looking into support MERG CBUS/VLCB in Traintastic. I spend some time reading the protocol documentation and made a start with building the basic pluming in Traintastic to support CBUS/VLCB.

Real CBUS/VLCB testing is a bit an issue as I don’t have any CBUS/VLCB hardware available yet, so if you have CBUS/VLCB hardware and wanna help, please let me know!

Hi Reinder,

I’ve forked the repository and pushed my files, also did a pull request.

As I see, you have also prepared files for engine message. I have no central station for CBUS. There are the MERG CANCMDB and the CAB Control as Kits for members of MERG. My focus is currently on control and feedback devices. I plan to build some own devices with more ports, i.e. with the PIC18F47Q83 - 128kByte Flash, 13kBytes RAM, 1k EEPROM, 40 Pins DIL Package and up to 36 I/O pins. MERG uses only the smaller 28Pin controller within their kits.

I am considering whether to order the CANCMDB control unit and the CANCAB2 hand controller. The CANCMDB has only a small H-Bridge for max. 1A, that’s not much. I am thinking about a central with the PIC18F47Q83 and my own booster, which has a H-Bridge without integrated bridge controller would be good for 5-10A with the MOSFET’s.

But I think, for testing purposing, it would be nice to have the original kits, too.

I have the complete equipment, Scopes, Logic Analyzer, PIC progammer and so on for Hardware testing, so I can take this part.

Greetings,

Tom

Hi Tom,

Saw the PR, after a quick scan it seems to be a copy of Traintastic DIY with a few minor changes, I’ve pushed my skeleton for CBUS/VLCB support, I think is it is best we work from that (don’t want to be rude ;)).

It has:

  • IOHandlers for CANUSB and CANEther
  • Track on/off logic
  • EStop logic
  • Rx/Tx logging option
  • At startup it send a RSTAT and QNN message.

Nothing is tested yet, so free to give it a try and report or fix the issues :slight_smile:
The CANUSB serial settings are now fixed at 115k2 8N1, just a guess.
For CANEther, there is probably a default port number, for now it is 0.

What is missing:

  • Locomotive control via DecoderController
  • Input monitoring via InputController
  • Output control via OutputController
  • Simulation support

I’m also considering to become a MERG member and order some hardware, based on some prices I’ve seen (modules are not that expansive), its still about 150-175 EUR for Membership+CANVOUT+CANCMDB+CANCAB2E+CANUSB+shipping+import+vat :frowning:

It would be great if you can do testing (and fixes :)), using the logging feature it is possible to log all traffic, I can use that to build a simulator which makes it easier to debug/test without hardware. Traintastic has protocol level simulator for all most all supported protocols :slight_smile:

We can start with the input/output, the things you need first, then do the CANCMDB later on.

A question:
Traintastic normally uses channel + address for identifying inputs/outputs.
How does input/output identifying work on CBUS/VLCB? Is is node/module based?

Best regards,
Reinder

Moin Reinder,

I worked as IT-Security and IT-Infrastructure Admin, not as programmer and I’m really not a C++ programmer, especially not with modern software design. I have many years of experience with C in hardware-related environments, i.e. microcontrollers, 8051, 68HC11, ATMega, a little bit STM32 and system-related programming under various operating systems in C. Also in Electronics, analog and digital. PIC controllers are new to me, Harvard architecture instead of von Neumann, which is quite a change :wink:

When I asked you if you would support CBUS/VLCB, I didn’t expect you to write code; I thought I would have to do it myself. So it’s really nice, that you build the skeleton for CBUS/VLCB, thank you very much!

CBUS/VLCB uses the producer/consumer model. So you don’t need to address a node, you have to teach the node on which event from which node it has something to do. But CBUS has also the possibilty to do direct addressing. There are two address configuration modes, SLiM with DIP Switches and FLiM. I think SLiM can be ignored; new nodes all use FLiM.

Normally you have <OpCode><Nodenumber Hi><Nodenumber Lo> followed by the Eventnumber, where the nodenumber is the producer node. A consumer could react on this event. MERG has a tool to setup the nodes and to teach them, what to do. FCU is the older one (only for Windows) and MMC is the node.js based tool for all platforms. Also JMRI has integrated these functions. I don’t know (and understand) how complete Rocrail has these functions.

With direct addressing <OPCode><NN Hi><NN Lo><Devicenumber Hi><Devicenumber Lo> the nodenumber will be ignored, there are OpCodes for this, i.e ASON (98). The different is, that every input and every output from a I/O node has an own device number.

The system is very flexible, I haven’t read all the docs until yet. I think the primary document is the Developer’s Guide for CBUS. I consider this to be basic documentation, also for VLCB.

However, I read the documentation more from a microcontroller perspective :wink:

Greetings

Tom

PS: This editor kills text within <> if it is not formated as Code.

Moin Tom,

Happy to assist, I like the puzzle of a new protocol and fitting it into Traintastic’s HAL, with each protocol the HAL is challenged as each protocol has its own specialties which somehow must be made general so the rest of the software doesn’t have to know about the hardware. So feel free to ask question if you need help on the CBUS/VLCB implementation, or just provide feedback and I do most of the implementation, that is also fine :slight_smile:

I’ll read the Developer’s Guide for CBUS with the PC perspective then :wink:
Need to build a mental model of the system, once it clicks in my head I’ll know how to implement it into Traintastic.

The CBUS/VLCB interface has a send() function (since Saturday), it can be used to send messages directly to CBUS/VLCB for testing/experimenting.

Example using a push button on a board:

local cbus = world.get_object('cbus_1')

world.get_object('push_button_1').on_pressed(function ()
  cbus.send([0x0A]) -- Request ESTOP
end)

The send() argument is a table with the data bytes in the CAN message.

Greetings,
Reinder

Did some reading on the short/long events.

For the OutputController two Channels are needed:

  • Short event
  • Long event

Address is the event number/device number. (the label should change then for clarity)

The nodeId for Traintastic sending is 0xFFFC (CANUSB).

The you’ll get something like this (edited the screenshot a bit):

As there is support for sending raw DCC commands, two additional channels can be added as well:

  • DCC Accessory
  • DCCext (RCN-213)

@DL7BJ would this work for you / CBUS?

Moin Reinder,

I’ve tested ACON, ASON and ASOF. I have configured the CANVOUT node with MMC and three events.

There are the events 14 and 15 as short events and the event 16 as a long event. Short events don’t use a node number, every node with configured short events reacts on this event. Long events need the node number.

This test was made with DecoderPro (JMRI)

JMRI  > >  CBUS |  ASON EN:15   Short Event On ON event using the event, no node. [+15] Dyn Prio: 2 Min Prio: 3 CAN ID : 126 [5fe] 98 00 00 00 0F RTR:N  

JMRI  > >  CBUS |  ASON EN:14   Short Event On ON event using the event, no node. [+14] Dyn Prio: 2 Min Prio: 3 CAN ID : 126 [5fe] 98 00 00 00 0E RTR:N  

JMRI  > >  CBUS |  ASOF EN:14   Short Event Off OFF event using the event, no node. [-14] Dyn Prio: 2 Min Prio: 3 CAN ID : 126 [5fe] 99 00 00 00 0E RTR:N  

JMRI  > >  CBUS |  ASOF EN:15   Short Event Off OFF event using the event, no node. [-15] Dyn Prio: 2 Min Prio: 3 CAN ID : 126 [5fe] 99 00 00 00 0F RTR:N  

This switches Out 7 and Out 8 ON and then Out 7 and Out 8 off, without a node number, only the event is needed. The CAN ID 126 is the ID of DecoderPro.

With the long event I have to add the node number of the node, which should do the event, as you see the node number is 1:

JMRI > > CBUS | ACON NN:1 EN:16 Long Event On ON event using the node and event. [+n1e16] Dyn Prio: 2 Min Prio: 3 CAN ID : 126 [5fe] 90 00 01 00 10 RTR:N

Both options are well running with DecoderPro.

Then I add a point to Traintastic.

This runs also very well and toggles Out 7 and Out 8 with the short events 14 and 15.

026-03-06 22:46:31.487358 cbus_1 D2001: TX: ASOF node=65532 device=15 [99FFFC000F]
2026-03-06 22:46:31.487391 cbus_1 D2001: TX: ASON node=65532 device=14 [98FFFC000E]
2026-03-06 22:46:34.625796 cbus_1 D2001: TX: ASON node=65532 device=15 [98FFFC000F]
2026-03-06 22:46:34.625830 cbus_1 D2001: TX: ASOF node=65532 device=14 [99FFFC000E]

But a problem exists with the long event:

2026-03-06 22:48:03.996735 cbus_1 D2001: TX: ACOF node=65532 event=16 [91FFFC0010]
2026-03-06 22:48:05.549055 cbus_1 D2001: TX: ACON node=65532 event=16 [90FFFC0010]
2026-03-06 22:48:07.191648 cbus_1 D2001: TX: ACOF node=65532 event=16 [91FFFC0010]

Traintastic sends its own node number here, not the number to which the event should be sent.

The definition of short event and long event here by MMC is slightly different from that in the developer’s guide. Short events are based on the P/C model, long events on hardware addressing.

If you switch to short event, the node number is always 0. So traintastic should use with long events the node number as address to which the event should be sent, not the own number.

I am still wondering whether the configuration of the nodes should be implemented in Traintastic or whether it would be better to use MMC for this. This could be quite complex, because various nodes can have completely different settings, including the teach mode. At the moment I think the configuration of the nodes with MMC is ok.

But, it’s very nice that the basics running fine!

Greetings,

Tom

Moin Tom,

Many thanks for testing it!, did you need to make any changes to the CANUSB iohandler, or did it just work?

Are Short event / Long event the common terms to use? If so, I’ll name them like that in Traintastic too.

For Long events adding a single Node number property between Channel and Address would work I think. The only limitation then is that e.g. a signal can only send Long events to a single node, mixing is not possible (but that would be weird anyway.)

Have you tried the Lua send() function?

When the CBUS/VLCB interface goes online it also sends a QNN, does the CANVOUT module respond to that? It would be nice to have a list of nodes/modules in the interface dialog. (That info can also be used for the node option for long events.)

I agree with you, using MMC for configuration is best. Traintastic should focus on control and automation.

Greetings,
Reinder

p.s. I just commited basic support for CANCMDB :slight_smile: