Seeing my children mastering swiping, touching and tapping on the tablet, gave me the idea of making a gesture based TV remote control. Using the Raspberry Pi, the Skywriter HAT from Pimoroni and an IR LED, this was made possible rather easily. Here’s how I did it …

Raspberry Pi

Preparing the Raspberry Pi is the same as always. I flashed the latest Raspbian Jessie image onto a 8GB microSd card using “dd”.

For this project, I’m using the Raspberry Pi A+ as it has the exact same form factor as the Skywriter HAT.

Skywriter HAT

The Skywriter HAT is an add-on board by Pimoroni, capable of detecting gestures. The HAT fits on top of the Raspberry Pi via the 40-pin GPIO header, and the software can be installed with a single command. The command takes care of installing the software dependencies, enabling I2C and providing some example applications. The documentation can be found on the Pimoroni GitHub page: https://github.com/pimoroni/skywriter-hat

After connecting the HAT, I executed the oneliner to install the software:

pi@raspberrypi:~ $ curl -sSL get.pimoroni.com/skywriter | bash 1 pi @ raspberrypi : ~ $ curl - sSL get . pimoroni . com / skywriter | bash

And that’s all there is to it. Compliments to Pimoroni for making this install so easy!

After setting up the software, the Skywriter HAT can be tested. One of the example applications is called “test.py” and reports the detected gestures on screen. To run the example, execute following command:

pi@raspberrypi:~ $ sudo Pimoroni/skywriter/test.py Depending on the movements made, the output will be different. Here's what mine looked like: ('Airwheel:', 45.8375) ('Airwheel:', 45.725) ('Got a flick!', 'east', 'west') ('Got a flick!', 'west', 'east') ('Touch!', 'center') ('Tap!', 'center') ('Touch!', 'center') ('Tap!', 'center') ('Got a flick!', 'west', 'east') ('Got a flick!', 'west', 'east') ('Got a flick!', 'north', 'south') ('Got a flick!', 'south', 'north') (0.1353759765625, 0.3520965576171875, 0.2229766845703125) (0.2788238525390625, 0.371307373046875, 0.2236480712890625) (0.455780029296875, 0.3703765869140625, 0.2238311767578125) (0.5930633544921875, 0.3404998779296875, 0.2238311767578125) (0.686553955078125, 0.2968902587890625, 0.224029541015625) (0.7591552734375, 0.252838134765625, 0.2248687744140625) (0.822540283203125, 0.222503662109375, 0.227203369140625) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 pi @ raspberrypi : ~ $ sudo Pimoroni / skywriter / test . py Depending on the movements made , the output will be different . Here 's what mine looked like: (' Airwheel : ', 45.8375) (' Airwheel : ', 45.725) (' Got a flick ! ', ' east ', ' west ') (' Got a flick ! ', ' west ', ' east ') (' Touch ! ', ' center ') (' Tap ! ', ' center ') (' Touch ! ', ' center ') (' Tap ! ', ' center ') (' Got a flick ! ', ' west ', ' east ') (' Got a flick ! ', ' west ', ' east ') (' Got a flick ! ', ' north ', ' south ') (' Got a flick ! ', ' south ', ' north ' ) ( 0.1353759765625 , 0.3520965576171875 , 0.2229766845703125 ) ( 0.2788238525390625 , 0.371307373046875 , 0.2236480712890625 ) ( 0.455780029296875 , 0.3703765869140625 , 0.2238311767578125 ) ( 0.5930633544921875 , 0.3404998779296875 , 0.2238311767578125 ) ( 0.686553955078125 , 0.2968902587890625 , 0.224029541015625 ) ( 0.7591552734375 , 0.252838134765625 , 0.2248687744140625 ) ( 0.822540283203125 , 0.222503662109375 , 0.227203369140625 )

Lirc

Lirc is the software in charge of the infrared (IR) signals. It is capable of recording signals from remote, as well as send them. This is why I have foreseen both an IR LED transmitter and and IR receiver.

Circuit

The circuit consists of two parts:

transmitter

receiver

For the transmitter part, an IR LED is controlled via a transistor and a GPIO pin. A resistor of about 50 ohms is put in series with the IR LED and the GPIO pin is connected to the base pin of the transistor using a 10k ohm resistor. The LED is powered using the Pi’s 3.3V GPIO pin.

For the receiver part, also powered at 3.3V, the data pin is connected to a GPIO pin via a 10k ohm resistor. Careful, depending on your type of IR receiver, the pinout could be different!

After prototyping the circuit and before soldering it onto a prototyping HAT, I verified basic functionality using an oscilloscope.

Software

First step is of course to install the lirc application itself. This can be done using “apt-get”.

pi@raspberrypi:~ $ sudo apt-get install lirc 1 pi @ raspberrypi : ~ $ sudo apt - get install lirc

Edit the module files and append following lines:

pi@raspberrypi:~ $ sudo nano /etc/modules lirc_dev lirc_rpi gpio_in_pin=23 gpio_out_pin=22 1 2 3 pi @ raspberrypi : ~ $ sudo nano / etc / modules lirc_dev lirc_rpi gpio_in_pin = 23 gpio_out_pin = 22

The default hardware config file won’t work. Here’s an example of one that will. I commented out the default values so you can see which ones changed.

pi@raspberrypi:~ $ sudo nano /etc/lirc/hardware.conf # /etc/lirc/hardware.conf # # Arguments which will be used when launching lircd #LIRCD_ARGS="" 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="UNCONFIGURED" DRIVER="default" # usually /dev/lirc0 is the correct setting for systems using udev #DEVICE="" #MODULES="" DEVICE="/dev/lirc0" MODULES="lirc_rpi" # Default configuration files for your hardware if any LIRCD_CONF="" LIRCMD_CONF="" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 pi @ raspberrypi : ~ $ sudo nano / etc / lirc / hardware . conf # /etc/lirc/hardware.conf # # Arguments which will be used when launching lircd #LIRCD_ARGS="" 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="UNCONFIGURED" DRIVER = "default" # usually /dev/lirc0 is the correct setting for systems using udev #DEVICE="" #MODULES="" DEVICE = "/dev/lirc0" MODULES = "lirc_rpi" # Default configuration files for your hardware if any LIRCD_CONF = "" LIRCMD_CONF = ""

Finally, one last change is required in the boot config.

pi@raspberrypi:~ $ sudo nano /boot/config.txt # Lirc dtoverlay=lirc-rpi,gpio_in_pin=23,gpio_out_pin=22 1 2 3 4 pi @ raspberrypi : ~ $ sudo nano / boot / config . txt # Lirc dtoverlay = lirc - rpi , gpio_in_pin = 23 , gpio_out_pin = 22

Don’t forget to reboot to apply all the changes. After that, you should have a “lirc0” device available.

pi@raspberrypi:~ $ ls -l /dev/lirc0 crw-rw---- 1 root video 245, 0 Feb 6 15:51 /dev/lirc0 1 2 pi @ raspberrypi : ~ $ ls - l / dev / lirc0 crw - rw -- -- 1 root video 245 , 0 Feb 6 15 : 51 / dev / lirc0

It is also possible to verify the correct modules (lirc_rpi & lirc_dev) have been loaded using the “lsmod” command.

pi@raspberrypi:~ $ lsmod Module Size Used by cfg80211 499834 0 rfkill 22491 2 cfg80211 8192cu 569532 0 snd_bcm2835 22317 0 bcm2835_gpiomem 3703 0 snd_pcm 92581 1 snd_bcm2835 snd_timer 23454 1 snd_pcm snd 68161 3 snd_bcm2835,snd_timer,snd_pcm lirc_rpi 8602 0 uio_pdrv_genirq 3690 0 uio 10002 1 uio_pdrv_genirq lirc_dev 11060 1 lirc_rpi rc_core 23581 1 lirc_dev i2c_bcm2708 6252 0 i2c_dev 6730 0 fuse 91981 1 ipv6 360374 28 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 pi @ raspberrypi : ~ $ lsmod Module Size Used by cfg80211 499834 0 rfkill 22491 2 cfg80211 8192cu 569532 0 snd _ bcm2835 22317 0 bcm2835 _ gpiomem 3703 0 snd _ pcm 92581 1 snd_bcm2835 snd _ timer 23454 1 snd_pcm snd 68161 3 snd_bcm2835 , snd_timer , snd_pcm lirc _ rpi 8602 0 uio_pdrv _ genirq 3690 0 uio 10002 1 uio_pdrv_genirq lirc _ dev 11060 1 lirc_rpi rc _ core 23581 1 lirc_dev i2c _ bcm2708 6252 0 i2c _ dev 6730 0 fuse 91981 1 ipv6 360374 28

If that’s the case, everything should be ready to use.

Record

When recording keys, the correct names need to be assigned to identify them. The full list of possible values can be obtained using the following command:

pi@raspberrypi:~ $ irrecord --list-namespace KEY_0 KEY_102ND KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 ... 1 2 3 4 5 6 7 8 9 10 11 12 pi @ raspberrypi : ~ $ irrecord -- list - namespace KEY_0 KEY_102ND KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY _ 8 . . .

In order to start recording IR signals from the remotes, the lirc process needs to be stopped.

pi@raspberrypi:~ $ sudo /etc/init.d/lirc stop [ ok ] Stopping lirc (via systemctl): lirc.service. 1 2 pi @ raspberrypi : ~ $ sudo / etc / init . d / lirc stop [ ok ] Stopping lirc ( via systemctl ) : lirc . service .

With lirc stopped, the recording process can start. Make sure you have the remote of the TV or decoder handy and follow the instructions.

pi@raspberrypi:~ $ irrecord -d /dev/lirc0 lirc-remote1.conf irrecord - application for recording IR-codes for usage with lirc Copyright (C) 1998,1999 Christoph Bartelmus(lirc@bartelmus.de) This program will record the signals from your remote control and create a config file for lircd. A proper config file for lircd is maybe the most vital part of this package, so you should invest some time to create a working config file. Although I put a good deal of effort in this program it is often not possible to automatically recognize all features of a remote control. Often short-comings of the receiver hardware make it nearly impossible. If you have problems to create a config file READ THE DOCUMENTATION of this package, especially section "Adding new remote controls" for how to get help. If there already is a remote control of the same brand available at http://www.lirc.org/remotes/ you might also want to try using such a remote as a template. The config files already contain all parameters of the protocol used by remotes of a certain brand and knowing these parameters makes the job of this program much easier. There are also template files for the most common protocols available in the remotes/generic/ directory of the source distribution of this package. You can use a template files by providing the path of the file as command line parameter. Please send the finished config files to <lirc@bartelmus.de> so that I can make them available to others. Don't forget to put all information that you can get about the remote control in the header of the file. Press RETURN to continue. Now start pressing buttons on your remote control. It is very important that you press many different buttons and hold them down for approximately one second. Each button should generate at least one dot but in no case more than ten dots of output. Don't stop pressing buttons until two lines of dots (2x80) have been generated. Press RETURN now to start recording. ................................................................................ Found const length: 108075 Please keep on pressing buttons like described above. ................................................................................ Space/pulse encoded remote control found. Signal length is 67. Found possible header: 4540 4423 Found trail pulse: 625 No repeat code found. Signals are space encoded. Signal length is 32 Now enter the names for the buttons. Please enter the name for the next button (press <ENTER> to finish recording) KEY_VOLUMEUP Now hold down button "KEY_VOLUMEUP". Please enter the name for the next button (press <ENTER> to finish recording) KEY_VOLUMEDOWN Now hold down button "KEY_VOLUMEDOWN". Please enter the name for the next button (press <ENTER> to finish recording) KEY_POWER Now hold down button "KEY_POWER". Please enter the name for the next button (press <ENTER> to finish recording) Checking for toggle bit mask. Please press an arbitrary button repeatedly as fast as possible. Make sure you keep pressing the SAME button and that you DON'T HOLD the button down!. If you can't see any dots appear, then wait a bit between button presses. Press RETURN to continue. .............................. No toggle bit mask found. Successfully written config file. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 pi @ raspberrypi : ~ $ irrecord - d / dev / lirc0 lirc - remote1 . conf irrecord - application for recording IR - codes for usage with lirc Copyright ( C ) 1998 , 1999 Christoph Bartelmus ( lirc @ bartelmus . de ) This program will record the signals from your remote control and create a config file for lircd . A proper config file for lircd is maybe the most vital part of this package , so you should invest some time to create a working config file . Although I put a good deal of effort in this program it is often not possible to automatically recognize all features of a remote control . Often short - comings of the receiver hardware make it nearly impossible . If you have problems to create a config file READ THE DOCUMENTATION of this package , especially section "Adding new remote controls" for how to get help . If there already is a remote control of the same brand available at http : //www.lirc.org/remotes/ you might also want to try using such a remote as a template . The config files already contain all parameters of the protocol used by remotes of a certain brand and knowing these parameters makes the job of this program much easier . There are also template files for the most common protocols available in the remotes / generic / directory of the source distribution of this package . You can use a template files by providing the path of the file as command line parameter . Please send the finished config files to & lt ; lirc @ bartelmus . de & gt ; so that I can make them available to others . Don 't forget to put all information that you can get about the remote control in the header of the file. Press RETURN to continue. Now start pressing buttons on your remote control. It is very important that you press many different buttons and hold them down for approximately one second. Each button should generate at least one dot but in no case more than ten dots of output. Don' t stop pressing buttons until two lines of dots ( 2x80 ) have been generated . Press RETURN now to start recording . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Found const length : 108075 Please keep on pressing buttons like described above . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Space / pulse encoded remote control found . Signal length is 67. Found possible header : 4540 4423 Found trail pulse : 625 No repeat code found . Signals are space encoded . Signal length is 32 Now enter the names for the buttons . Please enter the name for the next button ( press & lt ; ENTER & gt ; to finish recording ) KEY_VOLUMEUP Now hold down button "KEY_VOLUMEUP" . Please enter the name for the next button ( press & lt ; ENTER & gt ; to finish recording ) KEY_VOLUMEDOWN Now hold down button "KEY_VOLUMEDOWN" . Please enter the name for the next button ( press & lt ; ENTER & gt ; to finish recording ) KEY_POWER Now hold down button "KEY_POWER" . Please enter the name for the next button ( press & lt ; ENTER & gt ; to finish recording ) Checking for toggle bit mask . Please press an arbitrary button repeatedly as fast as possible . Make sure you keep pressing the SAME button and that you DON 'T HOLD the button down!. If you can' t see any dots appear , then wait a bit between button presses . Press RETURN to continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . No toggle bit mask found . Successfully written config file .

The above was created using the remote control of the TV. But as we also have a decoder for digital TV, I repeated the process for the other remote. Except this time, I ned the output file “lirc-remote2.conf”. Both config files were then combined (“lirc-remote1.conf” and “lirc-remote2.conf”) into a single file (“lirc-combined.conf”).

In the config file, it is also possible to giev the ramotes a proper name. I called mine “TV” and “Digibox”.

The finished file can then be copied to the proper location for the lirc application to use.

pi@raspberrypi:~ $ sudo cp lirc-combined.conf /etc/lirc/lircd.conf 1 pi @ raspberrypi : ~ $ sudo cp lirc - combined . conf / etc / lirc / lircd . conf

When all recording is done, the lirc process can be restarted.

pi@raspberrypi:~ $ sudo /etc/init.d/lirc start [ ok ] Starting lirc (via systemctl): lirc.service. 1 2 pi @ raspberrypi : ~ $ sudo / etc / init . d / lirc start [ ok ] Starting lirc ( via systemctl ) : lirc . service .

Send

Before sensing any commands, it’s good to check what is available matches what was recorded. This can be achieved using the “irsend LIST” command, followed by the remote name and empty quotes.

pi@raspberrypi:~ $ irsend LIST TV "" irsend: 000000000000e01f KEY_VOLUMEUP irsend: 000000000000d02f KEY_VOLUMEDOWN irsend: 00000000000040bf KEY_POWER pi@raspberrypi:~ $ irsend LIST Digibox "" irsend: 0000000000000001 KEY_POWER irsend: 0000000000000002 KEY_CHANNELUP irsend: 0000000000000003 KEY_CHANNELDOWN 1 2 3 4 5 6 7 8 9 pi @ raspberrypi : ~ $ irsend LIST TV "" irsend : 000000000000e01f KEY_VOLUMEUP irsend : 000000000000d02f KEY_VOLUMEDOWN irsend : 00000000000040bf KEY_POWER pi @ raspberrypi : ~ $ irsend LIST Digibox "" irsend : 0000000000000001 KEY_POWER irsend : 0000000000000002 KEY_CHANNELUP irsend : 0000000000000003 KEY_CHANNELDOWN

Once the commands have been confirmed, it’s possible to test out the signals using the “irsend SEND_ONCE” command.

pi@raspberrypi:~ $ irsend SEND_ONCE Digibox KEY_POWER pi@raspberrypi:~ $ irsend SEND_ONCE TV KEY_POWER 1 2 pi @ raspberrypi : ~ $ irsend SEND_ONCE Digibox KEY_POWER pi @ raspberrypi : ~ $ irsend SEND_ONCE TV KEY_POWER

In my case, the TV and Digibox turned ON. Repeating the same commands turned them OFF.

Combined

Combining the Skywriter HAT’s functinality with Lirc is simply a matter fo taking the skywriter example code and expanding/adapting the functions with the desired IR send commands.

View the code on Gist.

The code above does the following:

flick left and right to change the channel

flick up and down to change the volume

make a circular motion to turn TV and Digibox ON and OFF

Enclosure

For the enclosure, I milled two parts with the necessary slots for power, USB and the IR LEDs using the CNC. The two pieces are joined using four screws.

The enclosure’s finish is simple: a bit of sanding and oiling.



Let me know what you think in the comments! And don’t forget I’m giving away one of my Pi Zero to celebrate my first 1000 subscribers on Youtube and the fact that I’m going to exhibit at Maker Faire Paris: http://frederickvandenbosch.be/?p=1563