This is a project I built July 2009 for a friend's party. I'd been interested in 1) how to build a cheapish light dimmer circuit 2) controlling things from my iPod Touch 3) interactive engineering-art. So I set myself on this project. Two weeks and about 80 hours of work later, I had a solid working prototype (shown in the video).
I started by learning how to build a light dimming circuit. I knew triacs and solid state relays could be used to dim lights. Solid state relays are expensive so I took a look at a couple of existing light-dimmer designs that use triacs. This article by Andrew Kilpatrick was particularly helpful and will explain the theory of light dimming using triacs. Triacs, as well as most (maybe all) other AC light dimming methods, dim the lights by turning them on and off rapidly and in sync with the ac sine wave. I ordered the parts and set about making the AVR software that would control the TRIAC's timing.
The software on the microcontroller works like this: commands containing a light id and an intensity are received through the UART. Every time the AC voltage goes to zero (a zero-crossing), the light items are sorted by intensity, all lights that don't have an intensity of 100% are turned off, then an output compare interrupt is set for the time the next light needs to be turned on. When the output compare interrupt happens, the light specified in the top item in the array of lights is turned on, then another output compare interrupt is set up for the next light that needs to be turned on. A couple designs I saw used an interrupt that happened 256 times every AC cycle; while this certainly works, I wanted only to use output compare interrupts so that, the handler code only runs when a light is about to be turned off.
The router is a Fonera 2100 that has been updated to run a more plain version of OpenWRT Linux instead of the original FON firmware. I used the serial interface to do update the Fonera's firmware. The software on the Fonera was fairly simple: it receives commands light intensity commands via UDP and then forwards those out the UART to the AVR. To compile programs for the Fonera, I set up the OpenWRT buildroot in a VirtualBox virtual machine as per these instructions.
I learned some legit ObjectiveC iPhone/iPod programming using the Apple SDK for this project. ObjectiveC is a superset of C/C++ so it is still possible to program in C/C++ for the iPhone/iPod. For the UDP code, I used standard Unix function calls in C and the rest I wrote in ObjectiveC.