Cant get debouncing to work with 2 subroutines

Hi,

I'm trying to get a single button to run as a reset button and a start button. I cant seem to get it working.

here is my code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

int amberLed = 10;
int redLed = 11;
int p1Led = 8;
int p2Led = 9;
int piezoPin = 6; //set buzzer pin
int piezoFreq = 4000;

const int buttonPin = 2;
unsigned long startTime1;
unsigned long endTime1;
unsigned long startTime2;
unsigned long endTime2;
unsigned long duration1;
unsigned long duration2;
long wait;
byte timerRunning1;
byte timerRunning2;
int vs =3; // vibration sensor
int vs2 = 4; //vibration sensor 2
byte reset = 0;

int buttonPressed = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers


void setup() {
  pinMode(redLed, OUTPUT);
  pinMode(amberLed, OUTPUT);
  pinMode(p1Led, OUTPUT);
  pinMode(p2Led, OUTPUT);
  pinMode(vs, INPUT);
  pinMode(vs2, INPUT);
  pinMode (buttonPin, INPUT_PULLUP);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Welcome to");
  lcd.setCursor(4,1);
  lcd.print("Dual Cup");
  Flash(0);
  tone(piezoPin,piezoFreq,500);
  delay(500);
  tone(piezoPin,piezoFreq,500);
  digitalWrite(p1Led,LOW);
  digitalWrite(p2Led,LOW);
  digitalWrite(amberLed,LOW);
  digitalWrite(redLed,LOW);
}



void loop() {

  long measurement1 = vibration1();
  long measurement2 = vibration2();
  
  if (timerRunning1 == 1 && measurement1 > 500) { //if player 1 hits first
    endTime1 = millis();
    timerRunning1 = 0;
    duration1 = endTime1 - startTime1;
    lcd.clear();
  }
  
  else if (timerRunning2 == 1 && measurement2 > 500) { //if player 2 hits first
    endTime2 = millis();
    timerRunning2 = 0;
    duration2 = endTime2 - startTime2;
    lcd.clear();
  }

  int reading = digitalRead(buttonPin);

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == LOW) {
        buttonPressed = !buttonPressed;
      }
    }
  }

  if (buttonPressed == LOW && timerRunning1 == 0 && timerRunning2 == 0 && reset == 1){
    StartButton();
  }
  else if (buttonPressed == LOW && timerRunning1 == 0 && timerRunning2 == 0 && reset == 0){
    ResetButton();
  }
  

  if(timerRunning1 == 0 && timerRunning2 == 0 && duration1 != 0 && duration2 != 0) {//check if both throwers have finished
    ThrowEnd();
  }
  lastButtonState = reading;
}

long vibration1() {
  long measurement1 = pulseIn (vs, HIGH); //wait for the pin to get HIGH and returns measurement
  return measurement1;
}

long vibration2() {
  long measurement2 = pulseIn (vs2, HIGH); //wait for the pin to get HIGH and returns measurement
  return measurement2;
}

void ThrowEnd(){
  lcd.setCursor(0,0);
    lcd.print ("P1:");
    lcd.setCursor(3,0);
    lcd.print (duration1/1000.0,2);
    lcd.setCursor(8,0);
    lcd.print("P2:");
    lcd.setCursor(11,0);
    lcd.print (duration2/1000.0,2);
    
    if (duration1 < duration2) {
      lcd.setCursor(1,1);
      lcd.print ("P1 wins: ");
      lcd.print (duration1/1000.0,2);
      digitalWrite(p2Led,LOW);
      Flash(p1Led);
      digitalWrite(p1Led,LOW);
      duration1 = 0;
      duration2 = 0;
    }
    else {
      lcd.setCursor(1,1);
      lcd.print("P2 wins: ");
      lcd.print (duration2/1000.0,2);
      digitalWrite(p1Led,LOW);
      Flash(p2Led);
      digitalWrite(p2Led,LOW);
      duration1 = 0;
      duration2 = 0;
    }
    reset = 0;
}

void ResetButton(){
  lcd.clear();
  digitalWrite(p1Led,LOW);
  digitalWrite(p2Led,LOW);
  digitalWrite(amberLed,LOW);
  digitalWrite(redLed,LOW);
  lcd.print("Start");
  tone(piezoPin,piezoFreq,500);
  digitalWrite(redLed,HIGH); //red led comes on
  reset = 1;
}

void StartButton(){
    lcd.clear();
    lcd.print ("ready");
    tone(piezoPin,piezoFreq,500);
    digitalWrite(redLed,LOW); //red led off
    digitalWrite(amberLed,HIGH); //amber led lights up
    wait = random(2000,7000);
    delay(wait);
    digitalWrite(amberLed,LOW); //amber led lights up
    startTime1 = startTime2 = millis();
    timerRunning1 = timerRunning2 = 1;
    tone(piezoPin,piezoFreq,1000);
    digitalWrite(p1Led,HIGH); //both green leds light up and buzzer beeps
    digitalWrite(p2Led,HIGH);
    lcd.clear();
    lcd.print ("Throw");
}

void Flash(int qty){ //subroutine for led control

  
  if (qty == 0) {
    for (int i=0; i<4; i++)
    {
      digitalWrite(p1Led,HIGH);
      digitalWrite(p2Led,HIGH);
      digitalWrite(amberLed,HIGH);
      digitalWrite(redLed,HIGH);
      delay(500);
      digitalWrite(p1Led,LOW);
      digitalWrite(p2Led,LOW);
      digitalWrite(amberLed,LOW);
      digitalWrite(redLed,LOW);
      delay(500);
    }
  }
    else {
      for (int i=0; i<4; i++)
      {
        digitalWrite(ledPin,HIGH);
        delay(500);
        digitalWrite(ledPin,LOW);
        delay(500);
      }
      digitalWrite(ledPin,HIGH);
    }
  


}

What does that mean? Reset what? Start what?

What is the program supposed to do, and what doesn't work?

Assuming that you want to make a single button perform multiple functions, what conditions would cause one or the other response?

is really

 if (buttonPressed == LOW && timerRunning1 == 0 && timerRunning2 == 0) {
  if ( reset == 1)
    StartButton();
  else 
    ResetButton();
  }

So you might want to investigate the way variable 'reset' is handled...

here's one way of dealing with button presses ... debounce by just delaying 10 msec


#define Button  A1
#define LED     10

enum { Off = HIGH, On = LOW };

void
setup ()
{
    Serial.begin (9600);

    pinMode (Button, INPUT_PULLUP);

    digitalWrite (LED, Off);
    pinMode (LED,    OUTPUT);
}

void
loop ()
{
    static byte butState = Off;
           byte but      = digitalRead (Button);

    if (butState != but)  {
        butState = but;

        if (On == but)  {
            digitalWrite (LED, ! digitalRead (LED));

            const char *s = digitalRead (LED) ? "Off" : "On";
            Serial.println (s);
        }

        delay (10);     // debounce
    }
}

that actually helps loads. i think i just got tunnel vision. thankyou.

thanks. I will have a look at this when I get home. but I think aarg solved my issue without debounce but i definitely need to learn how to do it right.

Some stuff that blocks operation (from your code):

delay(500);
delay(wait);
delay(500);
delay(500);
delay(500);
delay(500);

How about a BWOD strategy?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.