Build your own kitchen timer with a dual alarm

Kitchen Helper

© Lead Image © besjunior, 123RF.com

© Lead Image © besjunior, 123RF.com

Author(s):

A simple kitchen helper with two timers assists budding chefs in coping with dishes that are unlikely to be ready at the same time.

Not all the recipes you cook likely need to be ready at the same time, especially if everyone in the household has their own idea of how long you need to boil eggs for breakfast. A simple dual timer solves the problem.

This project uses a Pi Zero and some cheap components sold by the usual mail order companies for a few euros, dollars, or pounds. In principle, it is possible to build the project from scratch on a breadboard without any soldering, which makes it perfect as a starter project for your own experiments.

On the Pi Zero you need to install Raspbian "Buster" up front; the Lite version will do the trick. The only additional package you need to install for the time being is wiringPi [1], which uses a numbering system different from the header pin and GPIO systems. If you want to work with a graphical user interface, you could switch to a Raspberry Pi 3 or 4, but these platforms are oversized for this use case.

Strictly speaking, even the Pi Zero is overkill because, in principle, any microcontroller could control an alarm clock. The advantage of the Raspberry Pi is that software implementation is faster and easier: I use Python in this project. Before you move on to the software for the project, you first need to wire the hardware.

Mini Displays

Segment displays based on the TM1637 driver are ideal for displaying times (Figure 1). Each digit can be displayed with seven segments, and suitable displays are easily found by searching for "7-segment display." The monochrome displays are inexpensively available in red, white, blue, yellow, and green. They are available with a colon in the middle (clock type) or with one decimal point per digit.

Figure 1: A typical seven-segment display.

Many sellers (especially on eBay) do not always provide the correct data. Often you will find a description of the clock type combined with an image of the decimal point display. Other sellers show both types to protect themselves against complaints relating to wrong delivery. Make sure you take a close look.

The connector pins are another potential source of concern. Pre-soldered specimens, as shown in Figure 1, are useful for experiments on the breadboard, but for installation in a housing, pins soldered from the back would be more useful. Finding the perfect device is not that easy.

TM1637 displays require two lines (CLK and DIO, or clock and data) in addition to power and ground. It is a lean I2C protocol that works on any pin. The device can handle 5V of input voltage, but the 3.3V on the Raspberry Pi are perfectly OK.

In this project, the displays are deployed on GPIO6 and GPIO12 (CLK) and GPIO13 and GPIO16 (DIO) on the left side of the display. Figure 2 shows the complete assembly with wiring for orientation.

Figure 2: Fritzing view of the wiring.

Sound the Alarm

A buzzer serves as an alarm signal. You want to use an active buzzer; for a passive version, you would have to generate the sound yourself as PWM signals. Buzzers are typically available with two or three pins. In the first case you just need to apply a voltage (set the GPIO to High); in the alternative case, you have a control pin in addition to voltage and ground. For the versions I used for this example, I had to set the control pin to Low to make the buzzer go off.

The alarm clock program expects the control pin on GPIO26. To check this functionality, enter:

$ gpio -g mode 26 out
$ gpio -g write 26 0
$ gpio -g write 26 1

The first line switches GPIO26 as the output pin, and the second line activates the buzzer. The third line switches it off again. At startup time, GPIO26 is an input pin and you might hear a short sound. If this annoys you, a low pullup resistor will prevent this happening.

Toggle

To edit the alarm times, you need to be able to switch between the two displays. To do so, you can use a slider, which is a button with two states. Of its three connectors, the central is grounded, and depending on the position of the switch, either the left or the right connector is grounded.

In this project, only the left connector GPIO20 and ground are wired. Also, the GPIO20 internal pullup is switched on. While the switch is on the right, GPIO20 is High, but otherwise Low. To test the wiring, enter:

$ gpio -g mode 20 in
$ gpio -g mode 20 up
$ gpio -g read 20

Repeat the command in the third line for different switch positions; depending on the position, the read command outputs a 0 or 1.

Buttons

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

GPIO

Wiring

17

C (command/press)

18

U (up)

22

D (down)

27

L (left)

23

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 https://github.com/bablokb/doubleclock.git
$ cd doubleclock
$ sudo tools/install

The program code is in the /usr/local/sbin/doubleclock.py 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
$ doubleclock.py

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.

Adaptations

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)
72
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.

System Optimization

The project is complete in principle, but you can take advantage of a few optimizations to round everything off. If you have a spare power outlet and want to keep the alarm timer running all the time, you don't need to worry about booting the system, but if you only turn on the alarm timer when needed, you will soon notice that booting takes a long time and the wait can be annoying. Fortunately, a couple of tricks will reduce the wait significantly [3].

Another optimization is related to the shutdown behavior. The alarm timer does not have a control for this, but you could retrofit one in the form of an additional button. Of course, in the heat of the moment, the chef might forget more than just the salt. It makes more sense to set up the system to be read-only, which means Linux then no longer writes to the SD card. Instead of shutting down, you can simply pull the plug [4].

In the special case of this example, a much simpler method also works, but only because the program does not even write temporary files and all the other programs on the Raspberry Pi are irrelevant: Simply comment out all lines in the /etc/fstab file. The kernel will still mount the root filesystem at startup, but in read-only mode, and the boot filesystem is unnecessary for normal operation.

Besides working under the hood, you also want the appearance to be pleasing. For the alarm timer, an attractive 3D-printed case is a good choice, because a breadboard with jumper cables is not something you would want in your kitchen. Because the atmosphere in the kitchen tends to be quite humid, you will want to use PETG instead of the more common PLA [5]. I already have a case in the making, so it's worth taking a look at the project [6]. By the time this article is published, it might even be finished.

Don't underestimate the time needed to get from the breadboard to the finished alarm clock that you would want to see in the kitchen every day. Four modules are connected to 3.3V, but the Raspberry Pi offers only two 3.3V pins. Without an additional board, nothing will work. You also need room for the cables without having an oversized housing.

Another question is how to fasten the case while leaving at least the power connection accessible from outside. Mounting the smaller components, such as the single switch or the slider, is by no means trivial. They need a firm hold, because in everyday life, they will have to withstand forces perpendicular to the housing.

Conclusions

Your own projects with cheap hardware can be prototyped with just a breadboard and a few jumper cables. The software usually takes a little more work, but thanks to the many examples online, the programming effort can be minimal.

Starting with this example as a jumping off point, you can realize your own ideas. If the alarm timer is not running, it would be a good idea to show the time and date on the two displays. I would be happy to field any corresponding pull requests. Another idea would be to convert the alarm clock into an electronic chess clock, where two buttons alternately start the timers. The possibilities offered by the Raspberry Pi are (almost) unlimited.

Infos

  1. wiringPi: http://wiringpi.com/download-and-install/
  2. Dual timer project: https://github.com/bablokb/doubleclock
  3. "Fast boot with Raspberry Pi" by Himesh Prasad: https://himeshp.blogspot.com/2018/08/fast-boot-with-raspberry-pi.html
  4. "Make your Raspberry Pi file system read-only (Raspbian Buster)" by Andreas Schallwig, Medium, 23 September 2019, https://medium.com/swlh/make-your-raspberry-pi-file-system-read-only-raspbian-buster-c558694de79
  5. "PETG vs PLA: The Differences – Simply Explained" by Lamin Kivelä, All3DP, 26 January 2020, https://all3dp.com/2/petg-vs-pla-3d-printing-filaments-compared/
  6. Tinkercad files: https://www.tinkercad.com/things/8dUa6ugfUpZ

The Author

Bernhard Bablok works at Allianz Technology SE as an SAP HR developer. When he's not listening to music, cycling or walking, he deals with topics related to Linux, programming and small computers. He can be reached at mailto:mail@bablokb.de.