Introduction: Read/emulate Remotes With Arduino and Raspberry Pi

Picture of 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:

Step 1: Go Get Stuff

Picture of 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

Picture of 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

Picture of 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

Picture of 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

Picture of 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.

Step 6: Decoding Value Using Arduino Code

Picture of 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?

#define IRpin_PIN       PIND          // Pins for IR sensor (do not change)
#define IRpin           2             // Pin number for IR sensor (do not change)
#define DATA_LOC        0             // Data located in which list? 0: OFF, 1: ON
#define LOW_VAL         550           // Value to interpret as 0
#define HIGH_VAL        1560          // Value to interpret as 1
#define START_ON        8500          // Start code's ON value
#define START_OFF       4200          // Start code's OFF value
#define RANGE1_START    17            // From which index to start decoding?
#define RANGE1_END      24            // Till where to decode?
#define RANGE2_START	25            // comment this #define if you do not have repeated data
#define RANGE2_END 	32            // comment this #define if you do not have repeated data
#define RANGE2_INVERTED	1             // is range2 inverse/complement of range1? 1: yes, 0: no
#define MAXPULSE        65000         // the maximum pulse we'll listen for - 65 ms
#define MAX_PULSE_PAIRS 60            // maximum number of pulse pairs to store
#define FUZZINESS       5             // What percent variation is allowed: 2 = 50%, 3 = 33.3%, 4 = 25%. 5 = 20%

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.

When you press a button on your remote, it will provide the decoded value for that button in the serial monitor.

Now your Arduino can know which button is being pressed. You can now assign different tasks to different buttons, such as turning an LED on and off with the power button, increasing/decreasing brightness with volume buttons, speeding up/slowing down blink speed with channel up/down buttons, etc.

Step 7: Emulating IR Signals Using Arduino

Picture of Emulating IR Signals Using Arduino

You can also send the IR signals using Arduino instead of using a remote. I modified ladyada's code so you can send code for any button by just providing its decoded value. This code will send the IR signal on reset and then after every minute.

To setup your own remote, choose any button from your remote and get the formatted C-array for it provided by the IR-reading Arduino code in Step-3. Replace the values assigned to uint16_t IRsignal[] array with the formatted array you got.

Now you can code it to send different IR signal by calling EncodeData() with the decoded value of the button you want to send as a parameter, and then calling SendIRCode(). For example you want to send IR signal for button whose decoded value is 2, call EncodeData(2) followed by calling SendIRCode(). As simple as that!

The attached arduino sketch waits for you to send the decoded value of the button you want to emulate and sends the IR signal for it. Remember to set line ending in serial monitor as 'Newline'.

Step 8: Reading IR Using Raspberry Pi

Picture of Reading IR Using Raspberry Pi

Reading and decoding IR signals using Raspberry Pi is extremely easy. We only have to use LIRC (Linux Infrared Remote Control) and it will handle the most of the heavy lifting work for us. So let's get started...

Connect an IR receiver to your Raspberry Pi as shown. IR sensor needs to be connected to 3.3V instead of 5V. We are connecting the data pin of IR sensor to Pin-18 of Raspberrty Pi.

Power up your Raspi, make sure you have internet connected.

Upgrade RPi2 firmware to newest version using these commands in order:

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update
sudo reboot

After reboot, type the following command to install LIRC:

sudo apt-get install lirc

Open the /etc/modules file:

sudo nano /etc/modules

and add these lines at the end to make LIRC start up on boot and set the IR sensor pin to Pin-18 and IR LED pin(for later) to Pin-17:

lirc_rpi gpio_in_pin=18 gpio_out_pin=17

To save, press Ctrl+X -> y -> Enter

Now we need to edit the LIRC hardware configuration file. Open it using:

sudo nano /etc/lirc/hardware.conf

Change the following lines:


That's it! To make it work, you need to reboot your Raspi once:

sudo reboot

Note: buda.suyasa found out that to make LIRC work on Raspberry Pi 2, you need to edit /boot/config.txt using:

sudo nano /boot/config.txt

add the following line to it:


Step 9: Reading and Recording IR Signals Using Raspi

Picture of Reading and Recording IR Signals Using Raspi

To check if your Raspberry Pi is reading IR sensor properly, you need to first stop the LIRC daemon(don't worry. There's no demon, it's just a fancy linux name for a background running process):

sudo /etc/init.d/lirc stop

To run a program to get the IR signal timings(similar to our IR-reading Arduino code), use:

mode2 -d /dev/lirc0

Now point your remote at the IR sensor and it should spit out a series of pulse-space(aka ON-OFF) IR timing values. This means everything is working perfectly.

Let's record the button values. The daemon needs to be in stopped state for this to work as well.

First, get the list of allowed button names using:

irrecord --list-namespace

Run the below command to start recording IR signals for each button and assigning an allowed name to it:

irrecord -d /dev/lirc0 ~/lircd.conf

It will take you through some weird but detailed instructions. Follow them and you will end up with a config file storing IR signals for each button. You can view it using:

sudo nano lircd.conf

It's best if you replace the name field value in the header with something relevant (I chose samsungTV).

Replace the default blank config file with your remote's new config file:

sudo cp lircd.conf /etc/lirc/lircd.conf

We're done with recording.

To test it out, start the LIRC daemon:

sudo /etc/init.d/lirc start

Run the following command to get the button's assigned name whenever you press that remote button:


Note: If you are getting multiple output per button press, you can add

suppress_repeat 2

in the /etc/lirc/lircd.conf file so it ignores the next 2 repeat values.

Step 10: LIRC With Python - Part I

Picture of LIRC With Python - Part I

Using LIRC with python is extremely easy. We'll use the bundled slidepuzzle python game to demonstrate. I'll use the arrow keys on my remote to move the tiles in game. I'll provide the finished file along with the simulate game I modified to play with remote as well.

Firstly, we'll need to make licrc config file. This file contains information on what string to send to python when a particular button is pressed. Create and open a file using:

sudo nano /etc/lirc/lircrc

Paste the following lines:

button = KEY_UP
prog = slidepuzzle
config = up
button = KEY_DOWN
prog = slidepuzzle
config = down
button = KEY_LEFT
prog = slidepuzzle
config = left
button = KEY_RIGHT
prog = slidepuzzle
config = right

Between each begin and end, button is assigned the button name, prog is the program name and config is the string to be sent. So when a button is pressed, LIRC sends config string to prog program.

You have to change the button names with 4 buttons names you assigned to your remote.

Step 11: LIRC With Python - Part II

Picture of LIRC With Python - Part II

To use LIRC with python, we need to import lirc module first. Open IDLE and open It should be in /home/pi/python_games. At the top with the other imports, add

import lirc

We need to create a connection to LIRC. For that, write the below line of code just before the main game loop starts:

sockid = lirc.init("slidepuzzle", blocking = False)

LIRC matches the first parameter(slidepuzzle) with the prog value in lircrc and only returns button matches for them. the second parameter(blocking = False) tells LIRC that it should not stop the python code execution to wait for the button press.

Just before we go into the event handling loop, write:

codeIR = lirc.nextcode()
if codeIR and isValidMove(mainBoard, codeIR[0]):
    slideTo = codeIR[0]

LIRC stores the button presses in a queue. lirc.nextcode() removes the next value from queue and return it. So if we pressed the remote button assigned to KEY_UP, we will get a list containing the string up i.e. codeIR will be ['up'].

In the next line, we check if codeIR isn't empty and that the move we are trying to make is a valid one. If yes, we set slideTo to the returned string in codeIR. Since slidepuzzle assigns up, down, left, right strings to slideTo to make the blocks move, we directly assigned that string saved in lircrc's conf to make it move.

That's all. I've done the same with python game and attached both of them. Enjoy the games with a remote!

Step 12: Recreating IR Signals With Raspi

Picture of Recreating IR Signals With Raspi

LIRC allows you to send the IR signals as well. If you have set up lircd.conf as instructed in Step-9, you can send IR signal for one of the recorded buttons using LIRC very easily. All you have to do is run the command:


Here, replace samsungTV with the name of the remote you set in header of lircd.conf. KEY_VOLUMEUP has to be replaced by the name of the button you want to send.

If you wish to send the IR signal using Python, just import at the top:

import os

Now wherever you want to send IR signal, just call:

os.system("irsend SEND_ONCE samsungTV KEY_VOLUMEUP")


AlexandreL62 (author)2017-12-29

I could follow your instructions at Raspbian Jessie (8) on Noobs 4.2.2

When I updated to the latest Raspbian released on Dec 2017 at Noobs 4.2.4, some instructions did not work (sudo /etc/init.d/lirc stop) and I could not send irsend.

Also, when I record the IR it requested the remote name and lot's of other things did not match your instructions.

If you could make another instruction it would be great!

VikiM4 (author)2017-10-15

i am using a multimedia remote which has a button named (input) while pressing it changes the Mode of music from AUX to Bluetooth to Radio respectively

i got the code for input button (807F6897) which is working fine and it loops it in changing the mode like the remote.

and i got the full code of it while pressing it three times as follows

Decoded NEC: 807F6897 (32 bits)
Raw (68): 12762 8900 -4450 550 -1700 500 -600 550 -550 600 -550 500 -600 550 -550 600 -500 550 -600 550 -550 550 -1700 550 -1650 550 -1700 550 -1650 550 -1700 500 -1700 600 -1650 550 -550 600 -1650 550 -1650 550 -600 550 -1650 550 -600 550 -550 550 -550 550 -1700 550 -550 500 -600 550 -1700 500 -600 550 -1700 500 -1700 600 -1650 550

Decoded NEC: 807F6897 (32 bits)
Raw (68): 8526 8900 -4500 550 -1650 550 -550 550 -550 600 -550 550 -550 550 -550 600 -550 500 -600 550 -550 600 -1650 550 -1650 550 -1700 550 -1700 550 -1650 550 -1700 550 -1650 550 -550 600 -1650 600 -1650 550 -550 550 -1650 550 -600 550 -550 550 -550 550 -1700 550 -550 550 -600 550 -1650 550 -550 600 -1650 550 -1650 600 -1650 550

Decoded NEC: 807F6897 (32 bits)
Raw (68): -4918 8900 -4450 550 -1650 550 -600 550 -550 550 -550 550 -600 550 -550 550 -550 550 -600 500 -600 550 -1650 550 -1700 500 -1750 550 -1650 600 -1600 550 -1700 550 -1700 550 -550 550 -1700 550 -1650 550 -550 550 -1700 550 -550 550 -550 600 -550 550 -1650 600 -550 500 -600 550 -1650 550 -600 550 -1650 550 -1700 550 -1700 500

now my question is i only use bluetooth mode and radio mode and dont want the button to cycle all the three modes but input press only gives one code(807F6897) whatever times we press it

can we use these raw codes to change the mode into bluetooth and radio mode

please help

VikiM4 (author)2017-10-15


i am using a multimedia remote which has a button named (input) while pressing it changes the Mode of music from AUX to Bluetooth to Radio respectively

i got the code for input button (807F6897) which is working fine and it loops it in changing the mode like the remote.

and i got the full code of it while pressing it three times as follows

Decoded NEC: 807F6897 (32 bits)
Raw (68): 12762 8900 -4450 550 -1700 500 -600 550 -550 600 -550 500 -600 550 -550 600 -500 550 -600 550 -550 550 -1700 550 -1650 550 -1700 550 -1650 550 -1700 500 -1700 600 -1650 550 -550 600 -1650 550 -1650 550 -600 550 -1650 550 -600 550 -550 550 -550 550 -1700 550 -550 500 -600 550 -1700 500 -600 550 -1700 500 -1700 600 -1650 550

Decoded NEC: 807F6897 (32 bits)
Raw (68): 8526 8900 -4500 550 -1650 550 -550 550 -550 600 -550 550 -550 550 -550 600 -550 500 -600 550 -550 600 -1650 550 -1650 550 -1700 550 -1700 550 -1650 550 -1700 550 -1650 550 -550 600 -1650 600 -1650 550 -550 550 -1650 550 -600 550 -550 550 -550 550 -1700 550 -550 550 -600 550 -1650 550 -550 600 -1650 550 -1650 600 -1650 550

Decoded NEC: 807F6897 (32 bits)
Raw (68): -4918 8900 -4450 550 -1650 550 -600 550 -550 550 -550 550 -600 550 -550 550 -550 550 -600 500 -600 550 -1650 550 -1700 500 -1750 550 -1650 600 -1600 550 -1700 550 -1700 550 -550 550 -1700 550 -1650 550 -550 550 -1700 550 -550 550 -550 600 -550 550 -1650 600 -550 500 -600 550 -1650 550 -600 550 -1650 550 -1700 550 -1700 500

now my question is i only use bluetooth mode and radio mode and dont want the button to cycle all the three modes but input press only gives one code(807F6897) whatever times we press it

can we use these raw codes to change the mode into bluetooth and radio mode

please help

AnthoE (author)2017-09-09

I followed your tutorial and working great with arduino but it's not working on Raspberry with Raspbian Stretch, tried several times with fresh OS installs but no luck, I get stuck when i run:

$ sudo /etc/init.d/lirc stop

I get "command not found" but it seems to work when i run:

$ sudo /etc/init.d/lircd stop

[....] Stopping lircd (via systemctl): lircd.serviceWarning: Stopping lircd.service, but it can still be activated by:
. ok

When I run mode2 I always get "Partial read 8 bytes",

$ mode2 -d /dev/lirc0

Using driver devinput on device /dev/lirc0
Trying device: /dev/lirc0
Using device: /dev/lirc0
Partial read 8 bytes on /dev/lirc0

Any help would be appreciated, I've been stuck for a few days ^^

AnthoE (author)AnthoE2017-09-19

EDIT: LIRC is not working on Raspbian Stretch, use Jessie if you have similar issues.

Antzy Carmasaic (author)AnthoE2017-09-10

Since you've followed a few tutorials, there might be a hotch-potch of settings clashing with each other. I suggest you to try with fresh install of Raspbian either on this card or another one.

Then, follow the instruction in Step-8 and 9 closely(especially the raspbian update and upgrade).

If after following it till end of Step-9 and things still don't work, you can try buda.suyasa's trick mentioned at the end of Step-8.

Antzy Carmasaic (author)2017-09-11

That's weird. Are you using Rapsberry Pi 3? As you say, could be a Raspbian Stretch problem. You can try with Jessie and see if it works. The archived firmwares are here and I guess this is the latest Jessie release.

AnthoE (author)Antzy Carmasaic2017-09-16

Hey Antzy! Finally had time to test a little more.
LIRC works on Wheezy and Jessie but not working on Stretch, might be good to indicate it on your tutorial (tested on both RPI3 and RZero). After install it seems like Stretch doesnt have a valid hardware.conf file. Looked around but couldn't find it anywhere. Won't work even after creating it myself. I'm back onto Jessie ^^

Dragojackc (author)2017-08-31

I'm using Ubuntu MATE on my Rasperry PI, and when I try to run the slidepuzzle game, it just says "no module named lirc". It seems I haven't installed lirc for python, so does anyone know the command I can use to get it?



Start from Step-8 and follow each step to install and setup lirc for using with python.

Also, make sure you are using IDLE and not IDLE-3.

thanks, I was using idle3. This is a great instructable antzy!


InvasionI (author)2017-08-06

In my case it doesnt work. The decoder works perfectly but im not able to emitt. Everything else works. I suppose it to be to slow. can anyone help me?

Chicagosparky (author)2017-04-22

using the Pi 2. After following the instructions exactly several times, I get the following after trying to install LIRC:

No valid /etc/lirc/lircd.conf has been found

Remote control support has been disabled

Reconfigure LIRC or manually replace /etc/lirc/lircd.conf to enable....

What did I miss?



Which command is giving you this error? Is it sudo apt-get install lirc?

Did you update your raspi before installing LIRC?

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update
sudo reboot

Antzy: Which version of the Raspberry Pi were you using when you wrote this?

I was using Raspberry Pi B at the time. But that shouldn't be the problem as many people have reproduced the steps on later versions as well.

Did you check whether /etc/lirc/lircd.conf exists or not?

I saw a comment here with the same problem and giving the solution:
I was having the same problems as Taavi. When I ran "mode2 -d /dev/lirc0" I got a permission denied error and when I added sudo I just got nothing. Turns out I had the IR receiver wired backwards. I probably misinterpreted your schematic (I'm pretty new at all this) but I think you have the VCC and OUT pins reversed (Also using a TSOP38238). So basically I had the software side working properly, just a couple crossed wires on the hardware side.

So please check your connections as well if you have anything connected to GPIO. Or remove everything and try once.

Chicagosparky (author)2017-04-23

I did all that then tried to install the lirc. The errors appear after the "apt-get install lirc" completes it's run. Thanks for the help!

Tany44 (author)2017-04-13

I followed the steps for Raspberry Pi. My Television Receives the message but then it seems that no key has been pressed. For example: When i send KEY_MUTE my tele receives the command but it does not mute. What might be the problem ??

Antzy Carmasaic (author)Tany442017-04-13

Try with another remote controlled device. LIRC might be having trouble that particular remote. Also, triple check the steps you performed with the ones listed in this instructable. Most problems arise because of missing something tiny but important.

Tany44 (author)Antzy Carmasaic2017-04-14

Yeah. I tried with a different remote and it works. Thank you very much. This tutorial is just very awesome.

PensionWiz (author)2017-04-02

Thank you very much for this tutorial - it was very helpful, but I'm not quite there yet. Everything seems to work exactly as you've described for the setup. When I make the modifications to the code for slidepuzzle, I get an error (using either python2 or phython3) with the sockid line:

File "lirc.pyx", line 122, in lirc.init (lirc/lirc.c:1755)

InitError: Unable to initialise lirc (socket was -1 from C library).

I also created a small test code just to see if I could read data from the IR remote and it gave the same error. Any help would be appreciated.

Thank you,

Pi Rookie

PensionWiz (author)PensionWiz2017-04-03

Aha - I have solved my own problem! I realized that I missed the line to copy my config file into the lirc directory. As soon as I did that - all worked fine! Thanks again for this excellent tutorial!

JuanM319 (author)2017-03-16

Hello, I am following the tutorial and I have managed to put the codes of two controls in the same file, but I have an air conditioner that I can not record the codes, it is a daitsu DS-18UIM, can you help me?

Antzy Carmasaic (author)JuanM3192017-03-16

You will have to be a bit more specific why you are unable to record it. Are you able to get any pulse-space readings with mode2 -d /dev/lirc0?

JuanM319 (author)Antzy Carmasaic2017-03-17

Hello, sorry for being so brief, with the command you say, I read the impulses just like with the television remote, when I have problems is when I save it in the configuration file, apparently, at that time does not read well , I have read for other websites that the controls of the arie conditioning works differently to the televisions for example

Antzy Carmasaic (author)JuanM3192017-03-19

AC remotes send values like temperature, fan speed etc. which is encoded into the signal which might be causing LIRC irrecord to find any pattern.

You can set LIRC for reading specific settings(like 25 degrees) which I'm pretty sure it will be able to record. Before recording, set temperature to 24 degrees on remote. Then during recording, increase it to 25 degrees. When it asks for multiple key presses during recording, just cover the remote's IR led and set temperature back to 24 degrees (so LIRC doesn't detect the code for 24 degrees). Then uncover the LED and increase it to 25 degrees again.

That's a laborious process but I think it should work and you can record IR code for a few commonly used values.

You can also try out this instructable specifically for decoding AC remotes using LIRC:

It's a bit technical and decodes the pulse-space pair values to get the IR codes similar to what I did with the Arduino version.

OmA8 (author)2017-01-23

Hello! I was amazed by your tutorial, I´ve found it after several days of research.

Now I am concern because for some reason the IR signals are not save at the lircd.conf file. I mean, I finish the process of recording, and the final leyend is "sucessfully written config file",

but, I have this message just before finishing recording.

"checking for toggle bit mask, and then No toggle bit mask found" (please see the attached image)

when I open the file there are no codes..

Do you have any idea? Maybe I am missing something, please if anybody could help me I will really thankfull!

JuanM319 (author)OmA82017-03-16

Hi, remember to press different buttons and no more than one second each

Antzy Carmasaic (author)OmA82017-01-26

A few remotes toggle a few bits of data every time you push a button. So if in the first push it sends 01110110 and it toggles the last 2 bits on every push, in the next button press it will send 01110101 and again 01110110 for pushing that same button again. So toggle bit mask is used to just check for those bits by making you press the same button multiple times. That is nothing to worry about if no toggle mask is found.

It has been a long time since I used LIRC last and I might be wrong, but as far as I can remember, it takes only valid button names during irrecord. Your button names seem to be non-valid as valid ones I used were in all CAPS. You can generate a list of all valid buttons using(given in step-9):
irrecord --list-namespace

OmA8 (author)Antzy Carmasaic2017-02-01

thank you very much Antsy! It finally works Now I am dealing with lirc_web..

ma 8az (author)2017-03-03

Amazing instructable! I could do everything really easily until step 9 were I got stuck every time I write mode2 -d /dev/lirc0 it comes up with

mode2: could not get file information for /dev/lirc0

mode2: default_init(): No such file or directory

Do you know how I could fix this?


Antzy Carmasaic (author)ma 8az2017-03-04

Which Raspberry Pi are you using? If using Raspberry Pi 2 or 3, use buda.suyasa's tip I've mention at the bottom of Step-8 and edit /boot/config.txt.

Sword_xx made it! (author)2016-10-07

The best ir tutorial i have found. Thank you so much!
i only tested the raspberry part. But this is very great.

P.S. there exists ir transmitter and ir receiver which already contain the transistors and resistors. For beginners i can recommend this ones.

JamesV41 (author)Sword_xx2017-01-18

Hey! I´ve got a question I bought the same package as you but it seems that the range is somehow only a few meters? Can you confirm that? For me it does not make any sense as in my understanding the light would travel further anyways... And I mean the signal length does not change over a longer distance otherwise my remote for the lightbulb would not work either.....

Maybe you have some insight for me?

Thanks in advance!

Antzy Carmasaic (author)JamesV412017-01-18

The circuit could be same as Sword_xx's but components could be different. Some IR LEDs throw light in all directions (like a light bulb) so you can aim a bit off target and it would still wor,k but don't work for long distance. Another kind has a focused beam and you have to aim it at the receiver to work, but since all light is concentrated in one direction, it will work from farther away.
There could be other reasons as well such as transmitting power, ambient IR light, receiver sensitivity etc. If you want to increase distance, replace the IR LED with one that has a better specs or use multiple IR LEDs.

JamesV41 (author)Antzy Carmasaic2017-01-19

Hey! I know the problem now. It seems that the lightbulb´s light is interfering with the signal! When I have my bulb on the lowest mode it works a treat! I have to play with the angles..

Thanks, though!

Bests from Germany

Antzy Carmasaic (author)Sword_xx2016-10-15

That is a great find. Using those ready-made boards certainly saves a lot of time and trouble in putting together the circuit, especially for beginners.

RupertK (author)2017-01-01

Thanks. I got the ir send working using your code but it did not repeat every minute as you stated above:"This code will send the IR signal on reset and then after every minute.". Looking thru the code I cant see this kind of code either? I want the IR to send every day at same time roughly for 5 days. Could I adjust such a delay from one minute to 24 hours? Where or what is the code? I can only spot a 1000ms dely in code?

Antzy Carmasaic (author)RupertK2017-01-03

For scheduling tasks, you should use cron to run the IR code. You can start off from here:

subzero69 (author)2016-11-16

I'm getting an error saying

'File "", line 9, in <module>

import lirc

ImportError: No module named lirc'

Have gone through the set up. Unsure what could be wrong. :(

There are 2 versions of Python (2 and 3) on Raspi. Try with both. Will probably work with one of them.

I used this and it worked.

sudo apt-get install python-lirc

MuhammadI221 made it! (author)2016-10-16

Thanks a lot for this instructable, using the IR_Reading.ino sketch
provided and some others info form other website, I succesfully decode
my Panasonic AC (without heater, for Indonesia market).

I have to
increase the number of pules pair in the sketch to 240, because it turns
out my Panasonic AC use 216-bit protocol, for total around 220 pulse
pairs, to be able to record the complete signal.

OvidiuP5 (author)2016-09-08

Hey guys. I have some weird situation. Everything seems to be working fine but when I do mode2 -d /dev/lirc0 I get lots of vaues even though I'm not pressing any buttons on any remote. Do you have any idea why that happens?


Antzy Carmasaic (author)OvidiuP52016-09-10

Check if the connections are proper. Could be a fluctuating voltage level due to a loose connection. Also try covering the receiver to see if the random values stop(could be another source in the room).

SeamusFrederick (author)2016-07-29

Your tutorials are very noob friendly. Thanks for that. Instant follow.

humpri (author)2016-03-18

Hi Antzy,

congratulations to this great tutorial!

I wanted to control my python prog on a RPi with a remote control. LIRC worked fine so far, with "irw" I could see all my button presses as output on the screen.

For use with python I also had to install python-lirc, right?

But whenever I start my python prog I get this error:

lirc.InitError: Unable to load default config ~/.lircrc or /etc/lirc/lircrc

although there is a lircrc file in /etc/lirc/

This now looks like this (for a first test)


prog = lcdtest2
config = CHdown
Antzy Carmasaic (author)humpri2016-03-18

That's peculiar. Did you put the spaces or tabs exactly as the format in the default lircrc file? You can see the spacing demo under the "The lircrc file format" section on this page:

humpri (author)Antzy Carmasaic2016-03-20

Solved it

and yes, it was something stupid as I expected:

I created the lircrc on a windows machine and copied it to the raspberry. So there was the problem with the different text file formats. After running

dos2unix /etc/lirc/lircrc

it worked!



humpri (author)Antzy Carmasaic2016-03-18

Many thanks for your quick response! And for the link. Unfortunately it didn'thelp, neither with tabs nor with spaces. I guess its probalby something really stupid. I will let you know when I have solved it!

About This Instructable




Bio: I'm programmer and an electronics hobbyist. I try to find that point where software meets hardware meets art. "Necessity is the mother of all ... More »
More by Antzy Carmasaic:IoT Time Warp Dali ClockPure White Background Photography Using SmartphoneRainbow Roller
Add instructable to: