An Arduino + TI TLC5940 driving 12 LEDs and 12 analog gauges. Displays server load relative to previous day’s maximum updating every second.
I am a part-time maker, full time nerd. By day, I am a Product Manager at OpenDNS, an amazing company with globally distributed datacenters serving 30 billion DNS queries per day. That’s a huge number and even more substantial considering that 1 out of every 100 people connected to the Internet is using the service.
OpenDNS is turning 5 years old and I wanted to build something cool for the office to commemorate the occasion. I wanted to make a beautiful object that would look amazing and would make people think about what we had accomplished. I was also way overdue for an Arduino project.
I love old sci-fi war rooms and power stations with hundreds of gauges. While I would love to build something on the scale of this old Soviet power station, lets start small and then scale up :).
My design goals were:
- Design must be have both vintage and contemporary elements. I love steampunk as much as the next guy but not for this project.
- Arduino driven. It has been a year since my last Arduino project and it’s time to get back to my favorite little microcontroller.
- Expandable – not everything has to be done at once but a little work now gets me more to play with later. I used RGB tri-color LEDs but only connected the red channel for the first iteration.
- Get others involved. I am surrounded by brilliant engineers at work. If I provide them with instructions on how to send data to the panel over USB, they will do a much better job than I ever could. While this write up is about my work, it was awesome to work with engineers Doug Tabacco and Adam on this project.
- Pre-finished Birch Plywood – cut to 18″x24″ pieces to fit on the laser bed.
- Arduino – I had an Arduino Mega sitting around but it’s overkill for what I need. I need lots of PWM outputs and the Mega only has 13.
- TI TLC5940 LED Drivers – I daisy chained two of these chips to drive up 32 PWM/analog outputs. Each chip is about $4 and there is a good library with plenty of examples of Arduino+TLC5940. The one odd thing is that the 594o controls the individual cathodes (negative) so all the LEDs have to be common anode.
- 5mm common anode RGB Leds – I am only controlling the red channel with fading for now but will hook up the rest of the colors later to allow color changes.
- 0-5v gauges – the Arduino+TLC5940 can drive up to 5v which makes these panel gauges ideal. I originally tested on a 0-1A gauge with the shunt cut off but having 12 identical gauges already set up for 5v made the project much simpler.
- Misc – a little bit of glue, some 22AWG wire, 22AWG butt crimps and tap splices and a breadboard.
The world map is from http://www.vectorworldmap.com/. I had to remove some detail before laser etching the map because of how close all of the tiny islands off Alaska and Europe. Laser etching can be done in one of two ways: Raster and vector. While raster mode allows for fill and shading, vector mode etching cannot be beat for detail and sharpness. All of the outlines were converted into hairline vectors in CorelDraw and vector etched at 100% speed, 10% power, 1200dpi.
I found the locations of our data centers on the map and added mounting holes for the LEDs. Since I am using nice 5mm RGB diffused LEDs, I wanted to show them off. Instead of drilling a single big hole, I decided to laser cut a hole for each lead (Red, Anode, Green, Blue). Each hole is 0.5mm in diameter with .75mm spacing between holes. This aligned the leads perfectly and snugly allowing me to attach wires from the back.
The gauges are voltmeters that measure 0-5v DC. I originally planned on replacing the face of the gauges but the stock gauges looked so good I didn’t bother. The ambiguity of 0-5 only seemed to add to the overall effect.
I ended up using calipers to measure the gauges and making some fit-test cuts out of cardboard first. To my surprise, the first cut was perfect.
I have been playing with box joints for a little while and really like the contrast of laser charred edges against a light birch face. I got my settings dialed in to the point that I was getting a dovetail-like fit. In fact the boxes you see here are incredibly hard to disassemble.
For this project, I will be assembling and disassembling frequently so I adjusted my settings to make for a looser fit.
The laser cutter at TechShop has an 18″ x24″ bed. This is a great size but scaling the world map to fit in that space with enough room for two rows of gauges left New York and Washington DC so close together that the LEDs would be touching. I needed to scale up.
Since I have 24″ on one end I decided to make the case 23″ x 23″ x 6″. The 23″x6″ sides/top/bottom cut easily. I then split the back into two pieces and the front into three pieces. By keeping the front modular, I was able to permanently glue the sides, top front and bottom front but allow the middle front and back to be removed. Why leave that extra space in the middle? I’m not sure yet but I think there may have to be some rocker switches, buttons and dials added to the panel in the future.
Assembly and Wiring
This picture pretty much tells it all. The clamps were probably unnecessary since the finger joints were holding just fine but one can never be too careful. The only part missing from the shot is the Arduino that sits along the bottom along with a breadboard holding two TLC5940 chips. Notice the hole in bottom left for USB cord.
Hot glue used to hold wires in place. I reversed colors (oops) and the common negative/cathode is black for the LEDs.
Tiny butt crimp connectors attach the LED leads to the wires. You’ll also notice the red wire taps to attach common anode. Electrical tape is covering up the unused green and blue pins.
Arduino and breadboard are attached to the bottom of the case using foam tape.
I couldn’t be happier with how it turned out! Currently sitting at my desk at OpenDNS HQ getting a nice week long continuously on burn in to test for any issues before moving to a more central area.
The Arduino makes serial communication pretty simple. The two tricky parts are keeping the serial connection open and debugging. I settled on the format of three digits and a character to indicate which location (LED+Gauge) was being updated. For example, updating Amsterdam to 100% (gauge pinned at 5, LED glowing brightly) send 100A or 050A for 50%. The computer does all the heavy lifting of fetching stats and scaling it.
At this point, uber-engineer and friend Doug Tabacco took over and wrote the control software. His python script scrapes the per-site stats data, normalizes it to a % value and sends that value over serial every 0.085 seconds.
Everything seemed to be fine but then a strange thing happened: after a few minutes of testing his Mac’s USB port stopped responding until the computer was rebooted. I was starting to freak out because we were planning on bringing the board to a party 5 days away and this was more than just a little weird glitch. My first assumption was that there was something wrong with the Arduino. Then after a good night’s sleep I realized I forgot to comment out one of my debug serial outputs in the Arduino code. The Arduino was sending a line of serial output every .085 seconds (12 outputs per second)… yep, that’s how you fill a buffer and cause weird things to happen. After commenting out that output line in the Arduino code, Doug’s script worked perfectly!