Sunday, June 30, 2013

Modular Light Box

  To go along with the continuous stream of data being produced by the water level sensor, I figured it would be nice to have some simple way of displaying the current water level just as one would display the time on a clock. The easiest way I can think of would be just to have a line of LEDs that light up to a certain length based on the incoming data.This seemed a little dull, so I decided to add a few features.
  To go along with the current water level, wouldn't it be nice to see the current temperature? Maybe even the weather prediction for the day (sunny, cloudy, rainy..)? Since I've already chosen a panel of LEDs for the water level, I chose to make another panel for the weather. With 2 roughly square panels of LEDs already, I figured the whole apparatus could just be one big cube. Each of the LED panels would form a vertical wall, and the controller would form the base.
  Of course, getting the data requires an internet connection. One option would be to use an Arduino Ethernet shield, but then you need an ethernet cable running to the device, along with the power cord. To eliminate the extra wire, I opted for the Arduino Wifi Shield mounted on an Arduino Uno.

In the end, I had settled on a modular light box design:
-Arduino base controller with wifi to handle data processing
-Up to 4 removable LED panels forming the box walls
-Each panel uses a standardized 6-pin connection to the base controller
-Panel display determined either by analog signal or simple serial commands

With 2 panels in mind:
-Water level panel - 8x8 matrix of blue LEDs lit to a certain height based on analog input
-Weather panel - 16x16 matrix of RGB LEDs set to a constant color and image based on serial commands

Initial concept drawing, very professional.

Other panels could be added later as long as the main Arduino board is updated to send the appropriate signals.

I won't go into too much detail of how I made the base. It's really just the Uno + Wifi mounted upside down on some male headers, a voltage regulator for each panel, and some wiring to allow one-way communication from the Uno to each panel. Since the Uno is upside down, I added a green LED to indicate when the board is plugged in, and a white LED that flashes when the Uno is being programmed.

I started out working on the water level panel since it was the easier of the two I had in mind. With a pile of blue LEDs and a large protoboard, I got to soldering.

96 blue LEDs all soldered up.

I didn't need to address any of the columns individually, so all of the LEDs on a given row were connected together in parallel. Instead of the 8x8 array I had planned, I went with a 8x12 array for a more vertical aspect ratio. Adjacent to each row I added a current limiting resistor and a NPN transistor to supply the current for that row. This way, all I needed to supply to each row was 5V logic from an IC to turn it on.

The next issue was how exactly to control each row. All the base controller would supply is a serial command specifying how high the water level was, so I needed some logic to turn that into an on/off signal for each row. To interpret the serial commands, I went with an ATtiny84 microcontroller with an Arduino bootloader. I wanted to keep the bottom two LED rows permanently on, which meant that the ATtiny had enough IO pins to control the other 8 rows without using any shift registers or demultiplexers.

ATtiny is the one IC in the lower left corner.

With the first panel finished, I loaded up a simple code to light up the rows and tested it out. This first thing I realized was that 96 LEDs on one panel can be very, very bright when each is pulling 20mA. The panel was also drawing way too much current for the voltage regulator to handle, so I had to quickly shut it off and think of a way to turn down the brightness. Changing out all of the resistors on the board would have done the trick, but it's not the peak current I'm worried about, it's the average current. Instead I opted for using Pulse Width Modulation (PWM) on each of the Attiny output lines to switch the LEDs on and off faster than the eye can register. This way, I could change the panel brightness at any point by changing the PWM duty cycle.

With the first panel working, I write a short code for the base to connect to a wifi network and grab the current water level every few minutes and send the value to the water level panel. For the panel I used an even simpler code that parsed the values sent to it and lit up some number of LED rows. Once the codes were tested, I closed it all up and let it run.

A small gap was left at the bottom due to a correspondingly small miscalculation.

I've let this box run continuously for a few months and haven't run into any problems. There's a second plug for another panel, but that will have to wait for another day.

Final resting place.