Guidance with deboucing

Hi, I am writing some code in order to let me get a momentary footswitch to switch a relay with a status LED too. I have come up with the below code which works but I wanted to delve a bit deeper with the debouce rather than just use delay.

// First attempt at latching relay with Arduino

#define LED 3         // the output pin for the LED
#define BUTTON 0      // the input pin for the switch
#define RELAY1 2      // the output pin for relay position 1
#define RELAY2 1      // the output pin for relay position 2

// Variables

int val = 0;         // val will be used to store the state of the BUTTON input pin
int old_val = 0;     // this variable stores the previous value of val
int state = 0;       // 0 = LED off while 1 = LED on

void setup()
{
  pinMode(LED, OUTPUT);      // sets the digital pin as an output
  pinMode(BUTTON, INPUT);    // sets the button pin as an input
  pinMode(RELAY1, OUTPUT);    // sets the RELAY1 pin as an output
  pinMode(RELAY2, OUTPUT);    // sets the RELAY2 pin as an output
}

void loop()
{
  val = digitalRead(BUTTON);  //read input value and store it

  //check to see if there was a transition
  if ((val == HIGH) && (old_val == LOW))
  {
    state = 1 - state;
    delay(30);
  }
  old_val = val; // val is now old_val, let's store it

  // check whether the input is HIGH (button pressed)
  if (state == 1)

  {
    digitalWrite(RELAY1, HIGH);  // set RELAYS1 to HIGH
    digitalWrite(RELAY2, LOW);   // set RELAY2 to LOW
    digitalWrite(LED, HIGH);     // turn LED on
  } 
  else {
    digitalWrite(RELAY1, LOW);   // set RELAYS1 to LOW
    digitalWrite(RELAY2, HIGH);  // set RELAY2 to HIGH
    digitalWrite(LED, LOW);      // turn LED on
  }

}

I found this code from http://drmarty.blogspot.co.uk/2009/05/best-switch-debounce-routine-ever.html which looks interesting but when I have tried to implement the below code into mine I keep ending up with a skecth that does not work. The main problem is my level of Arduino knowledge as at the moment it is pretty low but I am learning quickly, on this one I am stumped though.

int debounce(int SampleA)
{
static int SampleB = 0;
static int SampleC = 0;
static int LastDebounceResult = 0;

LastDebounceResult = LastDebounceResult & (SampleA | SampleB | SampleC) | (SampleA & SampleB & SampleC);
SampleC = SampleB;
SampleB = SampleA;
return LastDebounceResult;
}

Would any be able to give me some pointers on how to include this debouce code into my code with it actually working?

Thanks, Remmy.

The problem with bounce is that there is a time element,

If you know the average bounce time of your switch a simple delay work pretty good.

What the debounce() code does is take 3 samples over time SampleA,B,C.
What happens if you call this function realy often, then you might get a ‘hit’ in the middle of your bound area.
So you need to make sure you call the debounce code with good timedelays (>10ms).

Something similar but a bit more configurable would be:

int Bouncemaster2000(int pinnr)
{ static int avg = 0;

  if (digitalRead(pinnr) == HIGH)
  { if ( ++avg > 200 ) avg = 200;
  }
  else
  { if ( --avg < 0) avg = 0;
  }
    
  if (avg > 100)  return HIGH;
  else            return LOW;
}//Bouncemaster()

You can call this function really often/fast just make the High/Low threshold for avg higher (the 200 and 100)
If the function is called really slow you can make thresholds 20 and 10.

You could put the BounceMaster code somewhere in the loop()
val = bouncemaster2000(BUTTON); //read input value and store it

try this code maybe it will help u

uint8_t Switch = 2;
uint8_t Led =13;

boolean LedState =LOW;
int SwitchState =0;
int SwitchDebounce;
int LastSwitchState=HIGH;
int LastSwitchDebounce=LOW;

unsigned long LastDebounceTime = 0;
unsigned long DebounceDelay = 50;

void setup()
{
  pinMode(Switch,INPUT);
  digitalWrite(Switch,HIGH);
  pinMode(Led,OUTPUT);
  Serial.begin(9600);
}

void loop() 
{
  int CurrentSwitch = digitalRead(Switch);
  if (CurrentSwitch != LastSwitchDebounce)
  {
    LastDebounceTime = millis();
  } 
  if ((millis() - LastDebounceTime) > DebounceDelay) 
  {
    SwitchState = digitalRead(Switch);
    if (SwitchState != LastSwitchState) 
    {
      if (SwitchState == LOW)
      {
        LedState = !LedState;
        (LedState)?Serial.println("Led is On"):Serial.println("Led is Off");
      } 
    }
    LastSwitchState=SwitchState;
  }
  digitalWrite(Led,LedState);
  LastSwitchDebounce = CurrentSwitch;
}

astrofrostbyte:
The problem with bounce is that there is a time element,

If you know the average bounce time of your switch a simple delay work pretty good.

What the debounce() code does is take 3 samples over time SampleA,B,C.
What happens if you call this function realy often, then you might get a ‘hit’ in the middle of your bound area.
So you need to make sure you call the debounce code with good timedelays (>10ms).

Something similar but a bit more configurable would be:

int Bouncemaster2000(int pinnr)

{ static int avg = 0;

if (digitalRead(pinnr) == HIGH)
 { if ( ++avg > 200 ) avg = 200;
 }
 else
 { if ( --avg < 0) avg = 0;
 }
   
 if (avg > 100)  return HIGH;
 else            return LOW;
}//Bouncemaster()



You can call this function really often/fast just make the High/Low threshold for avg higher (the 200 and 100)
If the function is called really slow you can make thresholds 20 and 10. 


You could put the BounceMaster code somewhere in the loop()
val = bouncemaster2000(BUTTON); //read input value and store it

Thank you for the explanation and for the alternative method, I did not consider it but I understand the caveat you have mentioned, I’ll try the code out and see how it reacts to the switch I have.

ash901226: try this code maybe it will help u

uint8_t Switch = 2;
uint8_t Led =13;

boolean LedState =LOW; int SwitchState =0; int SwitchDebounce; int LastSwitchState=HIGH; int LastSwitchDebounce=LOW;

unsigned long LastDebounceTime = 0; unsigned long DebounceDelay = 50;

void setup() {   pinMode(Switch,INPUT);   digitalWrite(Switch,HIGH);   pinMode(Led,OUTPUT);   Serial.begin(9600); }

void loop() {   int CurrentSwitch = digitalRead(Switch);   if (CurrentSwitch != LastSwitchDebounce)   {     LastDebounceTime = millis();   }   if ((millis() - LastDebounceTime) > DebounceDelay)   {     SwitchState = digitalRead(Switch);     if (SwitchState != LastSwitchState)     {       if (SwitchState == LOW)       {         LedState = !LedState;         (LedState)?Serial.println("Led is On"):Serial.println("Led is Off");       }     }     LastSwitchState=SwitchState;   }   digitalWrite(Led,LedState);   LastSwitchDebounce = CurrentSwitch; }

Thank you for the incorporating the code, I appreciate your input, I'll test it out tomorrow to see how it goes :)

Remmy.