Labels

Linux (39) Thinkpads (4) lego (12) pi (20)

Monday, 23 December 2013

RemotePi Board power IR switch for Raspberry Pi [day 11 of 20-days-of-posts series]

A power switch was omitted in the design of the Raspberry Pi to keep costs down.  There was no easy interface provided to add one either, but there are many different options.  I had previously tackled the original topic in a previous post, comparing a few options, including building your circuit.

I had previously reviewed several different Raspberry Pi switches.  A new one came to my attention that I placed an order for.  It is the RemotePi Board by MSL Digital Solutions.



At its core, it promises the same functionality has the other board solutions that intercept the micro USB power connector on the Raspberry Pi, which is to control the power on/off state of the Pi through a switch and through software.  But instead of intercepting the power flow through the micro USB power connector, it controls the power through the GPIO.  Instead of connecting your power to the micro USB power connector on the Raspberry Pi, you connect it to this board.  You then either toggle the power state by pressing the black button on the top, or better, you can use a IR remote to toggle the power.

And there lies one of the key differentiators.  For application use-cases such as a media player where you need an IR receiver, this board accomplishes that purpose as well.  I discussed how you could construct your own IR receiver setup on the GPIO in a previous post, and also talked about HDMI CEC in the same post, but one of the issues that remains in either the case of adding an IR receiver or using your TV's built in HDMI CEC support (if it has it), is that you can't power on or off your Raspberry Pi using either your Pi or TV remote.  Your solution options were either to always leave the Raspberry Pi on, have it automatically turn on when your TV is on (either by a power bar or plugged into the USB service port on your TV) or manually turn it on using a hardware switch or plug when you want to use your Pi.

I don't always watch all my media content through the Raspberry Pi (such as when I play video games, watch TV channels etc), so I resorted to using the illuminated switch bundled with my IR receiver that allowed me to keep my Raspberry Pi off, when not in use, and turn it on manually by pressing the switch when I wanted to watch some Pi content.  There were a couple times I wanted to be able to use my Logitech Harmony remote to turn on the Pi.  One of the benefits of this switch implementation is that it will use the IR remote's power button to toggle the power to the Pi.  The IR receiver on the board will also work like any standard /dev/lirc device, meaning that it could replace the IR receiver I had setup on my Pi -- that it was completely compatible with XBMC.



The switch and IR receiver is contained on a single logic board.  It has a connector port that plugs directly into the GPIO.  This wasn't a concern for me, since on my XBMC Raspberry Pi units, I only use the GPIO for two purposes -- hooking up a power switch and hooking up a IR receiver.  The direct connection to the GPIO eliminated some wiring that I needed to contend with with the IR receiver and previous power switch.  The board also came with a screw with some watches and nuts so that it could be securely mounted directly onto the mount hole on the Raspberry Pi.  The first releases of the Raspberry Pis (the model B 256MB "rev 1") don't have this mount point but the board is still usable without the mount..

I decided to integrate the board with my model B bedroom TV Raspberry Pi case.  I had reviewed the lego case I had constructed for that project in a previous post.  I had still not integrated any power switch into this unit, so I was eager.

To keep inline with the pros and cons list I provided for the other switch mechanisms, here are the lists:

Pros:
  • very small
  • may need some modification to your raspberry pi case, but otherwise fits within the existing case (doesn't extend out from the board's footprint)
  • addresses the CLEAN SHUTDOWN and POWER OFF requirements fully
  • no issues with provided switch script (for other switches, I had problems and I had to make customizations to the scripts provided by other offerings)
  • fully integrated IR receiver that can be used to allow your IR remote to control XBMC
  • everything fully assembled

Cons:


I took apart my case's right wall to accommodate the new higher-oriented micro USB port.  I would be revamping the case completely now that I no longer needed to snake my IR receiver around to an opening on the front of the unit, I could now also drop down the height of the case due to the same reason and I would need to accommodate the hardware button to accommodate the manual switch.

The instructions provided were very simple.  After I applied the screw and plugged in the board, I connected the micro USB power to the board's port.  Immediately I saw the built in power LED flash green and red momentarily to indicate the unit had power.  I then press and held the power switch button down for 15 seconds, at which time the LED blinked between red and green continuously, indicating that it was ready to read the IR remote command for the power button.  I used the Logitech Harmony power button that had been setup for the WD TV remote profile that I had setup previously on the unit's previous IR receiver.  It really doesn't even have to be a power button -- it can be any unused button.  The blinking stopped and I could then press that button to turn on the unit.

When the IR power-assigned-button is pressed, the board's onboard LED starts blinking green, while the Raspberry Pi turns on.  Everything booted up as it would regularly.  I didn't have to make any changes to my lircd.conf profile.  I started using the unit as I normally would.



The blinking -- which is more of a "pulsing" -- for up-to-one minute on startup and shutdown give an indication that the command was received and also indicates that the unit won't respond to subsequent power on/off requests from IR during that period.  This prevents accidentally sending a second power on/off command to the unit while it works on the initial request.  It also prevents "repeating" if the IR remote sends the same commands multiple times.  .

If you are implementing this as a new IR implementation (not replacing an existing setup), you'd need to setup a remote and lircd.conf.  I discussed how to do this in a previous post.

I had no problem using the onboard IR receiver with all my Harmony remote commands or with the WD TV remote that I keep around as a backup to control the unit when my Harmony remote is lost in the room-somewhere or is charging.

To power off, I pressed the power button again.  The board passes on all the IR signals received to the Raspberry Pi, including the one assigned to the power button, but it will start triggering a shutdown when the power-assigned button command is received.  It does this by the irswitch.sh script that is installed as part of the setup.  It closely resembles the safe shutdown script (switch.sh) that I discussed using with the other power switches.  The board's LED flashes red while the board shuts down the Pi.  It continues to monitor the Raspberry Pi's shutdown for up to a minute.  When the Pi is safely complete it's shutdown, the power is cut off (so the Pi becomes powered off), and the onboard LED turns off.  You can then use either the manual power button on the board or again the IR remote's power-assigned button to turn the Raspberry Pi back on.



The onboard LED proved to be a great asset to this power switch.  I no longer had to position the front-face position in my original lego case:



I retweaked the right-side of the case to become the new front-end of the unit.

The before:



The after:



I placed a white window block where the onboard LED is positioned, that gives the unit a nice glow when lit.  I placed an inset blue window piece for IR window.  The IR range provided by the window is adequate enough to get at least a 45 degree angle using the remote.  I moved up the blocks for the micro USB power port to line up with the new port.  I also added some support around the SD card as it was previously hanging out of the system.  It is now protected from being hit (and damaging the SD card port).

A closer view:



I revamped the top of the case to integrate the power button as well:




I review all the changes I made to my Raspberry Pi lego case for this board in this follow-on post.  In general, it is very easy to integrate the board into most cases as it doesn't change the footprint size of the Raspberry Pi.  The only customizations that are needed are:

  1. hole on the top for the manual power switch,
  2. relocation of micro USB power source in a higher position and
  3. uncovering for IR and LED visibility.



Belkin WeMo Switch as a Raspberry Pi Power Switch [day 9 of 20-days-of-posts series]



Recently I purchased a Belkin WeMo Switch.  The switch makes a single electrical outlet become online by putting it on Wifi.  You can then use an iOS 6+ or Android 4+ app to toggle on/off the switch.  I didn't really see to much benefit of the app, as I already use Connected by TCP to control lighting around the home, providing me the ability to dim lights as well.

Of bigger importance to me was the IFTTT capability of the switch.  IFTTT, which stands for If This Then That, is an online service that lets you create recipes that can toggle the WeMo.    Because IFTTT is enabled for many other online services, you can tie the toggle on/off of the WeMo to other events, such as a gtalk or email message.  You could toggle the WeMo by the sending of a message to a IFTTT bot that contains a hash-tag that you assign to toggle your WeMo.  This makes it really easy to control a switch in your home from any device, not just your phone.  Likewise, IFTTT also has scheduled events as an ingredient, so you could use it to control what times your WeMo is on and off for.



There is a newer version, called Belkin WeMo Insight switch that has a much smaller footprint and also monitors and reports the power consumption of the device plugged in.  The Insight switch is about $10 more expensive.  It wasn't carried in any stores in Canada at the time of purchase (Home Depot, Canadian Tire, Future Shop / Best Buy, Amazon)

My particular interest in the Belkin WeMo Switch was as a Raspberry Pi power switch.  It makes a powerful switch for the following purposes:

  1. Serves purposes where something similar to as WOL (Wake on LAN) is needed.  I often use WOL on my systems, so remotely, I can connect to my home network and turn on computers as I need them, but issuing a WOL packet from the router to the PC.  For the Raspberry Pi, the Pi is always on as long as it has power supplied to it, therefore the USB-based ethernet switch doesn't feature the ability to turn the system on by WOL.  To do so, you would need to design and build your own power switch that could intercept the micro USB powered source and also reimplement the ethernet port by intercepting ethernet traffic capturing WOL packets and then controlling the power based on that.  There exists no ready-made logic board, so creating and implementing one would be impractical (and expensive).  With the WeMo, you can the toggle on power command straight to the switch, and anything connected to it will turn on.
  2. Scheduled on/off time.  If you need the system to be powered on during a certain time of the day (scheduled crontab job),  you can schedule the toggle on of the WeMo by a scheduler on  IFTTT.  Likewise, you can toggle it off at a different time.  Therefore, a scheduled crontab entry, I schedule my WeMo to be triggered on 5 minutes before the crontab entry is to run, and likewise, I schedule the WeMo to be triggered off 5 minutes after a matching crontab entry on the Raspberry Pi is scheduled to shutdown the system. Further, because there are three kinds of states you can use (toggle on, toggle off, toggle power state), if you toggle on the WeMo at a scheduled time, if it is already on, it won't be affected (as in, it won't be turned off by accident, unless you use the toggle power state as opposed to toggle on).
  3. Control your USB powered hub.  In my particular application, I'm powering the Pi using a power switch, which is plugged into a hub, where my USB devices are also plugged in (such as hard drive).  So, although I can schedule a shutdown on crontab which actually powers off the Pi with the addon power switch, the USB devices such as hard drive, remain powered on.  With the WeMo, I'm actually powering on/off the USB hub, so it would include automatically powering on/off the Pi itself.
  4. Remote hard-reset.  If (really more of a case of when) the Raspberry Pi becomes frozen or unresponsive where I'm not able to connect to it remotely to perform a reboot command, The WeMo allows me to either use my phone or IFTTT to toggle the power off/on.
Some conditions or other notes:
  • If you are strictly power off using the WeMo, you could corrupt the SD card or USB-based hard drive filesystem if you practice the habit of poweroff by cutting the power as opposed to safely shutting down prior with either a poweroff or shutdown now -h command.  In actuality, you could use a third party, such as Linux-capable router (which is my case), where if I need to perform a safe power down, I have the router issue a shutdown now -h over ssh to the Raspberry Pi, and then issue a #pi-off over email to IFTTT a minute later to actually power off the device.
  • If your Raspberry Pi starts up requiring root login to correct a disk issue, then you have no way around the issue other than to interact with the Raspberry Pi locally.  There is probably some way around this, some setting that lets you disable disk checks on startup, thus avoiding the prompt at startup for a root admin to log on to perform maintenance or CTRL-D to continue.  These prompts are not just tied to real disk corruption.  If I take my USB hard drive offline to sync it with another hard drive using another PC, if I write changes to it's supernode in the process, the next time I boot up on the Rasbperry Pi, it'll see the supernode has a timestamp newer than the system clock and thus refused to boot until a root user takes a course of action.  This nuance is for the fact the Raspberry Pi lacks a realtime clock, so on bootup, the present time will be the time at which the system was last on (stored to the SD card), so the fact the hard disk was updated or had changes to it with timestamps that are newer, it detects this as possible corruption-based issue.  Only after the system is booted up and on the network will the NTP set the time on the Pi to the current one.
  • You need an iOS 6+ or Android 4+ device even if  you intend to only control the WeMo via IFTTT.  The WeMO needs to be setup via the phone app.
The initial setup of the WeMo was fairly simple.  From what I read, the Android version of the app was created more recently and just came out of beta, and tends to have more bugs in it then the iOS version.  Therefore, I decided to dig my iPhone 3GS out of retirement for setting up this device, over the Android.  I plugged it in, then on my iPhone 3GS, I downloaded the WeMo app from the appstore.  As instructed by the app, you then need to change your Wifi access point on the phone to the one broadcasting from the WeMo.  Then at this point, the app will ask about the network setup of the WeMo, for which you provide the network key.  This was fairly simple.  But I did read online that a lot of users had problems at this point as their WeMo didn't accept network passwords with special characters (non-alphanumeric) such as spaces.  I'm not sure if this is resolved with a newer firmware, but if you have a network that uses one, you're out of luck with a out-of-box device until you get it onto a network it will accept.

As part of the setup, you provide it a name for the switch (assuming you may one day have multiples).  In my case, I just called it Raspberry Pi Server.  You can also assign it a user-created PNG graphic to depict the device image in the app.

After I got the device setup, I was prompted by the app to update the firmware on the WeMo as there was a newer one available.  This is where I began to quickly learn how buggy the firmware and app are.  I accepted the app to let the WeMo download the firmware.  At this point it instructs you that you can close the app, that the WeMo is downloading the firmware direct (indicated by flashing blue light) and will take about 10 mins to complete, at which time the WeMo will reboot and be ready for use.  I left the app open just the same, and went off to get a coffee.  When I got back I saw the WeMo was done the firmware upgrade, but instead of a steady blue light (indicating on) or no light at all (indicating off), I was presented with a blinking amber light.  It would seem this may have multiple meanings, but the initial one I found was that the device was not able to conenct to wifi or is still trying.  Checked the router and it confirmed the WeMo was not connected, having been connected and assigned an IP prior (since it had finished setup and had downloaded the new firmware).  I checked the phone app and it indicated the device was "firmware upgrading".  Unplugging it and plugging it back in proved futile.  I quickly learned of the restore procedure to try to trigger the device to restore to factory state.  So, went through the initial setup again, assigning the device a new name, giving it the network password etc.  This time at the completion of the setup, instead of letting me see the state of the switch in the app, it said the device was "firmware upgrading".  I had used a different name the second time, and it was the second named switch that it was in belief was firmware upgrading, whereas looking at the device, no said activity was underway.  Closed the app and started it again, and it was able to see the on/off state of the app correctly.

So, as you can see, both the app and the WeMo firmware are buggy, and I'll be more apprehensive on updating the firmware in the future.  Because it was freshly out of the box, I tend to take on more risky behaviour such as updating firmwares since I can just turn around and head back to the store to return the bricked device.  Had I updated in weeks or months following, I'd be at the mercy of the manufacturer RMA procedure.  

Setup was easier for IFTTT.  Activating the WeMo channel in IFTTT just involved providing it the  unique identifier number that the phone app provided so IFTTT could locate and use the WeMo.  I didn't have to open any firewall ports, etc.  Either the WeMo is pulling the requests or it is opening a port on the firewall itself.  I'll look into the details someday.  I'm interested in seeing what the packets look like going between IFTTT and the WeMo.

Pros:
  • IFTTT support
  • the latency is minimal; within 1-2 seconds of triggering a power toggle on the app or in IFTTT, the WeMo is toggled
  • this speaks more to IFTTT itself, but the time between emailed hash-tag emails to invoke the WeMo are processed usually around 5 seconds after the email request departs
  • survives power failures with settings preserved
Cons:
  • pricey (around $40 - $50)
  • firmware update process is buggy
  • requires the phone app for at least the initial setup
  • users report problems with network passwords with non alphanumeric characters
  • almost guaranteed to have problems with enterprise networks (such as ones that requires LEAP etc)
  • no surge protection; designed to fit outlets, not power-bar friendly, but it contains no surge protection and the huge footprint of the device causes hindrance plugging it into outlet surge protectors
  • unless your outlet plug sits flush with the surrounding wall, or extends out a bit, the overhanging of the switch will cause problems
  • causes havoc with powerbars; the footing is larger than power bricks, so even when a powerbar (or in my case APC UPS) has a "power brick outlet" to eliminate impact of a power brick on adjacent outlets, the footing still causes problems, barely allowing a two prong cable to clear (see picture of my setup)

[There is a newer version, called Belkin WeMo Insight switch that has a much smaller footprint and also monitors and reports the power consumption of the device plugged in.  The Insight switch is about $10 more expensive.]
  • network security issue; network details of the device are not transparent which is probably intentional to obscure security vulnerabilities 
  • it is essentially an embedded computer, so when you first plug it in (or turn a power bar on) it takes about 30-45 seconds for it to boot up (indicated by blue blinking LED) and another 30 seconds for the device to find and connect to the network (indicated by amber blinking LED)
  • consumes power (using a kill-a-watt reader, the device registers at 2 watts when idle and around 2.5 watts at bootup) -- the Raspberry Pi model B rev2 consumes about 2.5 watts, and the Raspberry Pi model A consumes about a constant 1.5 watts, so the WeMo consumes the same or more power than the Raspberry Pi.
Pros as a Raspberry Pi switch:
  • control the power switch remotely
  • lets you perform hard reboots remotely
  • control the power to the USB hub and all your Pi devices with a single switch
  • control the power to your Raspberry Pi using IFTTT, including implementing scheduled activities, activities based on other events
  • home automation necessity -- use in conjunction with motion sensors tied with IFTTT to aid in setting up home automation;  the WeMo switch is only one product available in the WeMo Home Automation category.
Cons as a Raspberry Pi switch:
  • no software shutdown support (need to software shutdown prior to avoid corruption of filesystem)
  • expensive

Saturday, 21 December 2013

Using the USB Big Red Button / Panic Button on the Raspberry Pi [day 10 of 20-days-of-posts series]

As I had allured to in a previous post, I had purchased a Panic/ Stress relief USB button from a local store.  Full specifications available at their manufacturer website.  I believe its available on the DX website as well, or at least a clone of it.



It features essentially a USB interface to 2 i/o streams that would be either high or low.   It has two input states -- one for the case cover being lifted and another for the button being pressed.




Taking apart the unit is fairly easy.  There are only 4 Philips screws.

As expected, inside we can see the button presses down on a standard button attached to a logic board.


The yellow cable leads to a set of electrical contacts that almost resemble tweezers.  This tells the logic board whether the case lid is open.


It's hard to see on a photo, but on the case, there is a leverage switch that pops out when the lid is open, which releases the "tweezers" contacts, breaking the current, which generates a 0 on the input.



That's all there is to the internals.  The components can be removed and setup in your own case.  If you use lego, it would be possible to create a button to press down on the switch, and some blocks to press or depress the electrical contacts for the lid switch.

My goal originally was to create a switch that could be used to shutdown the Raspberry Pi.  In actuality, it can be used for a multitude of purposes.

Pros:
  • cheap and resourceful
  • kind of geeky (re-pursing a device)
  • the casing can be taken apart and just the logical board with usb cable can be deployed

Cons:
  • a USB device that occupies a USB port


For the logic part, there are a few options I've found.  There is an open-source ruby gems implementation worth playing around with for fun:
https://github.com/derrick/dream_cheeky

I've ended up using a device driver written in C.  Malcolm Sparks provided a great device driver for this device on his blog:

http://blog.opensensors.io/blog/2013/11/25/the-big-red-button/

Malcolm goes into detail of pertaining to Arch Linux which didn't work as smooth for Debian.  I'll simply the procedure to follow below for the Raspberry Pi.

Three easy steps to follow.

First, test the device.  Plug in the device on the USB port.  Run dmesg to get the device information.

I saw something like this in dmesg output:


hid-generic 0003:1D34:000D.0004: hiddev0,hidraw0: USB HID v1.10 Device [Dream Link DL100B Dream Cheeky Generic Controller] on usb-0000:00:1d.0-1/input0

The device name is in that output.  In this case it is hiddev0. Check /dev for the existence of /dev/hidraw0.  You will need to change the permissions of /dev/hidraw0 if you won't be using the root user to run your script to interact with the buttons.  You can change the permissions by running sudo chmod 666 /dev/hidraw0. If the script runs under root, this is not necessary.  But it is necessary if you want to test out the switch with a non-root user.

Second, build the device driver.

Slightly modified version of Malcolm Sparks script, for the Raspberry Pi -- note the changes in BOLD, including changing the /dev/big-red-button to the actual device location (such as /dev/hidraw0).
(download big-red-button.c)

/*
,* Copyright © 2013, Malcolm Sparks <malcolm@congreve.com>. All Rights Reserved.
,*
,* A program to convert USB firing events from the Dream Cheeky 'Big Red Button' to MQTT events.
,*/

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LID_CLOSED 21
#define BUTTON_PRESSED 22
#define LID_OPEN 23

int main(int argc, char **argv)
{
  int fd;
  int i, res, desc_size = 0;
  char buf[256];

  /* Use a udev rule to make this device */
  fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK);

  if (fd < 0) {
    perror("Unable to open device");
    return 1;
  }

  int prior = LID_CLOSED;

  while (1) {
    memset(buf, 0x0, sizeof(buf));
    buf[0] = 0x08;
    buf[7] = 0x02;

    res = write(fd, buf, 8);
    if (res < 0) {
      perror("write");
      exit(1);
    }

    memset(buf, 0x0, sizeof(buf));
    res = read(fd, buf, 8);

    if (res >= 0) {
      if (prior == LID_CLOSED && buf[0] == LID_OPEN) {
         printf("Ready to fire!\n");
         system("sudo initctl stop xbmc");
         fflush(stdout);
      } else if (prior != BUTTON_PRESSED && buf[0] == BUTTON_PRESSED) {
         printf("Fire!\n");
         system("shutdown now -h");
         fflush(stdout);
      } else if (prior != LID_CLOSED && buf[0] == LID_CLOSED) {
         printf("Stand down!\n");
         fflush(stdout);
      }
      prior = buf[0];
    }
    usleep(20000); /* Sleep for 20ms*/
  }
}


You can modify the device driver to suit your needs.  There are really three states that can get triggered and be associated with tasks or activities:

  1. lid is raised
  2. lid is closed
  3. button is pressed

In the closed-form of the button, condition 3 can only happen when condition 1 is raised and is not possible when condition 2 is raised.  In a disassembled switch, you could repurpose condition 3 to behave differently based on whether it is condition 1 or 2 that is active (thus, you could add a 4th state in the device driver for buf[0] == LID_OPEN && buf[0] == BUTTON_PRESSED) since the two states can be independent based on your implementation of the physical button and contacts.

We'll use only states 1-3, assuming 3 can only occur when 1 is active.  Edit the behaviour of the device driver, where appropriate:
  • for when the lid is opened... [example showing stop XBMC]
      if (prior == LID_CLOSED && buf[0] == LID_OPEN) {
         printf("Ready to fire!\n");
         system("initctl stop xbmc");
         fflush(stdout);
  • for when the button is pressed...  [example showing shutdown system]     
      } else if (prior != BUTTON_PRESSED && buf[0] == BUTTON_PRESSED) {
    printf("Fire!\n");
    system("shutdown now -h");
    fflush(stdout);

  •  for when the lid is closed (depending it having been opened)...      

      } else if (prior != LID_CLOSED && buf[0] == LID_CLOSED) {
         printf("Stand down!\n");
         fflush(stdout);

Compile the device driver.
cc big-red-button.c -o big-red-button

Third,  install the device driver.

Install the executable by placing it in /etc/big-red-button.  Make sure the +x permission (i.e. sudo chmod 755 /etc/big-red-button) is set.  Add /etc/big-red-button & to the bottom of /etc/rc.local but before the exit.

Now when the Raspberry Pi boots up, if the USB Big Red Button is attached, it should load the device driver created above automatically, awaiting the change in state for the lid and button, taking appropriate action when activated.


Simplistic slim Raspberry Pi model A red lego case [day 8 of 20-days-of-posts series]

Intention: To be used as a small travel Raspberry pi that can be used with displays on-the-go (such as lapdocks)


Equipment:
  • Raspberry Pi (model A -- memory: 256MB, 1 USB port, no ethernet)
  • class 10 SD card (32GB)
Assumptions:
  • No need for the VIDEO port (going to use HDMI)
  • No need for AUDIO jack (going to use HDMI)
  • No need to access camera port, GPIO pins, etc


Like with most of my lego projects, I don't provide full schematics and block lists.  My opinion is that if you have unused lego that you can use for a project like this, you make use of what you have, improvising as you go.

This is the smallest Pi case that I could make, ideal for travelling.


Left-side view:




We have access to the USB port.  The Raspberry Pi LEDs are viewable through a window.

We can see the height of the case is exactly 2 + 1/3rd lego bricks high.  The width is 10 lego bricks.

Right-side view:



The SD card slot is accessible and the SD card sits flush to the case.  The micro USB power port is exposed for easy access.


Back-side view:


An opening is provided for eacy access to the HDMI port.

We can see the length of the case is 14 lego bricks in size.







Wednesday, 18 December 2013

Customizing your Raspberry Pi remote [day 7 of 20-days-of-posts series]

Yesterday I discussed how you could install an IR receiver on the Raspberry Pi so that you could use an IR remote to navigate XBMC.

Today I dig a little deeper into the configuration, settings and customization.

I assume your IR receiver is working (as described in the previous post).    We continue where we left off...


To create a configuration for a given remote, run the following:

  1. sudo /etc/init.d/lirc stop
  2. sudo irrecord -d /dev/lirc0 ~/lircd.conf
As part of generating lirc.conf, you'll be asked to enter a key name and then press that button on the remote so that it can read the IR signal and associate with that key.

To see a list of keynames, run irrecord --list-namespace .  Some very common ones are:

         KEY_HOME
         KEY_BACK   
         KEY_SELECT
         KEY_LEFT
         KEY_RIGHT
         KEY_UP    
         KEY_DOWN   
         KEY_REFRESH  
         KEY_FASTFORWARD     
         KEY_REWIND  
         KEY_PLAYPAUSE 
         KEY_INFO        

When prompted for a key name, you would enter something like KEY_HOME and then press the HOME key on the remote.  This would capture that input and the IR code associated with the key.  If you use an invalid key name or need to change it, you can do so by modifying the generated output (in this case,  ~/lirc.conf).

For a sample remote, I used a Western Digital TV (WD TV) player that I no longer use. and the generated output of that remote is as follows:
(download lircd.conf)
# 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 Sat Apr 13 23:25:54 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       8935  4503
  one           520  1709
  zero          520   606
  ptrail        524
  repeat       8935  2275
  pre_data_bits   16
  pre_data       0x219E
  gap          108035
  toggle_bit_mask 0x0
      begin codes
          KEY_BACK                 0xD827
          KEY_BOOKMARKS            0xF00F
          KEY_DOWN                 0x00FF
          KEY_ENTER                0x10EF
          KEY_FASTFORWARD          0x7887
          KEY_FAVORITES            0x08F7
#          KEY_FORWARD              0x7887
          KEY_HOME                 0x609F
          KEY_INFO                 0x58A7
          KEY_MENU                 0x58A7
          KEY_LEFT                 0xE01F
          KEY_NEXT                 0x807F
          KEY_PLAYPAUSE            0x50AF
          KEY_POWER                0x48B7
          KEY_PREVIOUS             0x40BF
          KEY_REWIND               0xF807
          KEY_RIGHT                0x906F
          KEY_STOP                 0x20DF
          KEY_UP                   0xA05F
      end codes
end remote
If you have a Logitech Harmony remote, life is even easier.  You can select almost any media player remote, push the settings to your Harmony remote, and then capture they keypresses like described in the above.  If you want to cheat, you could search for the remote setting for "WD TV" and then skip capturing the codes and just copy-and-paste the above lircd.conf as your own.  

If you didn't generate the lirc.conf in the correct location, or if you are copying it from a difference source, make sure you store it in /home/pi/ on your Raspberry Pi.

All you need to do now, is in Raspbmc Settings (under Programs), use the settings Enable Repeat Filter (enable/fill in dot), Enable GPIO TSOP IR Receiver (enable/fill in dot), GPIO IR Remote Profile select Custom (lircd.conf on pi's home folder).

Then either restart XBMC (you can kill -9 on the xbmc.bin process in a ssh session) or reboot the Pi, and once the Lirc service starts in XBMC, your remote should control XBMC.

We don't have to stop here.  We can further move onto some customization.

It might be handy, for instance, to associate a remote key to a function.  For example, there is no key set that would allow us to quickly access the Favourites Menu.  In actuality, we can associate almost any function in XBMC to a key on a remote (likewise can be done for keyboard, mice, and joysticks).

We can repurpose an existing key, such as KEY_HOME, which we will use for this example.  If you have a Harmony remote, you could create virtual keys fairly easy that would appear in the activity screen on the remote.  The "WD TV" device in Harmony actually contains a few such keys such as A, B and C.  You can look up any unusued key name in the keymap (running the irrecord --list-namespace that was ran earlier), and associate the IR signal to the key name and add it to your lircd.conf.  For simplicity, this example will simply repurpose the KEY_HOME.

On the Raspberry Pi, I will create a file /home/pi/.xbmc/userdata/Lircmap.xml .  I add the following entries to that file:
(download Lircmap.xml)

<lircmap>
 <remote device="devinput">    
<back>KEY_BACK</back>
<up>KEY_UP</up>
   <left>KEY_LEFT</left>
   <select>KEY_SELECT</select>    
<right>KEY_RIGHT</right>
   <down>KEY_DOWN</down>
   <stop>KEY_STOP</stop>
   <info>KEY_INFO</info>
   <skipminus>KEY_REWIND</skipminus>
   <play>KEY_PLAYPAUSE</play>
   <skipplus>KEY_FASTFORWARD</skipplus>
   <menu>KEY_HOME</menu>
 </remote>
</lircmap>
In  Lircmap.xml, I am associating my key names to functions in XBMC.  You can look up all the available function names from http://wiki.xbmc.org/index.php?title=keymap .  It appears they are case-insensitive (Play = play).  I can associate the keys to explicit functions.  Because you are using KEY_* names that are actually valid and common, these are mapped to their appropriate functions in XBMC by default.  Therefore, you could have stopped and not created this file, and still be able to use the keys to invoke common functions in XBMC.  You only have to create this file and start mapping keys once you have decided to reprogram their functions.  You can select any available function name (you cannot make up your own, but you can select an existing name and repurpose it).  We will select an unused <menu></menu> and associate the KEY_HOME to it as in <menu>KEY_HOME</menu>.

Finally, on the Raspberry Pi, I will create a file /home/pi/.xbmc/userdata/keymaps/remote.xml .  I add the following entries to that file:
(download remote.xml)


<keymap>
 <global>   
<remote>      
<menu>XBMC.ActivateWindow(Favourites)</menu>   
</remote> 
</global>
</keymap>
I invoke the XMBC.ActiveWindow function and pass it Favourites to open the favourites.xml in a Favourties menu.  There are a number of windows that can be opened to common function.  There are also a number of different functions that can be called.  Favourites does exist in XBMC (it is actually a Window ID type that automatically loads whatever is listed in favourites.xml).  There are also a bunch of different window IDs that you can do the same action on.  You could literally have a 400 key remote and still not have enough keys to satisfy all the functions and windows to call upon.

At this point, with the menu defined to the KEY_HOME in the Lircmap.xml and the menu defined with our custom action to open the Favourites Window in  remote.xml, we can either restart XBMC (you can kill -9 on the xbmc.bin process in a ssh session) or reboot the Pi, and once the Lirc service starts in XBMC, your custom key should perform the action of opening the Favourites menu.

The last time I have is troubleshooting.  If a key doesn't appear to be performing correctly or if you don't believe you've mapped it correctly, while in XBMC on the Raspberry Pi, ssh into the system and run irw. When you press keys on your remote to XBMC, the actions and key names invoked should appear in the ssh session.  This will quickly help identify the key name associated with the key.  If you press a key and it doesn't appear in the session, it means you haven't mapped it in the lircd.conf.  

Tuesday, 17 December 2013

Modified switch.sh for Raspberry Pi (Raspbmc or Raspbin) (for illuminated and rocker-style power switches) [day 14 of 20-days-of-posts series]

Here is my modified switch.sh (for illuminated and rocker-style power switches) that were discussed in an earlier post.
(download switch.sh)
#!/bin/bash
#this is the GPIO pin connected to the lead on switch labeled OUT
GPIOpin1=23
#this is the GPIO pin connected to the lead on switch labeled IN
GPIOpin2=24
echo "$GPIOpin1" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio$GPIOpin1/direction
echo "$GPIOpin2" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio$GPIOpin2/direction
echo "1" > /sys/class/gpio/gpio$GPIOpin2/value
oldpower=$(cat /sys/class/gpio/gpio$GPIOpin1/value)

while [ 1 = 1 ]; do
sleep 2
power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
if [ $power = 1 -a $oldpower = 0 ]; then
oldpower=1
sudo initctl stop xbmc
sleep 5
sudo shutdown -h now
fi
done

Install the script by placing it in /etc/switch.sh.  Add /etc/switch.sh & to the bottom of /etc/rc.local but before the exit.

What this script handles that the original does not:
  • The original script provided by the vendor had a flaw where when the power off is triggered, the sudo poweroff is repeately ran over and over in a loop without any interruption inbetween.  This would cause my Raspberry to crash while powering off.  It would appear that it was turning off and would shutdown, but in reality it was turning off before it could safely shutdown.
  • Gracefully stop XBMC (if it is running) before shutting down.
  • I prefer to use shutdown -h now rather than poweroff.
  • I've witnessed an odd behaviour that on a fresh startup/boot up, the switch will be in a shutdown mode, meaning that it thinks it detected a shutdown request during the startup request, so that GPIOpin1 is pushing a value of 1, that would normally trigger the script to shutdown immediately.  So the Raspberry Pi shutdown shortly after starting up, and continuing in this loop.  The revision to the script ignores the switch input if it is instructing the system to shutdown on its initialization. 

Adding IR to your Raspberry Pi [day 6 of 20-days-of-posts series]

If you are going to use your Raspberry Pi as an XBMC player, you will eventually have a desire to use an IR remote.

There are alternatives, including using a USB/bluetooth keyboard/mouse, a USB multimedia remote (such as Lenovo's Multimedia Remote), or just use an iOS 6+ or Android 4+ device (XBMC Remote app).

If your newer TV supports HDMI CEC (which none of my TVs do), you can control your Raspberry Pi using your TV's IR port.

But if you're in my situation, your best bet would be to add an IR receiver to the GPIO port on the Pi.  It's very easy to do and doesn't require any soldering.

Shopping list:

  • 38KHz TSOP4838 or compatible IR receiver (source: ebay in quantities, about $0.20 - $1 each depending on qty)
  • 3 jumper cables (female on both ends) (source: ebay in quantities, pennies each)
One of the hardest parts is making sure you place the proper cables on the proper pins.

First the IR.  The rounded end is the front or top.  The pin alignment start from left to right as shown below:


Pin 1 will most likely be the OUT pin on most models.  However, the voltage and ground can be either 2 and 3 or 3 and 2, depending on the model.  You can check the specification guide that I've uploaded to see if your IR model is listed, it will tell you which pin is voltage and ground.  You can also refer to the specifications that were sent with your device.  I am assuming a model TSOP4838 throughout this post, therefore, according to the specification, pin 2 (middle) is ground and pin 3 is voltage.  Pin 1 is OUT.

If you proceed with the wrong pin alignment (ground and voltage are switched), you will potentially burn out the IR receiver, if you invert them by mistake.

Slide the jumper cables onto the IR pins so that they stay in place but are not loose.



Now, the second tricky part.  I have provided a GPIO pin lineup below.  Although the older vs revised Pi units have some variations, the pins we will use are the same on all Raspberry Pi units, regardless of model or revision.


It is important to situate the board correctly and count the pins correctly so that you don't get confused and plug the IR into the wrong pins.  We position the board where the USB port(s) are pointing down (due south), and we will count pins from left to right, from top to down.  So the most left and top pin is pin #1 (noted as 3V3 in the diagram).



IR pin 1 (OUT) will be connected to GPIO12.  Counting from top-left to bottom-right, this is GPIO pin #12 on the GPIO (right side, 6 pins down from the top).  IR pin 2 (ground/GND) will be connected to GPIO pin #6 (right side, 3 pins down from the top).  IR pin 3 (voltage/V) will be connected to GPIO pin #1 (3V3) (left side, top most pin).

Compare your setup with the photo provided below.



When you startup your Pi, you should see the existence of a /dev/lirc0 device.  Whether you are using Raspbmc or Raspbian, connect to a terminal console (such as SSH into the device).

Test your device, run the following:
  1. sudo /etc/init.d/lirc restart
  2. sudo modprobe lirc_rpi
  3. sudo mode2 -d /dev/lirc0
Take any IR remote and press a bunch of keys.  You should see output of those key presses on screen.  This confirms the IR receiver is properly connected and in working order.

To create a configuration for a given remote, run the following:

  1. sudo /etc/init.d/lirc stop
  2. sudo irrecord -d /dev/lirc0 ~/lircd.conf

Follow the prompts to learn your remote.  It will generate a configuration file lircd.conf in your home directory.  This lircd.conf can be referenced in your XBMC remote settings so that you may use your remote to control XBMC.

Now just modify your case to situate your IR receiver.  You can to maximize the space around the IR so signals are picked up.




That's it, for now.