Over the past six months I've been designing a circuit which mimics the PKE meter from the movie Ghostbusters. This is the third project I've done since I first started seriously tinkering with electronics and the Arduino a little over one year ago.
Here is a video of the prop in the movie which I have been attempting to replicate: http://www.youtube.com/watch?v=xoAm0cZAvDQ
Here is a photo of the circuit partially assembled:
And here is a video of a fully assembled circuit in action: http://www.youtube.com/watch?v=X9TLqTSqfFA
There are two servos, two resistive touch switches, and a high current shift register and a DAC on a hardware SPI bus. Each wing has 7 leds. There are also 14 leds on the display (seven of which are used at a time... they are selected via a switch), as well as five more leds on the front of the device, for a total of 33 leds. I control most of these leds using the shift register, with 7 of the outputs each tied to three leds (one on each wing and one on the display) and the 8th output being used to blink one of two leds on the front of the PKE. The remaining leds are a power led which is always on, and two leds tied directly to the serial pins on the Arduino which indicate when the touch switches are being used. There's also four dip switches and four pots, three of which need to be read.
So this was a fairly difficult circuit to build. I had to learn how to use Cadsoft Eagle to design the PCB because the wings are curved and Pad2Pad couldn't handle something like that. I'd also never built a circuit which uses servos, or a dac, or a shift register. I'd never even used a bare AtMega328 before. My other PKE circuits had made use of Arduino Pro Minis. I also had space constraints to consider, so the whole thing had to run off a 9v battery, which initially gave me trouble with the servos causing my LEDs to dim until I upgraded the voltage regulator to something with a little more oomph. And to make the touch switches work I had to invent a new method of reading high impedance inputs on the Arduino quickly. (Stick a 10K pulldown on one analog pin and read it first!)
And the difficulty doesn't stop there either. The software is pretty complicated too.
The circuit has a DAC, and the DAC needs to be updated at 31250hz. But the servos need to be updated too. And if they're not updated at just the right time, they jitter. To avoid this jitter, when I go to update the dac, I peek at the servo interrupt timer to see if it is about to update. If it is, I skip that dac update. This causes a small hit to the sound quality, but I can't have the wings of the PKE shaking constantly. That would be noisy, look bad, and suck up precious battery life, which I don't have much of with a 9v, even with a LDO regulator.
Furthermore, the DAC needs to be fed with data, and where does that data come from? Well, here, that data comes from additive synthesis. The sound effect is being generated in realtime because I didn't have a lot of ram to store a sample and playing the same short sample repeatedly at different speeds sounded awful. I wanted something which could vary a lot. So I have a function which has ten oscillators and does all this fixed point math with sine tables and phase accumulators to adjust the frequency and volume in realtime as the speed of the PKE changes. This data is then fed into a 1024 byte buffer for the DAC to read from. I think I'm still not filling it fast enough for the DAC, but it sounds good enough anyway, so... success, I guess. :-)
If anyone wants to see the sound mixing code, I'll probably be posting that to one of the other forums here, to see if anyone has any suggestions for optimizing it. I'll be happy to show the tricks I used for the other parts of the project as well if anyone is interested in something in particular.