Introduction: Fun Hackable Speaker Timer
This is a fun speaker timer I made for some upcoming conferences. It uses a 4-digit charlieplexed LED (pseudo 7-segment) display and is driven by a AVR ATMega328 or an Arduino. It allows a default time to be set, can be paused, and will put out 5 Volts on several IO lines when 10, 5, 1, and 1 minutes are remaining. This allows for some fun (say firing up a NERF rocket launcher as you get closer to quitting time).
This is a fun and cheap project that makes use of AVR interrupts. If you are interested in using interrupts with the AVR this project is a good tutorial.
Step 1: Getting Parts
1. For the timer itself you will need a material to hold the LEDs. I used Lexan for mine, but some thin plywood or most any flat stock that you can drill easily should work.
2. 58 LEDs or your favorite color (14/digit *4 digits + 2 for colon). Wide angle diffused LEDs are best here. If I had it to do over I would probably use clear lensed LEDs to make it easier to read the clock. Also, if you put a piece of paper in front of the clock you can read it from a wider angle.
3. 4 momentary push buttons for reset, start/stop, minute+, and minute-.
4. 8 resistors or the appropriate size for your LEDs. This is determined by color (voltage drop) and current capacity. For my red LEDs with 20mA of current, the resistors are 75 Ohms. Note that there are several resistor calculators out there and that you will need to divide the value they give by 2 because there is a resistor on both the high and low line when charlieplexing.
5. An Arduino or AVR ATMega328 microcontroller. The plus side of using the Arduino is that you don't need to solder as much, but it costs more than all the other components for the project combined. If you use the raw chip (what I did) you will need a programmer and I would definitely recommend a 28-pin socket to avoid killing the ATMega328 during soldering and to allow for easy modifications.
6. Either a prototyping shield if you are using an Arduino or a small printed circuit board. I used a cheap one from Radio Shack ($3.19) with the copper pads on one side.
7. Terminal strip (optional). I got a 6 connector strip at Radio Shack for a few dollars. I use it to put out the trigger signals and also have a 5V and ground connector.
8. Power supply (optional). If you are using Arduino this is already covered. For using the raw ATMega328 you will need a source for 5V to power the chip and the triggers. I used a 7805 voltage regulator connected to a 9V battery clip. You could use 3.3V to power this for most color LEDs (don't forget to adjust resistor values if you do) and it would probably work. I wanted to be able to drive 5V devices (plus I had some 7805's laying around).
9. Wire. I used 20 AWG to wire up LED panel and 22 AWG for everything else.
10. Standoffs (optional) for mounting your circuit board on the back of the LED panel.
1. Soldering iron.
2. Needle nose pliers
3. Programmer if using raw ATMega328. I use the USBTinyISP from AdaFruit.
5. Drill bits, a small pilot bit and 3/16" bit for LED holes assuming your are using T1-3/4 (5mm) LEDs.
6. Screw Driver
7. Ruler and/or square for laying out LED holes
Step 2: Layout the LED Board
The first thing we want to do is create our LED board. We are essentially creating a large 7-segment display using 2 LEDs per segment versus buying an actual 7-segment display this size which would be very pricey. The display is symmetrical so you will want to figure out the distance you want between one side of each digit and the other and then use that value for the spacing of the 3 horizontal segments as well. It may help to draw boxes for the digit segments and then mark the LED locations on each side of your squares as 1/3rd of the square length in from each edge. See the pictures. One of the big time savers in this project is putting the LEDs close enough together that you can twist the leads to create a common connection. Don't make your display so large that this doesn't work. If you do use a large display, you might want to increase the number of LEDs as well. I used about 1.5" spacing.
Once you have everything laid out and double checked, I recommend you use a very small drill bit to drill the initial pilot holes. The nice thing about using a small bit is that even if you are off a little, it will likely not be noticeable in the final project. Now you can drill out the full size holes and get ready to start inserting LEDs.
Step 3: Install LEDs on Board
Now that you have your holes drilled in your LED board you are almost ready to install the LEDs. You may want to clean up the holes a bit first depending on the material you selected. LEDs are polarized so it does matter which way they are put in. The longer LED is positive. Also, if you feel around the circumference at the base of the LED the negative side is flat. The timer uses a method known as charlieplexing in order to light up all these LEDs using only 8 wires. While it is theoretically possible to drive this with only 7 wires, I chose to use 8 because it made the wiring simpler which was my primary goal all along. I won't describe charlieplexing here, but there are lots of articles and tutorials available on the Internet.
The following diagram comes from the C source code file. If you have questions about this project, look there first for answers. If this diagram looks messed up in your web browser have a look in the source file main.c.
/* Each 2 LED segment is activated by applying +5V to one line, grounding another and setting everything else
* to input (high impedence or an open circuit).
* The following diagram shows a REAR VIEW of my board so be warned the leftmost
* digit is the least significant.
* ^^ LED with circuit symbol pointing up (+ on bottom - on top)
* << LED with circuit symbol pointing left (- on left + on right)
* >> LED with circuit symbol pointing right (+ on left - on right)
* ## LED with circuit symbol pointing down (+ on top - on bottom)
* numbers refer to the charlieplexing line (note 0 runs around the the perimeter)
* 0 | | | | | | | | 0
* 0 ^^ ^^ ^^ ^^ ## ## ## ## 0
*0 -->>--1--<<-- 3 --<<--4-->>-- 2 1 -->>--4--<<-- 3 --<<--6-->>-- 0
*0 -->>-/ \-<<-- 3 --<<-/ \->>-- 2 -->>-- 1 -->>-/ \-<<-- 3 --<<-/ \->>-- 0
*0 ## ## 3 ## ## 2 1 ^^ ^^ 3 ^^ ^^ 0
*0 --<<--2-->>-- 3 -->>--5--<<-- 2 -->>-- 1 --<<--5-->>-- 3 -->>--7--<<-- 0
*0 --<<-/ \->>-- 3 -->>-/ \-<<-- 2 1 --<<-/ \->>-- 3 -->>-/ \-<<-- 0
0 ^^ ^^ 3 ^^ ^^ 2 1 ## ## 3 ## ## 0
0 | | | | | | | | 0
Double check the orientation of each pair of LEDs as you insert them. Once you have completed a digit you can twist together the leads in the centers of the 8's. Just a couple twists is good. Don't get too crazy or you might break some leads. After all the LEDs are installed, you can install the 8 charlieplexed lines numbered 0-7. Note there there are a couple of jumpers that will also need to be installed to connect clusters of the same number together. See the pictures if you are unsure. I would highly recommend numbering the wires with masking tape, at least until you get everything put together. Solder the connections together then trim any excess leads.
Step 4: Test the LED Board
Testing the display before continuing is strongly recommended. The easiest way is to use a 3V button cell battery. Consult the diagram from the previous step and/or source file to determine what two wires need to be connected in order to light up a pair of LEDs. Only one pair should light at a time. As an example, connecting wire 1 to plus and 0 to negative should light up the two top LEDs in the last digit (leftmost when viewed from the back).
Step 5: Build the Rest of the Circuit
Once you are sure this is working correctly you can build out the rest of the circuit. The wiring diagram for the circuit is also in the source file. Here is the pinout for the ATMega328. As with the other diagram, consult the code if this doesn't appear correctly below.
* This device uses an ATMega328 chip, although a 20-pin AVR MCU would
* work just as well. I just have some ATMega328 chips laying around so
* I decided to use them. Port B is used to drive the 8 wires for the
* display. Port C is used for setting the timer. Port D is used
* for outputs. Note that 1/2 normal value for resistors should be used since there
* is resistance on both high and low lines. About 150 ohms for red.
* Here is the pinout: ____________
* Pin 1 - NC normally RESET pin ----| |---- Pin 28 - NC
* Pin 2 - PD0 - 10 minute warning terminal ----| |---- Pin 27 - NC
* Pin 3 - PD1 - 5 minute warning terminal ----| |---- Pin 26 - PC3 - Restart button
* Pin 4 - PD2 - 1 minute warning terminal ----| |---- Pin 25 - PC2 - Start/Stop button
* Pin 5 - PD3 - overtime warning terminal ----| |---- Pin 24 - PC1 - Minute minus button
* Pin 6 - NC ----| |---- Pin 23 - PC0 - Minute plus button
* Pin 7 - Vcc - plus 5V ----| |---- Pin 22 - Ground
* Pin 8 - Ground ----| |---- Pin 21 - AVref - plus 5V
* Pin 9 - PB6 - charlieplex line 6 ----| |---- Pin 20 - AVcc - plus 5V
* Pin 10 -PB7 - charlieplex line 7 ----| |---- Pin 19 - PB5 - charlieplex line 5
* Pin 11 - NC ----| |---- Pin 18 - PB4 - charlieplex line 4
* Pin 12 - NC ----| |---- Pin 17 - PB3 - charlieplex line 3
* Pin 13 - NC ----| |---- Pin 16 - PB2 - charlieplex line 2
* Pin 14 - PB0 - charlieplex line 0 ----| |---- Pin 15 - PB1 - charlieplex line 1
If you are using an Arduino, you might want to either solder your resistors inline for the charlieplex lines or you can put them on your board.
Once the board is done you can connect the 8 charlieplexing lines to the ATMega328 pins on your main board. Note that you should not have the chip installed when you are soldering all this stuff. That is, unless you enjoy buying new chips. Besides you haven't programmed the chip yet anyway, have you?
Step 6: Program the Chip
Now that the circuit is ready you can program your ATMega328 chip (or Arduino). The source file and makefile are attached to this step. Note that this application uses interrupts. The interrupt handler is called at a rate of 1450 Hz which allows each of the 29 segments to update at 50 Hz.
I am running my chip at 8 MHz with the internal oscillator . If you are running at a different frequency you will need to adjust. I can tell you that the default 1 MHz will not work. If you are using the Arduino you will need to modify the code for a couple reasons. The Arduino runs at 16 MHz and it also uses an external oscillator which takes up 2 pins on the ATMega328 which I'm currently using for something else. Not big changes, but you will definitely have to make them.
Step 7: Power Up and Enjoy
You should now have a working timer. When you power it up it will default to 30 minutes with the timer paused. The timer can only be adjusted when it is paused. Pressing reset returns you to the default and also resets the 4 trigger outputs. Naturally you can modify the code to change this behavior.
Enjoy! If you questions or comments leave them here or on Twitter at @ppolstra.