In this tutorial I explain how to build a train departures board using a Raspberry Pi, an I2C LCD, Python and the Tokyo Open Data for Public Transportation API.
To get up and running you will need:
A Raspberry Pi
Any model with SDA, SCL, VCC and GND pins and a working network connection. I recommend the Pi Zero W or Pi Zero WH ( pre-soldered GPIO header).
An i2C LCD character display
I recommend a 20×4 display with a soldered i2C backpack like this
- Python 3 or later (3.7 at time of writing)
- The smbus python package
- An ODPT API key – Go to https://developer-tokyochallenge.odpt.org/en/info and register to receive an API key. It can take up to 24 hours for your application to be processed, so be patient!
Hook up the i2C display
Connect the display to the Pi’s GPIO pins like so:
Display SDA pin <------------> Pi GPIO 2 (SDA) pin Display SCL pin <------------> Pi GPIO 3 (SCL) pin Display 5V (VCC) pin <-------> Pi GPIO 5V pin Display Ground (GND) pin <---> Pi GPIO Ground pin
Some displays can operate on the 3.3V pin. Check the labeling / instructions for your display before connecting and powering on.
To help you out, here is a helpful pinout diagram from https://www.raspberrypi.org
Enable i2C on the Pi
Boot up the Pi. Open a terminal window if necessary. To open Raspberry Pi Config CLI, type:
9 Advanced Options then
P5 I2C to enable automatically loading the I2C service, then save, quit and reboot.
Download the i2C driver
To communicate with the LCD display via the i2C interface, you’ll need the I2C_LCD_driver.py script from Denis Pleic’s GitHub page.
Here is a direct link: I2C_LCD_driver.py
To allow Python to communicate via the i2C interface you’ll need to install the smbus package. This can be done with the following
pip install smbus
pip (PyPi Python Package Index) is installed by default in Raspbian Desktop images (but not Raspbian Lite). If the command above fails because it is not installed, you can install it with
apt like so:
sudo apt install python3-pip
Download my Departure Board Python script
Download my Python script that pulls data from the ODPT API, formats it for the LCD display and refreshes every 30 seconds.
GitHub Repo: https://github.com/ratticon/odpt-trainboard-pi-lcd
Direct link: odpt_train_board_pi_lcd.py
Save it to the same directory as the I2C_LCD_driver.py file you downloaded in the previous step.
I’ve included some default settings to get you started. Open
odpt_train_board_pi_lcd.py and modify the following lines as needed:
# Config Variables --------------------------------------- station = "Tokyu.Oimachi.Jiyugaoka" direction = "Outbound" lcd_width = 20 lcd_rows = 4 refresh_seconds = 30 overflow_animation = 'paging'
Here’s an explanation of how each variable works:
station – this string contains the railway operator, line, and station that we are requesting the timetable for. I plan on making a helper script so you can query the ODPT API and search for your desired station.
direction – this string should be either “Inbound” or “Outbound” (case-sensitive)
lcd_width – this integer describes how many characters can be displayed on one row of your LCD.
lcd_rows – this integer describes how many rows can be displayed on your LCD.
refresh_seconds – this integer describes how many seconds to wait between refreshing the timetable.
overflow_animation – I wrote two methods for animating destination names that are too long to fit on the LCD:
"paging" method show whole segments of the destination name.
"THISVERYLONGLOCATIONNAME" would be displayed as
"scrolling" method scrolls long destination names from left to right, one character at a time.
Export your ODPT API key
Once you have your API key, export it as an environment variable with the the
export command, like so:
Run the timetable script
Run the following command to launch the timetable program:
I wrote the script for Python 3, so be careful to type
python) if 3 is not your default version.
You should now have a working LCD timetable, and see three columns on the display:
Column 1 will show
EXP if the train is an Express train, or
Loc if it is a Local.
Column 2 will show the train’s departure time.
Column 3 will show (and scroll) the train’s final destination.
Bonus: Run it persistently in the background
If you are connecting to your Pi via SSH, you can run the script as a background process to free up the command line and keep it running after you disconnect. This can be achieved by using the
nohup command like so:
nohup python3 odpt_train_board_pi_lcd.py &
You should see a process ID and a message that nohup is appending output to a file, something like this:
 20918 user@pizero:~ $ nohup: ignoring input and appending output to 'nohup.out'
Enter to resume using the command line.
If you want to kill the process, here are two methods:
1. Get the PID with
ps and terminate it with
Run the following command to get the PID (Process ID) of the script:
ps aux | grep -i odpt_train
This should return something like:
user 20918 90.9 4.1 29408 18300 ? R Apr30 106705:27 python3 odpt_train_board_pi_lcd.py
The number in the second column (20918 in the example above) is the PID. To send a terminate signal (15 – SIGTERM) to the process, run:
kill -15 <PID>
htop then hit
F3 and type
python.Ensure that the name of the script is highlighted, then hit
F9 to open the kill menu. By default
15 SIGTERM will be highlighted. Hit
Enter to send the terminate signal and kill the script, then
F10 to quit.
Leave a Reply