Step 15: [Appendix] Circuit Schematic
This section describes the design of the Jar o'Fireflies circuit and is meant to shed light on some of the design decisions made. It is not neccessary to read or understand this section in order to build your own fireflies. However it will hopefully be of use to anyone wanting to modify or improve the circuit.
The following schematic describes the Jar of Fireflies circuit. In particular, there are a few notes to make about its design:
VCC - the positive terminal of your 3V power supply (i.e. battery), for those unfamiliar with electronic schematic naming conventions.
GND - likewise, this goes to the negative terminal on your battery.
R1 - 22.0K Ohm resistor - This is used as a pull-up resistor to drive the voltage at the reset pin high during operation thus preventing the chip from being reset. The circuit would actually work just fine if this resistor was simply replaced by a wire. However there would be one critical difference: you wouldn't be able to reprogram the chip once it was soldered to the board. The reason for this is because the chip programmer wouldn't be able to drive the reset pin low without shorting to VCC at the same time. That's the sole purpose of R1, to allow a chip programmer to toggle the reset pin without shorting to VCC. As such, the value of R1 isn't actually important, so long as it's 'large enough' (without so large as to block the reset pin from seeing VCC at all). Any value between 5k-100k is probably just fine.
R2,R3 - 100 Ohm resistors - The value of these resistors dependent on the characteristics of the model of LED's you happen to be using. Different LED's, even of the same size and color, have widely different characteristics, particularly when it comes to how much current they draw and how much light they produce. For instance, the model of LED's that I wound up using are spec'd to draw around 20mA at 2.0V and 10mA at 3V through a 100 Ohm resistor.
Now had I this circuit to do all over again, I probably would have chosen a slightly larger value for R2,R3. The reason for this being that, were I to see a firefly in nature glow as brightly as one of these LED's do at 10mA, I would expect it to explode in a wet green mist a millisecond later. That is to say, at 10mA these LED's glow too brightly to be realistic fireflies. This is an issue that I addressed in software by limiting the maximum brightness that the LED's are ever driven at. If you use the same part # LED's that I used, you'll find the firefly software to already be tuned to an appropriate brightness. Otherwise, unless you intend to change the brightness scaling in the source code, you may find yourself going back and fiddling with the value of R2,R3 to find a value more appropriate to whatever LED's you end up using. Fortunately, this shouldn't take much effort as SMD resistors are easy to rework.
PIN_A,B,C,D,E - These are names that I arbitrarily gave to the pins in order to tell them apart and I refer to the pins by these names in the source code. Pins A and B I refer to as "master" pins. If you don't plan on reading the source code, then this distinction won't make any difference. If you do plan on reading the source code, hopefully the comments I've placed in it will sufficiently describe the role of the master pins and how the LED's are driven.
Irregardless, here is the executive summary of how the LED's are driven:
Before a firefly 'song' is played, a random decision is made as to what LED is to be driven. This decision starts with the selection of the 'master' pin, either PIN_A or PIN_B. This selection narrows down the choice of what actual LED's can be driven. If PIN_A is chosen, then we have a choice between LED1, LED2, or LED3. Likewise for PIN_B and the other LED's. Once the master pin is chosen, then we randomly choose the specific LED to drive from the reduced list of candidates.
For example, lets say that we've chosen PIN_A and LED2.
To turn LED2 on, we drive PIN_A high and drive PIN_D (the pin that the other side of LED2 is connected to) low. To turn LED2 off again while playing the song, we leave PIN_A high and drive PIN_D high as well, thus removing the potential difference between the two sides of LED2 and stopping the current through it, turning it off. Since we leave PIN_A driven high all the time, we can also choose to play either of the other two LED's, LED1 or LED3, completely independently. In practice, the code is written to play a maximum of two songs at the same time (two firelies glowing at the same time).