LEGO Power Functions RC infrared control is specified in LEGO Power Functions RC v120.pdf
But I wanted to know what my controller (8879 LEGO Power Functions IR Speed Remote Control) was actually sending. So I hooked it up to a scope.
|Right STOP button||
1000 0101 1000 1010
|Brake then float, Output 1|
|Left STOP button||
1000 0100 1000 1011
|Brake then float, Output 0|
|Right CW (clockwise)||
0000 0111 0101 1101
|Decrement PWM, Output 1|
|Right CCW (counter-clockwise)||
1000 0111 0100 0100
|Increment PWM, Output 1|
I compared the bits to each of the sequences in the specification, to find that it was using “Single Output Mode” on page 9.
I used a Logitech Mini Blaster for the infrared (IR) LED output because I had one on hand. I used a meter to figure out the schematic. I added a 2N4401 NPN transistor driver to protect the Raspberry Pi GPIO and to make the LEDs brighter.
Download source code here. This code uses the LIRC driver by Aron Szabo. built into Raspberry Pi Linux. LIRC includes a bunch of stuff to record and play back IR. Since I didn’t want to do any of that, I just wrote directly to the driver (/dev/lirc0). lirc_rpi must be loaded with softcarrier=0 since the code writes every pulse.(modprobe lirc_rpi softcarrier=0)
Originally I wrote code to use /sys/class/gpio, and it worked, but was not very reliable. Because user mode code can be interrupted by lots of things going on in the OS, pulses and pauses were often too long. To fix this, you need to disable interrupts, and to do that you need a kernel mode driver. LIRC already had one, so it made sense to use it.
I also looked at using wiringPi, but it has the same timing problem as /sys/class/gpio since it also runs in user mode.
This code runs from http in cgi-bin, so parameters come from the QUERY_STRING environment variable. This complicates the code a little.
Another complication is the toggle bit needs to change for every command sent so multiple “increase speed” commands can be sent for redundancy, but the train only increases speed once. The computer science way to handle this is with a counting semaphore, which is what this code does.
I was disappointed to learn the 8878 LEGO Power Functions Rechargeable Battery Box has a 2 hour auto-shutoff. This means the power will likely be off when I want to run the train remotely. The 88000 LEGO Power Functions AAA Battery Box auto-shutoff can be disabled (by holding down the power button), but AAA batteries don’t last very long (they discharge when you look at them).
For more detail: Raspberry Pi Controls LEGO Power Functions Train