Automatic Christmas Train


Now that finals are over, I finally have some time to work on the projects I’ve been putting aside over the last few months. The first thing I checked off my list is something I’ve been promising my mother for a couple of weeks.

Christmas Train

We decided to put our Christmas tree outside on the front porch this year. My mom had the idea of setting up the train under the tree and having it automatically move around the track whenever someone came up to the front door. She setup the tree and the train, my task was to make it move.

Normally I’d use a relay for this kind of project. Unfortunately this train is battery power and since its been in our family for over twenty years I didn’t want to modify it. Instead, I decided to use the built-in infrared communication to control the train. I opted to record the output from the infrared remote and emulate it using a microprocessor whenever someone comes to the door.

The first thing I did was record the infrared waveforms. To do this I soldered an infrared photo transistor to a 1/8″ phono plug (headphone jack) and plugged the sensor into my laptop’s microphone input. For each of the functions on the remote (Forward, Back, Whistle, Stop) I held the remote up to the the sensor and “recorded” the waveform of the infrared command. I essentially used the sound card on my laptop as a storage oscilloscope.


Here are some images of the waveforms:





Using Audacity, my audio editing software, I amplified each of the waveforms until they clipped. Then I lowered the threshold enough that I had good square waves to deal with. This make it easier to accurately measure the width of each signal component. The final signal I used to measure the pulse widths looked something like this:


Luckily, the encoding for these signals is easy to understand/duplicate. I found there were three durations I needed to record. Each high pulse was 1.5ms wide. In between each pulse is a delay. The longer delays are 4.5ms and the shorter delays are 1.75ms.

In order to stay organized, I decided to define some of the “building blocks” of the waveform. It seemed to me that the information being carried was stored in the delay between pulses, so I called the longer delays 0 and the shorter delays 1. If this seems a little convoluted, the following image summarizes the information structure by showing an example of 1-0-1:


Using this scheme, each of the commands is easily translated into a binary representation:

Forward: 001111101010
Back: 001111001011
Whistle: 001111111001
Stop: 001101001100

Incidentally, these correspond to 1002, 971, 1017 and 844 in decimal — there does not seem to be any significance to these values.

The next step was to write the software to mimic this behavior. I chose to use a PIC18F4685. While this pic is WAY overkill for this project, I used it because I already had the breadboard ready to go from a previous project. I can use the same code with any smaller 18f series PIC or if I ever want to make this a permanent fixture I can write the code in assembly and program a very small 12F series PIC to handle this basic task.

I wrote the code in C because I did not want to spend very much time on this project and I knew with delays in the order of milliseconds the timing wasn’t critical. Using C, the code took me about five minutes. First I wrote two functions to handle delays. The first, called “pulse” sets the enable pin, waits 1.5ms and brings it low again. The second called “gap” accepts a variable called “value” and delays accordingly. So the waveform in my example above (1-0-1) could be represented with the code:


It isn’t the most elegant approach but its functional and quick — perfect for this project. I also attached a button to the pic to trigger the infrared LED sequence. Debouncing the button wasn’t necessary because the series of delay loops after the button was pressed lasted for many seconds.

Having finished the code, I attached the signal pin from the PIC to the base of a PN2222 transistor to act as a buffer. Then I attached two infrared LED’s to the transistor in series with a 100ohm resistor to supply them with about 50mA of current. Early on I noticed the train wasn’t very sensitive even to it’s built-in remote, so I knew I’d need at least two emitters with a decent amount of current.

I held the LED’s up to the train and pushed the button– the train wheels began to spin, the whistle started, and ten seconds later the wheels stopped. Success! Now all I needed was a way to trigger the train when someone walked up to my front door.

I considered a few ways to trigger the the train. Initially I wanted to use a motion sensor to trigger the train whenever someone approached our front porch. Unfortunately, time and budget constraints prevented that option. If I improve this project in the future I think I will try to incorporate a motion sensor into my design.

The solution I decided to use instead was very.. home made — but it ended up working surprisingly well. I decided to create a sensor that detected when someone stepped on my front doormat. I used two pieces of aluminum foil, some tapes, and a few drinking straws.

First I lay down a long strip of aluminum foil with some straws placed evenly across the surface:


These straws will be used as “springs” to prevent a short circuit between two pieces of foil.


After laying the top piece of foil over the straws I fastened it down with some electrical tape and trimmed off as much unnecessary foil as possible. This was necessary to prevent any unintended shorts.

Next, I taped wire to each piece of foil and attached the foot sensor to my breadboard.


Finally, I placed the sensor under my front doormat. Now whenever someone steps on the sensor the two pieces of foil make contact and the PIC starts the train. When the person releases their foot the combined strength of the straws keeps the foil apart again.

The circuit has been in place two days at the time of this writing and so far it is working very well. The only thing keeping it from working perfectly is the train itself — occasionally it steers itself off the track. I’m going to add some more track segments to make the turns a little wider which should remedy that problem.

This project was a lot of fun for me. It gave me a chance to reverse engineer a product and provided me with insight about infrared communication. I am intrigued by the encoding method and would like to learn more. For instance, why did the product designers use the values they did for the infrared commands? Does this encoding have a name?

If anyone reading this has some insight I’d love to hear it.

Anyway, thanks for reading, I’ll leave you with some more pictures and a video.

The tree lit up at night.

The breadboard.

“Hiding” near my front door.

This is the original remote.

The train comes to a halt with the emitter pointed at the infrared receiver.

I’m sorry the video came out SO dark – it gets a little better after the first fifteen seconds. I will try to post another video when I get a chance.


  1. Pingback: A welcome train for the holidays - Hack a Day

  2. Using your soundcard to capture the IR pulsetrain is pure genius :). It might be common practice maybe (or maybe not), but I never thought about it. Being a beginner with pics and electronics in general I’m gonna try the capturing this afternoon… Congrats with the Hackaday link, btw…

  3. If you’re interested in IR signals, one of the best places to look is In the files section you will find a program called CaptureIR. It has the ability to capture and identify most IR protocols. I would suspect that what you see as a high pulse is actually a 40khz carrier. You would have to sample at 80khz+ to see that. Many IR devices won’t respond if you don’t properly replicate the carrier.

  4. couldnt you have just recorded the the input from /dev/dsp0

    something like

    cat /dev/dsp0 >~/desktop/forward

    then hit crtl c after you were done

    then use a hex editor to grab only non null blocks

    then after you have these files for each input

    created a bash script like


    cat ~/Desktop/forward > /dev/dsp
    cat ~/Desktop/back> /dev/dsp
    cat ~/Desktop/whistle> /dev/dsp

    cat ~/Desktop/stop> /dev/dsp

    read command



    so you can just type forward, or simplify it to a number

    just send it back out

  5. Maybe I could have but..

    a.) I don’t primarily use a linux system
    b.) The train isn’t connected to a computer because I’d rather not leave a computer running outside my front door.
    c.) That doesn’t seem any simpler than my current implementation.

    But thanks for the suggestion. :)


  6. Pingback: neonascent » Blog Archive » Trains

Leave a Reply