Using debounce with interrupt

Hello Everyone!

I'm writing a code for Arduino Uno in which I want to add an interrupt when button is pressed. I want to add debounce while doing so.

 buttonState = digitalRead(buttonPin);
          if(buttonState==HIGH)
            attachInterrupt(0, pin_ISR, CHANGE);

How can I add debounce in this code?

The same way you’d debounce any button. There are tons of tutorials around. If you want help more specific to your particular code then you’ll have to show the rest of it otherwise there isn’t much that we can do.

The code shown never does anything for buttonState==LOW, and always does the same thing (without any counting) for buttonState==HIGH. Based on the code shown thus far, no debouncing is needed.

If this is in the loop() function, you should add a flag and a test to prevent the attach from happening thousands of times while the button is depressed.

What is wrong with the attach happening thousands of times?

vaj4088: What is wrong with the attach happening thousands of times?

If you get in the habit of only doing the things you need to do, following the logic of the required actions, it reduces the chances of hidden bugs occurring when programs get big and complex. Also, I don't believe there is any comment about calling attach repetitively in the current documentation so the fact that it is safe, is just serendipitous. It might change in the future. Such programming also wastes CPU time. You may think you have plenty to spare until you paint yourself into a corner and suddenly have to go back and rewrite everything. I would rather do it at the beginning.

Pritha01:
Hello Everyone!

I’m writing a code for Arduino Uno in which I want to add an interrupt when button is pressed. I want to add debounce while doing so.

 buttonState = digitalRead(buttonPin);

if(buttonState==HIGH)
            attachInterrupt(0, pin_ISR, CHANGE);




How can I add debounce in this code?

What are you trying to do?

What is the purpose of attaching the interrupt when the button is pressed?

What is the interrupt intended to detect?

…R

it is relatively easy to notice a button push using an interrupt and ignoring any bounciness...

not tested, not compiled

volatile bool buttonPushed = false;

void setup() 
{
  attachInterrupt(1, PushButton, RISING); // May need to change
}

void loop() 
{
  if(buttonPushed)
  {
    buttonPushed = false;
    // do something
  }
}

void PushButton() //interrupt with debounce
{
  volatile static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > 50UL)  // ignores interupts for 50milliseconds
  {
    buttonPushed = true;
  }
  last_interrupt_time = interrupt_time;
}

I use it for example when working with blocking code (radio TX, and RX). And need to notice an event happened.

BulldogLowell: it is relatively easy to notice a button push using an interrupt

I don't think the OP is using the interrupt to detect the button. AFAIK he wants to use the button to turn an interrupt on.

...R

Robin2: I don't think the OP is using the interrupt to detect the button. AFAIK he wants to use the button to turn an interrupt on.

...R

I'll have to spend some time on that statement. Interrupts turn off?

BulldogLowell: I'll have to spend some time on that statement. Interrupts turn off?

I wonder if you have misunderstood me (or perhaps I have misunderstood the OP).

I think the OP wants the interrupts to be OFF until the button is pressed to switch them on. I have no idea why, or what the interrupt is intended to detect.

Hopefull the OP will explain all :)

...R

This is my complete code. I’m coding for Arduino for the first time because of my final year project so please help me in optimizing my code and also please help me in attaching debounce in this because my code isn’t working properly.

/* This program reads the data drom ADXL3xx Accelerometer and whenever the reading becomes
 *  greater than "80" it sounds a buzzer for 5 sec. If within those 5 sec, button is pressed
 *  then the programs returns to continue reading another set of values from accelerometer
 *  If button is not pressed within 5 sec, an SMS is sent.
*/

#include <SoftwareSerial.h>
#include <elapsedMillis.h>
 
//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 8
 
//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 7
 
//Create software serial object to communicate with SIM800
SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);

void pin_ISR();
void sendSms();
 
int xpin = A3;                  // x-axis of the accelerometer
int ypin = A2;                  // y-axis
int zpin = A1;                  // z-axis (only on 3-axis models)

//setting default values
int x=0,y=0,z=0; //store current values
int xprev=0,yprev=0,zprev=0; //store previous values

//These values will be used for normalization
int zeroX=317;
int zeroY=326;
int zeroZ=282;

int buzzerPin = 13; // buzzer will be connected to digital pin 13
const int buttonPin = 2; // pushbutton will be connected to digital pin 2
 
boolean timer0Fired;//check if timer was fired
unsigned long timer; // the timer
unsigned long INTERVAL = 5000;// limit of 5 seconds

// variables will change:  
int buttonState = 0; 
int buzzerState= 0;

void setup()
{
  // initialize the serial communications:
  Serial.begin(9600);
  while(!Serial);
   
  //Being serial communication with Arduino and SIM800
  serialSIM800.begin(9600);
  delay(1000);
   
  pinMode(buzzerPin, OUTPUT); //define buzzer pin as output
  pinMode(buttonPin, INPUT);  // define button pin as input
  timer0Fired = false;
  Serial.println("Setup Complete");
}

void loop()
{
  //reading & normalizing sensor values
  x=zeroX-analogRead(xpin);
  y=zeroY-analogRead(ypin);
  z=zeroZ-analogRead(zpin);
  // print the sensor values:
  Serial.print(x);
  Serial.print("   ");
  Serial.print(y);
  Serial.print("   ");
  Serial.print(z);
  Serial.print("\n");
  if(abs(x-xprev)>80||abs(y-yprev)>80||abs(z-zprev)>80)
  {
    Serial.println(">80");
    digitalWrite(buzzerPin, HIGH);
    timer = millis();//start timer after buzzer is set to high
    here:  //just a label
    buttonState = digitalRead(buttonPin); //read button is pressed or not
    if(buttonState==HIGH)
    attachInterrupt(0, pin_ISR, CHANGE); //if button is pressed jump to ISR
    buzzerState = digitalRead(buzzerPin); //read state of buzzer
    if(buzzerState==LOW){goto there;} // check if buzzer has stopped after pressing the button, if yes them goto label "there"
    if ((!timer0Fired)&&((millis() - timer) > INTERVAL)) //check if 5 sec are over
    {
    digitalWrite(buzzerPin, LOW); //stop buzzer
    timer0Fired=true;
    sendSms(); //call sendSMS function
    }
    else
    {
      goto here; //time isn't over so repeat above steps to check if button is pressed
    }
  }
  // delay before next reading:
  there:// just a label
  xprev=x;
  yprev=y;
  zprev=z;
  delay(1000);
  timer0Fired = false;
}
void pin_ISR() {
  Serial.println("Button pressed...");
  digitalWrite(buzzerPin, LOW); //stop the buzzer because button is pressed
}

void sendSms()
{
   Serial.println("Time's UP!");
  Serial.println("Sending SMS...");
   
  //Set SMS format to ASCII
  serialSIM800.write("AT+CMGF=1\r\n");
  delay(1000);
 
  //Send new SMS command and message number
  serialSIM800.write("AT+CMGS=\"85xxxxxxxx\"\r\n");
  delay(1000);
   
  //Send SMS content
  serialSIM800.write("Msg from Arduino");
  delay(1000);
   
  //Send Ctrl+Z / ESC to denote SMS message is complete
  serialSIM800.write((char)26);
  delay(1000);
     
  Serial.println("SMS Sent!");
}

... my code isn't working properly.

void pin_ISR() {
  Serial.println("Button pressed...");
  digitalWrite(buzzerPin, LOW); //stop the buzzer because button is pressed
}

Not surprised.

Don't do serial prints inside an ISR.

http://www.gammon.com.au/interrupts

      goto here; //time isn't over so repeat above steps to check if button is pressed

Please, no.

As for the label name. "goto here;"? Excuse me? Don't you mean:

goto there;
    if(buzzerState==LOW){goto there;} // check if buzzer has stopped after pressing the button, if yes them goto label "there"

Oops, sorry, I didn't notice that you already have "goto there;".

Well, your code goes here, and there. What more could you want?

Pritha01: This is my complete code. I'm coding for Arduino for the first time because of my final year project so please help me in optimizing my code and also please help me in attaching debounce in this because my code isn't working properly.

How about answering my question from Reply #6 - "what are you trying to do?"

At the moment this seems like an XY Problem

...R

Robin2:
How about answering my question from Reply #6 - “what are you trying to do?”

At the moment this seems like an XY Problem

…R

Hello! I have described in my previous post about what functionality I am trying to achieve in my code. I wanted to sense if the button is pressed in a time interval of 5 sec (during which buzzer is ON) and for that purpose I’ve used the interrupt.

If button is pressed, then no action is taken. If it is’nt pressed then an SMS is sent!

Pritha01: I have described in my previous post about what functionality I am trying to achieve in my code.

I was not asking about the functionality of the code. I would like to know what the project is about so that I understand the context of your questions.

...R