Simple IR Remote Controls

by Boomer48 in Circuits > Arduino

3110 Views, 18 Favorites, 0 Comments

Simple IR Remote Controls

IR Sensor Output.jpg

A few years ago when I was only doing PIC microcontroller projects my first project was an LCD display interface. My second project was an IR remote control receiver that displayed the codes on the LCD display. After that I found a number of practical applications for receiving and decoding simple IR remote codes as well as an application for an IR remote transmitter. Most of my hobby projects these days use an Arduino or one of the ATmega or ATtiny chips and sometimes I translate an old PIC assembly language project to run on an Arduino. While there are many Arduino IR libraries and/or other how-to projects, many of them are overkill for real world applications. What I present in this Instructable are some simple, customizable, IR applications for adding remote control to your project.

IR Code Formats

NEC TX Protocol.jpg
NEC Bit Modulation.png
IR Sensor Output.jpg

There are a few different IR code formats out there but many manufacturers use the NEC format or some variation of that format. That’s what we will be using here. The pictures here show three aspects of the waveform. In the first picture we can see that the actual transmitted waveform consists of a long pulse on the front end, 32 data pulses, and an end of transmission pulse. The start pulse lasts for 9ms and is followed by a space of 4.5ms. Logic “0” is a 562.5us pulse followed by a 562.5us space. Logic “1” is a 562.5us pulse followed by a 1.6875ms space.

As can be seen in the second picture, each high pulse consists of many smaller pulses. This is the carrier frequency which, in the NEC format, is 38-kHz. That is what the receiver module looks for when decoding the transmission. The low parts of the waveform are basically an off time for the IR LED. In other words, no pulses are being transmitted. The term for this type of function is known as “signal gating”. Very simply, when we open the gate, a stream of 38-kHz pulses comes out and when we close the gate no pulses come out. We will see in the “IR Transmitter” section that this is easy to implement with the ATtiny chips.

The IR receiver needs to receive the bursts of carrier pulses and decode them into a usable TTL sequence. Fortunately, there are small, cheap modules that do the work for us. The third picture shows the output of the receiver module and, as can be seen, the module inverts the original signal. The software then measures the pulse widths to detect the start of the message and to determine the bit values. In the original NEC data format, the first byte is the address of the target device (e.g.: your TV), the second byte is the inverse of the address, the third byte is the command, and the fourth byte is the inverse of the command. That only allowed 256 address combinations so the format was revised to use the second byte to extend the address combinations to 65,536. I’ve seen remotes of both kinds around the house. Some manufacturers also use the fourth byte for their own purposes. A typical example of that is TiVo. If you build your own you can use whatever code scheme you like and even program those into a cheap learning remote.

IR Transmitter

ATtiny85 IR Transmitter.jpg
ATtiny84 IR Transmitter.jpg
IR TX Front.jpg
IR TX Inside.jpg

The IR Transmitter I originally made was just a breadboard tool so that I could generate the specific commands I wanted to program into a cheap learning remote. As seen in the pictures, I did make a usable remote for one of my projects. It’s battery operated so I used a low-power ATtiny85 circuit similar to what I used in my “ATtiny85 RF Remote” Instructable. For the IR remote I needed more power capability than in the RF remote so I used a 14500 Li-ion battery instead of a button battery. The 14500 is the same size as a standard AA battery but provides around 4 volts and can be recharged using most 18650 chargers. The circuit should also work OK with a pair of AAA batteries.

The hardware is pretty simple with the ATtiny generating a PWM frequency of 38-kHz that drives a small signal NPN transistor. The transistor, in turn, powers a common IR LED. The IR LED is one that I scrounged from a broken remote but they are cheap if you need to buy one. When I looked online at similar projects I found a wide variety of circuits and comments about the proper duty cycle and amount of current to apply to the LED. It really has to do with how much range you want for the remote. Keep in mind that we are applying short pulse bursts of current to the LED so it’s not the same situation as if we were turning it on for long periods. What I finally settled on was a 50% duty cycle for the 38-kHz pulses. I also wanted to keep the peak power below ½ watt so in my original prototype I wired a pair of 82 ohm, ¼ watt resistors in parallel for R1. Originally I used a single 75 ohm, ¼ watt resistor and that gave me a maximum range of about 14 feet. With the parallel pair of 82 ohm resistors (effectively 41 ohms) it worked at double that range.

I like to have a visible indicator of a button press so one of the ATtiny outputs is dedicated to blinking an LED when that happens. That only leaves 3 pins available for button inputs on the ATTiny85. If you need more than that, the ATTiny84 can provide 8 inputs. The provided software works for both chips. There is a “define” that needs to be uncommented to use it on the ATtiny85. The transmitted codes are set in the interrupt handler. There are three things to keep in mind when setting up the Arduino IDE for programming the chips. First, select the option for “no bootloader”. Second, select the option for the 8-MHz internal clock. Third, disable the "milli/micros" function. You will need to click on the “Burn Bootloader” command before loading the software into the chip. This actually sets the “fuses” in the chip for the selected options.

The ATtiny chips provide some dedicated pins for the PWM output. In order to gate the pulses on the selected pin all we have to do is to change the definition of the pin from an input to an output. To close the gate we simply change the pin definition back to an input. That is done on the fly in the software. There are “defines” at the top of the software for the number of microseconds needed to gate the pulses for each portion of the transmission. Even though we turned off the “millis/micros” functions, the “delayMicroseconds” command still works and that is what is used to time the gate periods.

IR Decoder

IR Decoder LCD.jpg
IR Decoder.jpg

The hardware connections are shown in the diagram above. The 3-pin IR Receiver I used came from some old piece of electronics equipment but you can buy an IR Receiver for less than a dollar. Make sure that the IR Receiver has the three pins shown in the diagram and that it receives on the 38-kHz frequency. It should be easy to find because that’s the most common version available.

I use a Nano for my IR detector mostly because I have some simple breakouts boards that make prototyping pretty easy. The hardware connections and the software should easily translate to other versions of the Arduino. I also include my simple version of the LCD software instead of using the Arduino library. The software measures the pulses decoded by the IR module, forms them into bytes, and then displays them on the LCD when all four bytes have been received.

IR Receiver

The IR receiver is based on the IR Decoder hardware and software. The primary difference is the elimination of the LCD display. The software receives the bytes but then the header bytes are checked for validity before decoding the command byte. Software can then be added to perform various tasks based on the received command. In a subsequent project I use the received commands to provide digital controls for power on, volume, and source selection for a cheap audio amplifier. A sample program is provided here to show where you can add controls for your application.