loading
Since I've started using the Arduino I've loved it. Although I found one thing very complicating with the Arduino that I couldn't figure out why it was happening until today, literally today. What is it? It's connected a push button to an Arduino interrupt pin to make it change certain variables. 

The application that I am working on requires the use of 2 push buttons, each will link into an Arduino (as an interrupt) and control the current position of the motor. I have 6 positions that I want the motor in. 

I originally set up my circuit like so: 


hi


The problem with this setup was when the button was pressed the interrupt was being called multiple times and even toggling other buttons. Why was this happening? It is caused from a switch bouncing feedback. To fix this, you need to modify your circuit around this manner below: 


hi2


What this did was when the push button was on (=1) the pin was HIGH and only HIGH. It never bounces around like it used to. 

-----

The project that I was working on had the following schematic (created with PSpice Student 9.1). 


hi3


The pin configuration is as follows: 
  • PIN 2 - Push button 1 (increase motor position)
    • interrupt 0
  • PIN 3 - Push button 2 (decrease motor position)
    • interrupt 1
  • PIN 22 - LED 1 (position 1)
  • PIN 24 - LED 2 (position 2)
  • PIN 26 - LED 3 (position 3)
  • PIN 28 - LED 4 (position 4)
  • PIN 30 - LED 5 (position 5)
  • PIN 32 - LED 6 (position 6)

What this application is going to do is start off in position 1 then as you push button 1, the LED will change based on the new position. I call these positions gears. Here is the Arudino code... it's really straight forward. 






const int led6 = 32;
const int led5 = 30;
const int led4 = 28;
const int led3 = 26;
const int led2 = 24;
const int led1 = 22;
volatile unsigned int current_gear = 1;

volatile long long timeout = 3000; // 3 seconds
volatile long long last_change_time = 0;

void loop()
{
  switch(current_gear)
  {
    case 1:
      digitalWrite(led1,HIGH);
      digitalWrite(led2,LOW);
      digitalWrite(led3,LOW);
      digitalWrite(led4,LOW);
      digitalWrite(led5,LOW);
      digitalWrite(led6,LOW);
      break;
    case 2: 
      digitalWrite(led1,LOW);
      digitalWrite(led2,HIGH);
      digitalWrite(led3,LOW);
      digitalWrite(led4,LOW);
      digitalWrite(led5,LOW);
      digitalWrite(led6,LOW);
      break;
    case 3: 
      digitalWrite(led1,LOW);
      digitalWrite(led2,LOW);
      digitalWrite(led3,HIGH);
      digitalWrite(led4,LOW);
      digitalWrite(led5,LOW);
      digitalWrite(led6,LOW);
      break; 
    case 4: 
      digitalWrite(led1,LOW);
      digitalWrite(led2,LOW);
      digitalWrite(led3,LOW);
      digitalWrite(led4,HIGH);
      digitalWrite(led5,LOW);
      digitalWrite(led6,LOW);
      break;
    case 5: 
      digitalWrite(led1,LOW);
      digitalWrite(led2,LOW);
      digitalWrite(led3,LOW);
      digitalWrite(led4,LOW);
      digitalWrite(led5,HIGH);
      digitalWrite(led6,LOW);
      break;
    case 6: 
      digitalWrite(led1,LOW);
      digitalWrite(led2,LOW);
      digitalWrite(led3,LOW);
      digitalWrite(led4,LOW);
      digitalWrite(led5,LOW);
      digitalWrite(led6,HIGH);
      break;
  }
}
void setup()
{
  Serial.begin(9600);
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  pinMode(led4,OUTPUT);
  pinMode(led5,OUTPUT);
  pinMode(led6,OUTPUT);
  attachInterrupt(0,up,RISING); // digital pin 2 // up
  attachInterrupt(1,down,RISING); // digital pin 3 // down
}

void up()
{
  Serial.println("-------------GOING UP-------------");
  Serial.print("Current Time - ");
  Serial.println(millis());
  Serial.print("Last Change Time - ");
  Serial.println((long) last_change_time);
  int difference = millis()-last_change_time;
  Serial.print("Difference - ");
  Serial.println((long) difference);
  Serial.print("Within Threshold? - ");
  if(difference > timeout || last_change_time == 0)
  {
    Serial.println("YES");
  }
  else
  {
    Serial.println("NO");
  }
  Serial.print("Previous Gear = ");
  Serial.println(current_gear);
  if((current_gear > 0 && ((millis()-last_change_time)>timeout)) || last_change_time == 0)
  {
    if(current_gear <= 5 && current_gear != 6) 
    {
current_gear++;
last_change_time = millis();
}
}
Serial.print("New Gear = ");
Serial.println(current_gear);
delay(150);
}
void down()
{
Serial.println("-------------GOING DOWN-------------");
Serial.print("Current Time - ");
Serial.println(millis());
Serial.print("Last Change Time - ");
Serial.println((long) last_change_time);
int difference = millis()-last_change_time;
Serial.print("Difference - ");
Serial.println((long) difference);
Serial.print("Within Threshold? - ");
if(difference > timeout)
{
Serial.println("YES");
}
else
{
Serial.println("NO");
}
Serial.print("Previous Gear = ");
Serial.println(current_gear);
if(current_gear > 0 && ((millis()-last_change_time)>timeout))
{
int tempGear = current_gear - 1;
if(tempGear != 0)
{
current_gear--;
last_change_time = millis();
}
}
Serial.print("New Gear = ");
Serial.println(current_gear);
delay(150);




There you have it, a switch debouncer that will work in any case. This tutorial was customized specifically for the Arduino! Enjoy!!

 

<p>Shame the author gone to ground.</p><p>7404 or 7414? Big difference. How about a parts list?</p><p>74XX14 Schmitt always helps</p>
<p>I am using a similar hardware debouncer like on http://hackaday.com/2015/12/09/embed-with-elliot-debounce-your-noisy-buttons-part-i/ But when using this in an interrupt, the interrupt is still called multiple times. Between 1 and 5 times when pressing the switch. </p>
<p>Btw, in my interrupt I only toggle a flag. &quot;flag = !flag&quot; nothing else. And it is still called multiple times using this hardware debouncer. </p>
<p>Maybe this is a good solution for end products, but I don't think for hobbyist and new comers like me this is suitable - because it is too complicated. </p><p>Will it be easier to use internal pull ups on button pin and connect it to GND when pushed, then just software debounce?</p>
This is a pretty good instructable, but shouldn't your Hex inverter actually be a 7414 Schmitt trigger? Also what diode are you using? <br> <br>
Is there a way to debounce with a small cheap capacitor?
<p>One capacitor and two resistors is all you need to do hardware debouncing. A capacitor only will produces current spikes that might damage your Arduino if you power it from your board through the voltage regulator.</p>
<p>Thank you for the diagram RioGiacco.</p>
<p>Actually there's no need for the inverter at all, just switch the button logic in software: LOW on digitalRead means 'button pressed', HIGH means 'button released'.</p>
<p>Looks good but I would've just done debouncing in code. Simply store the timestamp of the most recent button press and ignore wanted and unwanted button presses for a fixed period of time which is greater than the bouncing time.</p>

About This Instructable

54,997views

24favorites

More by mtrimm:Setup Daisy Chained RAID with LaCie's Little Big Disk Thunderbolt Arduino + Push Switch + Debouncing + Interrupts 
Add instructable to: