In this post I demonstrate how to use an infrared remote to control the GPIO on a Raspberry Pi.
Normally a remote would be used to control a TV card or XMBC, however they also provide a good interface to control the GPIO on a Raspberry Pi.
Adafruit has a Mini Remote and IR sensor which are perfect for this.


In this example we will use the remote to control a number of LEDs connected to some GPIOs on a Raspberry Pi.
Connect the IR Sensor to the Raspberry Pi
Connecting the IR sensor to a Raspberry Pi is very easy as there are only 3 pins on the sensor, GND, 3v and Output. We will connect the output to GPIO 18. You can choose another pin, just take note of it as you will need to specify this pin when installing LIRC.
We will also connected up three LEDs to GPIOs 23, 24 & 25, and a 270Ω on the GND sound of each LED.
Here is my setup;
![]() |
![]() |
Installing LIRC
LIRC is a package that allows you to decode infrared signals of many (but not all) commonly used remote controls. LIRC runs as a daemon that will decode IR signals received by the device drivers and provide the information on a socket. We will then write a program in the user space to monitor this socket for input events using the LIRC client library.
1. We need to install LIRC and client libraries.
2.Then add the two lines below to /etc/modules . This will start the modules up on boot. Pin 18 bellow will be used to take the output from the IR sensor.
lirc_rpi gpio_in_pin=18
Also edit your /boot/config.txt file and add:
3.Edit /etc/lirc/hardware.conf and have it appear exactly as shown below.
# /etc/lirc/hardware.conf
#
# Arguments which will be used when launching lircd
LIRCD_ARGS="--uinput"
# Don't start lircmd even if there seems to be a good config file
# START_LIRCMD=false
# Don't start irexec, even if a good config file seems to exist.
# START_IREXEC=false
# Try to load appropriate kernel modules
LOAD_MODULES=true
# Run "lircd --driver=help" for a list of supported drivers.
DRIVER="default"
# usually /dev/lirc0 is the correct setting for systems using udev
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
# Default configuration files for your hardware if any
LIRCD_CONF=""
LIRCMD_CONF=""
3.Reboot
A quick test
To perform a quick test to see if LIRC is working, we need to stop the LIRC daemon and start mode2. mode2 shows the the pulse/space length of infrared signals.
pi@raspberrypi ~ $ mode2 -d /dev/lirc0
When buttons are pressed on your remote, mode2 will give a similar output to what is shown below.
pulse 627 space 514 pulse 624 space 513 pulse 599 space 521 pulse 618 space 1668 pulse 589 space 532
Record IR codes from your remote
irrecord will help us discover the IR codes used by your remote and assist with creating a conf file which will be used by LIRC.
Once started, irrecord will show detailed instructions on how to setup your remote. However, here is summary;
1.When asked, press all buttons on your remote until asked to stop.
2.Assign a pre-defined name to each button. running irrecord --list-namespace will display a list of available names.
The config file for the Adafruit MinRemote looks like this;
# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0-pre1(default) on Tue Oct 8 07:05:38 2013
#
# contributed by
#
# brand: /home/pi/lircd.conf
# model no. of remote control:
# devices being controlled by this remote:
#
begin remote
name /home/pi/lircd.conf
bits 16
flags SPACE_ENC|CONST_LENGTH
eps 30
aeps 100
header 9006 4447
one 594 1648
zero 594 526
ptrail 587
repeat 9006 2210
pre_data_bits 16
pre_data 0xFD
gap 107633
toggle_bit_mask 0x0
begin codes
KEY_1 0x08F7
KEY_2 0x8877
KEY_3 0x48B7
KEY_4 0x28D7
KEY_5 0xA857
KEY_6 0x6897
KEY_7 0x18E7
KEY_8 0x9867
KEY_9 0x58A7
KEY_0 0x30CF
KEY_DOWN 0xB04F
KEY_LEFT 0x10EF
KEY_UP 0xA05F
KEY_RIGHT 0x50AF
KEY_BACK 0x708F
KEY_ENTER 0x906F
KEY_SETUP 0x20DF
KEY_PAUSE 0x609F
KEY_PAUSE 0x807F
KEY_STOP 0x609F
KEY_VOLUMEUP 0x40BF
KEY_VOLUMEDOWN 0x00FF
end codes
end remote
Now replace the existing conf file (which is most likely empty) with the new one you just created.
Restart LIRC
Test the new remote conf file
You can use irw to test the new config. irw sends data from Unix domain socket to stdout
You should get a similar output as below.... This was me pushing the 1, 2 and 3 keys on the remote.
0000000000fd08f7 00 KEY_1
0000000000fd08f7 01 KEY_1
0000000000fd08f7 02 KEY_1
0000000000fd8877 00 KEY_2
0000000000fd8877 01 KEY_2
0000000000fd8877 02 KEY_2
0000000000fd48b7 00 KEY_3
Creating your program to control the GPIO
We will use C to write a simple program that will be used to control three LEDs connected to the GPIO.
We will also require WiringPi to control the PINs and use the LIRC client library to get data from the IR sensor.
First, install WiringPi
pi@raspberrypi ~ $ git clone git://git.drogon.net/wiringPi
pi@raspberrypi ~ $ cd wiringPi
pi@raspberrypi ~ $ git pull origin
pi@raspberrypi ~ $ ./build
The code
The code below will allow you to control three LEDs connected to the GPIO of a Raspberry Pi. We will use the 1,2 & 3 buttons on the numerical pad of the Adafruit mini remote to turn these LEDs off and on.
The code includes alot of comments which will help you understand how it works.
#include <wiringPi.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lirc/lirc_client.h>
#include <time.h>
void flipLED (int led);
//The WiringPi pin numbers used by our LEDs
#define LED1 4
#define LED2 5
#define LED3 6
#define ON 1
#define OFF 0
int main(int argc, char *argv[])
{
struct lirc_config *config;
//Timer for our buttons
int buttonTimer = millis();
char *code;
char *c;
//Initiate WiringPi and set WiringPi pins 4, 5 & 6 (GPIO 23, 24 & 25) to output. These are the pins the LEDs are connected to.
if (wiringPiSetup () == -1)
exit (1) ;
pinMode (LED1, OUTPUT);
pinMode (LED2, OUTPUT);
pinMode (LED3, OUTPUT);
//Initiate LIRC. Exit on failure
if(lirc_init("lirc",1)==-1)
exit(EXIT_FAILURE);
//Read the default LIRC config at /etc/lirc/lircd.conf This is the config for your remote.
if(lirc_readconfig(NULL,&config,NULL)==0)
{
//Do stuff while LIRC socket is open 0=open -1=closed.
while(lirc_nextcode(&code)==0)
{
//If code = NULL, meaning nothing was returned from LIRC socket,
//then skip lines below and start while loop again.
if(code==NULL) continue;{
//Make sure there is a 400ms gap before detecting button presses.
if (millis() - buttonTimer > 400){
//Check to see if the string "KEY_1" appears anywhere within the string 'code'.
if(strstr (code,"KEY_1")){
printf("MATCH on KEY_1\n");
flipLED(LED1);
buttonTimer = millis();
}
else if(strstr (code,"KEY_2")){
printf("MATCH on KEY_2\n");
flipLED(LED2);
buttonTimer = millis();
}
else if(strstr (code,"KEY_3")){
printf("MATCH on KEY_3\n");
flipLED(LED3);
buttonTimer = millis();
}
}
}
//Need to free up code before the next loop
free(code);
}
//Frees the data structures associated with config.
lirc_freeconfig(config);
}
//lirc_deinit() closes the connection to lircd and does some internal clean-up stuff.
lirc_deinit();
exit(EXIT_SUCCESS);
}
void flipLED (int led)
{
//If LED is on, turn it off. Otherwise it is off, so thefore we need to turn it on.
if(digitalRead(led)==ON)
digitalWrite(led, OFF);
else
digitalWrite(led, ON);
}
Compile the above code with;
Create an empty lirc file, otherwise lirc will complain;
Start it with;




Thanks for the tutorial. I managed to get to the 'Creating your program to control the GPIO' but was wondering if you knew how to do that except in Python?
Thanks,
Isaac
If you have setup lirc correctly and are just looking to get a Python script, try my script here:
https://github.com/xavbabe/pi_scripts/blob/master/IR
Your Python Code is simple, however, will not work.
The Python-lirc package wants a valid lircrc file to be present, and it seems, it parses the button combinations from there.
I have tested it to be working well, provided there is a valid licrc file and stores the buttons combinations that are expected in the licrc format.
The C Program works flawlessly with an empty licrc file, whereas the python one cannot.
I have raised an issue here about the same here : https://github.com/tompreston/python-lirc/issues/5
Hope the author will respond soon.
So anyone who cannot get it to work inb Python, please make sure you have a valid entries like below in the licrc file.
begin
button = B_POWER
prog = myprogram
config = B_POWER
end
for each of your buttons.
Ah yes, I will update the post. Thanks!
Updated - thank you!
Great Tutorial! When I run the Code I get this error:
irexec: could not open config files /home/pi/.lircrc and /etc/lirc/lirc/lircrc
irexec: No such file or directory
Do you know what to do?
hi Fabian,
an empty file lircrc in /etc/lirc/ did help here
kutte
Fabian
I must have missed this. Let me know if creating an empty file fixes the issue and I'll update the blog.
Mark
Hey Mark
Awesome write-up. I had the same issue as Fabian and it had been resolved with the introduction of an empty file named 'lircrc' in the directory '/etc/lirc'. Otherwise I'd say it's a flawless writeup and one of the best tech blogs I've yet seen.
thanks Hari. Please let me know where in the instructions I should place the info of creating the empty lircrc.
Hey Mark,
Just add it before the last instruction (the one which executes the WiringPi example). By the way, I cited your blog in my site (tweakgeek.in).
Hi all, succeeded as per above info. How do I auto start at boot up.. Thanks. Michael.
How do you recive custom input from lirc on pi?
After running sudo /etc/init.d/lirc stop I get several messages saying /etc/lirc/hardware.config can't be found. The file is definitely there. Any idea why this might be happening?
Hey Hari,
Do i have to use three LEDs to GPIOs 23, 24 & 25, and a 270Ω on the GND or can i connect the ir receiver directly to the GPIO pins?? without the led's and the 270Ω. I'm interested in using it only to control my Openelec.
You can connect the receiver directly to the GPIO pins. No LEDs or resistors needed.
Thanks a lot...
thanks for the quick tutorial. I really enjoyed it. Worked right out of the box!
Excellent Article
how can I edit that program,because I used other string names in my config file from lirc
Thanks very much for the tutorial. Worked great for me. I have a Pi with 16x2 LCD in my car reading OBDII data through USB, displaying speed, MPG, etc., and playing audio files into my car stereo through the aux in. (The stereo's user interface is the pits.) Now it's being controlled with the remote for the car stereo, and it's fantastic! And all in Java. So sweet.
Hello,
January 25th 2015: Marc W. in the comments pointed out that in the 3.18.x RaspberryPi firmware you must modify one additional file for the lirc-rpi kernel extension to be loaded:
Edit your /boot/config.txt file and add:
dtoverlay=lirc-rpi,gpio_in_pin=18
https://github.com/pylover/aiolirc is good stuff
Hi i have a problem when i try to do the quick test in the part of:
mode2 -d /dev/lirc0
I get this:
mode2: could not get file information for /dev/lirc0
mode2: default_init(): No such file or directory
I was wondering can I send WOL when IR key is pressed? and how?
Hi
Thank's you very much for this nice lirc DIY but i was unable to find /dev/lirc0 until i found a "trick" wich is actually a prerequisite point !
Please, consider @diego master comment and adding a chapter about the declaration of dtoverlay=lirc-cpi in the boot config.txt for a happy ending !
Thanks
Done
I follow this great article for my IR LED and Receiver Installation, I used it in my Raspberry Pi control Room Temprature with Heater and Fan which combine a bunch of different sensor, smart devices to work together including Raspberry Pi, Smart Plug, Temperature Sensor, IR Receiver and IR LED. https://github.com/polease/HomeAutomation
Greetings!!..
While running ... (irrecord -d /dev/lirc0 ~/lircd.conf) this command i face a problem like this file lircd.conf does not contain valid data...How to rectify that?give me sugesstion to overcome this error.
good solution to python script to read the button presses here:
https://github.com/akkana/scripts/blob/0d9a2542a38ee138da84904ead3a020579cd8c53/rpi/pyirw.py