Blog IndexPosts by TagHome

Train Departures Board at Nottingham Hackspace

Posted <2024-03-02 Sat 18:38> by Aaron S. Jackson.

This is a project that ended up coming together really nicely. Nottingham Hackspace has had a railway departure board hanging off an RSJ for the past 10+ years. Unfortunately it's never done anything! I decided that we should change that and removed one of the LED boards to figure out how it was being driven.

Each side of the departure board consists of 4480 LEDs, split across two chains which are driven in parallel. The ASCII diagram below shows how these are configured.

|  A2              |  A1              |   A0             |  <--- Input
|  A5              |  A4              |   A3             |
|  B2              |  B1              |   B0             |  <--- Input
|//////////////////|  B3              |//////////////////|

Each chain has the following data lines:

The BCD lines are fed into a BCD decoder (CD4028BCN). The decimal outputs go off to a UDN2981A octal source driver, which switches 8 MOSFETs (IRF540) - even though this display only has 7 rows. The idea is to write out 384 pixels, pulsing the clock for each one, then update the BCD lines, then strobe - doing that quickly enough will draw the buffer. I got quite confused though. I had incorrectly assumed that all of the data lines were using 5V logic levels. I could tell that the mystery pin was high because I'd logged this with my logic analyzer, but it was actually slightly higher than high - about 7-8v. This is the power rail for the UDN2981A, and is roughly the voltage that gets used to drive the MOSFETs - once I realised this I was flying.

I decided to design a small circuit board in KiCAD to act as a breakout for the IDC headers, and to provide a stable voltage for the mystery pin. I think it turned out quite nice :)

Embarrassingly, in this photo, the LM317 voltage regulator was installed backwards, leading me to one night of confusion. But then I was off, writing Arduino code. I decided to use an Arduino Uni R4 (WiFi) for this project - they are super fast and the 5v voltage levels worked out ideally for the CMOS logic in the display. The main purpose of the display is to show Discord messages in real-time (the Discord bot I wrote earlier pushes these to MQTT), but I also wanted to display live train departures from Nottingham Railway station every 5 minutes or so. Fortunately, National Rail provide free access to their API, as long as you agree to their terms. A small script getting called by cron every minute does the job nicely, and pushes a condensed departure board to MQTT.


API_KEY="You can't have this"

departures=$(curl -s -H "x-apikey: ${API_KEY}" "${URL}" | \
  $HOME/jq -r 'try .trainServices[] | { destination: .destination[0].locationName, std: .std, platform: (.platform // "-"), etd: .etd }' | \
  $HOME/jq -sc)

mosquitto_pub  -t "nh/tdb/${CRS}" -m "${departures}"

At this point, I had something working, but it was a tad flickery and required some optimisation. I did a few things:

The display now runs at about more than 250 frames per second and my phone's "Slow Mo" mode is not able to see the rows being drawn. It does still blank briefly every 1.5 seconds for the mqtt.loop() call (I'm using PubSubClient).

So, here are the results.

I also made a demo video and posted to YouTube, but this was taken before the optimisations had been made.

Wanting to leave a comment?

Comments and feedback are welcome by email (

Related posts:

Tags: electronics

Blog IndexPosts by TagHome

Copyright 2007-2024 Aaron S. Jackson (compiled: Sat 2 Mar 19:08:03 GMT 2024)