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 😉


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



  • Use the Lego infrared signals to control the train
  • Detect the train
  • Send infrared commands to the train


  • Raspberry Pi
  • Arduino
  • 1.8v LED
  • Infrared LED


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.

infrared transmitter

KY005: Infrared Transmitter Module


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.



Pin 22: LED and IR Transmitter

GPIO 6: IR Sensor

Power Infrared Sensor and transmitter from 5v source

 IR Power Functions Circuit



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

sudo apt-get install lirc


  • Configure LIRC by editing /etc/lirc/hardware.conf to be
#Try to load appropriate kernel modules

# Run "lircd --driver=help" for a list of supported drivers.
# usually /dev/lirc0 is the correct setting for systems using udev


  • Add in /etc/modules the following line


  • 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


sudo mkdir -p /etc/lirc/lircd.conf.d/
for i in Single_Output Combo_PWM Combo_Direct ; do
  curl$i |
  sudo dd of=/etc/lirc/lircd.conf.d/Lego-$i.conf

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"


  • 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


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 “” development team!