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.
Required Hardware
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
Required Software
- 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:
sudo raspi-config
Select 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
Download smbus
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
or pip3
command:
pip install smbus
Warning: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:
The "paging"
method show whole segments of the destination name.
For example, "THISVERYLONGLOCATIONNAME"
would be displayed as "THISVERYLO"
, "NGLOCATION"
, "AME "
.
The "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:
export ODPT_API_KEY="PASTE_YOUR_KEY_HERE"
Run the timetable script
Run the following command to launch the timetable program:
python3 odpt_train_board_pi_lcd.py
I wrote the script for Python 3, so be careful to type python3
(not python
) if 3 is not your default version.
Enjoy!
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:
[1] 20918
user@pizero:~ $ nohup: ignoring input and appending output to 'nohup.out'
Hit 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 kill
:
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>
2. Use htop
:
Run 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.