Interrupt on button, switching programs

Hi,

I'm trying to set few different programs to one button which will trigger the interrupt and switch between them. So I have issue when program loop is executing I trigger the interrupt and get back to the loop I have to stop loop somehow and move to the next program. I tried it with If statement but it's quite impractical because I must have If statement in every program but it doesn't prove that will switch program instantly when interrupt is triggered because it has to finish loop first then IF.

I wonder if there is any other solution for that issue? I mean if it works in our TV-s or PC-s there should be some way to solve that.

I hope you can help me. Thanks in advance!

Regards

I suspect you are rather confused about what an interrupt is, or alternatively, what a microcontroller is.

The functions to support the sort of multi-tasking that is practical on a PC are simply not present on this microcontroller (and indeed, on very few overall).

If you want a program to do more than one thing, you write it to do more than one thing. This requires certain disciplines in organisation of a program which you need to develop.

If you care to explain what you actually propose to do - the task, not the way you have imagined it - then we can advise, though why this presently appears in the " LEDs and Multiplexing" category, I cannot fathom!

Bro2131:
Hi,

I'm trying to set few different programs to one button which will trigger the interrupt and switch between them. So I have issue when program loop is executing I trigger the interrupt and get back to the loop I have to stop loop somehow and move to the next program. I tried it with If statement but it's quite impractical because I must have If statement in every program but it doesn't prove that will switch program instantly when interrupt is triggered because it has to finish loop first then IF.

That's exactly how it works: you check the program to run at the beginning of each loop. The trick is to have the loop running fast enough to not have a noticeable delay between the falg change and the program change. How can you achieve that? If you do not hold the MCU into delay() or any other waits, but keep running your loop() function over and over, than it will probably re-roll around the loop() more than 100k times per second, which is definitely fast enough.

So, let's say you want to switch between two programs, one that blinks an LED every 1s (1Hz) and one that does blink an LED every 100ms (10Hz) you will have something like this gist: I have added a serial send function to have another example other than the classical LEDs.

Please note the libraries you use might contain some function holding the processing: you have to replace those libraries functions with their non-blocking equivalents.

Hi,

Thanks for all your answers!! It's a bit late response.

I get it to not use delay() in loop function, but i have multiple leds which act on different on/ off delays in order to represent certain shape. So that means i need to compare time with millis() after every change of LED? That's quite a lot of if statements. Or I can make function to do that, only thing i have to do is to call it at the right time?

Regards

Bro2131:
i have multiple leds which act on different on/ off delays

Try my library, attached.

Sample code below.... just add as many BWODs as you need.

/* Blink without Delay in a class in a library
*/

#include <BWOD.h>

BWOD myBWOD;
BWOD anotherBWOD;

void setup() {
  myBWOD.attach(8, 97, 110);      //pin, on interval, off interval
  anotherBWOD.attach(14, 1798, 1015);
}

void loop()
{
  myBWOD.manageBlink();
  anotherBWOD.manageBlink();
}

BWOD.zip (1.21 KB)

Hi,
Thanks for your answer I will try it and keep you updated.

btw. This is code for one program.
How can I remove delay() function but to leave functionality as it is?

case 1:
      for (int i = 0; i < 30; i++)
      {
        digitalWrite(a, HIGH);
        delay(del4);
        digitalWrite(a, LOW);
        delay(del4);
        digitalWrite(b, HIGH);
        delay(del4);
        digitalWrite(b, LOW);
        delay(del4);
        digitalWrite(c, HIGH);
        delay(del4);
        digitalWrite(c, LOW);
        delay(del4);
        digitalWrite(d, HIGH);
        delay(del4);
        digitalWrite(d, LOW);
        delay(del4);
      }
      break;

Regards

Well, you need to replace the for() loop with a global variable which you increment when appropriate and check if it has reached the maximum value. You will also need a global variable to keep track of which led is currently flashing. When all 4 have been flashed, its time to increment "i". You need a third variable to hold the time when each flash began, so you can compare it with millis().

Paul

How can I remove delay() function but to leave functionality as it is?

You can't.
You have to rewrite your function as a state machine like PaulRB told you.
For further examples:-
See my
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Or Robin2's several things at once
http://forum.arduino.cc/index.php?topic=223286.0