Google Analytics

Wednesday, October 21, 2015

Opening a garage door from the Internet

Who wouldn't want to be able to control their garage door over the Internet?  No one, that's who.

I've recently mounted a 7" Android tablet in my wife's car to control navigation, music, realtime ODB II data, and various other tasks.  My wife then asked if she could control the garage door with the tablet.  "Well..... you can, but I have to build something to do that."  "Ok, then build it."

The requirements of the build are as follows:
  • It must give the status of the door (open/closed/unknown)
  • It must be able to toggle the status of the door
  • The WAF must be very high
  • It must work with at least Android, but all platforms would be ideal 
  • It must be secure since it's Internet facing
  • It must be reliable and therefore simple

The obvious place for me to start is with a Raspberry Pi - it's cheap, has network connectivity, runs Linux, and I have a spare sitting around the house waiting for a project.

It also seemed logical to make this as a web app instead of a native Android app so 0) it would be instantaneously up to date, 1) it wouldn't cause any battery drain from having to check the status every 30 seconds to stay up to date, and 2) for me, a web app is much easier to develop.

My garage door (like most) has a simple mechanism to trigger opening and closing the door.  Simply short two pins via a push button or, in this case, a relay.  The problem is that a Pi can't activate a relay directly with GPIO.  Well, not safely anyhow.  So we need to a very small amount of power to trigger an NPN transistor in order to trip the relay.  Since I'm using a 5V relay, I can safely pull that voltage from the 5V pin on the Pi.  The diode is there to prevent damage to the Pi when the field from the relay's coil collapses.

The electronics are pretty straightforward. A transistor activates a relay to open and close the door and 2 magnetic switches report the door's status back to the Pi.

The 10K resistors are there as pull up resistors.  Basically it makes GPIO pins 23 and 24 read as "high" unless the switch is activated.  Once the switch is activated the voltage goes to ground and the pin goes "low".

If you look at other projects on this page, you'll notice that I'm a big fan of using Cat5.  It's great: it's cheap, reliable, and able to carry signals over long distances without degrading.  In this case I ran 1 line of Cat5 to the garage and split 3 pairs off of it. The blue pair go to the garage door, the green pair go to the "opened" switch, and the orange pair go to the "closed" switch.

I decided to use 2 different switches instead of one because "not closed" or "not open" is not good enough for this project.  I wanted 2 switches to be in agreement as to the state of the door.  These are cheap door switches from Amazon - about $7 for a pack of 5 but they work great.

The activation circuit.  The blue and blue/white wires go to the garage door.

The switch to confirm that the door is opened

The switch to confirm that the door is closed

I simply soldered the resistors inline instead of bothering with another PCB.
Heatshrink tubing is awesome.
The finished hardware on a shelf in the basement (where no one can see it).
Now on to the software!

I used Inkscape to generate the SVG that I used to display the status of the door.  This project was largely an exercise for me to learn a little about CSS and SVGs.  This is the first thing like this that I've done from scratch and I know that there's room for improvement.  Please share ideas in the comments section if you have any constructive insight!

The idea is that the SVG will have either opaque or transparent doors depending on the status of the magnetic switches when the page loads.  When clicked, the SVG will have an animation of the doors either going up or down.  Once the animation is complete (which gives the door plenty of time to open or close) the page will refresh showing the status of the door as a confirmation. 

The code can be found on my GitHub account here:

Security is accomplished via Apache with ModSSL and basic authentication.  The guys at DuckDNS and PortForward have everything that you need to access your Raspberry Pi from the Internet.  

Lastly, I have to say thank you to to Kevin Sangeelee for his great write-up on using a Pi's GPIO to activate a relay, Justin McCandless for patching jQuery's GLARING lack of SVG class support, and to Nate Krofft for giving me a huge hand with some of the CSS.  And, since I know that I'm going to get a lot of this... I know that I'm not the first person to do this; I simply wanted to share *my* way of doing this with everyone in case it can be helpful to someone else.

Thanks for reading!

Sunday, February 22, 2015

Building a clock to help kids tell time

My daughter is about 2 1/2.  She loves learning about colors, shapes, animals, dinosaurs, and all sorts of other things.  However, she's still too young to understand how to read a clock.  But now is a good time to start teaching her.

We wanted a clock that would change colors based on what it was time to do: play quietly, go to bed, get up and play, pick up toys, and so on.  Here is the result:

Alarm clock next to the baby monitors and entertainment center.

To start, I purchased a wife-approved, battery-driven clock from a local retailer for about $10.  This one was perfect for me: it has plenty of room inside, a nice, big face, some weight to it to hold it in place, and, to top it all off, it matched the wall.

OK, enough introduction, let's get down to it.  I've got a Pi running a baby monitor (another project, another write-up, but the LEDs in the lower left corner are a super bright infrared spotlight for night vision on the cameras), so I'll be driving it from that. And I've got some ShiftBrites leftover from version 1 of my DIY Ambilight (scroll down for more info on that project).  Perfect.  Let's build.

First, I needed a power supply.  Since we have an excess of USB ports, that's what we'll use.  I've already built a power supply based on the LM317T and it's been running for 7 or 8 years now.  Using this basic schematic, I built the power supply to take a 5V input:
(credit to for the picture)

(I know, my workbench is cluttered.  I do a lot of work on it.)
This power supply is going to supply ~3V to the clock internals and 5V to the ShiftBrite.

Now we need software to test with.  After I could not get this tutorial to work, I found Hive13's project on GitHub.  After playing with it for a bit, I compiled the C program and was getting good tests.  However, I could not figure out a dead simple way to to just set certain colors and the program looped until interrupted - all of this is great for what Hive13 and likely most people want to do with a ShiftBrite on a Pi, but I needed something different.  I forked his GitHub repo and made a few changes, namely the ability to push red, green, blue, purple, yellow, and cyan from the command line and immediately exit.  I also added an "install script" as well as a "crazyclock" script to cycle through the colors.  It's all kind of hackish, but since the code was written for only my specific example, I don't care - but sharing that code back to the community is still the right thing to do.  

Essentially, I just added 6 command line arguments so instead of only having "-c [0-255]" emitting a white color with the given intensity, I've added the following code:

printf("  -R: Set to constant color Red\n");
printf("  -G: Set to constant color Green\n");
printf("  -B: Set to constant color Blue\n");
printf("  -P: Set to constant color Purple\n");
printf("  -Y: Set to constant color Yellow\n");
printf("  -C: Set to constant color Cyan\n");
} else if (opt->mode == RED && opt->constant_value_red >= 0) {
img[0] = opt->constant_value_red;
return 0;
} else if (opt->mode == GREEN && opt->constant_value_green >= 0) {
img[1] = opt->constant_value_green;
        return 0;
} else if (opt->mode == BLUE && opt->constant_value_blue >= 0) {
        img[2] = opt->constant_value_blue;
        return 0;
} else if (opt->mode == YELLOW && opt->constant_value_yellow >= 0) {
        img[1] = opt->constant_value_yellow;
img[0] = opt->constant_value_yellow;
        return 0;
} else if (opt->mode == PURPLE && opt->constant_value_purple >= 0) {
        img[2] = opt->constant_value_purple;
        img[0] = opt->constant_value_purple;
        return 0;
 } else if (opt->mode == CYAN && opt->constant_value_cyan >= 0) {
        img[2] = opt->constant_value_cyan;
        img[1] = opt->constant_value_cyan;
        return 0;

All of this is on GitHub, but essentially calling the binary with "-R 255" will turn the LED red at full brightness and immediately exit.  Simple and straightforward.

It's also worth mentioning that since this box is secure and I didn't want to mess with the proper permissions to grant other users the ability to use SPI, I just changed the setuid attribute of the binary to always run as root.  Again, this would should never fly in a production environment but in this case it's nothing to worry about.  

SPI pins on the Pi.  
Next is the case mods.  There was not enough room to put the ShiftBrite, so my Dremel helped me make it fit. 

Essentially from here, I just hooked the Vout pin of the LM317T to the clock's battery terminal lines and attached the ShiftBrite directly to the 5V line coming off of the USB cable.  Then I crammed everything as neatly back in to the case as I could.  I had to cut some pins and use some hot glue to insulate some things, but it worked.

There is a USB cable running in to the back for the power supply and a piece of Cat5e running out the back for data from the Pi.
The clock installed next to the baby monitor cameras.

The last thing is setting the clock color automatically.  I found a nifty little project called Minicron. Essentially, it's a client/server setup that modifies your cron jobs and sends the output back to the server.  It's simple, straightforward to set up, and perfect for what I need (given my lack of web development skills).  I installed it on my web server and on this Pi.  Then I just configure what colors I want the clock to be and when.

Additionally, I've configured ConnectBot on my wife's phone to have different connections that will just log in using a public key and execute "/usr/local/bin/clock -G 255" for play time or "/usr/local/bin/clock -R 75" to turn the clock red at reduced brightness for nap.  The cron job will take care of almost everything, but she needed the ability to change it on demand.  

So, that's pretty much it.  I'll be happy to answer any questions below.  

UPDATE: I realize that I forgot to mention that it is important to keep the clock and Pi synchronized.  Since I use Raspbian on the Pi, here's how I ensure it has correct time by using a Stratum 1 time server in my home town.

apt-get install ntpdate
service ntp stop
update-rc.d ntp disable
echo -e '#!/bin/sh \n/usr/sbin/ntpdate' > /etc/cron.daily/ntpdate
chmod +x /etc/cron.daily/ntpdate
service cron restart

This will get the Pi to update its time every day.  If you notice a skew over the course of a day (since the Pis lack a realtime clock) then you can just move this script to the /etc/cron.hourly folder.  If you do so, please us a different time server than this one.

Friday, February 21, 2014

Making VMs play nicely with hosts (by passing URLs)

I've recently moved to Linux (currently Mint) as my primary desktop at work and I need to run a Windows VM in order to use Outlook.  I'm running Outlook 2013 in Unity mode and kept getting aggravated that when I clicked links it would open the link in Chrome on the VM and not in Chrome on my host OS.

 When VMWare Tools installed, it created a registered application named "Default Host Application" that is apparently used for VMware Fusion on OS X and is useless on a Linux or Windows host.  VMware Tools would give the following error:

Make sure the virtual machine's configuration allows the guest to open host applications.

After searching high and low for a solution other than to make it go away, I gave up and wrote my own.  Here's the idea:

Set up a listener on the host OS that will just listen for a client and pass anything that it gets to Chrome so it will open a new tab.  Now we'll set up a client on the VM to forward any URLs that it receives to the listener on the host.  And finally, we'll configure our client on the VM to be the default for all HTTP/HTTPS URLs.  Pretty simple, right?  Oh, and we'll use Perl so it will work with Windows, OS X, or Linux on the host OR the guest.

Let's get started by installing Perl on your Windows VM.  OS X and Linux should have it already.

So we'll start with the server code.  I borrowed the majority of this form a few sites online and tweaked it to my requirements.
use IO::Socket::INET;

# auto-flush on socket
$| = 1;

# creating a listening socket to listen to port 7777 on all IP addresses.
my $socket = new IO::Socket::INET (
    LocalHost => '',
    LocalPort => '7777',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1
die "cannot create socket $!\n" unless $socket;
print "Running on port 7777\n";

    # waiting for a new client connection
    my $client_socket = $socket->accept();

    # get information about a newly connected client
    my $client_address = $client_socket->peerhost();
    my $client_port = $client_socket->peerport();
    #print "connection from $client_address:$client_port\n";

    # read up to 1024 characters from the connected client
    my $data = "";
    $client_socket->recv($data, 4096);
    #print "received data: $data\n";
    #Put your path to Chrome here!!#
    system("'/usr/bin/google-chrome' \"$data\"");

    # write response data to the connected client
    $data = "ok";

    # notify client that response has been sent
    shutdown($client_socket, 1);


Simply change line 34 to point to on OS X or Chrome.exe on Windows.  Running this script will invoke Perl and it will sit listening for connections.
use IO::Socket::INET;

# auto-flush on socket
$| = 1;

# create a connecting socket
my $socket = new IO::Socket::INET (
    PeerHost => '',
    PeerPort => '7777',
    Proto => 'tcp',
die "cannot connect to the server $!\n" unless $socket;
print "connected to the server\n";

# data to send to a server
my $req = "$ARGV[0]";
my $size = $socket->send($req);
#print "sent data of length $size\n";

# notify server that request has been sent
shutdown($socket, 1);

# receive a response of up to 1024 characters from server
#my $response = "";
#$socket->recv($response, 1024);
#print "received response: $response\n";


Running this script on your guest VM with any arguments will pass the string to the host and attempt to open it with Chrome.  Simply replace on line 9 with the IP address of your host and you should be in business.  I've left some debugging code in there so if you have problems you can uncomment it and try again.

Finally, we need to register our client script as the default HTTP, HTTPS, and FTP handler in our Windows VM.  Start by saving this to install.reg, modifying it to point to the location that you've saved the client script (I used the root of the C: drive) as well as the path to Perl, and importing it.  It is safe, but you should know what you are doing if you are modifying the registry.

Windows Registry Editor Version 5.00

"ApplicationDescription"="VM URL Passer is a Perl TCP client that sends all clicked URLs to the specified TCP Server in order to open links clicked in a VM to the host."
"ApplicationName"="VM URL Passer"

@="\"C:\\Perl64\\bin\\perl.EXE\" \"C:\\\" \"%1\""



@="VM URL Passer Document"
"URL Protocol"=""



Now that our program is "installed" we need to tell Windows to use it.  Open Control Panel > Default Programs > Set Default Programs.  Find "VM URL Passer" in the list, click "Choose defaults for this program" and check the protocols you wish to have passed to Chrome on your host.  I chose most of them, but the important ones are FTP, HTTP, and HTTPS.

Click "Save" and you should be good to go!  Try clicking a link in Outlook on your guest VM or just open Start > run > type '' and press enter.  It should open in Chrome on your host!

Disclaimer:  This was a quick and dirty hack and there is no security at all.  Anyone on your network can send anything to your browser if they find that you have that port open.  Use this with caution and if anyone has suggestions for improvement, feel free to post below!

Tuesday, October 11, 2011

Updated DIY Arduino Ambilight

I have updated my DIY Arduino Ambilight!

After using my DIY Ambilight for a few days I got tired of plugging in and unplugging the power supply to the ShiftBrite shield, so I finally broke down and added a switch to turn it on and off.  Now that I've been using it for a few weeks, I'm tired of having to turn it on and off manually every time I want to watch TV.

I noticed that my Samsung TV had a serial interface in the form of the EX-Link connector to see if I could electrically tell if the TV was on or not.  No luck.  I tested the USB ports next and found that when the display is off, the USB interfaces have about .15V and just over 5V when the display is on.  Bingo.  Now to get a relay.

This relay requires 3.5V to activate and less than .25V to deactivate. 

My next step was to add a relay to my ShiftBrite shield and cut an extra USB extension cable and wire the +5V wire (red) and the ground (black) wire to the coil of a relay.  My DIY ShiftBrite shield is now wired as the above illustration indicates with the USB +5V & Ground lines coming from the TV.  Since the coil in the relay will cause a brief voltage spike that could damage your TV's USB port, it is important to make sure that the protection diode is added.  Just add it 'backwards' across your relay coil so the energy stays in the coil and doesn't go back into the USB port.

Here is what my finished ShiftBrite shield looks like (the protection diode is on the bottom out of view):

Since most LCD TVs now have USB ports, I figured that this build could end up helping someone else.  I certainly hope so!

Friday, October 7, 2011

Field Day - Shooting a 1 lb propane tank with an AR 15.

Field Day Autumn 2011

 We try to hold Field Day at least twice a year for our Desktop Engineering students.  This year Field Day was on 10/07/11.  We decided to try to shoot a propane tank this time.  Here is what happens when you shoot a 1 LB propane tank with an AR15 (.223) from about 35 yards.  I was standing about 15 yards off to the side filming this.  I'm glad Bryan is such a good shot.

Wednesday, September 21, 2011

DIY Arduino Ambilight using ShiftBrites

This is my DIY Ambilight for my home theater PC. In this tutorial I plan to give detailed instructions on how to build a multichannel Arduino-based Ambilight for about $40 plus the Arduino which can be reused for other projects.  The bill of materials include 6+ ShiftBrites (your call, I wouldn't do less than 6 though), a printed circuit board, wire, and headers.  Additionally this will require all of the components needed to get over 0.5 Amps at 5.5-9V DC on to the board to drive the ShiftBrites; this cannot be reasonably done over USB power.  My ultimate goal here is to give others some ideas on how to go about this project for less money than it would cost to essentially buy everything in a kit.  I went in to this trying to be resourceful and I feel pretty good about how it turned out.  If this guide has been helpful, please consider donating.


The first challenge was to construct my own ShiftBrite Shield.  They can be purchased from Macetech's store, but I wasn't interested in spending that much money on one when I could build what I needed for a fraction of that cost.  As you can see, my ShiftBrite Shield is a bit more complex than Macetech's because I didn't have a transformer that could push enough amperage at those voltages.  My solution was to use a 12V 2A transformer and step the voltage down using an LM317T voltage regulator.  Here is a rough design of my board.  The resistors represent the total resistance of the line (ie. 2 x 470Ω in parallel = 235Ω and 1.2kΩ + 100Ω = 1.3kΩ).  I've since added a power switch, but that should be simple enough to figure out.  If you have a 7V 1A transformer then the voltage regulator stuff can be skipped.  It is probably a really good idea to have at least a 1000µF capacitor (if not the 100µF as well) to help eliminate some line noise.

It may be important to point out here that the ground from the ShiftBrite Shield is connected to the ground of the Arduino.  This is necessary for the clock to work.  Also, make sure you don't send any voltage down an Arduino port or you could damage your device.

Additionally, unless you want to write your own code to handle sending packets to the ShiftBrites, the pins of the Arduino need to be mapped to these PWM pins on the ShiftBrite.  The Arduinoatmo Google Code site has some nice and efficient code to bitshift and use SPI to determine when to continue without using the dreaded delay function.  More on the code later - just make sure you know what you are doing if you use different pins.

As you can see above, you will likely need a decent heatsink for the LM317T to dissipate any heat.  This fairly large heatsink gets pretty hot to the touch after a few hours of operation.

Since I'm opting to use the materials that I have on hand to do this, I decided against buying cables as I have a ton of Cat5 laying around.  I needed 6 pins, so I cut off the blue wires and made sure to wire everything up the same way on both ends.  Once I finished wiring the ShiftBrites, I went back and applied hot glue to act as an insulator between the wires.  When wiring your ShiftBrites, take note that the Data/Latch/Enable/Clock pins are labeled I and O (as in Input and Output) and not 1 and 0.  Embarrassingly I did not pick up on that right away and was wondering why it would not work when I sent a signal over the D0 pins but did on the D1 pins.    

As you can see, I'm using ShiftBrite 1.0 because while I was building this version 2.0 came out.  One of the main changes to the design was to add a power filtering capacitor to the device.  As awesome as these devices are, they definitely need the capacitor.  Granted this 2200µF capacitor is overkill, it is what I had on hand.  I started with 2 of these capacitors on my chain, but because of noise issues that I was having, I went back and put a 220µF capacitor on every other ShiftBrite 1.0 in my chain.

On to the software.  For my setup, I'm using boblight on Fedora to capture from X11 because Mythtv does not have this functionality built in.  VLC and AtmoWin work very well on Windows if you are going that route.  Either way we get the same packet information to the Arduino over the serial interface. Fun3 has some good technical info on the Atmolight protocol.  Basically we get 4 bytes and then 14 bytes of actual data per packet.  The packet and protocol information is good to understand, but largely inconsequential if you are using the Arduino sketch from the Arduinoatmo project because it will handle things for you.

The next step is to upload the software to the Arduino.  It's probably a good idea to start with some sketches that don't require any input from the computer.  This will allow you to test your hardware setup on its own.  Both of these sketches require you to change the pinout to what we are using.


 The former is Macetech's code, the latter is Ashley Hughes' code - both modified to use the pinout described for the DIY ShiftBrite Shield.  Whichever way you go, you should be able to get the ShiftBrites to do something at this point.

For this to work with your videos, you need to get boblight compiled or installed on your HTPC.  I could not find an RPM for Fedora (although I'm sure they exist), but compiling it from source was pretty simple.  Just follow the instructions on the project wiki.  It wasn't any harder than installing the dependencies listed with yum (replace 'apt-get' with 'yum' on Fedora), running the ./configure script and then running make. 

Once that is set up, we need to configure boblight.  Below is my boblightd.conf file:

timeout         20
port            19333
interpolation   on
proportional    100.0
saturation      3.0
value           10.0
valuerange      0.0 1.0
use             yes
method          average
threshold       20

name            ambilight
type            atmo
output          "/dev/ttyACM0"
rate            38400
channels        15

interval        200
prefix          FF

name            red
rgb             FF0000
gamma           1.0
adjust          1.0
blacklevel      0.0

name            green
rgb             00FF00
gamma           1.0
adjust          1.0
blacklevel      0.0

name            blue
rgb             0000FF
gamma           1.0
adjust          1.0
blacklevel      0.0

name            center
color           red     ambilight 1
color           green   ambilight 2
color           blue    ambilight 3
hscan           25 75
vscan           25 75

name            left
color           red     ambilight 4
color           green   ambilight 5
color           blue    ambilight 6
hscan           0 10
vscan           0 100

name            right
color           red     ambilight 7
color           green   ambilight 8
color           blue    ambilight 9
hscan           90 100
vscan           0 100

name            top
color           red     ambilight 10
color           green   ambilight 11
color           blue    ambilight 12
hscan           0 100
vscan           0 15

name            bottom
color           red     ambilight 13
color           green   ambilight 14
color           blue    ambilight 15
hscan           0 100
vscan           85 100

This goes in the file: /etc/boblightd.conf.  When boblightd gets executed, it will run in the background listening for something to tell it what to do.  To break it down, boblightd talks to the serial interface on the Arduino over USB and listens for data from another program.  In this case I'm using boblight-X11 - a program that will run on the current X11 session and grab images from X11, process them, and send the information to boblightd which will in turn process it into the proper protocol (atmo) and then send the data to the specified device.  If you want to learn more about the protocol that you are using, it is easy enough to send the output of the boblight daemon to a text file so you can look at the data being sent; just replace /dev/ttyACM0 in my config file to the location of a file on the hard disk.  

So how can we find out what to put in the device field so boblight can talk to the Arduino?  Start by running 'tail -f /var/log/messages' from a shell.  You will likely see some things scroll by as DHCP leases get renewed and whatnot.  When you plug in your Arduino to a USB port, it should read something like this:

kernel: [453420.004354] usb 3-2: USB disconnect, address 7
kernel: [453422.904031] usb 3-2: new full speed USB device using ohci_hcd and address 8
kernel: [453423.052623] usb 3-2: New USB device found, idVendor=2341, idProduct=0001
kernel: [453423.052629] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
kernel: [453423.052633] usb 3-2: Product: Arduino Uno
kernel: [453423.052635] usb 3-2: Manufacturer: Arduino (
kernel: [453423.052638] usb 3-2: SerialNumber: 6493534363335130B041
kernel: [453423.054731] cdc_acm 3-2:1.0: ttyACM0: USB ACM device

Typically it will be something like ttyS0, ttyUSB0, or in my case, ttyACM0.  Simply put the device path into the boblight config file.  Once boblightd is running, the Rx light on the Arduino should be flashing pretty rapidly or on constantly.

By default boblightd does not fork, so if you want to run it from a startup script you need to call it with the -f parameter or it will die when the startup script is done.  Also by default boblight-X11 only samples the screen once every .5 seconds. I call 'boblight-X11 -t 0.1' so it samples it 10 times a second.  The behavior of this is up to you.  Be sure to use top to see how much CPU usage these two programs are using. 'top -d 1' will give you one second updates.  It should be using no more than 5% CPU on a reasonably new machine.  

Mounting the ShiftBrites to your television/display is going to likely be the last challenge in this project. After bouncing some ideas off of my friends, I decided to go with plexiglass mounted to the back of the TV by the wall mount holes.  On my Samsung the screws were 6 mm with 1.00 threads.  I used 40 mm long screws with full threads to make sure the plexiglass was far enough from the back of the display so it could vent.  I used 2 washers and a nut all tightened to the head to hold the plexiglass in place and another nut that would be tightened against the TV itself to hold the whole setup securely.  

 My power cable had enough room in the spacing to be manipulated, but the input cables did not.  Since I wanted a ShiftBrite at the bottom corner, I had to cut out a space for the input cables but leave a place for the LED.  We won't talk about the horrible job I did cutting it, but it works.

I needed to find a way to aim the ShiftBrites once I mounted them.  I didn't want to have them aimed directly back on to the wall, so again I looked for an unorthodox solution and found one in my wife's wedge-shaped makeup applicator sponges. Hot glue seemed to be a good adhesive choice since it is strong and I know I can get it off of the ShiftBrites without damaging the subcomponents.  The mass of tape on the left is that 220µF capacitor mentioned earlier.

Here is what the back of my TV looks like with the plexiglass and all of the ShiftBrites mounted.  As you can see, some of the LEDs (like the top center) need to be aimed a bit better.  But this is the gist of my mounting solution.  

The last thing that I needed to do is to find a good diffuser to put over the ShiftBrites.  Because of the proximity of my television to the wall I get some odd colors on the wall.  For example when a ShiftBrite is shining white, I can see the green subLED pretty strongly.  My solution to this was to cut up the flat sides of a plastic water jug in 2.5" squares.  I stapled two together on the edge of one side and attached them to the pieces of foam.  This acts as a good enough diffuser until I am able to find something better. 

Here is a sample video of what my DIY Arduino Ambilight looks like.  

Here are a couple of other example of what it looks like after I added the diffusers.  There's not much color on the first one, but it illustrates some of the difficulty that the ShiftBrites have with displaying pure white without seeing the individual subLEDs.  If you look really closely you can see some green tints in the video when there is only supposed to be white.  Those tints were really well defined and annoying before the diffusers and are almost unnoticeable in person after the diffusers. 

I'd love to hear any ideas that anyone else has on this or a similar project!  Please leave any comments below.  If this has been helpful, please consider donating. 

Quick $10
Other Amount

Disclaimer: I've tried to reduce errors, exaggerations, and outright lies in this tutorial.  If I missed something, something is wrong, or you have questions then please post below and I'll update the info in the post.  If you build one of these devices and it burns your house down then I cannot be held liable, yet I offer my condolences.  If you attempt to hold me responsible then I *will* laugh at you. This information is provided as-is with no warranty.

Creative Commons License

This article and contents therein by Don Howdeshell is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.