Introduction: Lego Trains & Blynk

Hey all! Since this is my first Instructable it probably will not be the best one, but I'd like to share this thing I made with you all out there!

I'm a huge fan of (Lego) trains ever since I was a kid but the time has passed along and now I want to do more with trains then just run around in circles. The Power Functions included with the new Lego trains work with simple infrared commands and libraries to get stuff working are easily obtainable. There is a bunch of work to be done to get this working, but when you are done, you will be able to address way more than the eight trains normally possible using the Lego Power Functions (Red/Blue each with four channels).

I'm gonna show you how to make a basic setup for controlling locomotives. You can then explore on your own and create many other things to go with this.


This thing is not for the faint of heart. I assume basic electrical skills and computer skills. Also I will be modifying the Lego train, so you probably loose warranty, just FYI :)

Also because we use 2.4Ghz transmitters, they may possibly interfere with your Wifi network! This is why I like to use Ethernet :)

***End Warning***

You need quit a bit of components, both on the hardware and software side:


  • Arduino UNO or MEGA as controller (MEGA preferably)
  • Arduino Nano's for the train (one for each locomotive)
  • A way to interface the Controller with your network (ethernet or wifi, I prefer ethernet)
  • NR24L01(+) 2.4 Ghz wireless transmitters (one for each locomotive)
  • Wiring, soldering iron, pin headers and such.
  • Couple of IR emitter-leds and some resistors (100 Ohm will do)
  • 5v to 3.3v convertors (for your Nano)


  • The most amazing Blynk (this is really a marvel of technology!)
  • Blynk Local Server
  • Blynk App for on your iPad, iPhone or Android (I like the iPad because of the screen size)
  • Arduino IDE for programming everything

Libraries for the Arduino

And that's about it! It doesn't look much, but it will take a lot of work to get everything working. Allright than, let's do it!

Step 1: Architecture Overview

The image shows the "architecture" of how this project is connected. The Blynk part is the connecting element. The guys at also provide cloud services, but I like to use a local server because that will eliminate most latency and trains need to react quickly to your commands.

The Arduino UNO will be sending out the commands to your trains via the NRF wireless transmitter (for future use: you can send commands back from the train to the controller to ...). You will be giving out commands via the Blynk App to your Arduino UNO controller.

Now we are gonna make the Blynk Local server. This software is Java based so it will run on anything that supports Java. This includes the Raspberry Pi but I think it's a bit to slow. I run the Server software of my MacBook, which works fine.

You can start here

There you will find an explanation of the Local Blynk Server and how to configure stuff. For this tutorial you don't need to bother with configuring the server. It will run fine for this out of the box. Also the certificates are not really needed since I assume you won't be running this server 24x7 connected to the Internet so everyone can play with your trains (... well, there's an idea ... ). Blynk has a very active community and the developers of this bunch are also really active on the forum, so you can ask a lot of questions there too :)

Once you got this up and running (which should take about 20 minutes) we can get to programming the Controller node and configuring the Blynk Dashboard on your mobile device. The fastest way to check of the server is running is by doing a "telnet localhost 8443" from your local machine. If you get disconnected really quick, it works.

Step 2: Controller

As I mentioned in the introduction, it may be wise to get a MEGA for this project instead of an UNO. The libraries are not the smallest in size and also memory is starting to get an issue for me personally and all I do is move the trains forward and backward ...

I've attached a sample controller.ino file to upload to your Arduino.

Attaching the hardware to your Arduino comes next (or first, what ever you want!). First I want to check that the Blynk part is working correctly so We'll add an ethernet interface. I like using the cheap ENC28J60 because it's pretty much super-stable and dirt cheap. I've hooked it up with a small, home made shield as you can see. This is because both the NRF transmitter and the ENC use the SPI bus to communicate. The difference is the CE and CSN pins on the NRF. I've changed those to pin 9 and 8 instead of 9 and 10. (Yes, I know, some wires are a little burnt, or well-done if you like ;-).

The last ENC's I ordered can be powered with either 3.3v or 5v, so you can take your pick with those. The NRF is a 3.3v device, so beware!

All wires hook up as following to your UNO


  • CS > D10
  • SI > D11
  • SO > D12
  • SCK > D13
  • RST > RESET (if you want, this is not really needed)
  • INT > D2 (probably also not needed, but I hooked it up anyway)
  • VCC > 3.3v or 5v, be sure to take the right pin
  • GND > GND


  • VCC > 3.3v
  • GND > GND
  • CE > D9
  • SCN > D8
  • SCK > D13
  • MOSI > D11
  • MISO > D12

After you hooked everything up we need to generate an Auth token code on our mobile device to identify your hardware to the Blynk server. Install the Blynk app and now press the three little dots on the login page. Now set this to custom and enter the IP address of your local server. Now when you press OK, you can go and create a user. It will automatically login and you should see something like "Create Project". So, create a new project and select the appropriate hardware platform. After that you click on the Auth token, it will get copied to your clipboard or try typing ... because we didn't configure the Local Server, mail isn't working, so you have to get the Auth token another way. Copying to clipboard and mailing it to yourself works fine. Click "Create Project" now.

You will end up with an empty dashboard which we need to configure. If you tap anywhere on the dashboard you will get to a list of Widgets you can add to your dashboard. You can start with adding two Large Sliders. The first slider we'll be using to control the train speed and the other one to select which train we will be controlling.

Also add a button. This button will control if the train is moving forward or reverse.

Ok, we got a dashboard, now edit the Sketch (which you already downloaded of course ;-) and replace the auth token and IP information for your network. Remember to change the "server_ip" to point to your local server. You can now upload the whole thing to your Arduino UNO controller.

If you installed all fore mentioned libraries you should be good to go! If you started your Blynk local server, you can check the log files in the log/ folder and examine the blynk.log file. It should mention somewhere "hardware joined". This means the hardware is found. On your mobile device, you need to tap the Play button on your dashboard in the top-right corner. If you get a message "Your Arduino is offline" you've done something wrong, but normally it should just do nothing because it's connected.

Step 3: Configuring the Dashboard

Great, you uploaded your Sketch and the Blynk Hardware and the Blynk App are both connecting to the (Local) Server you installed or the cloud service!

Now we can configure the Widgets on the Dashboard. As you may (or may not) have noticed in the above screenshot, the Widgets have a little more information then just the empty ones you have on your dashboard. If your App is still in Play-mode, stop it. This is because we can only edit the Widgets in Stop-mode.

Tap the first Slider widget and configure the settings as follows:

PIN: V0, to / from values: 0 ~ 7

You can change name if you want to something like "Speed" and play with the colors.

The second Widget gets:

PIN: V31, to / from values: 0 - 2, name it something like "Selected Train"

The button settings are:

PIN: V30

Mode: SWITCH (this is really important!)

Awesome! We are getting well under way. The next step will be building the Nano's to fit into the train as "decoders".

Step 4: The Decoders

Just like in model railways we are gonna make a decoder to get the signals to the train via a simple IR LED. The decoder will be made of 3 components:

  • NRF wireless transmitter
  • Infrared LED to get signals to the Power Functions motor
  • Nano to combine it all

I've include a piece of code form my 2nd decoder running a blue freight train. This sketch will be making use of the LegoPowerFunctions library. So make sure you install that.

The NRF will be connected to the Nano as follows (note the SCN pin is different from the UNO):

  • VCC > 3.3v
  • GND > GND
  • CE > D9
  • SCN > D10
  • SCK > D13
  • MOSI > D11
  • MISO > D12

I made a little print which just about fits in the train with a little pushing around wires.

Furthermore I added a 5v to 3.3v convertor which is hooked up to the Lego battery pack to power the Nano. I made a little wire from the Vout of the convertor to a Vin pin on the Nano because it's on my Nano's serial port.

On Pin 2 of the Nano there is an Infrared led connected via a 100 Ohm resistor. This LED will be handling the actual signals to the Power Functions motor. The idea is to place this LED as close as possible to the receiver. You can cover it up with a piece of Lego or paper. With this method, because you address the NRF transmitter, not the actual Lego addressing, you can address way more than eight trains since every train has it's personal IR LED and not a central one like from the Power Functions controller.

I hope the pictures are good enough to get an idea of how it's made. If you have any questions, please don't hesitate to ask. I'm in the proces of making things and figuring stuff out as I go along, so documentation isn't really a priority.

As for the connection to the Lego battery pack, I just soldered on two wires which lead to the Voltage convertor and from there on hooked everything up to that.

Basically you are all set to go now. Via the Blynk Dashboard you should be able to control your train(s).

You should however, set the Channel and Color per decoder. The included Sketch for the decoder has address "2". This corresponds with the following code in the Controller sketch (because the controller sketch needs to know which decoder matches with what train):

const int trains[3][3] = {
{ 1, 0, 0 }, /* ICE , NRF 1, Red , Ch1 */

{ 2, 1, 0 }, /* Freight , NRF 2, Blue , Ch1 */

{ 3, 1, 1 } /* Freight , NRF 3, Blue , Ch2 */


Excuse me for not using the "code" option, but that seems to mess up my code. In this little array we will define what trains are know to the decoder and on what actual Lego frequency they are. The first digit is the decoder address, second on the color, third on channel. Because we can cover up the infrared receivers on the trains they could well all be on Red Channel 1, it wouldn't matter because the train is addressed via the NRF instead of the Infrared Lego thing.

Do note that if you add more trains, the "const int trains[3][3]" has to be changed to "const int trains[5][3]" if you want to add five trains. Of course everything has to be uploaded to the controller again.

The movie I added was from my first attempt, but it illustrates what can happen. With the sliders on your dashboard you can select which decoder you want to control and how fast the train needs to be going. If you press the reverse button, the reverse codes will be send. I have done nothing whatsoever with first slowing down, so that's something to think about.

Currently I'm investigating adding lights to the trains, which includes back/front lights and signal lights. Not sure how and when, but the options are limitless now I think. The next big step will be train detection and automation...

Enjoy! If you have any questions, please let me know via the comments or my email

Arduino All The Things! Contest

Participated in the
Arduino All The Things! Contest