Restart loop after interrupt?

Hi, Does anyone know if it is possible to start a program from the beginning of the loop() function after an external interrupt has been executed instead of picking up where it left off? I have a program which checks the speed of the car, distance traveled, average speed etc.. and when the interrupt is activated, it is supposed to toggle through the different modes. The problem I have is that if the car is standing still and the magnets are not passing the reed switch, I need to wait 6 seconds for each screen to advance. I would like to make it so that it advances instantaneously and causing the program to start from the beginning of the loop after the interrupt has been tripped would do this. If anyone knows of another solution that would work, please let me know and so I could try that.

Here is a link to my project so far: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293063615 And the full code: http://ubuntuone.com/p/Vqh/

Also, is there any way I could write a cleaner version of this code? It is supposed to calculate the time it takes a magnet to make one revolution across a reed switch and if it exceeds 6 seconds, it should stop waiting and move on with the code. (Basically this is for a speedometer and if it takes more than 6 seconds it will display a zero speed) I was thinking of using an interrupt, but am not sure how to implement this. If anyone has a good example of using an interrupt like this that would be greatly appreciated. I did see something on timer interrupts and will try to find a better example on that. Am I heading in the right direction here, or is there a better way?

void tripuino::rech(unsigned long *timestart, unsigned long *timeend, int *stehen){
  unsigned long check;
  check = millis();
  while (digitalRead(3) == HIGH){
    if((millis() - check) > 6000){
      *timestart = 0;
      *timeend = 40000;
      *stehen = 0;
      break;
    }
    }
    *timestart = millis();
    while (digitalRead(3) == LOW){
      if((millis() - check) > 6000){
      *timestart = 0;
      *timeend = 40000;
      *stehen = 0;
      break;
    }
    }
    while (digitalRead(3) == HIGH){
      if((millis() - check) > 6000){
      *timestart = 0;
      *timeend = 40000;
      *stehen = 0;
      break;
    }
    }
    *timeend = millis();
}

Thanks in advance,

Firestork

Does anyone know if it is possible to start a program from the beginning of the loop() function after an external interrupt has been executed instead of picking up where it left off?

Not directly. The normal course of action is to resume right where it left off. You could set a global flag in the interrupt service routine, and check that before each call in loop, and return if it was true.

Reset the flag to false at the start of loop.

Thanks for the help PaulS, but do you have a link to how I would go about this? I do not have much experience with interrupts. A simple example would do too.

Thanks, Firestork

The assumption from your original post is that you have an interrupt, but when it kicks off the loop does not restart at the beginning (as it was not coded to do so). Since I don’t have your complete program to use, I created a very simple sample based on the code you did provide.

In this, a timer based interrupt is used to simulate your interrupt. When triggered, it sets the global flag mentioned by PaulS, in this case called “inReset” … meaning we need to reset. The loop condition(s), (maybe multiple in your case) should check for the setting of this flag and exit. See the comments in the below code for more details - hope this helps you get over the hump.

/* Sample Application: Interrupt resetting a loop process

Purpose: This example starts with a process that simply writes a counter to the serial port.
Without the timer enabled, it will run to over 50 and then reset back to 0.
With the timer enabled, it stops under 10 and restarts at the top of the loop (new counter).

*/
//--- Using timer interrupt for this example
#include <TimerOne.h>

//--- inReset is set by the interrupt to tell main loop to stop
boolean inReset = false;

//--- temp counter used by timer process
int timerCounter = 0;

//--- timer process, sample code kicked by interrupt
void Timer1Demo(){
  timerCounter++;
  if( timerCounter > 10 ){
    timerCounter = 0;
    //--- timer process sets global variable, which will 
    //    trigger the loop to stop what it is doing and start over

    // Important: If your loop has more than one process in it's own loop
    //  then they all must have a check for inReset. 
    inReset = true;
  }
  //... whatever else your interrupt may do
}

void setup() {
  Serial.begin(19200); //or whatever you normally use, maybe 9600 default if not showing in monitor 

  //Create sample timer interrupt and attach to sample routine
  Timer1.initialize(50000);
  Timer1.attachInterrupt(Timer1Demo); 
}


void loop(){
  int tmpCounter = 0;
  unsigned long check;
  check = millis();
  //Sample program had while statement based on pin value - here just true for this example
  while (true){
    //Sample program had none delay timer, perfect to add the reset switch to
    //Notice the || inReset - this checks for the global flag and ends just like the timer would
    if( (millis() - check) > 6000 || inReset){
    //If the reason for the reset was the flag being set - reset it back
      if( inReset )
        inReset = false;
      break;
    } else {
      //Take some demo action
       Serial.println(tmpCounter++,DEC); 
       delay(100);
    }
  }
}

Thank you marklar,

This is perfect, I do not have much time today, but ill try to play around with this tomorrow.

Happy New Year

It would probably be cleaner to take out the while(true) from loop() and replace break; with return; This would work even in nested while loops and is more clear what your intentions are.