Electronic – Software Debouncing to detect if switch has been pressed for T seconds

armbuttondebouncemicrocontrollerswitches

I need to detect if a switch has been pressed for longer than a set time, without using any Timer registers in my embedded code.

I am using software debouncing in the following manner to detect a normal switch press.

int buttonPress (void)
{
  static int downCount= 0; // static = value isn't lost between calls.

  int currentButton = ((IO0PIN & 0x00000200) == 0x00000200); 

  if (currentButton ) { // button is down

    if (downCount == 5) { // button has been down for 5 counts
      downCount++;      // increase the count so we don't trigger next time
      return 1;
    } else {              // some count other than 5
      if (downCount < 5)  // increase if it's less than 5
        downCount++;
    }
  } else   {    // button is up
    downCount = 0; 
  }
  return 0;
}   

However, I would like to detect whether this button has been pressed for 5 seconds or longer. The problem I am facing is that I cannot seem to be able to count up to 300,000 and if this is not reached, fall back on the original downCount of 5 to mark as a normal button press.

(Since the clock speed for my micro-controller is at 60 MHz, then it will take 5 seconds to reach 300,000.)

I have played around with some logic as follows, however in the case shown below,due to the introduction of the while statement, I am counting up to 300,000 irrespectively of how long the button has been pressed.

if (currentButton ) {   // button is down

  if (downCount == 5) { // button has been down for 5 counts
    downCount++;      // increase the count so we don't trigger next time
    while (downCount > 5) { 
      if (debounce == 300000) {
        flag_5SEC = 1;
      } else if (debounce < 300000) {
         debounce++;
      }
    }
    return 1;
  } else {              // some count other than 5
    if (downCount < 5)  // increase if it's less than 5
      downCount++;
  }
}

Any tips or suggestions on how to go about this task?

Note: I want to detect for a longer switch press explicitly in the debouncing code above, since doing anything else may have adverse side-affects on the rest of the code, which someone else had previously wrote.


I have managed to complete the aforementioned task using timers, however, since then, I have used all timer registers (and match resisters that are available) for more important tasks within the same project.

I do not need to detect an accurate time delay, simply if the button has been down for longer than, say, 2-3 seconds.

Comment by @DiBosco clarifies further:

So what you're saying is that if you get a switch pressed for, say, twenty counts and it is released that acts as normal press that does one function, and if it is pressed and held down for two seconds or so it carries out a different function…

Best Answer

I have managed to complete the aforementioned task using timers, however, since then, I have used all timer registers (and match resisters that are available) for more important tasks within the same project.

In that case, you're going about this all wrong. Unless you absolutely need the high resolution, low jitter, or other hardware features of the hardware timers, you should be doing your timing in software, using one of the hardware timers to generate continuous periodic interrupts that you can count in the ISR.

A "heartbeat interrupt" with a period of anywhere between 100 µs and 100 ms (or more) is a common feature of embedded systems. This allows you to create an arbitrary number of software timers.

Even if you're already using all of the hardware timers, as long as at least one of them is doing something periodic, such as generating a PWM signal or creating a clock for a serial interface, you can enable interrupts on it and use them for your software timebase. The period might not be a "convenient" value, but that is a simple scaling problem that the software can deal with.