A countdown reminder needs a clear stop button

If you are making a desk timer, a classroom activity tool or a simple session reminder, the countdown is only half the interaction. When it sounds, the person using it needs to know how to silence it, and whether that action pauses, resets or finishes the session.

We built a small timer with a real-time clock, an OLED, a buzzer and a physical stop switch in an acrylic case. The assembly works, and its code makes one design decision very visible: the stop input silences the buzzer and resets the demonstration countdown to ten seconds. It does not leave the device idle until someone starts a new session.

That behavior may suit a repeating demonstration. For a finished timer, it has to be a deliberate choice. This note follows our build and lists what to check before a reminder goes into a user's hands.

Decide what should happen after the sound

People building timers hit this early. In a February 2022 Arduino forum post, a beginner describes start, stop, resume, reset and silence actions spread across two buttons. The hard part is defining those actions, not wiring another switch.

A more recent example is Jonathan Whitaker's Timrrr write-up, published in August 2026 and updated in September. His time-awareness device used a brief recurring vibration. The update says he kept forgetting the device existed and decided not to build another version. That is one maker's experience, not a market signal, but it is a good reminder to test whether a physical prompt fits a person's routine at all.

For this prototype, state the expected outcome before changing code. A kitchen-style timer might stay silent after acknowledgment. A classroom exercise might reset for another round. A work-session timer might offer pause and resume. Each is a candidate use; none has been tried with users yet.

Build the clock, display and acknowledgment input

Our build uses a DS1307 real-time clock module for date and time, an SSD1306 OLED, a passive buzzer and a limit-switch module as the stop input, on a Raspberry Pi Pico (RP2040) GraftPort carrier:

Part Carrier connector Role
DS1307 module I2C0 Date and time
OLED I2C1 Clock and countdown display
Buzzer DIO1 Audible prompt
Limit switch DIO0 Stop and reset input
Board button Board input Pause and resume of the countdown task

The connector names are carrier labels, not GPIO numbers. Our scans found the RTC at 0x68 on one bus and the OLED at 0x3d on the other; check the addresses in your own build.

A real-time clock is a calendar clock. In this firmware the remaining countdown is a separate software variable, so reading the DS1307 neither makes the countdown survive a restart nor guarantees an accurate elapsed time.

There is one correction to make before relying on the code. Our main program requested 400 kHz on both I2C buses, while the DS1307 datasheet specifies a maximum SCL frequency of 100 kHz (page 3). Run the RTC bus within that limit and verify communication on the real board. A successful scan at an out-of-spec setting does not prove it is reliable.

The small limit-switch lever is easy to reach on the open assembly. Whether it is the right control for a finished enclosure is a separate question; a larger external button may suit better, with its own mounting, electrical and interaction checks.

Keep the control reachable after enclosure assembly

The board and modules sit on a perforated base on M3 standoffs, with acrylic panels screwed around them. Keep the stop control and the power connection reachable when you move to a more finished case. On one of our power cables red was ground and black was positive, so check polarity at the connector, not by color. On this carrier, RUN switch 2 must be on when no external watchdog module is fitted.

The battery module's charge indicator is handy during setup, but it does not tell you how long the timer runs. The coin cell on the clock module is a different supply from the main battery. The DS1307 supports backup timekeeping, but we have not run a power-loss test of the complete device.

Follow the actual two-task behavior

The firmware runs two scheduled callbacks. The display callback runs every second: it subtracts one from the countdown, reads the RTC and refreshes the OLED. The alarm callback runs every 200 ms: when the counter is zero or below, it requests a 2 kHz tone lasting 500 ms and sets the counter to one. It then checks the stop input, and if the switch is pressed, it sets the counter to ten and stops the buzzer.

Because the display task keeps running, the counter immediately starts counting down again. Holding the switch resets it repeatedly; releasing it lets the cycle continue. Our early flowchart said "reset to twenty" and described a different sound pattern, so trust the code over the diagram, and keep the two in step in your own project. These are configured timings, not measured response times.

Do not confuse pause with silence

The board button follows a different path. It pauses or resumes the display and countdown task, but the alarm task keeps running. The same handler also tries to switch something off through a variable that is not defined in that file, and quietly catches the resulting exception. It is not a working mute control.

A prototype can live with a known quirk. A user-facing timer needs a clear, tested answer for every button press. The console log from our run shows the two I2C scans, advancing clock values, tone messages and stop messages. It does not show behavior after every pause, held switch, restart or disconnected module. The startup banner in that log was also copied from another project, which is one more reason to keep version records with the firmware.

Test the next version as a person would use it

Before trying a long session, use a short countdown and write down the expected result of each action. Press the stop switch before expiry, during the tone and right after it. Hold it, release it, then wait longer than the countdown. Test the board button on its own.

If the timer should finish once, add an explicit finished state so an acknowledgment does not silently start another countdown. If pause is needed, show it on screen and decide whether the clock display keeps updating. Treat elapsed-time accuracy and restart recovery as separate requirements, not benefits the RTC provides automatically.

Then run the simplest user trial: ask someone to stop the reminder without explaining the controls, and ask what they expect to happen next. If their answer differs from what the program does, fix that before adding features.