Color Pong is a small electronics project I created to experiment with some new technologies, and also to create a fun little conversation piece for my cubicle at work. In a nutshell, theres a couple of tri-color LEDs, hidden under a ping pong ball-half, that can be mixed in brightness to create any of the visible light colors. There are three knobs (one each for red, green, and blue) that allow a person to specify the intensity of each of the components. The knobs have a SPST switch at one extreme, and if that switch is closed, then the microcontroller will slowly vary the intensity of the corresponding color component. It is actually pretty simple in hardware and software, but the end result gathers quite a crowd and lots of conversation among a bunch of software engineers at work.
In the pic to the left, you can see the red and green knobs. When I ordered the stuff, my supplier was out of the blue knobs, so that is backordered and will show up someday (I hope).
 |
|
|
 |
|
Solderless Prototype and SMT |
|
|
 |
|
|
 |

As always, I built a solderless prototype of the circuit while doing the deign and basic software proof of concept. At first, I used normal sized transistors and got the circuit working. As I was laying out the PCB in Eagle CAD, I needed to use a surface mount package, and I wanted to test it first in my prototype. To the right, you can see an adapter I created by soldering wires onto each of the tiny leads on the SMD package, and then attaching them to a 3-pin header spaced at .1" so I could slip it into the breadboard.

On the right you can see a thumbnail of the whole solderless prototype. The transistor adapter is all the way on the left. You can see two exposed LEDs and the pingpong ball is friction-fit over the third. You can see an adapter I made for the ATtiny44 µC in the SOIC-14 package. I made a tiny PCB for that, it was actually more fun to make that than I expected, not sure why though. You can also see a Lego space man torso that I use as a housing for an AVRISP adapter. I use it to connect the breadboard's 1x6 layout to the AVRISP's 2x3 layout. Its actually a spaceman from when I was a kid in the early 80's, so he's been around the block a few times.

Once the solderless prototype was done, and a very basic firmware proof of concept was complete, then its time to convert the circuit to a Printed Circuit Board. Using Eagle CAD, I made a schematic, and then a board layout. This takes me a long time, mainly my own fault, because I like to convert each and every component I use into a custom component in my own library. Makes it easier over time because I generally re-use the same basic set of components from project to project.
This PCB was a new concept for me because it was the first time I was using SMT components and the first time I was routing on the top layer of the board. Ended up OK, except I still feel I need to make the board too big (not dense enough) in order to have the autorouter route most of the traces. I'll probably need to learn to do double sided stuff some day.
You can see the 3 switches/POTs streaming out the bottom. A drop off center, there are the 3 tri-color LEDs. And finally, out the top, you can see dongles for the power connection, a 4-pin connector for my as-yet-unfinished debugging board called OverBoard v0.2, a shrouded 6-pin connector for in system programming via AVRISP, and an on/off switch. Just to the right and above the LEDs is the tiny little 14-pin ATtiny44 microcontroller.
To house this little project, I went to a dollar store and browsed around for something presentable. I ended up with a little picture frame called a "shadow box". Its like a normal picture frame, only its a bit deeper, and it comes with a silly little 3-d cardboard scene (rather than being designed to receive your own pictures). Its perfectly sized for my need.
The front face was originally glass. I got all ambitious and though I'd drill out the holes for the POTs through the glass. I went to Lowes and bought a special glass drill bit. About 30 seconds into drilling at low speed, I shattered the whole glass plate. Oh well. On to plan B. I took a nylon tile (just like the ones I used to build a line following race track) and cut it to size. Fits perfectly, and the holes drill out easily. Plus, with a Dremel tool and a grinding stone bit, I carved out the large/irregular hole for the LEDs to protrude through.
There are a couple of fun things to note about the enclosure.
- I spray painted most of the surfaces ultra-flat black, which gives a nice contrast to the colored ping pong ball.
- Using a Dremel with a grinding stone and a cut-off wheel, I carved out a pingpong ball to fit over the LEDs.
- All the data connections are glued into holes in the side-panel for easy access.
- And a fun rear-view of the whole thing.
There's not all that much interesting going on in the firmware. It is written using Atman AVR C development environment and the AVR-GCC compiler. I use two timers. The first timer is used as my "scheduler". Its ISR runs 10,000 times a second, and decrements some counters. In my main program loop, I act on those counters when they reach zero. The counters specify:
- check user input dials for new ADC value
- check user input dials for SPST switch open/closed state
- if the SPST switch is closed, then alter the intensity value for the respective color (see description of OCR and CNT below for more detail).
The second timer serves as a home-brew PWM for the colors. Each color has an "OCR" value (borrowing some terminology from Atmel and the built-in PWM). For each color, this timer ISR will increment the color's CNT value, which represents the color's current counter value. It starts at zero, and the LED is turned off. As the value is incremented, it is compared to the color's OCR value. Once you hit the OCR, then the LED is turned on. Once the CNT reaches 255, it is reset back to 0 and the process starts over.
This approach makes it pretty easy for me to use varying techniques for specifying the intensity of each color. If the user input dial for red is active (meaning the SPST switch is open and the user has specified a value on the POT), then I just read the ADC for RED. This gives me a 10-bit value. I convert it to an 8-bit value, throwing away the lowest two bits. And I'm all set, I just stuff this value into red's OCR, and the Timer ISR takes care of the intensity. If the red SPST switch is closed, then my main loop just makes periodic small changes to red's OCR, slowly shifting it from full off to full on. To make the colors blend somewhat randomly, my definition of "small changes" is 1 for red, 2 for green, and 3 for blue. Over time, you get a color pattern that does not seem to repeat to the naked eye.