Interrupts, buttons, delay?

Hello, I've just started to use/learn interrupts. I wanna know how to use them properly. I know that using any delays in interrupt instruction is bad idea. However delays are necearry to make switches work properly, due to them physical structure etc. I wrote simple code to understand how interrupts work. It works but I wanna to use code properly for the bigger/future projects. Is it good or am I have to somehow change delays in interrupt? Thanks

#define ledPin2 11
#define ledPin1 13
#define button 7
#define interruptPin 2

volatile boolean state = HIGH;


void setup() {

  for (int i = 11; i < 14; i++)
  {
    pinMode(i, OUTPUT);

  }
  pinMode(button, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button), button_interrupt, FALLING);
}

void loop() {

  digitalWrite(ledPin1, HIGH);
  delay(200);
  digitalWrite(ledPin1, LOW);
  delay(200);

}

void button_interrupt ()
{
  if (digitalRead(button) == LOW)
  {
    delayMicroseconds(20000);
    state = !state;
    while (digitalRead(button) == LOW);
    delayMicroseconds(20000);
  }
  digitalWrite(ledPin2, state);

}

Well, you can safely record and compare time stamps in an ISR. That is how delays are supposed to be done in an ISR, unless they are extremely short.

Using a delayMicroseconds(20000) in an ISR is a big no-no.

Really, using millis() in an ISR is only a little different than using it in loop(). Just realize that the millis() value won't change inside the ISR.

I know that using any delays in interrupt instruction is bad idea.

It's not just a bad idea. Most delay techniques rely on interrupts firing, which doesn't happen when your ISR is running.

However delays are necearry to make switches work properly,

No. Suppose you are a teacher, and have a class with a dozen kids. You have a rule that says that one student can't answer more than one question in a row. Suppose you ask a question, and Johnny answers it. That is equivalent to noticing that a switch was pressed. Now, you ask another question, and Johnny raises his hand. You can go over and break his arm (a forced delay while it heals) OR you can ignore him, just as you would ignore a pin that changed state again sooner than is reasonable.

Is it good

Not even close. The delayMicroseconds() calls have to go. The while statement has to go.

am I have to somehow change delays in interrupt?

Think about my analogy earlier, and see if you can figure out how to implement it.

aarg:
Well, you can safely record and compare time stamps in an ISR. That is how delays are supposed to be done in an ISR, unless they are extremely short.

using @aarg's point, you can write an ISR like this:

#define DEBOUNCE_TIME 25
#define ledPin2 11
#define ledPin1 13
#define button 7
#define interruptPin 2

//volatile boolean state = HIGH;


void setup() {

  for (int i = 11; i < 14; i++)
  {
    pinMode(i, OUTPUT);

  }
  pinMode(button, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button), button_interrupt, FALLING);
}

void loop() {

  digitalWrite(ledPin1, HIGH);
  delay(200);
  digitalWrite(ledPin1, LOW);
  delay(200);

}

void button_interrupt ()
{
  static unsigned long lastInterruptMillis = 0;
  if(millis() - lastInterruptMillis > DEBOUNCE_TIME)
  {
    digitalWrite(ledPin2, !digitalRead(ledPin2));
    lastInterruptMillis = millis();
  }
}

Yes, and if the required action is something much longer than just a digitalWrite, you can communicate with the main program using flags.

Ok, thanks. I'll try all those advices and write about results.