Lego Train Automation

This is a special post because it was the main driver for building this blog! I could not find any way to control the Lego infrared power functions using NodeJs. There are libraries available for Arduino sketches and Python for Raspberry Pi, but neither worked well with my environment.

Today we will discuss how the IR power functions work, various resources and how I eventually got it to work. I hope that this is beneficial to somebody and that you share your experiences and other ideas. Ideally, somebody could take the time to write a nice NodeJS NPM to simply include into a project and share with the group 😉

Goal:

Detect train at the City Station, stop it for 5 seconds and then resume moving.

Challenges:

Use the Lego infrared signals to control the train

Detect the train

Send infrared commands to the train

Components:

Raspberry Pi

Arduino

1.8v LED

Infrared LED

Circuit:

The circuit for controlling infrared Lego power functions is not that complicated. We basically just need to attach an infrared LED and a standard LED to the Raspberry Pi GPIO pin 22. The standard LED will be used for visual feedback that the infrared LED is transmitting. This is extremely helpful while troubleshooting.

I’ve chosen to use the Keyes KY005 infrared transmitter, as it was part of this awesome sensor kit I purchased.

There will also be an infrared proximity (reflective distance) sensor to detect when the train has arrived at the station. This is attached to an Arduino because of a larger project, but could easily be connect to the Raspberry Pi instead.

Schematic:

Pin 22: LED and IR Transmitter

GPIO 6: IR Sensor

Power Infrared Sensor and transmitter from 5v source

Code:

This code was created from searching the Internet and reading forums that only got me half way there. The only NodeJS infrared module was called lego-ir but was designed for the (expensive) Tessel transmitter module. There is also an Arduino sketch library that I imagine would work very well, but that’s not the language I am working with. But then I found the answer! I used the following code/guide from Diomidis Spinellis who was kind enough to post this on GitHub. Click here for the complete work. Ultimately, the answer is to use the LIRC infrared linux driver. By using NodeJS to call a native Linux command, I was able to easily send signals to my Lego power functions.

We will first follow the steps outlined in Diomidis’s GitHub post to get the Raspberry pi using the IR transmitter.

LIRC installation and configuration

Install LIRC

sudo apt-get install lirc

Configure LIRC by editing /etc/lirc/hardware.conf to be

#Try to load appropriate kernel modules LOAD_MODULES=true # Run "lircd --driver=help" for a list of supported drivers. DRIVER="default" # usually /dev/lirc0 is the correct setting for systems using udev DEVICE="/dev/lirc0" MODULES="lirc_rpi"

Add in /etc/modules the following line

lirc_dev

For kernels before 3.18 lacking a “device tree” also add in /etc/modules the following line

lirc_rpi gpio_in_pin=23 gpio_out_pin=22

For a 3.18 kernel (or newer), which has a device tree, uncomment and adjust the following line in the file /boot/config.txt ; you can find full instructions here

dtoverlay=lirc-rpi,gpio_out_pin=22,gpio_in_pin=23

Copy the PWM command configurations generated by this modified PWM generation program file to the Raspberry Pi’s LIRC configuration directory.

sudo mkdir -p /etc/lirc/lircd.conf.d/ for i in Single_Output Combo_PWM Combo_Direct ; do curl https://raw.githubusercontent.com/dspinellis/lego-lirc/master/$i | sudo dd of=/etc/lirc/lircd.conf.d/Lego-$i.conf done sudo dd of=/etc/lirc/lircd.conf <<\EOF # This file is not required in modern versions of LIRC # but seems to be required for lircd 0.9.0-pre1 that currently # comes with Raspberry Pi's Debian GNU/Linux 7.8 (wheezy) include "/etc/lirc/lircd.conf.d/Lego-Single_Output.conf" include "/etc/lirc/lircd.conf.d/Lego-Combo_Direct.conf" include "/etc/lirc/lircd.conf.d/Lego-Combo_PWM.conf" EOF

Reboot your pi

Test the sending of Lego commands from the command line.

irsend SEND_ONCE LEGO_Single_Output 1B_5 sleep 1 irsend SEND_ONCE LEGO_Single_Output 1B_M1 sleep 1 irsend SEND_ONCE LEGO_Single_Output 1B_BRAKE

Now we can work easily with Infrared using the Raspberry Pi !!

Basic Flow

Create a function to utilize the LIRC infrared commands

Detect train at station

Stop train for 5 seconds

Start train

Wait for an additional 5 seconds before detecting a train again

Source

Download Source Code: citystation.js

Now save and close your file.

Note: If this is your first project, you will need to initialize the folder and add the johhny-five module.

Run the following two commands before launching your new app.

npm init npm install johnny-five --save

If you have been following along with previous projects, we will need to still add support for external commands with NodeJs and to use the GPIO pins on the Raspberry Pi (more info about using Raspberry Pi with Johnny-five here ).

npm install exec raspi-io --save

Now run the code and test!

node citystation.js

The train is running on schedule!

Special thanks to the “rasp-io” and “Johnny-Five.io” development team!