In this Instructable we will explain how infrared signals are used by a remote to control a toy or device, then show how a simple circuit can be added to an Arduino to operate the same device through free, Open Source software.
This document is part of a series covering the Puzzlebox Orbit, a brain-controlled helicopter that features an open design, open hardware, and open software. The helicopter can be operated via an EEG headset plus either a mobile device or the dedicated Puzzlebox Pyramid remote control unit. The Puzzlebox Pyramid includes a micro-controller based on the Arduino.
While we refer to the Puzzlebox Orbit in our examples, the principles, source code, and to a large extent software are all directly applicable to most any toy or devices which use infrared (IR) for remote control.
Step 1: The Remote Control
Here we explain in a very broad sense how an infrared remote control works.
There is at least 1 infrared LED (or Infrared Emitter, IR LED, IR Emitter) inside every infrared remote control, including the one you use to control your TV set. When you press a button on the remote, the IR LED will give out a certain series of "LOW"s and "HIGH"s which represents a series of "0"s and "1"s. (To be strict, it is common that a "HIGH" and a corresponding "LOW" consist of a "0", and another combination of "HIGH" and "LOW" with different period represents a "1".) Different series of "0"s and "1"s can mean different things, for example maybe "1100100000111" can mean "Turn Off the TV", and "001101011100" can mean "Volume Down".
Infrared is also cast by light and heat sources all around you: light bulbs, sunlight, heaters, even people. Therefore the remote control needs to have a distinct method of sending out infrared code to the receiving device (TV set, helicopter, car, etc.). That's why infrared normally transmits with "carrier" - a high frequency square wave sequence (normally 36kHz, 38kHz and 40kHz). So, if you were to capture and zoom in on an infrared signal, you would find each "HIGH" consists of a sequence of square waves rather than a continuous "HIGH" voltage level.
Check out Wikipedia:Infrared Remote Control for more information about infrared remote controls.
Step 2: Capturing the Control Signal
You might have a question: How can you learn the IR code used by a remote control?
One way is to use a Logic Analyzer.
A logic analyzer is an electronic instrument which displays signals in a digital circuit. (Digital circuits represent signals by discrete bands of analog levels, rather than by a continuous range. Basically if there's only two different voltage level in a circuit, say 5V and 0V, then it's a digital circuit. If the voltage in the circuit can be any voltage in between, then it is a analog circuit.)
Since we already know that an IR code is a digital signal rather than an analog signal, we can use a logic analyzer to capture and record the code emitted by the IR LED. First clip in to the Common (some times marked as GND, meaning "ground") Cathode pin of the IR LED, and then clip a signal channel of the analyzer in to the Anode pin of the same IR LED. Then tell the Logic Analyzer to start recording the signal. If you don't know which sampling rate to use, then use the highest option available.
It's easy to identify IR LED's polarity is simple even after they were soldered: There are two electrodes inside an IR LED, the bigger/longer one is Cathode, and the smaller one is Anode. See photo.
NOTE: It should be mentioned that if the logic analyzer fails to read an IR signal, but the controller is able to make the helicopter fly, it is possible that the test leads are clipped on the wrong way around, and that the ground and signal leads should be switched.
Step 3: Understanding How IR Commands Are Represented by Binary Codes
Here we explain how the raw control signal was decoded such that an algorithm could be written to reproduce it.
Take a look at Picture 1. You can see the IR LED is sending out IR commands almost every 0.1 seconds.
Take a look at Picture 2, and pay attention to the timestamps and compare it to Picture 1. Load the A_H3RMFM.logicdata file (in the .zip file) with Saleae Logic software, move the signal data to 4s, zoom in, and you'll see the exact same data as shown in the image.
Let's give the combination of one "HIGH" and one "LOW" a name, say a "bit". Then the first two bits in Picture 2 is different from the rest with HIGH=0.768ms, LOW=0.477ms, so Iet's put them aside, because it is very possible that these two bits are specially timed to denote the start of an IR command. (Actually if you look at other commands, they always lead by these two bits.)
Then let's look at the rest. There are only two kinds of bits left, one is HIGH=0.715ms, LOW=0.759ms, another is HIGH =0.377ms, LOW=0.422ms. let's call the first kind of bit "7", the second kind of bit "4". Then the code shown in Picture 2 is 4 4 7 4 7 7 4 7 7 7 4 7 4 4 7 7 4 4 7 4 4 7 7 7 7 7 4 7 7 4 7. We can re-assign 7 to be "1" and 4 to be "0" (or the other way round). If we do so then this command equals 0010110111010011001001111101101.
Step 4: Decoding the Control Signal
Next we need to decode the command, which basically means to understand how the comand works, and what each bit of the signal stands for. This process is quite challenging, with much guesswork involved. A good foundation of arithmetic, logic and sometimes imagination is required.
Our result for decoding the Puzzlebox Orbit's signal has been placed in to an Open Office spreadsheet file (in the .zip). A screenshot of that document is also included in this step.
While testing we moved the throttle and directional joystick into various positions and recorded each with the logic analyzer. Then we tried to decode the command from the recorded signal.
In column A, T1~T5 means throttle level 1~5, L2 means left max, R2 means right max, F2 means forward max, B2 means back max. A B and C refer to three different "channels" (different channels can be used to control multiple different helicopters in the same location at the same time without their signals interfering with one another).
The meaning of the signal begins to become clear once organized and displayed in this way. The 7 bits in the yellow block defines the throttle level, the 7 bits in the green block defines the left and right turning speed, the 6 bits in red defines leaning forward and backward, and the two bits in blue defines which channel to use. (again, channels are used when you have more than one helicopter at the same place and want to control them separately. Having three channels means there's a maximum of three helicopters can be in a same room and still fly independently).
What's the deal with cyan block?
This refers to a checksum. A checksum is a common mechanism in any communication system where you need to make sure that the information received matches what was sent out. A checksum is a number calculated from the rest of the code, with a predefined algorithm. When the device receives the code, it will first try to calculate checksum by itself, then compare it to the checksum attached in the message. If they are equal then the message is correct, otherwise something much have gone wrong during transmission For example the lighting system in a bright room may be interfering with the IR sensor. If the checksums do not match, the receiving device normally will ask the transmitter for the same message again. If the device is not capable of two-way communication (as in the case of most infrared devices) then the message has to be ignored.
The algorithm used to generate the checksum can be simple or extremely complex. Some common method includes bitwise sum and bitwise XOR.
The following algorithm is used by the Puzzlebox Orbit:
Start from the 3rd bit (include the leading 2 bits and assign them to 0)
Add up every 4 bits
Get the last 4 bits from the result
Use 0B10000 (10000 in binary equals 16 in decimal) and subtract those last four bits
Take T1 for example:
The last 4 bits is 0B0011.
0B10000-0B0011=0B1101, which matches the checksum found at the end of the control signal.
Step 5: Uploading the Control Program to the Arduino
Once the infrared commands signals have been decoded, we can follow the same algorithm to generate our own control commands and send them through an IR LED connected to an Arduino micro-controller.
Arduino is an Open Source electronic rapid prototyping project, and is widely used by makers, artists, students and hobbyists.
Arduino micro-controllers can be programmed through an Integrated Development Environment, or IDE. The Arudino IDE is complete free software. If you are not familiar with how to setup the Arduino IDE on your computer, visit Arduino.cc
Our source code is attached. For this project we used the Arduino Uno (R3), but the code should be capable of running on other Arduino models based on the ATmega 168/328. Decompress the .zip file, put everything in your sketchbook path, and restart Arduino IDE. Click File, move cursor to Sketchbook, and you'll see puzzlebox_orbit_Uno_V3. Upload that file to your Uno and you're half way there!
P.S. There is a PWM library file included, which is required for arduino to generate certain PWM signals. Sincere thanks to the author Sam Knight.
Step 6: Building the Circuit
Next we need to build a simple circuit to safely connect an IR LED to the Arduino.
Please refer to the included schematic for the following instructions.
There are 4 components in the circuit 2 resistors (4.7k, 47 OHM) , 1 IR LED (IR333C/H0/L10), and 1 NPN transistor (2N3904).
- Resistors are not direction specific, both ends are the same.
- IR LED symbol, pin 1 is Anode (longer lead), pin2 is Cathode(shorter lead).
- 2N3904 is the NPN transistor. Looking at the flat face, the left lead is Emitter (pin 1 in schematic), the middle lead is Base (pin 2 in schematic), the right lead is Collector (pin 3 in schematic).
Solder components (or use a breadboard) as shown in the schematic:
- 47 Ohm resistor to Collector on NPN transistor
- 4.7K resistor to Base on NPN transistor
- Anode of IR LED (longer lead) to Emitter NPN transistor
- Another end of 50 Ohm resistor to +5v pin on Arduino. (An alternative would be use a bigger resistor, say 100 Ohm, to replace the 50 Ohm one, and connect the other end to Vin Pin on Arduino.) This resistor is to make sure we won't burn the IR LED. The IR LED can only accept a maximum of 100 mA current, so if we use 5V to drive the IR LED, we need to make sure the current running through the LED is limited to less than 100 mA, which yields the resistance R=5V/100mA=50 Ohm. The nearest commonly-found resistor is 47 Ohm.
- Another end of 5K Ohm resistor to Pin 10 on Arduino Uno. The nearest commonly-found resistor is 4.7k Ohm.
- Cathode of IR LED (shorter lead) to GND on Arduino Uno.
There's a total of 6 connection. After each of these connections are made, you're all set.
Step 7: The Finished Circuit
Here you can see the completed circuit, assembled using a breadboard to connect each of the components.
Step 8: Testing the Circuit
Many mobile phones have cameras which can actually see infrared light.
In this step, we take a mobile phone , enter camera mode, and hold the lens over the IR LED.
The "live preview" mode of the camera should be sufficient to see a blinking light emanating from the IR LED.
Even though you can't see this light with your own eyes, your mobile phone can reveal it!
If the IR LED is blinking, you should be able to power up the helicopter and hold it over the IR LED. The blades should begin to spin after a few moment's delay.
NOTE if you are using iPhone, this method might not work. The iPhone seems used a infrared filter lens, so that you can't see infrared with an iPhone camera. (We tested with an iPhone4S).
If the helicopter does not work, make certain that the IR receiver on the back of the helicopter is lined up with the IR LED.
Step 9: Flying the Helicopter
At this point you should have a working, tested circuit, and are ready to begin flying the Puzzlebox Orbit helicopter.
In Step 5, we discussed how to use the Arduino IDE to connect to your Arduino board and upload the software. Under the "Tools" menu of the Arudino IDE you will find an option for "Serial Monitor." Pulling that up and making sure that baud rate is set to 9600 will allow you to use your keyboard to set control commands to be issued to the helicopter.
The following commands can be entered, one at a time (followed by pressing "Enter"):
U: Increase throttle slightly (this value causes the helicopter to lift off the ground)
D: Decrease throttle slightly
L: Increase yaw slightly (this should cause the helicopter to tilt and fly to the left)
R: Decrease yaw slightly (this should cause the helicopter to tilt and fly to the right)
F: Increase pitch slightly (this should cause the helicopter to tilt and fly forward)
B: Decrease pitch slightly (this should cause the helicopter to tilt and fly backward)
P: Set throttle to 85% (approximately equivalent to hovering in the air)
0: Set throttle to 0 (land).
Many IR devices support the concept of "channels" which allow multiple versions of the same vehicle to be operated in the same area at the same time without controls interfering. This can be controlled through the software as well:
1: Select control channel "A"
2: Select control channel "B"
3: Select control channel "C"
There is an additional control scheme by which you can directly set a specific throttle level. In other words, if you wanted to make the helicopter go from sitting at rest to hovering at a specific level, through experimenting with the "U" and "D" commands you might determine that a 85% throttle is just about right to make it stay in one place. You could then immediately set this level by using the "x" control command followed by a three-digit number:
x085: Set throttle to 85%
x000: Set throttle to 0%
x100: Set throttle to 100%
x048: Set throttle to 48% (etc.)
This last control mechanism is particularly helpful if you were a developer seeking to write an application that could fly the helicopter autonomously or according to specific external conditions. For example, when the Puzzlebox Orbit is being operated under brain-control using an EEG headset, it might be desirable to have the helicopter take off and hover whenever mental concentration and focus are above a certain threshold. Software connected to the Arduino via a USB port could simply issue the hover throttle command at that moment("x085"). When concentration fell back down below that threshold, the 0% throttle command could be issued ("x000").
Taking this one step further, it would be possible for a loop to cause the helicopter to smoothly take of and land by briefly sending intermediate values (x030, x040, x050, x060, x070, x080, x085 and vice versa to land).
Finally, a complete "flight plan" could be created to cause a helicopter to rise, fly forward, circle the room, and land again, using a pre-programmed combination of methods above.
If you wish to purchase your own Puzzlebox Orbit, at the time of writing it is available through Kickstarter:
neliuz made it!