<p>
Most Raspberry Pis are connected to a TV.<br />
Nearly all TVs have an infrared (IR) remote control.<br />
Using Linux Infrared Remote Control (LIRC), you can control your Raspberry Pi with an IR remote control.
</p>
<p>
This tutorial was written for Raspbian 9 (stretch) in January, 2019.
</p>

<h3>Contents</h3>
<ul>
<li><a href="#ir_receiver">Hardware: Infrared Receiver</a></li>
<li><a href="#lirc_rpi">Driver: Kernel Module</a></li>
<li><a href="#lirc">Software: LIRC</a></li>
<li><a href="#first_test">First Test</a></li>
<li><a href="#config">Configuration</a></li>
<li><a href="#test_config">Test Configuration</a></li>
<li><a href="#applications">Applications</a>
<ul>
  <li><a href="#lircmd">LIRC as a Mouse Input Device</a></li>
  <li><a href="#irexec">Execute Commands</a></li>
  <li><a href="#audacious">Audacious Audio Player</a></li>
</ul>
</li>
<li><a href="#disable_add_features">Disable Additional Features</a></li>
<li><a href="#known_issues">Known Issues</a></li>
</ul>

<h3 id="ir_receiver">Hardware: Infrared Receiver</h3>
<p>
Run the following command on the Raspberry Pi to show the pin layout:
</p>
<pre><code class="language-bash">pinout</code></pre>
<p>Connect an IR receiver to the following pins:</p>
<table class="cellborders">
<tr>
<th>Raspberry Pi 3</th>
<th>IR receiver TSOP4838</th>
</tr>
<tr style="color:purple">
<td>(12) GPIO18</td>
<td>1 = OUT</td>
</tr>
<tr style="color:black">
<td>(14) GND</td>
<td>2 = GND</td>
</tr>
<tr style="color:red">
<td>(17) 3V3</td>
<td>3 = VS</td>
</tr>
</table>
<p>
Be sure to check the datasheet if you are using another IR receiver.
</p>
<ul>
<li>
<a href="https://www.raspberrypi.org/documentation/usage/gpio/" target="_blank">
https://www.raspberrypi.org/documentation/usage/gpio/</a>
</li>
<li>
<a href="https://www.conrad.at/de/ir-empfaenger-sonderform-axial-bedrahtet-38-khz-950-nm-vishay-tsop4838-171115.html" target="_blank">
https://www.conrad.at/de/ir-empfaenger-sonderform-axial-bedrahtet-38-khz-950-nm-vishay-tsop4838-171115.html</a>
</li>
</ul>

<h3 id="lirc_rpi">Driver: Kernel Module</h3>
<p>
By default, the kernel module <code>lirc_rpi</code> uses GPIO18 for receiving
and GPIO17 for transmitting.<br />
A reboot loads the kernel module. When it is loaded,
the device <code>/dev/lirc0</code> will be available.
</p>
<dl class="file">
<dt><code class="filename">/boot/config.txt</code></dt>
<dd>
<pre class="file"><code class="language-plaintext"># Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi
</code></pre>
</dd>
</dl>
<ul>
<li>
<a href="http://aron.ws/projects/lirc_rpi/" target="_blank">
http://aron.ws/projects/lirc_rpi/</a>
</li>
</ul>
<h4>Addendum, 2019-05-22</h4>
<p>
Kernel 4.19.y requires <code>gpio-ir</code> to be loaded. <code>lirc-rpi</code> is no longer available.
</p>
<dl class="file">
<dt><code class="filename">/boot/config.txt</code></dt>
<dd>
<pre class="file"><code class="language-plaintext">dtoverlay=gpio-ir
</code></pre>
</dd>
</dl>
<ul>
<li>
<a href="https://wiki.libreelec.tv/infrared_remotes#important_changes_in_libreelec_90" target="_blank">
https://wiki.libreelec.tv/infrared_remotes#important_changes_in_libreelec_90</a>
</li>
</ul>

<h3 id="lirc">Software: LIRC</h3>
<p>
Install LIRC:
</p>
<pre><code class="language-bash">sudo apt install lirc</code></pre>
<dl class="file">
<dt><code class="filename">/etc/lirc/lirc_options.conf</code></dt>
<dd>
<pre class="file"><code class="language-ini">[lircd]
driver = default
device = /dev/lirc0

[lircmd]
uinput = True
</code></pre>
</dd>
</dl>
<ul>
<li>
<a href="http://www.lirc.org/html/configuration-guide.html" target="_blank">
http://www.lirc.org/html/configuration-guide.html</a>
</li>
</ul>
<h4>Addendum, 2020-03-15</h4>
<p>
Config files (<code class="filename">lirc_options.conf</code> and
<code class="filename">lircd.conf</code>) are missing in the lirc package
in Raspbian 10 (buster).<br />
This causes an error during installation of the package.<br />
Writing the missing files before the package is installed fixes the error.
</p>
<dl class="file">
<dt><code class="filename">/etc/lirc/lircd.conf</code></dt>
<dd>
<pre class="file"><code class="language-plaintext">include "lircd.conf.d/*.conf"
</code></pre>
</dd>
</dl>

<h3 id="first_test">First Test</h3>
<p>
Reboot to load the kernel module:
</p>
<pre><code class="language-bash">sudo reboot</code></pre>
<p>
Stop LIRC daemon:
</p>
<pre><code class="language-bash">sudo /etc/init.d/lircd stop</code></pre>
<p>
Show raw signals from IR receiver (use a remote to generate some signals):
</p>
<pre><code class="language-bash">mode2 -d /dev/lirc0</code></pre>

<h3 id="config">Configuration</h3>
<p>
List valid button names:
</p>
<pre><code class="language-bash">irrecord --list-namespace</code></pre>
<p>
Record signals from a remote control and
generate a configuration for decoding:
</p>
<pre><code class="language-bash">irrecord myremote.lircd.conf</code></pre>
<p>
Use the configuration system-wide:
</p>
<pre><code class="language-bash">cd /etc/lirc/lircd.conf.d
sudo mv devinput.lircd.conf devinput.lircd.dist
sudo mv /home/pi/myremote.lircd.conf /etc/lirc/lircd.conf.d/
</code></pre>
<p>
Restart LIRC daemon to load the new configuration:
</p>
<pre><code class="language-bash">sudo /etc/init.d/lircd restart</code></pre>

<h3 id="test_config">Test Configuration</h3>
<p>
Show decoded signals:
</p>
<pre><code class="language-bash">irw</code></pre>

<h3 id="applications">Applications</h3>

<h4 id="lircmd">LIRC as a Mouse Input Device</h4>
<dl class="file">
<dt><code class="filename">/etc/lirc/lircmd.conf</code></dt>
<dd>
<pre class="file"><code class="language-plaintext">PROTOCOL IntelliMouse

ACCELERATOR 2 32 2

MOVE_N * KEY_UP
MOVE_E * KEY_RIGHT
MOVE_S * KEY_DOWN
MOVE_W * KEY_LEFT

# mouse wheel
MOVE_OUT * KEY_CHANNELUP
MOVE_IN * KEY_CHANNELDOWN

# left and right mouse buttons
BUTTON1_CLICK * KEY_OK
BUTTON3_CLICK * KEY_MENU
</code></pre>
</dd>
</dl>
<ul>
<li>
<a href="http://lirc.org/html/configure.html#lircmd.conf" target="_blank">
http://lirc.org/html/configure.html#lircmd.conf</a>
</li>
</ul>

<h4 id="irexec">Execute Commands</h4>
<dl class="file">
<dt><code class="filename">/etc/lirc/irexec.lircrc</code></dt>
<dd><pre class="file"><code class="language-plaintext">begin
  prog   = irexec
  button = KEY_POWER
  config = shutdown -h now
end

begin
  prog   = irexec
  button = KEY_VOLUMEUP
  repeat = 1
  config = amixer sset PCM 1dB+
end

begin
  prog   = irexec
  button = KEY_VOLUMEDOWN
  repeat = 1
  config = amixer sset PCM 1dB-
end
</code></pre>
</dd>
</dl>
<ul>
<li>
<a href="http://lirc.org/html/configure.html#lircrc_format" target="_blank">
http://lirc.org/html/configure.html#lircrc_format</a>
</li>
</ul>

<h4 id="audacious">Audacious Audio Player</h4>
<p>
Install Audacious:
</p>
<pre><code class="language-bash">sudo apt install audacious</code></pre>
<p>
Enable the <em>LIRC Plugin</em> under <em>File &gt; Settings &gt; Plugins</em>.
</p>
<dl class="file">
<dt><code class="filename">/home/pi/.lircrc</code></dt>
<dd>
<pre class="file"><code class="language-plaintext">begin
  prog   = audacious
  button = KEY_PLAY
  config = PLAY
end

begin
  prog   = audacious
  button = KEY_STOP
  config = STOP
end

begin
  prog   = audacious
  button = KEY_PAUSE
  config = PAUSE
end

begin
  prog   = audacious
  button = KEY_NEXT
  config = NEXT
end

begin
  prog   = audacious
  button = KEY_PREVIOUS
  config = PREV
end

begin
  prog   = audacious
  button = KEY_FASTFORWARD
  repeat = 1
  config = FWD
end

begin
  prog   = audacious
  button = KEY_REWIND
  repeat = 1
  config = BWD
end
</code></pre>
</dd>
</dl>
<ul>
<li>
<a href="https://audacious-media-player.org/" target="_blank">
https://audacious-media-player.org/</a>
</li>
<li>
<a href="https://github.com/audacious-media-player/audacious-plugins/blob/master/src/lirc/lirc.cc" target="_blank">
https://github.com/audacious-media-player/audacious-plugins/blob/master/src/lirc/lirc.cc</a>
</li>
</ul>

<h3 id="disable_add_features">Disable Additional Features</h3>
<p>
If you do not want to receive keystrokes when you press a button on the remote,
disable this feature:
</p>
<pre><code class="language-bash">sudo systemctl disable lircd-uinput.service</code></pre>

<h3 id="known_issues">Known Issues</h3>
<ul>
<li>
<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=860300" target="_blank">
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=860300</a>
</li>
</ul>