This project builds up on the great work done by @harkle for controlling a single split-flap module and expands it to control an entire display with several modules.
Some time ago, I took over an old split-flap display from the Swiss federal railways SBB. Based on the available flaps, I concluded that it used to hang on platform 1 of the Seuzach station. The display came as dismounted and includes 12 split-flap modules (six per side) with the entire electronics. Lights, ventilation, temperature sensor, and heating are all intact. Also 15 years worth of dead spiders, flies, bugs, and dirt came with it. The thing weighs about 150kg and measures 208 x 47 x 58 cm.
I used the following hardware.
To run from a computer:
- USB to RS485 adapter https://www.digitec.ch/de/s1/product/oem-yf-usb-zu-rs485-adapter-diverse-elektronikmodul-5999133
To run independently:
- Raspberry Pi 4 https://www.digitec.ch/de/s1/product/raspberry-pi-4-4g-model-b-full-starter-kit-armv8-entwicklungsboard-kit-11764848
- Raspberry Pi 4 ventilated case https://www.digitec.ch/de/s1/product/joy-it-acryl-gehaeuse-mit-luefter-fuer-raspberry-pi-4-gehaeuse-elektronikzubehoer-gehaeuse-11621552#gallery-open
- Relay (to control the light) https://www.digitec.ch/de/s1/product/sertronics-relais-modul-stromkomponente-elektronikmodul-8194039
- Jumper Cables https://www.digitec.ch/de/s1/product/play-zone-jumperkabel-elektronikkabel-stecker-5997953
The data cable coming from the station was cut, otherwise everything remained in there. It took a while figuring out what the individual components do and tracking down every cable.
I connected the serial output of the Raspi (GPIO 14/15 = pins 8/10) to the old data output, from where it is conducted to all modules in series. Each side is served through a separate channel, i.e. every module of one side sees all the signals, but only reacts on the signal that is preceded by its address (see the doc for a detailed explanation on the commands).
Instead of using the serial ports of the Raspi, you can also use a USB-RS485 converter plugged directly to your computer. You might need to unlock your serial device (see Debugging section below).
There is a 12 V power supply for the ventilation. The modules get 35 V over a transformer. A 230 V power socket next to the fuses can be used to power the Raspi.
The lights are directly connected to the main 230 V supply. I bridged the supply of the lights over a relay (normally open) that is controlled by the GPIO 17 (pin 11, pins 1 and 9 for power).
A heat sensor switch is located on both sides in the center top. If the temperature inside the display gets too high, the four ventilators are turned on. They consume around 135 W.
A resistance heating surrounds the glass on both sides. It consumes around 250 W.
The software from @harkle is a Node JS application that allows to control a split-flap display consisting of several modules via serial port. It offers a webinterface, and two API (Websocket and REST). I extended the existing code to communicate to all modules and added new modes to play with it.
The easiest way to deal with node and npm is via nvm.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
Restart your terminal and run
nvm install 10.20.1
npm install
This should install node version 10.20.1
and npm version 6.14.4
.
The configuration of the modules is read from the database in config/modules.db
. Change the configuration of your modules in the database to reflect your setup. There are three tables:
-
modules
with columnsaddress, type, bladeCount, moduleWidth, moduleColor, textLanguage, is_used, serial_address
e.g.
3|train|62|3|blue|de|1|/dev/ttyUSB0
-
moduleData
with columnsmoduleAddress, bladeId, text, textColor, backgroundColor
e.g.
3|4|ICE|white|red
-
colors
with columnscolorId, description, hexCode, redDec, greenDec, blueDec
e.g.
2|blue|2d327d|45|50|125
The module address is usually written with pencil on top of the module. Set
is_used
to1
if you want to control it. Possible types arehour
,minute
,delay
,train
,via
,destination
,clock_hour
,clock_minute
,alphanumeric
.
Start the application by running
node server.js
The interface is served on http://localhost:3000
, accessible from a browser with any device connected to the same network.
You can control the display either through the web interface or via command line.
Commands:
help [command...] Provides help for a given command.
exit Exits application.
status show module status
light <status> turn the light on/off
reset reset module position
manual <command> <address> [value] send manual commands
message [address] get current message
position [address] get module position
list <address> get module messages
find <address> <string> move the module <address> to searched <string>
step step the module 1 step ahead
move <address> <position> move the module <address> to <position>
time <action> display the time
date display the date
timetable <action> get and display timetable
schedule <from> <to> get live schedule
weather <location> get live weather data
Examples:
> light on % turn on the light
> manual 0xC0 0x03 0x13 % move module 3 to position 19
> list 4 % list texts of module 4
> find 3 ICN % find and display ICN on module 3
> move 2 20 % move module 2 to position 20
> time start % start displaying the time
> timetable stop % stop displaying the timetable
> schedule romanshorn zürich % show next connection from romanshorn to zurich
> weather paris % show current weather in paris
You can find the documentation how to send commands here.
The time
and date
command send to the additional modules that I have ontop of the display.
The command timetable
displays and updates the predefined timetable from the file config/timetable.json
. The command schedule
makes an API request to https://transport.opendata.ch/ and displays the time, delay, train types, via stations, and destination using the available flaps. The weather
command requires an API key set in config/api_secrets.json
as:
{
"api_keys" :
{
"openweathermap": "<your api key>"
}
}
You get an API key by creating a free account on openweathermap.org. The additional symbols required to display the weather can be added on the flaps by hand.
- Problem when running
node server.js
Check that you use node and npm versions compatible with the code. Latest version do not work (yet).
- Problems running
npm install
Try: npm audit fix
then npm rebuild
- Connect serial device with USB adapter
Summary
lsusb
sudo modprobe usbserial vendor=0x<vendor id> product=0x<product id>
dmesg
- Serial device is locked
sudo su
cd /dev
chown username /dev/ttyUSB0
or
sudo usermod -a -G dialout your_user_name
followed by a proper logout.
- g++ required for module onoff
Run apt-get install gcc-c++
- Turn on serial hardware on Raspi
Run sudo raspi-config
Choose 5 Interfacing Options
→ P6 Serial → No (shell) → Yes (hardware) → OK, then run reboot
This work is licensed under the MIT license. Feel free to do whatever you want with it.
The documentation for controlling the modules is the result of hard work and reverse engineering by @eni23 and licensed under GPL-3.0.
The station clock used in the web interface is generated using the tool from Rüdiger Apple http://www.3quarks.com/de/Bahnhofsuhr/ and licensed under CC BY 3.0 DE.
The autocomplete code is taken with courtesy from @kasperite https://stackoverflow.com/questions/53603611.
This project is work in progress and a lot of trial-and-error. Don't hesitate to ask if you have any question, simply drop me a message at [email protected] or open an issue. I hope that I can help.