Does attachInterrupt() pause delays?

Hello everybody,

Explanation:

For a recent project of mine, i want to read inputs from a rotary encoder with a relatively high precision (1000lmp/U) .
I need to read every pulse that passes throug the three inputs (A, B and the reference pulse).
the reference pulse is there to exactly know the position of the reader head, you can read this by reading the state of a wire, wich pulls high when the reader head passes through a specific place in the encoder.

Moving on:

when this reference pulse is triggered, i want to hear a buzzer when that reference pulse has been found and to make it hearable, i need to put a delay between when i start the buzzer and when i stop it.
I am using a hardware interrupt on pin 3 to read the A wire on the encoder wich reffers to a function where i store the pulses in a variable.

now for my question:

do these hardware interrupts pause the delay i set for the buzzer and actually pauses that delay to work on the function when the delay is active and if not, how can you make it work like that?

/* 
the line where i attach the interrupt is line 53
the line where the delay starts is on line 84
the function i reffer to when the A wire is changed to high starts on line 95
*/
//schermcode
#include <TFT_HX8357.h> // Hardware-specific library
#include <Adafruit_GFX.h>    // Core graphics 
TFT_HX8357 tft = TFT_HX8357();
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define GRAY    int(210/8*2048) + int(216/4*32)+ int(224/8)
// eind schermcode
#define CHA 3
#define CHB 4
#define CHR 2
#define CW_LED 13
#define CCW_LED 12
int statusled = 5;
int buzzer = 11;
volatile int i = 0;
volatile int master_count = 0; // universal count
volatile byte INTFLAG1 = 0; // interrupt status flag
volatile byte INTFLAG2 = 0; // interrupt status flag
volatile int mapmaster = 0;
int pulsecounter = 0;
int readyr = 0;
void setup() { 
  tft.begin();
  pinMode(CHA, INPUT);
  pinMode(CHB, INPUT);
  tft.setRotation(1);
  tft.fillScreen(WHITE);
  tft.fillRect(10, 10, 460, 300, GRAY);  
  tft.setCursor(20, 20);
  tft.setTextColor(YELLOW);  
  tft.setTextSize(2);
  tft.setTextWrap(false);
  tft.print("status: no reference.");  
  tft.setCursor(20, 40);
  tft.print("turn counter clockwise.");
  tft.setCursor(240, 60);
  tft.setTextSize(3);
  tft.print("pos: 0");
  while(!digitalRead(CHR)){
    i = i;
  }
  
  attachInterrupt(1, flag, RISING);

  
  
  // interrupt 0 digital pin 3 positive edge trigger
  
}

void loop() {
  if(INTFLAG1 == 1){
    tft.setCursor(384, 60);
    tft.setTextSize(3);
    tft.fillRect(384, 60, 180, 22, GRAY); 
    
    tft.print(map(master_count, 0, 1000, 0, 360));
    INTFLAG1 = 0;
  } // end if

  if(readyr == 1){
    tft.setTextSize(2);
    tft.setCursor(20, 20);
    tft.setTextColor(GRAY);
    tft.print("status: no reference.");
    tft.setCursor(20, 40);
    tft.print("turn counter clockwise.");
    tft.setCursor(20, 20);
    tft.setTextColor(GREEN);
    tft.print("status: found reference");
    digitalWrite(buzzer, LOW);
    analogWrite(buzzer, 120);
    delay(200);
    digitalWrite(buzzer, LOW);
    readyr = 2;
  }


} // end loop



void flag() {
  if(readyr >= 1){
    INTFLAG1 = 1;
  }
  
  // add 1 to count for CW
  if (digitalRead(CHA) && !digitalRead(CHB)) {    
    master_count++ ;
    mapmaster = map(master_count, 0, 1000, 0, 360);   
  }
  
  if(master_count >= 1000){
    master_count = 1;
  }
  
  
  
  // subtract 1 from count for CCW
  if (digitalRead(CHA) && digitalRead(CHB)) {   
    master_count-- ;
    
    if(master_count <= 0){
      master_count = 999;
    }
    
    mapmaster = map(master_count, 0, 1000, 0, 360);
  } 
  if(readyr == 0 && master_count >= 50){
    readyr = 1;
    master_count = 0;
    
    
  }

}

Thanks already
Inzywinki

pulsecounter-forum.ino (2.77 KB)

Interrupts do get called during delay.

 if(readyr == 1){
    tft.setTextSize(2);
    tft.setCursor(20, 20);
    tft.setTextColor(GRAY);
    tft.print("status: geen referentie.");
    tft.setCursor(20, 40);
    tft.print("draai tegen wijzerszin.");
    tft.setCursor(20, 20);
    tft.setTextColor(GREEN);
    tft.print("status: referentiepuls gevonden");
    digitalWrite(buzzer, LOW);
    analogWrite(buzzer, 120);
    delay(200);
    digitalWrite(buzzer, LOW);
    readyr = 2;
  }
if(readyr == 0 && master_count >= 50){
    readyr = 1;
    master_count = 0;    
    
  }

You will only get the buzzer one time. readyr is will never get reset to =1. When the value is set =2 the code won't enter the conditional which resets it.

Why use delay() ?

is there another way that i can hear the buzzer without using delay?

Inzywinki:
is there another way that i can hear the buzzer without using delay?

Yes. Use the BlinkWithoutDelay principle as in the example with the same name.

I thought of that too, but it takes so much speed of the arduino having to count every millisecond and that's not good for reading every pulse of the encoder.

Inzywinki:
I thought of that too, but it takes so much speed of the arduino having to count every millisecond and that's not good for reading every pulse of the encoder.

The Arduino is counting every millisecond anyway so why not take advantage of it ? Two comparisons each time through loop() when the buzzer is sounding and only one when it is not. Is that so much ?