Timer Project

This is my first nontrivial electronics project. The goal is to create a better kitchen timer; over the years I’ve had many break, and the model I’m currently using has an annoying UI and is usually too loud.

This page last updated June 22, 2007. For history and news, see my weblog.

What it does so far:

What it doesn’t so far:

Hardware

Photo of the prototype timer. This is the current prototype as of June 21, 2007. The parts are those I had lying around, or from a microcontroller starter kit provided by Ben Jackson.

The prototype’s outputs consist of a single 7-segment LED display and a piezo speaker (still attached to its watch back). The inputs consist of a 10-position “BCD” rotary switch (for digit entry), two pushbuttons (set and start/stop), and two bits of a 8-position DIP switch (timer selection).

The breadboard on the right of the photo contains the microcontroller (PIC16F877) and most of the other components of the timer; the breadboard on the left contains the serial-port adapter circuit used for programming and the DIP switch (which was added after I ran out of space on the right).

I am maintaining a schematic of the prototype circuit (using gschem) together with the program, to document the intended circuit for each version of the program.

Each of the attached devices is connected to a separate IO pin of the PIC; the LEDs and piezo element have series current-limiting resistors (for the LEDs, to protect and regulate them; for the piezo, to protect the PIC); the switches are connected to +5V with pull-down resistors to ground. (Since connecting the switches, I have learned several reasons why pull-up is a better configuration, but have not yet needed to rebuild them.)

On the speaker: it is connected directly to an output pin. A piezo element behaves like a capacitor, so I only put it in series with a resistor to limit the worst-case current below the maximum specified in the PIC's datasheet.

Software

The software is written in PIC assembly. I compile it using gpasm and write it to the PIC using XWisp and WLoader. (I had to modify XWisp to work around its assumption that serial port devices are identified by numbers, which is not true for Mac OS X.)

I learned to program it by reading the PIC16F877's datasheet; section 13, "Instruction Set Summary", is sufficient to understand the language. (The W register is mentioned but not explained in the datasheet: it is a general-purpose register with no address. All other state is stored in addressable registers.)

The timers are maintained in BCD; 8 bits for each of hours, minutes, and seconds. I considered counting in binary and converting to BCD for displaying, but decided that this would be simpler.

The program's main loop continuously refreshes the display. The PIC's Timer0 is set up to produce an interrupt about 240 times per second; the interrupt handler updates the timers, cycles the displayed digit, and drives the speaker.

This interrupt is too slow for the desired alarm sound frequencies, so I plan (2007-07-22) to move the speaker control into either the main loop or a separate interrupt.

User interface

There are four independent timers, each of which has a current time, direction either upward or downward, and is either running or stopped.

The DIP switch selects the timer to be displayed. The value of the selected timer is displayed a digit at a time (hhmmss), with a blank pause between each digit and a longer pause between repeats. (In the final version, there will be a display showing all the digits at once, of at least one timer.)

Times are entered with the the rotary switch and the set button (on the right); each press of the set button inserts the digit on the switch at the right and shifts the existing digits to the left. (In the final version, the BCD switch will be replaced; probably with a rotary-encoder knob or a decimal keypad.)

The start/stop button will pause or resume a previously-running timer; if the time has been altered with the set button then it starts counting up if the time is 00:00:00, and counting down otherwise.