How to turn a cheap toy-train into an IoT device
(And make it voice-controlled, just because it’s easy)
‘Twas the first Christmas as a Olisto team and we had the idea we needed to do something nice in the office. We all love cool stuff and gadgets but that’s too easy. So here’s what we did.We found the cheapest fake-tree in town and decorated it with bells, balls and presents. And we did some more. Of course.
I mean, why have a Christmas tree if you can’t control it with Olisto? So we used several individually controllable Philips Hue LED-strips to give it the most awesome lighting you’ve ever seen in an office Christmas tree. One that you can make triggs for, such as: turn red when the continuous integration build fails, automatically switch on- and off depending on whether there are people in the office. Or just play around with one of those nice apps you’ll find in appstores to create awesome Christmas-tailored light & sound shows (yeah, we couldn’t help ourselves – check the video here…
One day my colleague Frank came into the office with a very cool new addition for the Christmas corner. In all honesty, he brought in the one thing that is every boy’s (small and large alike) wish – an electric train! It was plastic, it was cheap, and it was awesome.
It had one major drawback though – it had an old-fashioned on-off toggle switch. One that did not allow for control by Olisto. This was not acceptable, so I decided to hack it a bit and make it controllable over the WiFi network. And this is the result:
Let the hardware hacking begin!
Because I want this to be a hobby-grade project and use parts that are easy to obtain and work with, I’ll go the Arduino route. Yes, you can try this at home! Basically, there’s 4 main components that we’ll need to make this work:
- The main controller
- An interface to connect to a WiFi network
- An interface to control the train engine
- A power source
The main controller
Since we want all of this to fit inside the trains housing and I’m not expecting the software to be terribly complicated, we’ll go with the smallest part that is still easy to work with (AKA, can be powered & programmed over a USB connector). The “Arduino Nano” type of controller is perfect for this. However, I choose one from the brand ‘RobotDyn’, since it has the far more common micro-USB connector and has stronger power regulators. Also, it’s cheaper. I choose the version that did not have the headers soldered on, so that the end-result will be more compact.
Interface to connect to the WiFi network
A quick googling-session thought me about these popular, cheap, and tiny modules that seem to be the perfect fit to build WiFi connectivity into an Arduino-based project. It’s called ESP8266. I looked no further and added it to my shopping list.
Interface to control the train engine
Although I did not put any research into it, I made an educated guess that hooking up the train’s engine directly to the Arduino pins would not be a good idea. It would probably draw too much current, and hooking inductive loads directly to electronic controls without special provisions is not a good idea in general. I looked for a simple module with an H-bridge type of power driver. The online shop where I already found the Arduino and WiFi module had one called ‘L9110S’.
The whole thing needs one more part: The power source. The Arduino is perfectly happy with a 5V USB power supply and the train is originally power by 2 1.5V AA batteries. Any sufficiently powerful USB powerbank will do, it just has to be small enough to be put in the train somewhere. We had some good candidates lying around, so that was easy.
Before we can get it to work
There are two minor difficulties with using the ESP8266 module that we need to fix.
- It’s IO’s are 3.3V and will not survive a 5V signals. This can easily be solved with a voltage divider made from 2 resistors. I used 10K ones, but any value between roughly 1K and 27K should work, as long as the two resistors are equal or correctly balanced to produce an output between 2.5 and 3.3V.
- It’s serial port may be operating at 115200 bps According to the internet they are sometimes delivered with a setting of 9600 and sometimes with 115200 bps. With mine it was 115200, which is too high for an Arduino Software serial port. An easy fix is to initially connect the module directly to the Arduino pins that are also connected to the USB-Serial converter so we can communicate with the module directly from the Arduino serial monitor.
We will build up the whole project in 3 steps, where step 1 is just to be able to correctly configure the WiFi module. And possibly play around with it a bit, so that we can get to know it. After that we will connect the modules to each other and add it to the train.
Putting it together
Step 1: Connect the WiFi module to the USB/serial port
Here is the wire-diagram for step 1.
As you can see there is a voltage divider for the serial signal going to the WiFi module and the WiFi module is connected to the Nano’s RxD and TxD pins. The sharp reader might notice that the RxD pin of the WiFi module (the pink wire) is connected to the RxD pin of the Nano board and that the same goes for the TxD pins, which is not what you might expect. This is because we don’t want to communicate between the module and the Nano CPU itself, but between the module and the Nano’s serial/USB transceiver. Also, we’re pulling the Nano’s reset pin low. This will keep the Nano in reset state, so that it won’t try to use the USB/serial transceiver itself. I choose to remove the pin header from the WiFi module and solder the wires through the holes directly to get a more compact result. Once we have this built up we can go ahead and connect it to the computer.
Start the Arduino software. Select the right port (Tools->port) and while we’re at it, let’s select the right board and CPU type (Tools->Board and Tools->Processor). Now start the serial monitor (Tools->Serial Monitor). This will bring up the serial monitor window. Set the speed to 9600 baud and the line endings to ‘Both NL & CR’ in the bottom-left corner. Now let’s try to see if it works. In the text-entry field, type
and press ‘Send’. If the module is set to 9600 bps it will respond with ‘OK’ and we are good to go. If you get just garbage, or nothing at all, set the speed to 115200 and try again. You should get the ‘OK’ response now, meaning that the module is indeed programmed to communicate at 115200 bps. Let’s change this to 9600. Type:
AT+UART_DEF=9600, 8, 1, 0, 0
It should respond with ‘OK’. This will set the default serial speed to 9600 bps. Now select the 9600 bps in the serial monitor and unplug/replug your USB cable to reboot the WiFi module. If you retry the ‘AT’ command now, it should reply with ‘OK’ in 9600bps. This means we’re good to continue onto step 2! Although you might want to play around a bit to get to know it’s instruction set. Check out it’s command reference, for example in the ‘instruction set’ document
Step 2: Rewire the module and add code
In this step we’ll re-wire the WiFi module for normal operation and add the motor driver.
Aside from the addition of the motor-driver, these are the changes with relation to step 1:
- The connection between the GND and RST pin of the Nano is removed
- The connections from the Nano to the WiFi module are not on IO’s 2 & 3
There’s also a reset- and a ground wire that should just be long enough so you can bring them somewhere where you’ll be able to make contact between them, outside of the train. When everything is a connected, the electronics should be functional. So now would be a good time to program the controller. You can download my project from Github. Download the files and open the project with the Arduino software. In the first few lines you’ll see placeholders for the WiFi network name and password; replace these with your own. Then connect the USB cable. Open the serial monitor and change the speed back to 115200, since that is the speed at which the Nano communicates through the USB/serial convertor. Finally, upload the code (Sketch->upload). After a few seconds the status bar should read ‘uploading done’ and you should see some output from Nano in the serial monitor. Joining the WiFi network should take a few seconds, after that you’ll see it print the IP address. This is useful to write down 😉 When everything is considered the Nano’s on-board LED should be on.
Step 3: Connect the motor and light
In this final step we’re going to connect the trains motor and light following the diagram below.
Start out with removing the trains cover. Remove the battery contacts, the on/off switch and their wiring. I also removed the speaker because the sound quickly drove me crazy. I haven’t tested it but I suspect that the sound won’t work properly anyway when we’re going to control the motors speed. I did leave the board though, mainly for the capacitor; a little extra capacitance never hurts. When this is done, connect the motors’ wires to the motor controller and the lights’ wires to the Nano pins. For the light the polarity shouldn’t matter. The motor will just run backwards if we connect it the wrong way, in which case we’ll simply have to swap them.
Now the time has finally come to see if everything works! Connect the Nano to the PC and open the serial monitor again. You should see the same output that you saw the first time. Not it’s time to send some commands! Open up a browser, and in the address bar type the following:
Where YOURIPADDRESS is obviously replaced by the IP address the you saw being printed in the console. This should turn on the trains light! Now try
This should set the motor speed to 50 percent. If everything works then it is now time to fit all the electronics into the train. I managed to fit everything into the batteries’ former compartment, just be sure not to make any accidental connections on the PCS’s soldering points. I used some duct-tape to provide some isolation. Lead the reset-wires somewhere where you’ll be able to access them once the train-cover is installed. Or you could connect them to the original power-switch. You’ll need it to give the Nano an initial reset after you power it up; for some reason it won’t properly start-up otherwise. Also find a nice place for your battery pack; I used the car that has the snowman and the tree; after removing those, and cutting away some plastic, it gives a nice and flat surface. An even better solution would be to put it inside the passenger car if it fits; my battery pack was slightly too large for that unfortunately. When this is done, hook the battery car to the engine car, connect the battery and give the Nano the initial reset pulse. A few seconds after this, you should be able to control your train over the WiFi network!
Controlling it with Olisto
Now that we have our train ‘connected’, of course we’ll want to be able to control it with Olisto. And we can! With Olisto Connect we can activate URL’s from triggs and include values such as the speed setting in them. There is just one challenge remaining: In order for this to work, Olisto will need to be able to access the train from the public Internet. Right now, the train is only accessible in your local (home) network, just like the other devices in your home. There are two ways to solve this.
- Set up a port-forwarding rule in your router.
- Use a bridging service to make the train accessible from a public address
Set up a port-forwarding on your router
If you know how to configure your internet router, you can set up a port-forwarding rule on it to forward all requests on your internet connections’ public IP address to your trains’ internal IP address. The server on the train will then become visible to the world and Olisto can send requests to it. Keep in mind however that everyone else will also be able to do so.
Use a bridging service
I happen to be working on a little side-project called mythingy.net. It lets users create publicly accessible addresses and will forward all requests send to those addresses to the users’ own private network. The user must run a client program inside their own network to make this possible. To try it out, do this. First, make sure you have installed node.js. Then, in a command-prompt window, do this:
npm install mythingy-client cd mythingy-client node mythingy-client
From this point on, the train will be accessible at .mythingy.net, so we can use it in Olisto connect! You can also use this trick to make any other HTTP server from your local network publicly available. Be aware though that anyone knowing your URL’s can access it; therefore it’s best to choose hard-to-guess names of at least 8 characters. Also be aware that this service is in a very early stage and there are absolutely no guarantees about its stability or future availability.
Once we have this set up you can start making triggs to control the train. Choose any condition you like (such as ‘When I am at location ‘home’). For the action choose the ‘Send HTTP request’ option in the ‘Olisto Connect’ channel. For the address fill in the public address of the train (either your internet connections’ public IP or your mythingy.net url), followed by /speed?value=80. So it will look like this, where abc123 is replaced by your chosen name:
From now on, the train will start running automatically whenever you get home!
This is a demo on how you can use Olisto to make anything in your house connected to Olisto. All it takes is some fantasy, time and good will. Let us know what you will do with Olisto and Olisto Connect.
PS: And the voice-controlled part? Yeah…consider that a sneak preview of what’s to come at Olisto in the very near future…