A project for that unloved Pi-3 or Pi-4!
I'm aware of at least two companies who sell LED Matrix Departure Boards to have on the wall at home... being a long-time train enthusiast I'd often thought of having one, but found the price and subscriptions a bit off-putting.
So being a techie I decided to make my own, thinking "How Hard Can it Be".
Detailed step-by-step instructions and code to build your own are on my website: anotherpartialsuccess.com. All free - just buy the parts and away you go!
Thought I'd share with fellow Pi enthusiasts and for anyone who's wanted to build their own!
This probably isn't as all-singing all-dancing as the commercial products, but it does the job and I'm pretty happy with it!
You will need:
- Pi4 or Pi3
- 3 or 4 HUB75 LED Matrix boards. (Ali Express is good)
- A HUB75 HAT from Adafruit or ElectroDragon (links on my site)
- A 5V, 5A power supply
- A free subscription to the data on the Rail Data Marketplace
Hardware Summary
It's a good idea to buy the full number of matrix panels you need in one go - that way you can be sure all the colours match. Not a big deal for a Departure Board, but worth a mention!
Connecting the panels is pretty straightforward as most are supplied with all the cables you'll need.
I've provided some scripts to create 3D-printable 'joiners' so you can bolt the panels together - in the absence of a 3D-printer there are many, many other options for the creative mind!
One thing worthy of note is the power. A Raspberry Pi doesn't have enough power to operate the matrix panels, so you'll need something with a bit of oomph. I use a bench-top power supply and normal operation is about 2A.
However you'll likely want to do other things with the panels in which case you'll need more - the most I've peaked at is about 4.5A and that's with all the LEDs on!
The Adafruit HAT does a fine job and is readily available. The alternative is from ElectroDragon and is better in that it can support up to three rows of panels and is a good deal cheaper. The downside is that it'll take a while to come from Hong Kong.
I've used both and ultimately it comes down to how much you want to spend and how long you want to wait.
For both of these the Pi gets powered via the Hat, so no need to have a separate Pi supply.
Pi Configuration
You'll need to install a minimal OS and switch off anything you don't need so that all CPU power can go to the departure-board processing.
No desktop, bluetooth, sound and so on - I've provided instruction on this.
After that it's a case of installing the dependencies and the Departureboard code from github.
Display Configuration
Either via a config file or a very simple UI - all you need to do is set the station you want, the platform you want (or it'll do all platforms), the dimensions and number of LED panels and the type of Hat and away you go!
There are a myriad other parameters to tune - things like the speed of the text scrolling, the gap between data-refresh and so on. Have fun!
Challenges and the Journey
I wrote the code in C++ for performance reasons and because I like C++!
There are a lot of projects written in Python, however I wasn't sure on the performance.
Parsing the data
The first version of the project used the 'garden-variety' departure data. This was fine, but it did't allow me to do things like report which stations a train was between... so I started on Version 2 which uses the "staff" data from the Rail Data Marketplace.
Great data, but there's a lot of it... so I had to engineer a lazy-loading cached parser.
What this does is cache the data about a service which doesn't change - scheduled time, it's ID, how many coaches it has and so on.
This means that on a refresh I could skip anything which I already had cached and only add new or delete old services.
The other data is 'things which change' - arrival time, cancellation, where the train is and suchlike. This is lazy-loaded so is only hydrated when needed.
A big change as the first version used to work out everything for every service - not scalable on a limited resource like a Pi!
Displaying the data
In the first version it constantly refreshed the whole display - this was kind of OK, but it meant that scrolling would get slow.
In the second version I only refreshed display elements which changed - mainly the scrolling text and the periodic change of Services.
The challenge was to write drivers for each type of display (text, scroll, clock) without having to duplicate loads of code.
Efficiency
This was somewhere I spent a lot of time as I wanted to squeeze as much as possible out of the Raspberry Pi.
Highlights were to fork of the API-refresh routines, to avoid the whole thing pausing while the API call was made, the display-management (per above) and caching, and down to creating a Hot/Warm/Cold cache for often-used data
Overall...
... I had a lot more fun making this than I would have done buying one and sticking it on the wall... and every now and then I think "how about I can make this change/optimisation" and I go and get stuck in again.
I'm sure that the commercially available Departure Boards which are advertised on social media and whatnot have superior functionality, but for the cost, making and result I think this is a pretty decent substitute.