IMG_9148

Booze Bookshelf with LEDs and built-in dance party

When my girlfriend and I moved into our small apartment in San Francisco we wanted to setup some sort of compact liquor cabinet and wine rack. After a quick trip to IKEA we had a bookshelf we could easily convert into a fancy boozeshelf unit! *insert music montage here* After adding holders for wine glasses and bottles it was good, but still a bit boring and not quite perfect. At night it would just stand there against the wall in a shadow, not presenting our handiwork at all. A true insult to all the alcohol we had on display. I felt like it needed something more — some light…and sensors…and might as well throw in a dance party while I’m at it.

IMG_9089 photo

IMG_9146 IMG_9148

And here’s a silly video demoing the entire thing…

Adapting the IKEA bookshelf

Turning the IKEA bookshelf into a boozeshelf was surprisingly easy. We just added some upside-down wine glass holders to the top and a wine rack on the bottom. Classy.

The upside-down wine glass holders were just a few strips of wood that we cut slots in and screwed to the top. You can also find pre-made ones all over the internet.

IMG_9088 photo 3 photo5

The wine racks were a gift from my parents and just happened to be the right color and fit almost perfectly. I just needed to shave about 1/16″ from both sides and then they fit snugly in the bottom shelf.

photo 1

The Electronics

A few days after the conversion I realized that the shelves were a bit too dark at night. I wanted it to welcome me by gently lighting up the shelves every time I stepped up for a drink. So I rigged an ultrasonic range sensor to an Arduino Mega 2560 and 2 meters of RGB LEDs strips.

I quickly realized that it would be boring and downright blasphemous to use that many RGB LEDs and only shine white light. (this is how feature creep works, kids) So I grabbed an IR receiver and SparkFun IR remote – that I just had lying around – and built a few IR activated & controlled programs:

  • Program A: Fades each shelf a random color, independently (otherwise known as Dance Party Mode).
  • Program B: Cross fades each shelf at the same time between red, green and blue.
  • Program C: You choose the color for all shelves via the up/down and left/right arrows on the remote. It saves the chosen color to the on-board EEPROM for next time. Kinda like a simple version of the phillips hue.

IMG_9090 IMG_9091 IMG_9095 IMG_9135

Hidden Sensors

No ugly sensors sticking out here. The ultrasonic range sensor and IR receiver are hidden in one of the wine rack holes. It blends in pretty well and isn’t visible unless you’re looking for it. Especially when there are more wine bottles in the rack.

As a side note, we’ve had some problems keeping the rack filled. Could be a leak in the system somewhere; more research is required.

IMG_9121 IMG_9122 IMG_9123 IMG_9128 IMG_9130 photo 1

This is just a couple pieces of cardboard painted a dark brown to match the wood. One is a flat piece with two small holes that that the sensors are mounted through. The second is a tube that directs the ultrasonic sound waves out of the hole without prematurely reflecting back.

Circuit

full_circuit

The Arduino Mega treats each shelf as an independently controllable RGB output — which means I’m using 12 PWM pins for 4 shelves (4 shelves x 3 colors = 12 PWM). The diagram only shows one shelf, for reference.

Maxbotix’s new line of HRLV ultrasonic sensors support TTL output if you solder a jumper. I’m using that for distance calculations instead of the standard analog output that most tutorials use.

The IR receiver is, unfortunately, being processed through a Pro Mini board and then sent to the mega via Serial1. It’s an ugly hack that I explain later in the Firmware section.

IMG_9098 IMG_8874 IMG_8876

LEDs and MOSFETS

Following a pretty standard approach, and outlined by Ladyada, I used 12 MOSFETS to connect the LEDs to ground. The one thing I changed about her example is the addition of 100 Ohm resistors pulling the gate pin to ground. These pull-down resistors keep the MOSFET switches closed when the pins are not high. Without it you can get some LEDs turning on until you manually zero out the pins.

Instead of using the traditionally large MOSFETS, I picked up a bag of small SPT ones from Jameco. Even still it was a challenge to cram them all on the shield board — some were soldered underneath the shield to fit.

MosfetLED_circuit_picture_transparent
MosfetLED_schematic

Download Fritzing files

Firmware

All the code was written in raw C++ on eclipse, via the arduino plugin. I’ve posted the main program source code up on github.

Controlling 12 PWMs — Otherwise known as Hot PWM Action

I spent most of my time figuring out how to get the Arduino Mega to control all 12 PWM outputs independently without slowing the program down at all. Most common LED fading techniques use delay() to set the speed of the fade. The delay method, of course, makes the rest of the program unresponsive to range input, IR input or any other actions.

To fix this, I created the LEDFader arduino library. Instead of using delay, each cycle it checks the processor’s time and change the PWM value as needed. For example, to fade from 0 to 255 in 2 seconds, it would increase the PWM by 1 every ~8 milliseconds (2000 / 255 = 7.84). The library is also written to automatically “catch up” if the animation was falling behind due to other things delaying the processor.

In my testing it’s lightweight, fast and fairly precise at controlling all 12 of the LEDs independently without imposing any significant delay to the processor.

IR Input

The one annoying catch in this project was that the IRremote library was causing the program to crash. I’m not entirely sure why, but when I started using the IR remote it would receive the first few IR codes and then the arduino would become unresponsive. I’ve heard that it’s use of system timers can conflict with other libraries, but I’m not sure if that’s what is going on here.

Instead of spending much time on this, I grabbed an extra Arduino Pro Mini, threw the IR receiver on that and then had it send the IR codes to the mega via Serial1. Quick and dirty.

Done!

Fork me on GitHub

Comments