LEGO Train Track Switch

The 8:45 express train is coming and we need somebody to switch the tracks quickly! If only we had a way of doing this remotely.

Goal:

– Remotely switch the train track and use lights to indicate the direction.

Challenges:

– Construct the traffic signals with micro LEDs to fit in my LEGO lights.

– Construct the mechanics to switch the track. This switch is very tough, so power will be an issue.

– Control a servo motor to move the track to position.

– Send a command remotely to switch the track.

Supplies:

– Raspberry Pi (or any NodeJS host)

– Arduino (I used the Mega 2560 but any will do)

– 2x micro SMD LEDs

– 12v power supply

– 2x NPN transistors

– servo

– breadboard

– 2x resistors

– button

Circuit:

LED

The SMD LEDs fit nicely in the LEGO lights and I found these on eBay for a good price.

SMD LED

Servo Motor

I will be using a 5v hobby servo with 180 degrees of rotation to control the switch arm.

hobby servo

Push Button

A simple push button will be used to toggle the track locally.

Push-Button-Switch

Fritzing Circuit Diagram

train track switch fritzing

The LEDs will actually be positioned so that only one is lit above each track. Since there are only two states, I have combined the four lights into two circuits.

Programming:

We will need to initialize the board as usual and then define the two LED pins for our lights and the servo for the track switch. Then we need to define the two states that the switch will be in; straight or turn. Each state will represent the current lights and position of the servo.

To understand what position we set the servo at will take a lot of trial and error. I have tried several LEGO mechanical ideas to provide enough torque to switch the track. Each version resulted in different servo positions. This is where the REPL comes in really handy. You can easily adjust the position of the servo without exiting the code. Once its dialed in, you just have to update your code once.

Basic Flow

  • Set initial state “straight”
  • Listen for server or REPL command
  • Toggle servo and LEDs to proper state configuration

 

Source Code

The code uses NodeJS and the Johnny-Five.io robotics framework to control the devices.

PubNub is an enterprise messaging service using the Publish/Subscription model, which is ideal for IoT projects. We will use this service to send commands from the Internet.

 

// traintrackswitch.js

/****************************
// Lego Train Track Switch
// This app uses the Johnny-Five.io framework to control a servo and lights
// The servo will switch the track to the desired location and update the direction lights
// Commands can be sent from the "iol" PubNub channel
// {"command":"track_straight"}
// {"command":"track_turn"}
// {"command":"track_toggle"}

// Written by Cory Guynn
// www.InternetOfLego.com
// 2016
****************************/



/****************************
// Server Code
****************************/
// The config file will be used to store API details. Its separate for security reasons.
var config = require('./config');

var pubnub = require("pubnub")({
    ssl           : true,  // <- enable TLS Tunneling over TCP
    publish_key   : config.pubnub.publish_key, // These will be YOUR PubNub API keys
    subscribe_key : config.pubnub.subscribe_key
});


// Publish Messages

var message = { "news" : "Train Track Switch online!" };
pubnub.publish({
    channel   : 'iol',
    message   : message,
    callback  : function(e) { console.log( "Server: PubNub SUCCESS!", e ); },
    error     : function(e) { console.log( "Server: PubNub FAILED! RETRY PUBLISH!", e ); }
});


/****************************
// Circuit Code
****************************/

// Arduino Johnny-Five
var five = require("johnny-five");
var board = new five.Board();

board.on("ready", function() {

    // Track Switch Components
    var trackSwitchLedA = new five.Led(26); // Green for straight, Red for turn
    var trackSwitchLedB = new five.Led(27); // Red for straight, Green for turn
    var trackSwitchServo = new five.Servo(6); // Track Switch
    var trackSwitchButton = new five.Button(2); // Toggle Button

    // Add devices to REPL (optional)
    this.repl.inject({
        trackSwitch: trackSwitch,  // example: trackSwitch(Straight)
        trackSwitchServo: trackSwitchServo // example: trackSwitchServo.to(90);
     });

    // Button
    trackSwitchButton.on("down", function(){
    	console.log("trackSwitchButton pressed");
    	trackSwitch();
    });

    // Track Switch with Lights
      // Accepts a direction, or will toggle if no parameters sent
    var trackSwitchState = "straight";
    function trackSwitch(trackSwitchState){
        if (trackSwitchState == "straight"){
          console.log("track switched: Straight");
          trackSwitchLedA.on();
          trackSwitchLedB.off();
          trackSwitchServo.to(90);
          trackSwitchState = "straight";
        } else {
          console.log("track switched: Turn");
          trackSwitchLedA.off();
          trackSwitchLedB.on();
          trackSwitchServo.to(130);
          trackSwitchState = "turn";
        }
    }

  /* ---------------------------------------------------------------------------
  Listen for PubNub Messages
  --------------------------------------------------------------------------- */

  pubnub.subscribe({
      channel  : "iol",
      callback : function(msg) {
          console.log( "Server: PubNub Received message and sending to circuit: ", msg );
          if (msg.command === "track_straight"){
   	        trackSwitch("straight");
   	      }
   	      if (msg.command === "track_turn"){
   	        trackSwitch("turn");
   	      }
          if (msg.command === "track_toggle"){
            trackSwitch();
          }
      }
  });

}); //end board.on()

Source Code Download: Gist

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 and pubnub module.
Run the following two commands before launching your new app.
npm init
npm install johnny-five pubnub --save
Now run the code
node traintrackswitch.js

Node-RED

To easily interact with the train track switch, we will use Node-RED. I am running TheThingBox image on my Raspberry Pi, so Node-RED is already installed. To use it with PubNub, I just installed the additional NPM module by running this command on the Raspberry Pi from within the .node-red folder.

npm install node-red-contrib-pubnub

Now I can quickly create this flow to send messages to my LEGO track.

Train Track Switch - NodeRED

The function blocks are very basic:

traintrackswitch nodered function block

LEGO Train Track Switched!

Gallery

Control the Lego track switch via Arduino and Raspberry Pi using NodeJS with Johnny-five.io, Node-RED and PubNub

Posted by Internet of Lego on Wednesday, January 6, 2016

Feedback, ideas, better way of writing the code? Please share with the group!

Complete IoL City Project Code on GitHub