Sometimes, you write a program or build a circuit because you actually want it to do something useful. Or at least something fun. Other times, you build it specifically to try out a particular technique or learn how something works. This week, I’ve been doing more of the latter than the former.
Take the circuit on this breadboard (please!). I’ve been continuing to teach myself how to program the Arduino, and I’ve been trying to learn how a few more electronics components work, and this is the result. I never would have set out with a goal to build this, and even if I had, I wouldn’t have done it this way. So what does it do? Well, it flashes the 16 LEDs in a particular pattern. And when you press the button, it plays the first couple bars of the main theme to Star Wars.
The point isn’t what it does, but how it does it. For example, there are 16 LEDs, and I can turn them all on and off individually, in any pattern I want. My Arduino doesn’t have enough output lines to address each LED individually. Instead, I’m using a pair of 74HC595 shift registers to control the light – they’re sitting in the center of the breadboard hidden by all the wires. The Arduino talks to the first register using the same kind of SPI serial I used a couple weeks ago with the C64 and the ADC chip. That register has 8 individual lines to control LEDs, and it forwards data from the Arduino to the 2nd shift register to control the remaining 8. The code on the Arduino side is really simple:
digitalWrite (latchPin, LOW); shiftOut (dataPin, clockPin, MSBFIRST, high_byte); // 2nd register shiftOut (dataPin, clockPin, MSBFIRST, low_byte); // 1st register digitalWrite (latchPin, HIGH); // latch in the new values
There’s a good tutorial about using shift registers with the Arduino here. The really interesting thing about the shift registers is that you can hook several of them up in serial. It’s an easy way to add a lot of individual output lines to a device like the Arduino. I wanted to try them out because I figure they’ll come in handy down the road if I want to communicate with something that has, for example, 16 address lines going into it.
The music playing function, on the other hand, started out because I was curious about how interrupts work on the Arduino. You may recall I used interrupts to control the timing for my C64 display scrolling hack, and I wanted to do the same thing here. The main loop() method in my Arduino sketch just managed the lights, and my plan was to use a regularly-occurring interrupt to update a state machine that would control the music.
For the actual music player, I started with one of the examples from SparkFun’s Inventor’s Kit for Arduino. Unfortunately, that code wasn’t really well suited to turning into a state machine, so I ended up rewriting everything except the storage for notes and frequency values. For the music player to work, it had to be based around a function that would be called at regular intervals and which would return fairly quickly, so timing notes with a for loop or something wasn’t going to work. With the state machine, each time the function was called it would look at its current state and either start playing a note, stop playing a note, or do nothing (if it was in the middle of a longer note or rest).
For the actual source of the interrupt, I had several choices. The Atmega chip in the Arduino has 3 internal timers which can be used to generate timed interrupts. That would actually be perfect for my purpose, but maybe a little too convenient. And remember, being convenient wasn’t the point – learning was the point.
The Arduino also supports two input lines for external interrupts, and that’s what I ended up using. It’s analogous to what I did with the C64, where the VIC chip sent an interrupt to the 6510 CPU. The actual source of the interrupts is a 555 timer chip, which sends a regular pulse to the Arduino at a frequency of 31 Hz. I wanted to use the 555 timer because I’ve been playing with them as I work through more of the examples in the Make: Electronics book. I’ll talk about exactly how that works in a week or two; for now it’s enough to know that it works.
The end result of all this tinkering was a circuit that, while kind of silly, was still fun to play with. I’ve had it sitting on my desk for the last few days, and I keep hitting the button for a random Star Wars fix. More importantly, it gave me a chance to put into practice three separate tasks: Using a shift register, writing interrupt handlers for the Arduino, and generating signals with a 555 timer chip. My plans are still kind of nebulous, but I suspect all these things are going to be useful somewhere down the road.
Oh, and why Star Wars? Come on, what kind of question is that? Besides, those notes are indelibly etched into my head from learning to play the theme on a recorder when I was in the 4th grade.