Build your own kitchen timer with a dual alarm


The project uses a five-way switch to set the alarm times (Figure 3). One press toggles between setup and standby, left/right changes the position in the row of digits, and up/down changes the value. Although the vendor recently discontinued the switch I use in this example, you can find similar models – even with two additional buttons – on eBay at a low cost (Figure 4). Search for navigation button. The Cytron switch has a pull-up resistor and a debouncing capacitor for each connector that are often missing from eBay products.

Figure 3: A five-way switch by Cytron.
Figure 4: An alternative no-name button on eBay.

Because the Raspberry Pi has configurable pullups, the lack of resistors is easy to remedy. You can either upgrade the capacitors (100pF) yourself or simply debounce them in the software (see below). My eBay button was even pre-soldered, and I was able to build the project on a breadboard without any soldering.

The Raspberry Pi needs a separate pin for each direction of the navigation switch. The pin assignments can be found in Table 1. Check to see that everything is wired correctly (Listing 1). The test waits for the corresponding direction to be pressed in turn and then outputs a message.

Listing 1

Testing the Button

01 #!/bin/bash
02 echo -e "\nOrder: set, up, down, left, right\n\n"
03 for pin in 17 18 22 27 23; do
04   gpio -g mode "$pin" in
05   gpio -g mode "$pin" up
06   gpio -g wfi "$pin" falling
07   echo "GPIO$pin is now LOW"
08 done

Table 1

Pin Assignments




C (command/press)


U (up)


D (down)


L (left)


R (right)

To do this, line 6 uses the wfi function, which stands for wait for interrupt and means that the program waits until the pin triggers an interrupt. In this case, only the transition from High to Low is of interest (i.e., falling; additionally, you can have rising or both signals).

Besides the five-way button, a large, easy-to-use button starts and stops the alarm timer. The button is connected to GPIO5, and you can test it as described before. The Raspberry Pi provides the pullup for this button, and debouncing is done by software.

Alarm Timer Software

If you are looking for a challenge, you can write the software yourself. To make things easier, download the program from my GitHub repository [2]. If you have not already done so, install the git package and then set up the software with:

$ git clone
$ cd doubleclock
$ sudo tools/install

The program code is in the /usr/local/sbin/ file. The installation program sets up a systemd service that starts the alarm timer at boot time.

For some initial tests, however, it is advisable to disable the service right away and start the program manually with:

$ sudo systemctl disable doubleclock.service

The advantage of the manual call is that you can see potential program errors on the screen. Ideally, the two display segments now fill up with zeros. You can terminate the program at any time by pressing Ctrl+C.

The structure of the program is simple: The main thread updates the displays twice per second. Asynchronously, methods react to control commands. For example, the do_left() method processes five-way switch presses to the left.

Once the alarm timer is running, another thread counts down the remaining time. If the alarm timer rings, a third thread takes care of the buzzer and elicits rhythmic sounds. All of this is achieved with a little Python wizardry contained in about 200 lines of code plus comments.


Depending on the available hardware, the next step is to customize the program. Listing 2 shows a section of the switch configuration. The variable names that start with PIN_ are constants; the corresponding GPIO numbers are assigned early in the program.

Listing 2

Switch Config Snippet

64 GPIO.setup(PIN_PUSH,     GPIO.IN)
65 GPIO.setup(PIN_UP,       GPIO.IN)
66 GPIO.setup(PIN_DOWN,     GPIO.IN)
67 GPIO.setup(PIN_LEFT,     GPIO.IN)
68 GPIO.setup(PIN_RIGHT,    GPIO.IN)
69 GPIO.setup(PIN_SLIDER_L, GPIO.IN,  pull_up_down=GPIO.PUD_UP)
70 GPIO.setup(PIN_START,    GPIO.IN,  pull_up_down=GPIO.PUD_UP)
71 GPIO.setup(PIN_BUZZER,   GPIO.OUT, initial=1-PIN_BUZZER_ON)
73 GPIO.add_event_detect(PIN_PUSH,     GPIO.FALLING, self.on_push)
74 GPIO.add_event_detect(PIN_UP,       GPIO.FALLING, self.on_up)
75 GPIO.add_event_detect(PIN_DOWN,     GPIO.FALLING, self.on_down)
76 GPIO.add_event_detect(PIN_LEFT,     GPIO.FALLING, self.on_left)
77 GPIO.add_event_detect(PIN_RIGHT,    GPIO.FALLING, self.on_right)
78 GPIO.add_event_detect(PIN_SLIDER_L, GPIO.BOTH,    self.on_slider)
79 GPIO.add_event_detect(PIN_START,    GPIO.FALLING, self.on_start, 200)

Except for the buzzer, the program defines all the pins as input (lines 64-71). If the switch module you use does not have pullups, you will need to add lines 64-68, as per line 69. Lines 73-79 each assign a method to the pins that is executed by the program when the user presses a button.

The last parameter in line 79 is the debounce time – 200ms here. The other buttons have capacitors for debouncing and do not need this delay. If the device you use does not have capacitors, then add the third parameter to lines 73-77, as well.

No further adjustments should be needed. If you want to rebuild the project with just one display, connect the left display (GPIO6/GPIO13), do without the slider, and connect GPIO20 to ground. No changes to the software are required.

Regardless of the necessary adjustments, the code allows you to configure various parts to suit your preferences. For example, the audible alarm signal from the left alarm timer stops automatically after 10 seconds, whereas the right alarm continues to run indefinitely. You can even control the maximum brightness of the display (values between   and 7). Last but not least, you are free to choose the pin assignments.

If you wired and set up everything correctly, the commands

$ sudo systemctl enable doubleclock.service
$ sudo systemctl start doubleclock.service

enable and start the service.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • ARM64 Assembly and GPIO

    Reading, writing, and arithmetic with the Raspberry Pi in ARM64 assembly language.

  • Elixer

    The Elixir programming language on a Raspberry Pi lets you create distributed projects in just a few lines of code.

  • GPIO on Linux Devices

    The general purpose input/output interface is not just for small-board computers anymore: You can use GPIO on your Linux desktop or laptop, too, through the USB port.

  • Rasp Pi Fox Trap

    As a countermeasure to predators of rare ground-breeding birds, live traps are monitored by a microcontroller and a Raspberry Pi.

  • 01000010

    Talk to your Raspberry Pi in its native assembler language.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More