Read emulate remotes with Arduino and Raspberry Pi

Remotes are everywhere. They are the interface to your TVs, music systems and what-not. You probably have a few spare ones lying around, devastated at the demise of their better halves. Cheer them up and put them back into use! (Skynet approves…)

Here are some reasons why you should implement or emulate remotes in your projects (there is really no need to write down any reasons, but the things is, I really like lists):

  • if you need to hide your project someplace and need to operate it covertly like spy devices.
  • if project will be installed in some inaccessible or high reaching place like DIY overhead projector, bird house water supply, etc…
  • if you need to remove all those ugly buttons on your project enclosure.
  • if you want to control your remote-controlled devices like TV with an Arduino or Raspberry Pi.
  • if you want to survive the singularity (earn brownie points with Skynet while you still have a chance)
  • because remotes are cool

In this instructable, I'll show you how to: (Warning: Another list follows)

  • Using Arduino:
    • read remote signals using interrupts, so you can do other stuff on your Arduino while waiting for someone to press that button. Also interrupts will get the most accurate timing data.
    • decode remote codes to identify individual buttons without overflowing your memory. Usually saving a few button's IR codes will fill up your Arduino's memory…
    • recreate IR signals for any of your remote's button super easily. Control your TV with an Arduino!
  • Using Raspberry Pi:
    • read IR signals and implement it in your Python scripts. Play games with remotes!
    • recreate IR signal using Raspberry Pi. Make a universal remote control.

Note: Since posting this instructable, I've discovered Shirriff's IR library for Arduino and I suggest that for the Arduino part of this instructable as it's extremely easy to use. But if you want to understand how IR really works on those remotes, the instructable will provide a good read. Maybe if I get some free time, I'll add steps for Shirriff's IR library: emulate remotes with Arduino and Raspberry Pi

Step 1: Go get stuff

What you need depends on what all you want to do. Still the list is quite short:

  • IR sensor (adafruit link)
  • IR LED (adafruit link)
  • Arduino or Raspberry Pi
  • NPN Transistor PN2222
  • 1K ohm resistors
  • 220 ohm resistor
  • Some connecting wires
  • Of course, a remote control

Step 2: IR basics

There are already very detailed instructions on how to read and recreate IR codes from a remote. I'll try to build upon ladyada's IR tutorial. I'll explain the basics and give a brief overview, but I'll keep linking to ladyada's tutorial's pages for detailed instructions.

IR stands for Infra-Red. This is a part of the spectrum that goes beyond the red color and invisible to us. IR can be better called as heat waves. Whenever something radiates heat, be it a bulb, fire or sun, it radiates infrared rays. Even something that is not glowing(like a hot-plate) will be emitting IR. The IR we work with is generated by an IR LED. The IR is very weak and you will not feel its heat, but it is very useful for sending invisible focused rays to transfer data. Tip: Your average digital camera(even mobile camera) can view some amount of IR. Take a look at your remote's IR LED through your camera.

IR remotes use a technique called modulation to reduce noise and data loss. They take a frequency(38kHz is most commonly used for remotes) and turns the IR LED on and off at that frequency. The IR LED's cycle will be 1/38000 seconds = 0.0000263 seconds = 0.0263 milliseconds = 26.3 microseconds long. So the LED will turn on for half of that duration, i.e. 26.3/2 = 13.15 microseconds, followed by being off for the same duration, and this goes on over and over again. Data is read/sent by measuring how long we keep turning the IR LED on-off at 38kHz. A simple IR code might be: blinking/modulating IR LED at 38kHz for 1500 microseconds, then keeping the IR LED off for 50 microseconds, then again modulating IR LED for 1500 microseconds, followed by finally turning off the LED until user presses a button again.

The IR receiver is a 38kHz demodulator. It can only read remotes using that frequency to modulate signals. It will remain in HIGH state if you simply connect an IR LED to battery and shine on it. It will only give a LOW on its Vout pin when 38kHz modulated IR light falls on it. Create this simple circuit by ladyada to test your IR sensor. If we used a remote to shine the above simple IR code on the IR receiver, we will get a LOW on Vout for 1500 microseconds, then HIGH for 500 microseconds, then 1500 microseconds LOW, and finally HIGH indefinitely.

Step 3: Reading IR codes using Arduino

Now let's get to the interesting stuff. Connect your IR sensor to Arduino as shown in the image. I soldered some longer wires to my IR sensor and covered the joint with heat shrink. Make sure of the pinout of your sensor from its datasheet. Connect Arduino to PC and open up Arduino IDE.

I modified the code from this tutorial by ladyada to read a remote's IR codes so that it uses interrupts. Upload it to your Arduino. The .ino file is attached to this step.

As I mentioned in the previous step, the remote code is nothing but how long the modulated signal was being sent and how long it was not. On your Arduino IDE's serial monitor, you'll get a series of OFF-ON duration. This is the raw data sent by the remote. If we had a remote sending the example IR code we used in the previous step, we'd have something like this:

Ready to decode IR!!!

1234 usec, 1500 usec
500 usec, 1500 usec

int IRsignal[] = {
// ON, OFF(in 10's of microseconds)
150, 50,
150, 0}

The first block of codes is the raw time values in microseconds, the second is the same values divided by 10 and presented in the form of a C array, so we can directly use it in our Arduino code(we'll use it while recreating the IR signal). Notice that raw value columns are OFF-ON and the formatted values are ON-OFF. The first raw data value (1234 usec) is useless as it is the measure of time there was no signal(OFF) before we started receiving the first ON signal (so doesn't appear in formatted values). In the values formatted as an array, last value will always be 0 as the last OFF duration will only end when you press a remote button again.

Step 4: Decoding IR signal manually – Part I

Decoding IR signal implies mapping a different number to each button. So you can easily recognize the button by comparing the integer value representing that button instead of storing long IR codes for each button and comparing each value. To do this, we will process the IR timing values we got in the last step for each button. This step varies a lot from remote to remote. There are hundreds of remote protocols out there. This instructable aims to provide a basic understanding to cover most remotes, but the technique and codes can be modified to suit a complex one as well.

There will be a starting signal to your timing data. The starting signal is a unique ON-OFF pair value at the beginning to identify a remote. For my remote, it was: 8400, 4160. For some remotes, it might be more than a single ON-OFF value pair. Rest of the values(except starting code) can be usually grouped under 2 categories(about 20% difference is acceptable). All the values(besides start values) lies near to either 55 or 167 for my remote. If the starting code appears multiple times and the code which follows is always the same, then that means your remote is sending the same code over and over and you can remove the repetitive data.

Now pick a spreadsheet editor of your choice. You can use excel or any similar software. I chose LibreOffice(free & open source!). Write down the button names for all your buttons in the column headings. Copy-paste the value for your first button IR code into the spreadsheet. You can use the delimit function to separate the ON-OFF values. Remember to delimit using commas and spaces so there are no leading or trailing spaces to your values, else they will be interpreted as text instead of numbers. Place the OFF values below the ON value in the same column after a gap of one row. Do the same for the next button. Look closely and bold those values in column-2 which vary from those in column-1 for the same row. A difference of less than about 15-20% can be ignored.

Do this for 3-4 more buttons. Usually, all the values that change from one button to another will lie in the ON list or the OFF list. We only need the values that change from button to button since that is the data. Mine were in the OFF list, so I removed all the ON values from the spreadsheet. Then I laboriously copy-pasted the OFF values for all the buttons. Remember to bold the values that differ from the previous column. In this way, we'll be able to easily visualize in which range all the data lies. My bold values(i.e. data) lies in the index 17-24 and 25-32. There is no data for index 24 and 32 as the number of buttons easily fit within 7 bits and so the 8th bit is unused, but I'll include it in my range as well.

Step 5: Decoding IR signal manually – Part II

You'll need to have a basic understanding of binary numbering system for this step, since the data being sent will be decoded in binary. Create a new sheet and copy the rows with data(i.e. ones with bold values). I replaced all the values nearby 50 to 0 and those near 150 to 1. You can choose the reverse as well. I used a simple formula: =FLOOR(B3/100, 1) to convert all values below 100 to 0 and all above to 1. Each row is a single bit in the byte data for the button.

It is clearly visible in the image that values in range 3-10 are the complement of those in 12-19 for my remote, i.e. wherever there is a 0 in 3-10, the corresponding value in 12-19 is 1 and vice-versa. So the remote is sending the same data for each button press twice, one being the complement of the other. Generally, there will be less than 8 bits of data per button. 8 bits(= 1 byte) is enough to represent 256 buttons uniquely.

Choose one of these ranges. I chose the range 3-10 as this yielded smaller values, but that doesn't make much difference. Convert the collective value in your range for each button to form a binary value. You can do it manually if you find formulas confusing. I used this formula to concatenate all the bits and form a binary number in row-21: =CONCATENATE(B10,B9,B8,B7,B6,B5,B4,B3)

Convert this binary to decimal. You can do it using a scientific calculator or use this formula in row 22: =BIN2DEC(B21) This final value you get is the decoded value for that button.Read emulate remotes with Arduino and Raspberry Pi schematic

Step 6: Decoding value using Arduino code

Use the attached code to decode the value in your program. A few modifications have to be made in the variables on top.

DATA_LOC : set this to 0 if the data values(which we highlighted in bold) are in OFF list, else 1 for ON list

LOW_VAL : the value you are taking as 0 for decoding

HIGH_VAL : similarly, the value you are taking as 1 for decoding

START_ON : the value for the start code under ON

START_OFF: similarly, the value for the start code under OFF

RANGE1_START : where to start reading values for decoding for the first range. Do not use the excel row number. The first row is 0, next is 1 and so on…
RANGE1_END: similarly, where does the last value for decoding liefor range 1?

RANGE2_START : if your values are duplicated, then where does the duplicated values begin?

RANGE1_END: similarly, where do they end?

RANGE2_INVERTED: are the duplicated values in range 2 the complement of values in range 1?

Why are we using the 2 ranges if they are the same, or just complement of each other? It's just an extra check to see if both matches. Comment out #define for RANGE2_START if you do not have a range 2 or don't want to use the extra check.


For more detail: Read/emulate remotes with Arduino and Raspberry Pi

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top