Interrupts that interrupt an interrupt

This is more of a general question. Is it possible to make a timer interrupt which would, when overflow happens, do its thing. But if during that timer interrupt another timer interrupt would overflow, it would be used as some kind of "go to" and Arduino would start executing things from void loop.

Nope.

The only way to get interrupts to interrupt interrupts is to reenable interrupts in the interrupts which you want to be interrupted, but you run the risk that the interrupt that was interrupted will have been interrupted by an interrupt from the same source which is very dangerous and can very easily lead to recursion and a crash.

If you are writing a program which requires an interrupt to be interrupted, you need to seriously rethink your code.

But if during that timer interrupt another timer interrupt would overflow, it would be used as some kind of "go to" and Arduino would start executing things from void loop.

Your Arduino spends virtually all its time executing code in "loop()" (unless you put an infinite loop in "setup()") - what are you getting at?

The only way to get interrupts to interrupt interrupts is to reenable interrupts in the interrupts which you want to be interrupted, but you run the risk that the interrupt that was interrupted will have been interrupted by an interrupt from the same source which is very dangerous and can very easily lead to recursion and a crash.

Reminiscent of Monty Python's Meaning of Life move your coat to a lower peg scene...

AWOL:

But if during that timer interrupt another timer interrupt would overflow, it would be used as some kind of "go to" and Arduino would start executing things from void loop.

Your Arduino spends virtually all its time executing code in "loop()" (unless you put an infinite loop in "setup()") - what are you getting at?

In loop I have some code. Interrupt "number1" would often check if one button went from LOW to HIGH and execute some instructions. Then during "interrupt1" another "interrupt2" would also often check if the same button went from LOW to HIGH and if it did, it would return to the code in loop. That is what I'm trying to accomplish, but I'm not very familiar with interrupts so I don't know what is really possible.

Have the interrupt set a global variable whenever the button has changed then return as quickly as possible. In the loop have an if statement which checks this global variable and does some action.

If you have two interrupts then have two global variables to check for different things. Try then to avoid delays in your loop function as that would slow down any reaction to events.

The code you put in an interrupt should be anything which critically must happen as soon as the interrupt event occurs (e.g. reading in some buffer for serial, or incrementing a counter). Do anything else in the main loop.

Don't forget to qualify your flag variable "volatile".

In loop I have some code. Interrupt "number1" would often check if one button went from LOW to HIGH and execute some instructions. Then during "interrupt1" another "interrupt2" would also often check if the same button went from LOW to HIGH and if it did, it would return to the code in loop. That is what I'm trying to accomplish, but I'm not very familiar with interrupts so I don't know what is really possible.

Are you sure that you need to use an interrupt at all ? Interrupts are meant to be handled quickly so the chances of the second transition from LOW to HIGH happening during the interrupt should be very small bearing in mind that this is a button input that you are talking about. How fast can you press/release/press a button I wonder, especially if you include debounce code, which you should.

How often does the button state need to be checked to trigger the first actions ? What else is going on in the loop() function ?

It's time for you to post your code I think so that we can see what you are doing in the interrupt. Not Serial.print() or delay() I hope.

I have connected 6 push buttons, all on analog pin 5. Using this code:

int a=0;
 
void setup()
{
  Serial.begin(9600);
  pinMode(A5, INPUT_PULLUP);
}
 
void loop()
{
  a = analogRead(5);
  Serial.print("  analogRead() ");
  Serial.print("  value is :");
  Serial.println(a);
}

I have found out that if first button is pressed analogRead = 1023, if second button is pressed analogRead = 73, if third buttons is pressed analogRead = 127, if fourth button is pressed analogRead = 215, if fifth button is pressed analogRead = 253 and if sixth button is pressed analogRead = 287. First button means "FORWARD", second button means "BACKWARD", third button means "LEFT", fourth button means "RIGHT", fifth button means "GO" and sixth button means "RESET". What am I trying to do. Arduino should constantly watch if any of the buttons was pressed. If some of the first four buttons was pressed, it should store the number of the button in an array and keep doing that until fifth - "GO" button is pressed or until the end of array. If it comes to the end of array it should start storing values from the beginning of the array. If fifth button was pressed it should start blinking LEDs on this way: read the values from array, if it is 1 blink LED3 and LED 4 (meaning forward), if it is 2 blink LED1 and LED2 (meaning backward), if it is 3 blink LED1 and LED4 (meaning left) and if it is 4 blink LED1 and LED3 (meaning right). If at any time during blinking, fifth "GO" button is pressed, Arduino should stop blinking LEDs and again start watching for press of any first four buttons. Until now I made this:

#define MAX 50
const int LED1 = 2;
const int LED2 = 3;
const int LED3 = 4;
const int LED4 = 5;
int array[MAX];
int old_b = 0;
int val;
int counter = 0;
int i;
int temp;
int L1;
int L2;

void setup () {
  pinMode (A5, INPUT_PULLUP);
  Serial.begin(9600);
}

int readButtons (int pin) {
  int b, c;
  c = analogRead(pin);
  Serial.print("analogRead =  ");
  Serial.println(c);
  delay(100);
  if (c > 1015) b = 0;
  else if (c > 70 && c < 76) b = 1;
  else if (c > 122 && c < 128) b = 2;
  else if (c > 169 && c < 175) b = 3;
  else if (c > 209 && c < 217) b = 4;
  else if (c > 247 && c < 256) b = 5;
  else if (c > 280 && c < 291) b = 6;
  else b = 0;
  if (b == stari_b) {
    return 0;
    old_b = b;
  } 
  else {
    return b;
    old_b = b;                                 
  }                           
}

void loop () {
  while ((val = readButtons(5)) != 5) {
    if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {
      array[counter] = val;
      Serial.print("In  ");
      Serial.print(counter);                
      Serial.print(" saving ");            
      Serial.println(val);
      delay(100);
      counter++;
      if (counter == MAX) {
        counter = 0;
      } 
    }
  }

  temp = counter;
  counter = 0;

  for (i = 0; i < temp; i++) {
    if (array[i] % 2 == 0) {
      L1 = 2;
      L2 = array[i] / 3 + 3; 
    } 
    else {
      L2 = 5;
      L1 = array[i] % 3 + 3;    
    }

    if (readButtons(5) != 5) {
      digitalWrite (L1, HIGH);
      if (readButtons(5) != 5) {
        digitalWrite (L2, HIGH);
        delay(1000);
        digitalWrite (L1, LOW);
        digitalWrite (L2, LOW);
        if (readButtons(5) == 5) {
          i = temp;
        }
      } 
      else {
        digitalWrite (L1, LOW);
        i = temp; 
      }
    }  
  }
}

Code doesn't work like it is supposed to. It doesn't always remember/store every button that was pressed and it doesn't always start/ stop blinking (sometimes I need to press it several times). I have searched for help. Got some advice, but none of them seem resolvable and concrete. Among them was that I should somehow use interrupts. I'm not really familiar with them. Please help me. I'm trying to accomplish this using only things that are in the schematics. I have been working on this for two months know.

Eerm, where is the pullup resistor in your circuit - all the switches pull the analog input down to ground, but what pulls it up?

Edit:
Noticed you are using INPUT_PULLUP - that is a bad idea as you don't know the exact resistance of the pullup and it is temperature/current varying. This means that your analog values for each switch will vary. You will need to add an external pullup resistor.
Do you have a proper schematic of your circuit (fritzing breadboard pics do not a schematic make).

I'm not sure what you mean by proper schematic. Is is the schematic when in fritzing "view mode" is changed to schematic?

I have connected 6 push buttons, all on analog pin 5. Using this code:

I am sure that the code is very interesting but I cannot see what it has to do with an interrupt interrupting an interrupt ?
What did I miss ?

In another thread Saving statesof 6 push buttons - Programming Questions - Arduino Forum you say

I have determined that if none of the buttons is pressed reading is 1023, if number 1 is pressed reading is 73, if number 2 is pressed reading is 126, if number 3 is pressed reading is 173, if number 4 is pressed reading is 215, if number 5 is pressed reading is 253 and if number 6 is pressed reading is 287.

but in this one you say

I have found out that if first button is pressed analogRead = 1023, if second button is pressed analogRead = 73, if third buttons is pressed analogRead = 127, if fourth button is pressed analogRead = 215, if fifth button is pressed analogRead = 253 and if sixth button is pressed analogRead = 287.

As you see there is a discrepancy. Is the circuit the same in both cases ?

UKHeliBob:

I have connected 6 push buttons, all on analog pin 5. Using this code:

I am sure that the code is very interesting but I cannot see what it has to do with an interrupt interrupting an interrupt ?
What did I miss ?

In another thread Saving statesof 6 push buttons - Programming Questions - Arduino Forum you say

I have determined that if none of the buttons is pressed reading is 1023, if number 1 is pressed reading is 73, if number 2 is pressed reading is 126, if number 3 is pressed reading is 173, if number 4 is pressed reading is 215, if number 5 is pressed reading is 253 and if number 6 is pressed reading is 287.

but in this one you say

I have found out that if first button is pressed analogRead = 1023, if second button is pressed analogRead = 73, if third buttons is pressed analogRead = 127, if fourth button is pressed analogRead = 215, if fifth button is pressed analogRead = 253 and if sixth button is pressed analogRead = 287.

As you see there is a discrepancy. Is the circuit the same in both cases ?

I was thinking that maybe, since my code doesn't work properly, it might work with inerrupts.

Yes you are wright, it is the same circuit as in the other thread. In this one I have written it wrong, it should be:

I have determined that if none of the buttons is pressed reading is 1023, if number 1 is pressed reading is 73, if number 2 is pressed reading is 126, if number 3 is pressed reading is 173, if number 4 is pressed reading is 215, if number 5 is pressed reading is 253 and if number 6 is pressed reading is 287.

I'm sorry, I'm losing the plot here - where do the interrupts come into this scheme?

I'd be very wary of testing for equality where ADC readings are concerned.

Even if you do decide to use an interrupt I don't see how the one interrupting another scenario arises ?

You cannot use an interrupt with the current circuit so the point is moot anyway.

Since my code didn't work, I was thinking of making a while loop which, as the one already, would check for buttons presses. But it wouldn't check for the fifth "GO" / "STOP" button. There would be "INTERRUPT1" which would be offently overflowed and then checked if the 5th button was pressed. If it was it would read the array and execute upon that. Second "INTERRUPT2" would also offently overflow and somehow check if the fifth button was pressed during blinking. If it was it would make Arduino to start watching for the button presses again, that is start from the vooid loop. This is how meant to do it, but I don't know enough about interrupts yet to implement that.

None of what you describe would solve your basic problem of reliably reading the buttons, storing the input and playing back the sequence. Of all the things that may be wrong with your current approach it is not that the buttons cannot be read fast enough.

I think I see what you are trying to do with this line of code

  while ((val = readButtons(5)) != 5) {

but what does it do in practice ? If it works then it is surely only by accident. What is it that is being tested to see whether it is not equal to 5 ?

Once that line is sorted out then the next one

    if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {

is overkill because you could just check to see whether val is zero or a number as you know the range that readButtons() can return. Incidentally, readButtons() can return a value up to 6 but you seem to be only checking for 1 to 4, Is that what you meant to do ?

UKHeliBob:
None of what you describe would solve your basic problem of reliably reading the buttons, storing the input and playing back the sequence. Of all the things that may be wrong with your current approach it is not that the buttons cannot be read fast enough.

I think I see what you are trying to do with this line of code

  while ((val = readButtons(5)) != 5) {

but what does it do in practice ? If it works then it is surely only by accident. What is it that is being tested to see whether it is not equal to 5 ?

Once that line is sorted out then the next one

    if ((val == 1) || (val == 2) || (val == 3) || (val == 4)) {

is overkill because you could just check to see whether val is zero or a number as you know the range that readButtons() can return. Incidentally, readButtons() can return a value up to 6 but you seem to be only checking for 1 to 4, Is that what you meant to do ?

Answer to both questions is yes. In the if statement I'm checking only for 1,2,3 or 4 since they represent the way LEDs are supposed to blink.

What about my question this line ?

  while ((val = readButtons(5)) != 5)

UKHeliBob:
What about my question this line ?

  while ((val = readButtons(5)) != 5)

If the 5th button is pressed, Arduino will start blinkinh LEDs, and if it is pressed while blinking LEDs it should stop blinking and start watching for press's of any of first four buttons.