Labels

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

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.


    My headless Raspberry Pi server [day 5 of 20-days-of-posts series]

    Intention: To be used as a headless download server -- nzbget, transmission, http stream download, gdrive upload/download, etc.


    Equipment:
    Assumptions:
    • No need for the VIDEO port (going to use HDMI)
    • No need for AUDIO jack (going to use HDMI)
    • Minimal need for HDMI; only for troubleshooting boot issues
    • No need to access camera port, GPIO pins, etc
    • Continued use of a 1.8/2.5" SATA drive for primary storage
    The headless server will be connected directly to the router via ethernet (no need for wifi).  There is no need for a keyboard or mouse.  One USB port will be occupied with a connect to the hub.  The 2.5" SATA hard drive will be plugged into the powered USB hub.  The second USB port would be used for a keyboard when needed for troubleshooting.


    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 my "spruced" up Raspberry Pi, where I have integrated a rocker-style power switch (with reset butt) and integrated 7-port USB hub (Monoprice 7-port USB hub).  The hub is powered by a 2amp power brick.  The power brick is fairly slim -- in a power bar, it would prevent another brick being plugged into the plugs next to it, but it does provide enough clearing to allow someone to plug a power cable into adjacent plugs.  The hub will provide enough power (1amp) to power the Pi.  Unlike other high-powered USB hubs that I have tried, the hub will provide greater than 0.5amp to device connected to it even though there is no host connected to it.  This is critical.  A lot of other hubs I have tried, they will provide high-power to a USB device connected to the hub only if there is an established host connection to the hub.  Therefore, if you try to connect a Pi to the hub, it is not able to provide enough power to the Pi to start it up because there is no host connected to the hub.  The Pi needs to be powered up before it will establish a host connection with the hub.

    With the Monoprice 7-port USB hub, the hub will provide enough power the usb connections to power the Pi up even before the host connection is established.  This is witnessed by a red light on the hub, which indicates it is powered on.  When the Pi itself is powered on and started, blue lights will turn on the hub to indicate connections of those devices to the host have been established.



    The hub also prevents backpowering over USB if there is a USB cable connected to the micro USB power port on the Pi using any one of the powered USB ports on the hub.  This allow for a switch to actually work.  Without this ability, the power switch would be futile as the Pi would become powered on automatically via the host connection between the Pi and hub when the hub gets powered on.

    The hub will provide 3 internal USB connections (used for things embedded into the lego case), 2 top USB connections and 2 USB connections along the same side as the Pi's USB ports.

    First actions that were performed was the readying of the USB webmail notifier, (disassembling, cutting and resoldering the wires) described in a previous post.

    Second actions that were performed was the readying of the USB hub.  The plastic case was removed, which was fairly simple enough.

    Power Consumption:

    Measured with a kill-a-watt meter, here are the power consumption numbers for this Raspberry Pi server.

    Consumption (Watts)
    USB Hub (idle) ~ 0 W
    Raspberry Pi
    w/ rocker power switch
    w/ USB Hub
    2.5 W
    Raspberry Pi
    w/ rocker power switch
    w/ USB Hub
    w/ 2.5" 5400rpm Hard Drive
    5.5 W (idle)
    6 - 6.5 W (spin up)


    Front-side view

    Before:

    After:

    Like the original server-pi case I constructed previously, I have a 2.5" HD drive bay for which I provide ventilation lego bricks.  You can see where the deconstructed hub sits, right on to of the Pi.  The left inset window shows the lights from the hub (red and blue).  The right window where I have situated one of the deconstructed USB WebMail Notifier LED lights.  It is plugged directly into a USB port on the hub (one of three that are "internal", obstructed by the lego case).

    Not much to see from the front side view; no special windows or openings.  The ventilation holes are for 2.5" SATA hard drive.  The bottom extends out 1 lego brick outward to accommodate the 2.5" hard drive being wider than the size of the Raspberry Pi.

    The video and audio ports are intentionally inaccessible.  The Raspberry Pi LEDs are also covered.

    The height of the original case was 5 blocks.  The revised case uses 7 blocks.  The length of the case is 16 blocks, which is actually down by 2 blocks (originally was 18 blocks), even considering that we added a power switch that is 3 blocks in length.

    Right-side view:

    Before:

    After:

    The SD card slot is now accessible.  The SD card depicted has a plastic "extension tab" tapped to it so that I can slide it in and out.  I needed to accommodate the power switch on this side, and that prevented me from dropping the length of the front side by another block size, that would have provided me enough access to the SD card without an "extension tab".  The micro USB power connect of the Pi is now opened up (as opposed to the old setup of internally wiring the port to the opposite side).  I've added a "flag" swing door.  There are these two pole holders on the case (one is depicted with a black lego pole).  I use have these attached so I can slide out these poles and use them to hit the internal reset button on the power switch (more on that later).

    A top side perspective of the same-side:



    Back-side view:

    Before:

    After:



    You can see the minimum width of the case has been extended by 1 block size, and around the HDMI port, the unit's width gradually extends further out two block sizes.  This is to accommodate the hub that sits overtop the pi.  There is a slight opening of 1/3rd block size along the base of the daughter board board on the hub.  Two of the upright facing ports are attached to the hub by a daughter board.  Instead of making the unit an additional block size in width, I leave this gap to accommodate this board.

    The blue window swings open from the top and provides access to the HDMI port.  I only use this when troubleshooting boot-up issues.



    Left-side view:

    Before:
    After:

    There are a lot of changes on this side.  We have access to the ethernet port and the two USB ports.  The Raspberry Pi LEDs are no longer covered up, viewable through a window.

    I have added a flag door, similar to the opposite side, where it can be swung up or down, to cover up partially or completely, the two USB ports on the Pi.

    With the integrated hub, we now have two USB ports accessible that are powered by the hub.  The entire unit (with Pi) are powered by the dim socket, connected to a 2amp 5V power brick supplied by the hub.  The right micro USB port on the hub is the host connection port.  It will be wired to one of the Pi USB ports by a short micro USB cable, depicted later on.

    The 1.8" or 2.5" SATA hard drive slides in the bottom base.   The door panel mechanism that I used to snap on before has been replaced (since I found they often fell off).  Instead, I have another one of those flag pole mechanisms, where I slide it vertically up or down.  When in the down position, it will obstruct the drive bay opening, preventing a hard drive from sliding out.


    Top-side view:

    Before:

    After:

    From the top view, we can see have access to two upper powered USB ports.  These are handy for plugging in flash drives, external hard drives, etc.  One I typically will use to power the Pi using the power switch.  You could also just backpower the Pi using the host connection alone, but then you won't be able to power the device on/off with the rocker-style switch, nor reset it using the reset button.

    The rocker-style power switch is accessible by the swinging upper door.  The reset button (next to the switch) can be toggled by using the flag pole.


    And the bottom....



    From the bottom-side view, we can see the base the size is 16 by 12 blocks.

    Wired up...


    Now time for some action shots.

    The first video demonstrates booting up and turning off.



    With the test.sh script running on the integrated multi-coloured LED.





    USB WebMail Notifier [day 4 of 20-days-of-posts series]

    I picked a few of these USB WebMail Notifiers from TheSource (made by Dream Cheeky).  They are common, places like DX carry a multitude of them cheaply.  The local store had them on clearance for less than a dollar.



    The model number is 8003037.

    The raw USB device information is:
    DEVTYPE=usb_interface
    DRIVER=usbled
    PRODUCT=1d34/4/2
    TYPE=0/0/0
    INTERFACE=3/0/0
    MODALIAS=usb:v1D34p0004d0002dc00dsc00dp00ic03isc00ip00in00

    The instructions for the device: http://www.thesource.ca/sitelets/gadgetree/downloads/8003037_om_en.pdf

    It comes with a mini-CD for installing drivers for Windows XP.

    The designed use of the device is to flash different colours based on various email incoming alerts.

    It's a basic USB device.  There are several cross-platform projects, most implemented in Python, since USB device driver support is extensive in Python.  One such project is https://github.com/konker/dreamcheeky_notifier

    If you are using Linux, you can control the device using the /sys/devices/..

    If you do a search for a handler call "green" such as find /sys | grep green, you should find where the device is located.

    On my system I get /sys/devices/pci0000:00/0000:00:1a.1/usb2/2-1/2-1:1.0/green.  For the device, there should be inputs blue, red and green.  Each input represents the lighted value for that colour.  The value accepts input values from 0-255.  In actuality, each colour has effective values from 0-100, 0 representing off and 100 representing maximum light intensity.

    Either through a Python script using the PyUSB device driver, a developer's open-source offering or by controlling the colours manually with the device driver, you can use the device for an infinite number of applications.  You can essentially use the device as a multi-coloured LED that you can turn off or flash different sequences or colours based on a set condition.  The controlled intensity makes the LED very visible.

    You can control the device by echoing the value 0-100 into a combination of blue, red and green.  You'll need to first give your user ability to write to the device (sudo chmod 666 blue; sudo chmod 666 red; sudo chmod 666 green).  Then a simple echo 50 > blue would set the device to exhibit the blue colour on the LED with half intensity.

    Here are two videos displaying the sequence demonstrated in the script below:



    script: test.sh
    Here is a video demonstrating the transitions from 0 to 100:


    script: transition.sh

    When you take the device apart, you see it's essentially a multi-coloured LED attached to a simple logic board.


    For my application, I further cut the cable near the USB plug and near the logic board.  I then used a pair of scissors (carefully!) to splice away the shielding cable from the connector.  I then shaved away the shielding cable from the cut ends, spliced off the 4 wires, and soldered the two ends back together.  Heat seal tape over the solder joints (to avoid wires of different types from contacting eachother) and then heat seal tape over the bundle so that I'm left with a logic board connected to the USB connector by a short set of wires.  I then slid this into one of my raspberry pi lego cases, providing a multi-coloured LED that I can use to view various conditions on the pi (this pi runs as a headless server pi, so there is no screen attached, making it difficult at times to quickly check on things).  I use the LED programmed in a bunch of different scripts to visually display statuses to me, so I can visually see the status by looking at the unit.


    A simple system LED as easy as pi ;)