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;
![]() | ![]() |
[wp_ad_camp_1]
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;
[wp_ad_camp_1]
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 16×2 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
I have followed this tutorial to the letter several times and I still can’t get lirc install on my Pi. I get all the way to running a quick test and I get an error saying sudo /etc/init.d/lirc stop coomand not found then when i try to run the next line it says “using driver devinput on device /dev.lirc0 cannot initiate device /dev/lirc0. Can anyone help me figure out what I did wrong
Ik krijg het ook niet voorelkaar.
bij sudo /etc/init.d/lirc stop
krijg ik de melding sudo: /etc/init.d/lirc: opdracht niet gevonden.
bij het komando mode2 -d / dev / lirc0
Too many arguments.
Kan het te maken hebben met de versie op raspberry?
re:
Ik krijg het ook niet voorelkaar.
bij sudo /etc/init.d/lirc stop
krijg ik de melding sudo: /etc/init.d/lirc: opdracht niet gevonden.
bij het komando mode2 -d / dev / lirc0
Too many arguments.
Kan het te maken hebben met de versie op raspberry?
________________________________________
yep, me too
WiringPi is no longer available in the new Raspberry Pi os (for Pi4). Is there any way to make this tuto working in new RPI devices?
Hello,
Thank you Mark for this wonderful tutorial and all the others who have contributed to it.
In the tutorial, all the three LEDs are in toggle mode. (Key press changes the state of the LED. Same key press, again, changes it back to its original state.)
I would like one of the LED to give a pulse output of say 500uSec.
What changes do I make to the ‘C’ code?
I am not good at C so any help is much appriciated.
Thank you!