Go Down

Topic: Unreliable input from button (Read 494 times) previous topic - next topic

friol

Hello ppl,
I am testing input on the Arduino via this kind of buttons:

http://www.robot-italy.com/it/pulsanti-quadrati-colorati-assortimento-15pz.html

Unfortunately, the input seems to be unreliable. I've linked the button to a "volatile" counter in my sketch, and I increment the counter each time the button is pressed. Unexpectedly, sometimes the counter is incremented more than one time for each press (say, it steps from 3 to 7 instead of 4).

This is the code I'm using to the bare minimum. I attach also an image of the circuit (but it's very simple).

Code: [Select]

#define INPUTPIN  3

volatile int counter=0;

void changeState()
{
  counter++;
}

void setup()
{
  digitalWrite(INPUTPIN,HIGH);
  attachInterrupt(1,changeState,RISING);
 
  Serial.begin(9600);
}

void loop()
{
  Serial.println(counter);
 
  delay(1000);
}


Thanks in advance for your help.

Grumpy_Mike

How are they wired?
You might have contact bounce problems using interrupts like this.

holmes4

Your problem is call "bounce". Look at the debounceing example.

Mark


Boffin1

and you have the switch pulling down the input ( correct ) so you are looking for FALLING when you press the switch.

You would be better as the guys say to use the normal debounce methods
With my mobile phone I can call people and talk to them -  how smart can you get ?

wildbill

Do you have a particular need to use interrupts? Polling will work just as well, unless you're using the button to emulate something that will generate large numbers of pulses later. You'll still have to debounce with polling though too.

friol

Thanks for introducing me to the "bounce" problem :)

The situation is much better using this type of approach in the interrupt function:

Code: [Select]

void changeState()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();

  // debounce 
  if ((interrupt_time - last_interrupt_time) > 100)
  { 
    counter++;
  }
 
  last_interrupt_time = interrupt_time;
}


Also, "millis" should work in this context since it should show the time the interrupt function was called.

Thanks

holmes4

Use micros() not millis() for debouncing and note that millis() and micros() are not incremented during interrupts.

Mark

Go Up