I'm trying to program a stopwatch using 2 buttons - the first button starts/stops the stopwatch and the second button resets it to zero. I want to use two pin change interrupts for the two buttons, use timer interrupts for the time. I need help sketching out a basic skeleton of the what the coding should look like as far as setting up my counters, registers etc. This is my introduction to programming in C as well.

Why use interrupts for this rather simple task?

How would I go about this?

How would I go about this?

You code can be:

 * Created by
 * This example code is in the public domain
 * Tutorial page:
 * This example:
 *   + uses debounce for multiple buttons.
 *   + reads state of multiple buttons
 *   + detects the pressed and released events of multiple buttons

#include <ezButton.h>

ezButton button1(6);  // create Button object that attach to pin 6;
ezButton button2(7);  // create Button object that attach to pin 7;

int stopWatchState = 0;
unsigned long stopWatchStartTime = 0;
unsigned long stopWatchTime = 0;

void setup() {
  button1.setDebounceTime(50); // set debounce time to 50 milliseconds
  button2.setDebounceTime(50); // set debounce time to 50 milliseconds

void loop() {
  button1.loop(); // MUST call the loop() function first
  button2.loop(); // MUST call the loop() function first

  if(button1.isPressed()) {
    Serial.println("The button 1 is pressed");
    if(stopWatchState == 0) {// is stopped
      stopWatchStartTime = millis();
  stopWatchState = 1; // it is starting
 } else {
  stopWatchState = 0; // stop it

  if(button2.isPressed()) {
    Serial.println("The button 2 is pressed");
 stopWatchTime = 0;
 stopWatchStartTime = millis();
 stopWatchState = 1; // it is starting

  if(stopWatchState == 1) {
    stopWatchTime += (millis() - stopWatchStartTime;
 Serial.print("stopWatchTime: ");

Above code print stopWatchTime to Serial Monitor. You can modify it to print stopWatchTime on LCD 16x2. See LCD 16x2 tutorial

Note that the above code use ezButton library, which supports debounce and detecting the pressed event.

If you are not familiar with button and may ask why needs to debounce, see this post

As a beginner, it is incredibly unlikely that interrupts will be useful to you.

A common “newbie” misunderstanding is that an interrupt is a mechanism for altering the flow of a program - to execute an alternate function. Nothing could be further from the truth! :astonished:

An interrupt is a mechanism for performing an action which can be executed in “no time at all” with an urgency that it must be performed immediately or else data - information - will be lost or some harm will occur. It then returns to the main task without disturbing that task in any way though the main task may well check at the appropriate point for a “flag” set by the interrupt.

Now these criteria are in a microprocessor time scale - microseconds. This must not be confused with a human time scale of tens or hundreds of milliseconds or indeed, a couple of seconds. A switch operation is in this latter category and a mechanical operation perhaps several milliseconds; the period of a 6000 RPM shaft rotation is ten milliseconds.

Unless it is a very complex procedure, you would expect the loop() to cycle many times per millisecond. If it does not, there is most likely an error in code planning; while the delay() function is provided for testing purposes, its action goes strictly against effective programming methods. The loop() will be successively testing a number of contingencies as to whether each requires action, only one of which may be whether a particular timing criteria has expired. Unless an action must be executed in the order of microseconds, it will be handled in the loop().

So what sort of actions do require such immediate attention? Well, generally those which result from the computer hardware itself, such as high speed transfer of data in UARTs(, USARTs) or disk controllers.

An alternate use of interrupts, for context switching in RTOSs, is rarely relevant to this category of microprocessors as it is more efficient to write cooperative code as described above.