Debounce Immediately Records Key Press on Commencement of Program

Hello,

I'm quite new to electronics.

I'm working on a pet project which is a stopwatch and countdown timer.

I've attached a photo of the project.

On the top right hand side are 2 LED's and there is a button below it.

What the button does is it switches between countdown mode and stopwatch mode. And it turns on the LED that represents that mode.

I've used the debounce example on this website but I've altered it a little so that the routine is inside a function which either returns false or true to the button having been pressed.

In all other respects, I think the logic is the same.

When I first run the program, I initialise the program to one of these modes.

And what I'm finding when I first run the program is that it immediately recognises a button press even though I haven't touched the button.

Has anybody else experienced a similar issue.

As I mentioned, I think my code matches the debounce example so I'm wondering if this is normal.

Cheers

Tony

_3_MyCountdownClock_5_Seven_Segment_Displays2.ino (7.26 KB)

#define FALSE 0
#define TRUE 1

Instead of true and false, which are already defined?

#define COUNTDOWN_MODE 1
#define STOPWATCH_MODE 2

You really should be using an enum, called mode, with two values, countDown and stopWatch.

int digits[] = {252, 96, 218, 242, 102, 182, 190, 224, 254, 246}; // digits one to nine

Why int? Those values all are byte-sized.

unsigned long millis_start_or_reset_value = 0;

The millis in the name is useless. The value is a time. startOrResetTime makes a lot more sense, to me.

long millis_countdown_remaining=0;
boolean debounce(int button, int* buttonState, int* lastButtonState, long* lastDebounceTime) {

Pass by reference would make far more sense. The code is far simpler, too. So is the call to function.


So you can have -2134 milliseconds to count down?

int button_1_state;
int last_button_1_state = LOW;
long button_1_last_debounce_time = 0;

Why do you need to number one item?

  pinMode(COUNTDOWN_STOPWATCH_SWITCH, INPUT);

So, you are not using the internal pullup resistor. How IS the switch wired?

  // Clear Seven Segment Display
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  digitalWrite(LATCH_PIN, HIGH);

This just screams "Make me a function". Do so. Shut it up.

  millis_countdown_original_value = 28801000;   //  8 hours and one second

That should be:
millis_countdown_original_value = 28801000UL; // 8 hours and one second

  int reading = digitalRead(button);

  if (reading != *lastButtonState) {

Now, it's probably just me, but wouldn't it make more sense to call the current button state currButtonState?

Personally, I think that is a really crappy example of debouncing, since the names don't make any damned sense, and there is nothing that makes them related, to me.

To really understand what is happening, we need to know how the switch is wired, and why you are not using the internal pullup resistor (which makes wiring the switch incredibly simple).

// Clear Seven Segment Display
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, 0);  
  digitalWrite(LATCH_PIN, HIGH);
void clearDisplay()
{
  digitalWrite(DATA_PIN, LOW);
  digitalWrite(LATCH_PIN, LOW);
  for (uint8_t i=0; i<nbr_displays*8; i++)
  {
    digitalWrite(CLOCK_PIN, HIGH);
    digitalWrite(CLOCK_PIN, LOW);
  }
  digitalWrite(LATCH_PIN, HIGH);
}

Your switch is actually connected to positive by a 10k resistor, but the input pin seems floating. Try to move the input pin wire on row 60, use pinMode(INPUT_PULLUP) and read a LOW value instead of HIGH for the switch, this may work.

Cheers, Ale