Using irrecord to allow LIRC to recognize extra buttons, as from an unused remote and/or a Harmony remote

A few days ago we published an article on Using the Raspberry Pi to control AC electric power. We ended that article by showing how you could control the Raspberry Pi’s GPIO pins using a standard remote associated with a Home Theater PC on the same local network. Actually, come to think of it, there’s nothing to prevent someone from sending such commands across the Internet to a distant system, if one has an application that requires it. But I digress…

One problem that some users might encounter is that there are simply no free buttons on the remote control that can be used for other functions. Or maybe there are extra buttons, but they don’t seem to do anything. Or maybe you have a Logitech Harmony Remote or some other type of universal remote, and you downloaded a configuration for it to match your existing remote and infrared receiver but it added some additional buttons that appear to do nothing. Or, failing all that, maybe you have a spare infrared remote from a no longer utilized or broken device, that you’d like to use to control some additional functions (such as the GPIO pins on the Raspberry Pi, as in the aforementioned article). The question is, can you get your Home Theater PC (the one to which you have the infrared receiver attached) to recognize those additional button presses?

In our experience, the answer is that there’s a high probability, but it seems to depend on whether your infrared receiver can properly receive and decode the additional button presses. Which it just might be able to, even if it’s not doing that now. So, how can you tell what it’s now recognizing, and whether it can be made to recognize additional button presses?

First of all your system must be using the LIRC software for this to work. Most Linux-based home theater software does, so if you have a Home Theater PC and it’s not running some variant of Windows, it probably already has LIRC installed. Note that LIRC is actually a small collection of programs, none of which are actually named lirc, so just doing “which lirc” from a command prompt probably won’t tell you if it’s installed. Instead, you can check for one of the included programs — for example, try “which lircd” (lircd is the lirc background process) and see if it shows a path to that program.

Before you go any further, from a terminal prompt enter this:

irrecord --list-namespace

You may want to copy the output of that command to a text file that you can keep open in another window while you proceed, or just open another terminal window so you can refer back to this one. You could even print out that list if you think it would help. You are probably only going to be concerned with the entries that start with the characters KEY_ (and NOT those that start with BTN_, which may seem counter-intuitive, but that’s just how it is, at least with “MCE” compatible remotes — MCE = Windows “Media Center Edition”, in case you were wondering).

Next you will want to find out which buttons are already recognized. You should do this from a terminal prompt, with none of the software that normally responds to remote control commands running (so kill any instances of XBMC or similar software before doing this). Enter the command “irw” (without the quotes) and then start pressing buttons on the remote. For each button that LIRC recognizes, you will see one or more lines of text appear. Note any buttons that irw doesn’t print out anything for. If you are wanting to add a second remote to get additional usable buttons, see if irw responds to any of those buttons (it’s very unlikely that it will). The buttons that irw does not recognize are the ones we will try to add in the following steps.

Also, as you are pressing buttons and watching the output of irw, note the key names that are already used (they will likely be in the next to last column. Here is why. When you add previously unrecognized keys, you have to give them a name that LIRC understands, which can be any name from the output of “irrecord –list-namespace” that is not already used. If you duplicate an existing button name, one of the buttons won’t work. So, take note of the names already used, and also of the buttons that currently don’t do anything. When you have pressed all the buttons on your remote(s), use Control-C to exit irw.

Now before going any further, take a look at the file /etc/lircd/lircd.conf (at this point we are only going to read it, not write to it, so don’t use sudo):

nano /etc/lirc/lircd.conf

Note that file may contain a bunch of comments, and then a line such as this:

include “/usr/share/lirc/remotes/mceusb/lircd.conf.mceusb”

Whatever file is referenced in that “include” is the file we will be working with, which for simplicity’s sake I will henceforth refer to as the lirc remote configuration file. So close lircd.conf and go to that file:

nano /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb (or whatever file was included in lircd.conf)

You should see some preliminary configuration at the top, and then if you scroll down a bit you should see a line that says “begin codes” — below that, the lines that are not commented out will show key codes that LIRC currently recognizes (even if they do not appear on your remote) followed by hexadecimal values. Now this is where it gets a little confusing. When you are naming buttons in the next steps, you do not want to use any button names that already appear in this file. So the general rule for naming buttons in the following steps are:

1. DO use names that appear in the output of “irrecord –list-namespace”. BUT…
2. DO NOT use names that already appear in the lirc remote configuration file.
3. DO NOT use names that appear when you are using irw to find existing buttons (this should be a subset of ).

Now you are ready to try to add additional buttons to the list that LIRC knows about. The lircd process must NOT be running at this time, so do this:

sudo killall lircd

Now, to see if the additional buttons (or alternate remote) can be used, do this (note this assumes your IR receiver is at /dev/lirc0, which it probably is, but if not you may need to change that reference):

sudo irrecord -d /dev/lirc0 ~/lirctest

The irrecord program will first have you do several things to get some basic information about the remote – this will involve a bit of time and several button presses, so be patient and just follow the on-screen instructions. Then, after it has figured out what it needs to know about your remote, it will ask you to enter a key name — be sure to keep in mind the rules mentioned above! — and after that it will have you press the button on the remote. You can repeat this cycle as often as necessary to get all the buttons you want to add, and at this step you should only add buttons that it doesn’t already know about (ones that did not elicit a response from the irw program). Only do one remote at a time — don’t try to add buttons from different remotes on the same run of irrecord. If, for any reason, you have to quit irrecord before you are finished, delete the file ~/lirctest before you start over.

There may be cases where irrecord simply will not recognize a remote. or does so only with great difficulty. If that is the case, it probably means that either the batteries are dead in that remote, in which case you should restart the irrecord program after changing the batteries, or that the remote is not compatible with your infrared receiver. Different IR devices can operate on different infrared wavelengths, and your IR receiver is probably “tuned” to receive IR commands in a relatively narrow portion of the infrared spectrum. So, don’t be too surprised if some alternate remotes work fine, while others don’t work at all.

After you have run irrecord, the configuration should be in the file ~/lirctest (lirctest in your user directory). What you need to do now is copy the non-comment lines from that file (in other words, the section from begin remote to end remote, including those lines) to the end of the lirc remote configuration file. Before saving the additions, change the name line (right below begin remote) to have a value that is short and meaningful, using all lowercase letters and no spaces (such as name old_vcr if you are adding buttons from an old VCR remote). You may want to save a copy of the original lirc remote configuration file before making any changes, just in case you mess something up. For that matter, I’d also save a copy after you make the additions, since we’re not entirely sure whether the lirc remote configuration file might revert back to the original configuration if an upgrade to lirc comes along. So you may want to keep both a “before” and “after” copy in another directory.

If you want to add buttons from yet another remote, just repeat the process using irrecord. Remember to give the buttons unique names from the list you got when you ran irrecord –list-namespace. Note that the button name you use in irrecord does not need to bear any actual relation to the button name on the remote itself, it just has to be a name that’s not already in use.

Once you have made the additions to the lirc remote configuration file and rebooted the system (to restart lircd and read the new configuration file), run irw again and verify that the new buttons are being recognized. Now you can use those added buttons in your .lircrc file, or in the remote configuration file for a particular piece of software (for example, ~/.mythtv/lircrc for the MythTV frontend, if you are running that).

Readers with Harmony remotes may have noticed that when they looked into the lirc remote configuration file, there was already a lot of buttons defined that do not appear on their remotes, and might have wondered if it is possible to get the Harmony remote to learn those codes. While we have found that getting a Harmony to learn button presses from another remote is relatively easy using the Harmony configuration software — which means it would be easy to add buttons from that old VCR remote, assuming that irrecord was able to recognize it — it’s either difficult or impossible to add raw codes to a Harmony without having another remote that generates them. We tried to figure out if it could be done, but pretty much hit a dead end. If you should figure it out, please feel free to leave a comment explaining the procedure.

Link: How to use the DS18S20 and DS18B20 temperature sensors with Arduino or Raspberry Pi

Did you know that you can measure temperature, from one or more locations, with a Raspberry Pi or Arduino? And that you can do it with as few as two wires (or even just a single wire with ground return, though three wires are preferred if available) connecting to as many temperature sensors as you want to use? Here are a few articles that explain how to do this:

Arduino and DS18B20 – 1-wire digital thermometer (Ogalik OÜ) (Read this one first to see the wiring options)
How to use the DS18S20 and DS18B20 temperature sensors with Arduino (Dedication to DIY and programming)
Working with Dallas DS18S20 and DS18B20 temperature sensors (Tutorialpedia)
Raspberry Pi 1- Wire Digital Thermometer Sensor (Raspberry Pi Spy)
RaspberryPI DS1820 (Webshed)
Raspberry Pi + DS18B20 Temperature Sensor + RRDtool (Tony Tosi)
DS18B20 Temperature Sensor with Raspberry Pi (Chris Swan’s Weblog)
Raspberry Pi – Python & Temp Sensor DS18B20 (Stuff about code)
WebUI for a Raspberry Pi thermometer (github.com)
Monitor your home temperature using your Raspberry Pi (PrivateEyePi Project)

A note on that last link, only “Step 1” is needed to get the temperature sensor working on a Raspberry Pi. All the steps after that are just to install and use their software, which you might not wish to do if you don’t plan on completing their Home Alarm System project.

Note that the DS18B20 temperature sensors are available for only a few dollars at eBay, Amazon, and other places. You can even buy them in the form of a waterproof probe, which would be preferred for outside temperature readings.

By the way, there are more types of 1-Wire Devices than just temperature sensors available. One that seems like it might be useful in Raspberry Pi projects is the DS2413 1-Wire Dual Channel Addressable Switch, though I don’t think many people have explored that option yet. But if I understand it correctly (and I might not, so don’t take my word for it), you could use one or more of those to emulate GPIO pins (sort of) but without any real limitation on the number, and also they could all be placed on the same wire(s) and controlled from the same GPIO pin on the Raspberry Pi or Arduino (maybe even on the same wires that the temperature sensors are on, if you’re also using those?). And there are many other 1-Wire Devices available.

Using the Raspberry Pi to control AC electric power

Notice
VERY IMPORTANT NOTE: THIS IS NOT A HOW-TO ARTICLE. This article explains how the author used a Raspberry Pi to control electric current. However, the author is NOT an electrician, and just because he did something doesn’t mean YOU should, particularly if you are unfamiliar with how to wire electrical devices safely. WIRING A DEVICE IMPROPERLY CAN RESULT IN FIRE, PROPERTY DAMAGE, BODILY INJURY, AND/OR DEATH! So DO NOT just blindly do what the author has done, unless you are certain you know what you are doing and are willing to take full responsibility for your own actions! This article is for INFORMATIONAL PURPOSES AND DISCUSSION ONLY, and is NOT intended to be a guide to building any device!

WE ARE NOT RESPONSIBLE IF YOU ATTEMPT TO BUILD ANYTHING BASED ON WHAT YOU SEE IN THIS ARTICLE AND INJURE YOURSELF OR HAVE PROPERTY DAMAGE AS A RESULT. STOP READING THIS ARTICLE NOW IF YOU ARE UNWILLING TO TAKE FULL RESPONSIBILITY FOR YOUR OWN ACTIONS!!!! AGAIN, THIS IS ONLY TO REPORT ON WHAT THE AUTHOR OF THE ARTICLE DID, AND WE ARE NOT SUGGESTING THAT YOU DO LIKEWISE, PARTICULARLY IF YOU DO NOT FULLY UNDERSTAND AND APPRECIATE THE DANGER OF WORKING WITH LIVE ELECTRIC CURRENT! PLEASE CONSULT WITH A LICENSED ELECTRICIAN BEFORE ATTEMPTING TO BUILD ANYTHING THAT WILL UTILIZE HOUSEHOLD ELECTRICAL CURRENT!

EDIT: This article is getting somewhat dated now, and while the principles shown in this article are still sound, they involve wiring or using devices that directly switch AC power. Also, the quality of the relay boards used is not always great – we have seen several instances of a single relay that simply fails to work correctly on a board of four or eight relays. And many people don’t have the skills to do this, or they are (with some justification) uncomfortable with doing anything that involves AC power. So we’ll just point out that there is another way to do this that doesn’t involve working with AC power directly, and it is explained in an article entitled How to use a Raspberry Pi to trigger wireless remote controlled outlets (and probably other wireless devices). That method has an additional convenience factor, in that the actual switched outlets can be at some distance from the Raspberry Pi. If you know next to nothing about electricity, perhaps consider going that route instead of trying what is shown here.

We were trying to figure out if a Raspberry Pi could be made to control a device that is powererd by 120 volts AC. Our first idea was to build a device based on this wiring diagram, which would have let us control two electric outlets individually, using GPIO pins 17 and 18 on the Raspberry Pi. We tried using a Solid State Relay rated at 25 Amps rather than the 40 Amp one shown in the diagram, but the wiring of the two devices is the same (click on the diagram to enlarge):

Pi Power Controller Wiring Diagram SSR

What we found was that the above method worked IF you get good Solid State Relays. Unfortunately, we purchased two of them, and only one of them would work with the Raspberry Pi. While the rated trigger voltage on the label is 3 – 32 volts DC, we found that one of the relays we purchased required something closer to four volts to trigger. We then found other reports where other purchasers of those types of relays have encountered similar issues. Some people could buy several and find they all worked, others were not so fortunate and would have issues like we did.

We returned the bad one for a refund, and searched for another solution. But we do note that some of those Solid State Relays such as the ones shown in the diagram can handle up to 40 Amps, assuming you use a good heat sink, and even the less expensive units we purchased can handle up to 25 Amps with a heat sink, so had we been trying to control a heavy load we might have been willing to order another one and try it. It’s quite possible that these relays would work better with a proper transistor and resistor added to the control circuit (and connecting one leg of the transistor to the +5 Volt supply on the Raspberry Pi), but since we aren’t electronic engineers we did not attempt to design such a circuit.

We then tried this, but only because there was nothing better available at the time. We no longer recommend this due to the low current-carrying capacity of the relays, and the availability of relay boards better suited for this application. For an example of a better solution, see How we made a Raspberry Pi controlled 8-outlet power box:

Pi Power Controller Wiring Diagram SainSmart

The above circuit uses a SainSmart 2 Channel 5V Solid State Relay Module Board. Unlike the Solid State Relays mentioned earlier, these devices do require a +5 volt power connection, but they only require a trigger voltage of 2.5V – 20V. We purchased one of those and tried it, and had no problem triggering it from the Raspberry Pi. However, we no longer recommend these due to the low current rating of the relays, as explained below.

SainSmart 2-Channel 5V Relay Module (NOT tested by us)
SainSmart 2-Channel 5V Relay Module (NOT tested by us)

The only downside is that these devices are only rated to handle 2 Amps (Volts x Amps = Watts, so if your voltage is 110 volts then that means you could in theory use up to a 220 watt load. Remember that motors and some other devices can draw many times their rated load for a second or two when starting up). We only wanted to switch power to devices that draw perhaps a couple dozen Watts at most, so the 2 Amp limitation wasn’t an issue. If you need to control something that draws more current, or you want to control a DC load, then perhaps this SainSmart 2-Channel 5V Relay Module for Arduino DSP AVR PIC ARM (pictured at right) that uses mechanical relays would work for you, but we have never attempted to use one of those, so cannot comment on whether or how well those would work. (EDIT December 21, 2013:) We have discovered that the mechanical relay boards are wired a bit differently than the solid state ones, due to differences between the Arduino and the Raspberry Pi, so at a very minimum you would probably want to add something like a ULN2803A or ULN2003A integrated circuit (the first can handle 8 channels, the latter only 7) to shift the levels, and use a separate external power supply to power the relay coils, as shown in this diagram (which shows the 4-channel version of the mechanical relay board) and discussed in this thread (also this thread and this one). Alternately, you could use individual NPN transistors and resistors to shift the levels. We’ve also been made aware of the SupTronics Expansion Board Made for Raspberry Pi that among other things provides an “8-channel darlington Driver chip allowing to control electronic circuits which require more current to drive them”, that might be suitable for driving one of these relay boards — it uses a ULN2803A integrated circuit (see full details here, and please note that we have not tested one of these boards to see if it would work in this application). We are not electronic engineers, but suffice it to say that the Raspberry Pi GPIO pins send +3.3 volts when turned on, whereas the Arduino sinks current to ground when on, and the mechanical relay board was definitely designed to work with the Arduino, not the Raspberry Pi.

EDIT (October 16, 2016): Although the SainSmart boards were designed for use with Arduinos and not Raspberry Pis, there now is a relay board available that was designed for use with the Raspberry Pi. You can read a review of it here: ModMyPi PiOT Relay Board for Raspberry Pi, or you can watch one of these videos:

Or, just visit the manufacturer’s page for the ModMyPi PiOT Relay Board.

EDIT (March 19, 2018): Another board that seems to work quite well with a Raspberry Pi, and that uses relays rated to handle 10 Amps looks like this:

Elegoo 8 Channel DC 5V Relay Module with Optocoupler
Elegoo 8 Channel DC 5V Relay Module with Optocoupler

This unit is sold on Amazon by Elegoo, and the only caveat is that it appears the GPIO pin states are inverted from what you’d expect. So, when a GPIO pin is at logical 0, the relay turns on, and switching it to logical 1 turns the relay off. However the relays have both normally open and normally closed contacts, so you should still be able to control whatever you want to control. If you can wrap your head around that, these work well – all you need to do is connect the Raspberry Pi to the 10 pin strip on the relay board: The Vcc pin on the relay board connects to 5 volts on the Pi (Pin 2), the Gnd pin on the relay board connects to any of the GND pins on the Pi (pin 25, for example), and the other pins (In1 through In8) connect to GPIO pins on the Pi (we suggest using the pins that are color coded green in the pinout diagram on this page).

An example of a power control box built using one of these relay modules can be seen here:  How we made a Raspberry Pi controlled 8-outlet power box

This YouTube video shows a guy using a similar relay board to the one shown above, though from a different seller. And, he’s also using different GPIO ports from the ones we would recommend using, just so his ribbon cable connection looks a bit neater. Regardless, the video does show that these types of relay boards can work quite well with a Raspberry Pi:

EDIT August 26-28, 2013: Someone (not us) posted a link to this article on Reddit, where in the comments it was criticized for showing a regular outlet in a circuit that can only draw 2 Amps. One commenter labeled this “a pretty irresponsible article” and noted that “using a 2 amp rated, but normal looking outlet with nothing to interrupt the circuit if it is overloaded sounds like a terrible idea and risks starting a fire. It is not hard to exceed 2 amps.” But as someone else noted, you can’t readily purchase a special outlet that is intended for use only with smaller loads. We only show the outlet to illustrate how a small device, for example a device powered by a typical “wall wart” power supply that only draws a few watts, could be controlled. The diagrams above are for conceptual and illustrative purposes only – we are NOT actually advising you to build any such circuit or to use that type of outlet, but if you nevertheless attempt to build such a thing and thereby assume all the risks of doing so, we at the very least suggest you affix a conspicuous label showing the maximum amperage and wattage ratings (for example: MAXIMUM RATING 2 AMPS / 220 WATTS PER OUTLET or whatever is appropriate for the circuit you build). It might also be a good idea to put some type of additional protection, such as a 2 amp fuse or circuit breaker, in each leg of the circuit between the hot side of the outlet and the Solid State Relay Module Board. Or, a far better alternative would be to substitute one of the mechanical relay boards with relays rated to handle 10 Amps (and of course, be careful to never connect anything drawing more than 10 Amps to an outlet). But again, this is not and was never intended to be a hardware construction article, so if you attempt to build anything such as this, please be sure you know what you are doing!

Also, it should go without saying that you should NEVER UNDER ANY CIRCUMSTANCES permanently connect a circuit of this type to your home’s electrical wiring. Don’t even think about it; it’s not safe to do that and probably would violate at least a dozen sections of the electrical codes where you reside. We shouldn’t even have to say this, but apparently the use of a regular outlet in the illustration led a couple of Reddit commenters to think we might actually be advocating something like that. Apparently they completely overlooked the cord and plug in the diagram, which would not be used in any kind of permanent installation. We are NOT advocating permanently connecting a circuit of this type directly to your home’s wiring because that would be an extremely stupid and dangerous thing to do, not to mention illegal!

We notice that the harshest Reddit commenters were apparently too cowardly to leave their most scathing comments in our comment section, where we might have addressed them more directly. Since we are not Reddit users (we read it very occasionally, but don’t post there) we will not further dignify some of their more irrational statements, particularly since the true intent of this article was to explore the methods that can be used to control a circuit of this type. In other words, the focus of this article is the software, not the hardware. But on that topic, for those that are interested in the hardware side of things, we’ll just note that SainSmart also makes these Solid State Relay Module Boards in 4-channel and 8-channel models. If you prefer the boards with mechanical relays rather than the solid state type, those also come in 4-channel and 8-channel models.

We were a little concerned that the power supply used to power the Raspberry might not support the additional load of the control circuits on the solid state relays. According to the description on the SainSmart site, the board we used requires 5 Volts DC at 160mA. According to this page on the Raspberry Pi web site, “Model B owners using networking and high-current USB peripherals will require a supply which can source 700mA (many phone chargers meet this requirement). Model A owners with powered USB devices will be able to get away with a much lower current capacity (300mA feels like a reasonable safety margin).” We aren’t using any USB peripherals at all, let alone high-current ones, and the power supply we are using produces 1000mA (1 Amp), so it would appear that the power consumption is well within the power supply’s capacity. And, we haven’t had any power issues. Still, it might not hurt to oversize your power supply a bit (use one rated for 2 Amps, for example), particularly if you are using the mechanical relays.

NOTE: Devices shown in the diagrams are NOT exactly to scale.

EDIT (September 21, 2016): If you do not wish to build your own device OR do not have the knowledge to do it safely, there is a commercial alternative available that may work. We are NOT recommending this, simply because we have neither owned nor tested one, and we do not know if it has received the necessary approvals for various countries, including wherever you may live. We’re simply alerting you that this product exists, but if you choose to buy one we assume no responsibility whatsoever for any outcome of your decision, good or bad.

The product is the IoT Power Relay from Digital Loggers (the same people that make the Atomic Pi) and its advertised features are as follows:

  • Universal control voltage 3-60VDC or 12-120VAC connects to Arduino, Raspberry Pi, PIC or other micro. Or connect directly to a 12V to 48VDC or even 120VAC circuit.

  • High voltage wiring and safety hazards are eliminated.

  • A single input signal switches four outlets: 2 normally on + 2 normally off.
  • Optical isolation, relay hysteresis and de-bounce protection add safety.

  • A large MOV clamps surges for clean  90-140VAC power.

  • The durable SPDT control relay is rated at 30/40A, >400,000 operations at 12A or 2 million+ operations at 5A.

  • A 12A thermal safety circuit breaker switch prevents overloads.

  • Standard 24″ C-13 detachable cord included free, cords up to 25′ are optional.

  • Professionally built and tested. Not a kit.  Be up and running in minutes.

IoT Power Relay from Digital Loggers
IoT Power Relay from Digital Loggers (NOT tested by us)

For those that have wanted a solution that did not require building from scratch, this might be it, at least in countries that use 120VAC as the standard voltage and use the standard USA/Canada style power outlet. We do not know at this time whether the scripts below would need any modifications to work with this device.

Controlling the device:

Controlling the device is a matter of turning the GPIO pins on or off. We came up with a couple of simple bash scripts to do this. Note that you MIGHT need to invert the on and off values for certain mechanical relay boards (send 1 for off and 0 for on, etc.):

For GPIO17 (filename /root/gpio17.sh):

#!/bin/bash

if [ -z $1 ]
then
    opt="toggle"
elif [ -n $1 ]
then
    opt=$1
fi

let "sleep = $RANDOM + 10000"
sleep "0.$sleep"

if [ $(pgrep gpio17.sh|wc -w) -gt "2" ]; then
    exit
fi

if [ ! -e "/sys/class/gpio/gpio17/value" ]
then
    echo "17" > /sys/class/gpio/export
    echo "out" > /sys/class/gpio/gpio17/direction
fi

case $opt in
    on)
        echo 1 > /sys/class/gpio/gpio17/value
        ;;
    off)
        echo 0 > /sys/class/gpio/gpio17/value
        ;;
    toggle)
        value=`cat /sys/class/gpio/gpio17/value`
        if [ $value -ne 0 ]
        then
            echo 0 > /sys/class/gpio/gpio17/value
        else
            echo 1 > /sys/class/gpio/gpio17/value
        fi
        ;;
    reboot)
        echo 0 > /sys/class/gpio/gpio17/value
        sleep 30
        echo 1 > /sys/class/gpio/gpio17/value
        ;;
    status)
        exit
        ;;
    *)
        echo "Invalid option - use on, off, toggle, or reboot (toggle is the default)."
        exit
        ;;
esac

sleep 3

And for GPIO18 (filename /root/gpio18.sh):

#!/bin/bash

if [ -z $1 ]
then
    opt="toggle"
elif [ -n $1 ]
then
    opt=$1
fi

let "sleep = $RANDOM + 10000"
sleep "0.$sleep"

if [ $(pgrep gpio18.sh|wc -w) -gt "2" ]; then
    exit
fi

if [ ! -e "/sys/class/gpio/gpio18/value" ]
then
    echo "18" > /sys/class/gpio/export
    echo "out" > /sys/class/gpio/gpio18/direction
fi

case $opt in
    on)
        echo 1 > /sys/class/gpio/gpio18/value
        ;;
    off)
        echo 0 > /sys/class/gpio/gpio18/value
        ;;
    toggle)
        value=`cat /sys/class/gpio/gpio18/value`
        if [ $value -ne 0 ]
        then
            echo 0 > /sys/class/gpio/gpio18/value
        else
            echo 1 > /sys/class/gpio/gpio18/value
        fi
        ;;
    reboot)
        echo 0 > /sys/class/gpio/gpio18/value
        sleep 30
        echo 1 > /sys/class/gpio/gpio18/value
        ;;
    status)
        exit
        ;;
    *)
        echo "Invalid option - use on, off, toggle, or reboot (toggle is the default)."
        exit
        ;;
esac

sleep 3

Be sure to make the scripts executable. If you want to control any of the other GPIO pins, just copy the text of either of the above scripts into a text editor (one that will not change the line endings) and then do a global search and replace for the pin number – for example, if you use the script for pin 18, and you want to control pin 4, just replace all occurrences of “18” with “4”, and then save the script as /root/gpio4.sh and make it executable. Besides 4, 17, and 18, other GPIO pin numbers you can use are 22, 23, 24, 25, and 27 – that’s on a Revision 2 board, but if you happen to have a Revision 1 board then substitute 21 for 27. And if you think the GPIO pin numbering on a Raspberry Pi makes absolutely no sense at all, you are not alone, since the GPIO pin numbers are not in any logical sequence, and bear no relationship whatsoever to the actual positions of the pins on the board. The best thing you can do is look at a chart such as this one to help you keep track of which pin is which.

(Strictly speaking, you may be able to control certain other pins on the Raspberry Pi as well, but the eight GPIO pins mentioned in the previous paragraph should be your first choices for any projects of this type, and controlling any of the others is beyond the scope of this article. Also, note that the wiring diagrams above show Revision 2 boards, which have slightly different pinouts from Revision 1 boards, although none of the pins actually used for wiring in those diagrams are different between revisions. This article assumes you have a Revision 2 board, so if you have Revision 1, substitute any references to pin 27 with pin 21).

The scripts accept four arguments – on, off, toggle, or reboot (actually it also accepts a fifth, status, but that is for a special purpose and it not really intended for use directly from a command prompt). toggle is the default if no argument is specified.

There is a small section at the top of each script that may confuse some readers:

let "sleep = $RANDOM + 10000"
sleep "0.$sleep"

if [ $(pgrep gpio17.sh|wc -w) -gt "2" ]; then
    exit
fi

That section delays a random amount of time (0.1 to 0.42767 seconds), then checks to see if the script is already running, without writing anything to the Raspberry Pi’s SD card (which could shorten the card’s lifespan if done too frequently). If the script is already running it bails out. While it is unlikely that a user would attempt to start the same script twice, this pretty much guards against it. That’s also the point of the “sleep 3” at the end of the script, which keeps devices from being toggled on or off too quickly. If you know of a better way to do this, feel free to modify the script, and also to post your suggested modifications in the comments (but, please do not suggest reading man pages. If that is all you can be bothered to offer, please just move along).

The reason we used two scripts for the two pins, rather than just one with an added option to specify which pin to control, is so that you could control the two different pins simultaneously without being denied access to one because the script is already running on the other.

The options should be pretty obvious:

on – turn the pin on
off – turn the pin off
toggle – if the pin is currently off, turn it on, and vice versa (this is the default if no option is specified)
reboot – turn the pin off for 30 seconds, then turn it on

The hidden one, status, is a do-nothing command that only makes sure that the pin is initialized, but does not change its state. It is meant to be used when you are calling this script from Asterisk. Yes, you can do that, once the above scripts are enabled and you know they are working properly!

Controlling the device from Asterisk/FreePBX:

This section assumes that the Raspberry Pi is running Asterisk for Raspberry Pi (RasPBX), though it should work with any other FreePBX-based distribution that runs on the Raspberry Pi. To allow Asterisk to control the GPIO pins, you could add the following lines to /etc/asterisk/extensions-custom.conf (note this requires a few custom recordings and a bit of additional configuration, which will be discussed in a moment):

[custom-picontrol]
exten => s,1,Set(TIMEOUT_LOOPCOUNT=0)
exten => s,n,Set(INVALID_LOOPCOUNT=0)
exten => s,n,Set(_IVR_CONTEXT_${CONTEXT}=${IVR_CONTEXT})
exten => s,n,Set(_IVR_CONTEXT=${CONTEXT})
exten => s,n,Set(__IVR_RETVM=)
exten => s,n,GotoIf($["${CDR(disposition)}" = "ANSWERED"]?skip)
exten => s,n,Answer
exten => s,n,Wait(1)
exten => s,n(skip),Set(IVR_MSG=custom/please-enter-rpi-pin)
exten => s,n(start),Set(TIMEOUT(digit)=3)
exten => s,n,Set(PIGPIOPIN=Background(${IVR_MSG}))
exten => s,n,ExecIf($["${IVR_MSG}" != ""]?Background(${IVR_MSG}))
exten => s,n,WaitExten(5,)
exten => 4,1(ivrsel-4),Set(PIGPIOPIN=4)
exten => 4,n,Goto(custom-validpipin,s,1)
exten => 17,1(ivrsel-17),Set(PIGPIOPIN=17)
exten => 17,n,Goto(custom-validpipin,s,1)
exten => 18,1(ivrsel-18),Set(PIGPIOPIN=18)
exten => 18,n,Goto(custom-validpipin,s,1)
exten => 22,1(ivrsel-22),Set(PIGPIOPIN=22)
exten => 22,n,Goto(custom-validpipin,s,1)
exten => 23,1(ivrsel-23),Set(PIGPIOPIN=23)
exten => 23,n,Goto(custom-validpipin,s,1)
exten => 24,1(ivrsel-24),Set(PIGPIOPIN=24)
exten => 24,n,Goto(custom-validpipin,s,1)
exten => 25,1(ivrsel-25),Set(PIGPIOPIN=25)
exten => 25,n,Goto(custom-validpipin,s,1)
exten => 27,1(ivrsel-27),Set(PIGPIOPIN=27)
exten => 27,n,Goto(custom-validpipin,s,1)
exten => i,1,Set(INVALID_LOOPCOUNT=$[${INVALID_LOOPCOUNT}+1])
exten => i,n,GotoIf($[${INVALID_LOOPCOUNT} > 3]?final)
exten => i,n,Set(IVR_MSG=custom/sorry-not-valid-rpi-gpio)
exten => i,n,Goto(s,start)
exten => i,n(final),Playback(no-valid-responce-transfering)
exten => i,n,Goto(app-blackhole,hangup,1)
exten => t,1,Set(TIMEOUT_LOOPCOUNT=$[${TIMEOUT_LOOPCOUNT}+1])
exten => t,n,GotoIf($[${TIMEOUT_LOOPCOUNT} > 3]?final)
exten => t,n,Set(IVR_MSG=no-valid-responce-pls-try-again&custom/please-enter-rpi-pin)
exten => t,n,Goto(s,start)
exten => t,n(final),Playback(no-valid-responce-transfering)
exten => t,n,Goto(app-blackhole,hangup,1)
exten => return,1,Set(_IVR_CONTEXT=${CONTEXT})
exten => return,n,Set(_IVR_CONTEXT_${CONTEXT}=${IVR_CONTEXT_${CONTEXT}})
exten => return,n,Set(IVR_MSG=custom/please-enter-rpi-pin)
exten => return,n,Goto(s,start)
exten => h,1,Hangup
exten => hang,1,Playback(vm-goodbye)
exten => hang,n,Hangup

[custom-validpipin]
exten => s,1,Set(TIMEOUT_LOOPCOUNT=0)
exten => s,n,Set(INVALID_LOOPCOUNT=0)
exten => s,n,Set(_IVR_CONTEXT_${CONTEXT}=${IVR_CONTEXT})
exten => s,n,Set(_IVR_CONTEXT=${CONTEXT})
exten => s,n,Set(__IVR_RETVM=)
exten => s,n,GotoIf($["${CDR(disposition)}" = "ANSWERED"]?skip)
exten => s,n,Answer
exten => s,n,Wait(1)
exten => s,n(skip),Set(IVR_MSG=custom/rpi-gpio-pin-state-selection)
exten => s,n(start),Set(TIMEOUT(digit)=3)
exten => s,n,ExecIf($["${IVR_MSG}" != ""]?Background(${IVR_MSG}))
exten => s,n,WaitExten(5,)
exten => 0,1(ivrsel-0),Set(PIPINSTATE=off)
exten => 0,n,Goto(custom-pincontrol,s,1)
exten => 1,1(ivrsel-1),Set(PIPINSTATE=on)
exten => 1,n,Goto(custom-pincontrol,s,1)
exten => 2,1(ivrsel-1),Set(PIPINSTATE=toggle)
exten => 2,n,Goto(custom-pincontrol,s,1)
exten => 3,1(ivrsel-1),Set(PIPINSTATE=reboot)
exten => 3,n,Goto(custom-pincontrol,s,1)
exten => 4,1(ivrsel-1),Set(PIPINSTATE=status)
exten => 4,n,Goto(custom-pincontrol,s,1)
exten => i,1,Set(INVALID_LOOPCOUNT=$[${INVALID_LOOPCOUNT}+1])
exten => i,n,GotoIf($[${INVALID_LOOPCOUNT} > 3]?final)
exten => i,n,Set(IVR_MSG=no-valid-responce-pls-try-again)
exten => i,n,Goto(s,start)
exten => i,n(final),Playback(no-valid-responce-transfering)
exten => i,n,Goto(app-blackhole,hangup,1)
exten => t,1,Set(TIMEOUT_LOOPCOUNT=$[${TIMEOUT_LOOPCOUNT}+1])
exten => t,n,GotoIf($[${TIMEOUT_LOOPCOUNT} > 3]?final)
exten => t,n,Set(IVR_MSG=no-valid-responce-pls-try-again&custom/rpi-gpio-pin-state-selection)
exten => t,n,Goto(s,start)
exten => t,n(final),Playback(no-valid-responce-transfering)
exten => t,n,Goto(app-blackhole,hangup,1)
exten => return,1,Set(_IVR_CONTEXT=${CONTEXT})
exten => return,n,Set(_IVR_CONTEXT_${CONTEXT}=${IVR_CONTEXT_${CONTEXT}})
exten => return,n,Set(IVR_MSG=custom/rpi-gpio-pin-state-selection)
exten => return,n,Goto(s,start)
exten => h,1,Hangup
exten => hang,1,Playback(vm-goodbye)
exten => hang,n,Hangup

[custom-pincontrol]
exten => s,1,Noop(GPIO pin selected is ${PIGPIOPIN} and pin state is ${PIPINSTATE})
exten => s,n,System(sudo /root/gpio${PIGPIOPIN}.sh ${PIPINSTATE})
exten => s,n,Playback(custom/pin)
exten => s,n,SayNumber(${PIGPIOPIN})
exten => s,n,Playback(en/ha/is)
exten => s,n,ExecIf($["${SHELL(cat /sys/class/gpio/gpio${PIGPIOPIN}/value):0:1}" = "0"]?Playback(en/ha/off):Playback(en/ha/on))
exten => s,n,Goto(app-blackhole,hangup,1)
exten => h,1,Hangup

The [custom-picontrol] context above actually allows you to enter any of the possible GPIO pins (available to the user) on the Raspberry Pi, but in our example we’re only using pins 17 and 18, so if you don’t plan on using any other GPIO pins, you may want to remove all the lines that start with exten => N, where N is any number other than 17 or 18. The first two contexts are based on FreePBX IVR logic, except that instead of using the selection to transfer to an extension or other destination, the choices made are stored in variables for use by the [custom-pincontrol] context.

In order for this to work, there are a few extra steps you must take. First, you must give Asterisk permission to run the scripts. Run the visudo command as root, and use it to add these lines to the end of /etc/sudoers:

asterisk ALL = NOPASSWD: /root/gpio17.sh
asterisk ALL = NOPASSWD: /root/gpio18.sh

If you want to allow Asterisk to control all the GPIO pins rather than just 17 and 18, here’s a complete list of the lines to add to /etc/sudoers. Note that you must create the additional scripts and make them executable:

asterisk ALL = NOPASSWD: /root/gpio4.sh
asterisk ALL = NOPASSWD: /root/gpio17.sh
asterisk ALL = NOPASSWD: /root/gpio18.sh
asterisk ALL = NOPASSWD: /root/gpio22.sh
asterisk ALL = NOPASSWD: /root/gpio23.sh
asterisk ALL = NOPASSWD: /root/gpio24.sh
asterisk ALL = NOPASSWD: /root/gpio25.sh
asterisk ALL = NOPASSWD: /root/gpio27.sh

You must also create some system recordings and place them in the /var/lib/asterisk/sounds/custom directory. These can be added using the FreePBX System Recordings module, which is actually the preferred way because it will make sure all the permissions are set correctly. These are the four new recordings you need, and the suggested scripts:

please-enter-rpi-pin.wav: “Please enter the Raspberry Pi GPIO pin number you wish to control:”
rpi-gpio-pin-state-selection.wav: “Press zero to turn the GPIO pin off, one to turn it on, two to set it to the opposite of its current state, three to initiate a reboot sequence, or four to hear the current status of the pin.”
sorry-not-valid-rpi-gpio.wav: “I’m sorry, that is not a valid Raspberry Pi GPIO pin number. Please try again.”
pin.wav: “Pin”

If you are handy with an audio editor such as Audacity, you can probably slice the word Pin off of one of the existing recordings that start with the word “Pin” (found in /var/lib/asterisk/sounds/en for English-language speakers). For the others, you can record them yourself, or you could perhaps use text-to-speech software to generate them. There’s also the option of using flite text-to-speech synthesis if it is installed on your system, but you’ll need to modify the contexts accordingly (we don’t care for the sound of flite, so you are on your own with that).

Finally, you must go into FreePBX and under Admin/Custom Destinations, add a Custom Destination called “Raspberry Pi control”, then give it this destination:

custom-picontrol,s,1

Then go into Applications/Misc Applications and add a new Misc Application called “Raspberry Pi Control” or whatever you want. Give it an extension number you want to use when controlling pins on your Raspberry Pi – we used 774 (“RPI” on a standard touch-tone keypad). For the destination, select “Custom Destinations” and “Raspberry Pi control”, then apply the changes and you should be all set.

Other ways to control the pins:

There are many other ways you can control the pins. You can even do it from another computer on your network. For example, we have set up SSH Passwordless Logins from another computer on our local network. Having done that, we can create scripts on that computer that look like this (note you do NOT put these on the Raspberry Pi!):

In ~/gpio17.sh place these two lines:

#!/bin/bash
ssh root@IP_address_of_Raspberry_Pi "/root/gpio17.sh $1"

In ~/gpio18.sh place these two lines:

#!/bin/bash
ssh root@IP_address_of_Raspberry_Pi "/root/gpio18.sh $1"

Replace IP_address_of_Raspberry_Pi with the IP address of your Raspberry Pi – of course, this works best if the Raspberry Pi is always on the same IP address.

Now we can run the bash scripts from a another system, just as if we were logged into the Raspberry Pi. But the beauty of this is that you can call those scripts from other software on the system. Let’s say the other system is a home theater PC, and it has a ~/.lircrc file to accept commands from the remote. You could possibly add lines like this (note these are dependent on the remote you are using, and are just examples):

begin
 prog = irexec
 button = KEY_RED
 config = ~/gpio17.sh &
 repeat = 0
endbegin
 prog = irexec
 button = KEY_BLUE
 config = ~/gpio18.sh &
 repeat = 0
end

Now every time you press the red button on the remote, GPIO17 on the Raspberry Pi would toggle to the opposite of its current state (since no option is specified). And if you pressed the blue button, GPIO18 would toggle. So you could use a remote on a different system to send commands to the Raspberry Pi to power a device on or off. Or you could create a script or program that switches things on or off at certain times. We’ve actually done this so we know it works!

There is software available that allows you to use a web interface to control the GPIO pins, such as BerryIO and WebIOPi. It seems that the possibilities are endless. I could envision building something like an automatic lawn watering system controller that could go out and download the weather report, and then decide to water or not water based on the probability of significant amounts of rain. That’s just one example of the sort of thing you could do if you have the ability and the expertise.

Again, should you foolishly ignore our advice to not try building anything like this unless you know how to protect yourself when working with household electrical current, PLEASE remember to use extreme caution! We would really hate to see anyone kill or injure themselves, or set their house on fire (but we will not be responsible if you do that, because we’ve warned you every way we can think of!).

 

Link and video: Add Voice Control to Your Home with LightwaveRF and a Raspberry Pi

Voice control of our home electronics was promised long ago, but it’s still one of those things that most of us don’t have. If you want to add little voice control to your home on the cheap, blogger Chipos81 shows off how to do it with a Raspberry Pi.

Read more here:
Add Voice Control to Your Home with LightwaveRF and a Raspberry Pi (Lifehacker)

Link: Remotely control your Raspberry Pi

Take control of your Raspberry Pi from your smartphone, tablet or PC, from anywhere in the world

People are starting to do all kinds of things with their Raspberry Pi, like having it open and close a garage door, automate lighting and heating in the home, and so on. Even if you don’t yet have a project like this, this tutorial will still serve as a useful introduction to writing web applications with Python.

Full article here:
Remotely control your Raspberry Pi (Linux User & Developer)

Link: Raspberry Pi – Driving a Relay using GPIO

There’s something exciting about crossing the boundary between the abstract world of software and the physical ‘real world’, and a relay driven from a GPIO pin seemed like a good example of this. Although a simple project, I still learned some new things about the Raspberry Pi while doing it.

Full article here:
Link: Raspberry Pi – Driving a Relay using GPIO (SusaNET)

Related artcle:
Tutorial: How to use your Raspberry Pi like an Arduino (Limina.Log)

Link: OctoPi – 3D Printer Web Server Distribution for the Raspberry Pi

I am happy to say that I am a backer of the Rigidbot 3D printer, (which you can pre-order already), I am expecting it to arrive in August. In the meantime, I have ordered a Raspberry Pi to play with and started visiting a local maker community known as XLN.

This led me to find a really cool project called OctoPrint, which lets you control 3D printers using a Raspberry Pi over a web interface, however people were not installing it on their Pis because there was no out-of-the-box solution. Today I am happy to announce that a solution is here! I give you Octoprint + Rapberry Pi = OctoPi. A raspberry Pi distribution which runs OctoPrint out of the box, with support for time-lapse video on webcams (there is also an experiential version in the works that supports streaming from a raspberry Pi camera).

Full article here:
OctoPi – 3D Printer Web Server Distribution for the Raspberry Pi (Guysoft’s Weblog)

Link: Say hello to PiCast, the open source solution to Chromecast using a Raspberry Pi

There is a lot to love about the Chromecast. It lets you stream your browser, your desktop, and a number of apps directly to your TV with little more than a $35 dongle that plugs into HDMI on your TV. However, lately, a few problems have arisen. For one, it’s really difficult to find one unless you’re willing to wait weeks for the next stock to come in. Additionally, the root method that was discovered over at XDA has since been patched. So Google isn’t letting everyone play fast and loose with their new dongle. It’s still a great device, but it’s not perfect and now there is an alternative called PiCast.

PiCast was started by a developer named Lance Seidman. The premise? To use a $25-$35 Raspberry Pi computer to do almost exactly what Chromecast can do. It’s an open source project that’s currently in development and it has a lot of promise.

Full article:
Say hello to PiCast, the open source solution to Chromecast using a Raspberry Pi (AndroidAuthority.com)

Video and Link: Turn a Raspberry Pi Into an AirPlay Receiver for Streaming Music in Your Living Room

Few things are better than kicking back on the couch and streaming your favorite album wirelessly to your stereo from your phone. It’s a remarkably easy thing to do with AirPlay, but if you don’t want to pay for Apple’s solutions, a $35 Raspberry Pi does the job remarkably well.

Full article:
Turn a Raspberry Pi Into an AirPlay Receiver for Streaming Music in Your Living Room (Lifehacker)