Third party cookies may be stored when visiting this site. Please see the cookie information.

PenguinTutor YouTube Channel

PyVLCB / CBUS GUI Application

I'm currently working on a GUI Application to use a Raspberry Pi to control a model railway using CBUS / VLCB.

This is currently in early development and I hope to update this with more information in the future. I have created some videos showing some of the challenges I faced, including trying to interpret the CBUS protocol and performance issues due to the software architecture.

Learning the CBUS protocol

In this video I explain about the steps I took to understand the CBUS protocol. This involved some reverse engineering through reading source code files, capturing traffic with Wireshark (see: using wireshark to monitor USB packet data), and finding useful documentation that explained the protocols.

Based on this I was able to create a GUI application that can send and receive messages to CBUS and can switch points and control a DCC locomotive. See below for the source code.

I've provided a copy of the document mentioned in the video: CBUS Developer Guide Version 6B

Software Engineering / Software Architecture / Programming Language

Raspberry Pi CBUS Model Railway API Server Architecture

In this video I explain some of the challenges that I faced in developing the program. This was down to some limitations of the programming languages and the architecture.

I first tried to have this all controlled from within the GUI. As the GUI was programmed in Python I was already aware of issues with Python Global Interpreter Lock (GIL) when using QThreadPool. Normally this can be avoided by using full multi-processing but due to the number of different processes and interprocesss communication this was too slow to be usable. I therefore looked at different client-server models. My first attempt used Zero Message Queue (0MQ), which worked initially but was too slow for the level of response I was hoping for. I had better success using client-server software using a Web API and a simplified server model. I tried using both C and Python code for the server. I'm likely to continue development if the Python version in future.

Refactoring the Code

I've continued developing the Python based server along with the GUI. I've increased the support for various CBUS features, including full support for controlling a DCC locomotive using the CANCMD2 CBUS DCC command station. This has gone well up to the point of creating code for the layout control panel, when I decided a different approach was needed.

As I'd been developing the code I was already aware that the amount of code in the MainWindow class was growing, and that it was becoming tightly coupled with several other classes. I'd put this off in favour of adding new features, but decided it reached a point where I needed to take a step back and refactor the code.

This involved a significant refactoring and redesign of many of the classes. The following video explains that it's taken a week and involved changing over 1000 lines, to provide an improved structure.

The main thing I achieved was to remove the mainwindow for needing to be passed to many of the features, this is to move it more towards the Model-View-Controller design pattern (MVC). I don't think I've quite reached he full sepearation that the MVC pattern provides, but it's certainly a lot less coupled than it as previously.

I've also moved the Device class to a DeviceModel based around the Domain Model design pattern. This is based around a singleton class which is shared with other classes removing the need to call this through the MainWindow.

Thirdly I've moved the communication between the various components to an Event Bus pattern. This fits in well with CBUS which uses a hardware event bus using a producer consumer model. Events from both the CBUS API and the GUI are published to the Event Bus, from where the various components (including API and GUI) listen for the events.

This makes it easier for creating different events and passing them to the relevant consumers, but will also be important when I look at adding model railway automation as the project progresses.

The code may not be completely decoupled and still has a few things that could be improved but is certainly in a much better state than it was before. This has been a worthwhile excercise and will hopefully result in better progress and cleaner code in future.

Source Code for PyVLCB

Whilst this is currently work in progress I've made all the current source code available on GitHub.

About CBUS

The following information is from my MERG / CBUS model railway page.

DCC Digital Command and Control for Model Railways with Raspberry Pi

This video explains about the CBUS DCC model railway controller kit from MERG. In the video I look at three kits, including a DCC command station, handset controller and a RJ22 connector kit. This provides a way of controlling model railway DCC locomotives and accessories, using CBUS and a home made controller. Generally the kits are fairly straight forward, but the hand-held controller is significantly more challenging to solder. I’m fairly proficient with a soldering iron and I found some of it difficult, although it shouldn’t be beyond the abilities of most.There is an alternative if you are interested in computer control.

See the following link to understand more about rotary encoders.

3D printed holder for DCC controller

I also designed a holder for the DCC controller so that it could be mounted on the back of the baseboard. I had to make some adjustments, but I'm happy with the current version. See the video below for more details.

You can download the STL files and the latest version of the FreeCAD design from Thingiverse. See the link below.

More Information

Find out more about MERG or about my other model railway projects.

Related projects

Also see:

Future projects

For the latest updates please:
Subscribe to the PenguinTutor YouTube Channel
and
Follow @penguintutor on Twitter

Previous Using Raspberry Pi with JMRI
Using Raspberry Pi with JMRI
Next 3D / 2D Design and 3D printing
3D / 2D Design and 3D printing