Understanding Interrupts

I need to query sensors while running an algorithm simultaneously. The sensor querying updates an array that is referenced by the algorithm. That is, I need the algorithm to access values in the array and know that they are the most recent values observed. I have a function for querying the sensors attached to an interrupt, which I believe means the sensors will be queried at a consistent time step.

If my Arduino is in the middle of a very long while loop, and the interrupt is called, will both the while loop and the function attached to the interrupt be carried out simultaneously? If not, what will happen? Which takes priority?

On a related note, in the same situation as above, if both are run simultaneously, and I have delay(x) in my sensor query, will that pause the whole system as it would were delay(x) used in the main loop?

will both the while loop and the function attached to the interrupt be carried out simultaneously

No. When the interrupt fires it the program will finish the current instruction, vector to the interrupt, run the interrupt code and then return to the program where it was before the interrupt. There can be no code running simultaneously.

Delay() should not be used in an interrupt service routine (nor serial communication) as interrupts are disabled while an ISR is executing.

If you need to sample at a regular and accurate interval polling would be a better choice, using the blink without delay method (see example in IDE. File, Examples, Digital).

What causes the interrupt to start the query of the sensor?

Interrupts are processed when they occur - so your long while loop would stop, the interrupt processed, and the loop continues from where it was.

This does not sound like a situation that requires using interrupts. Using interrupts introduces several issues and makes the solution more complex - my advice for interrupts is to use them only when absolutely necessary and then only reluctantly and as little as possible.

In this case what you need to do is design your sketch to use a non-blocking approach, which means it can control several activities concurrently and independently. "Non-blocking" means that you code does not stop (block) to wait for time to pass or an outside event to occur before doing something - instead the code tests for all the events which are relevant to it and handles them as they arise. The 'blink without delay' example sketch is the simplest demonstration of this approach. See Robin2's sample code posted recently for a more complicated and realistic example.

I believe I have the querying function attached to the overflow. So my understanding is that it would be called overtime there is an overflow on that interrupt, which would be at a regular time step.

PeterH, thank you for your suggestion. That does make a lot more sense. I am curious about this process though. Above it appears there are two different answers from CrossRoads and groundfungus: 1) The while loop finishes and then the ISR is executed 2) The while loop pauses until the ISR is finished.

Any sense of which it is?

Upon further thought, I'm not actually sure how the Blink Without Delay method could be leveraged here. My algorithm consists of a main while loop, and each pass through it might take more or less time. Therefor, I don't see how I could get a consistent time step using the Blink Without Delay strategy.

I did not mean that the while loop finishes, I said that the current INSTRUCTION finishes where ever it is in the loop. Execution goes to the ISR and returns to the next instruction in the loop. You interrupt the loop and then go back to the place you left off in the loop.

Wonderful! Thank you. That clears things up quite nicely.

This one: 2) The while loop pauses until the ISR is finished.

I believe I have the querying function attached to the overflow.

Overflow of what? This interrupt is timer based?

Yes it is a timer interrupt. Sorry I did not make that clear. I understand you can attach an ISR to a pin for differing values, or a timer. I'm looking for it to be a timer interrupt so that at some known timestep the ISR is called.

Ok, making more sense now.

ahadik: Upon further thought, I'm not actually sure how the Blink Without Delay method could be leveraged here. My algorithm consists of a main while loop, and each pass through it might take more or less time. Therefor, I don't see how I could get a consistent time step using the Blink Without Delay strategy.

A single pass through loop() will be very fast (unless you have a delay() function) so the minor timing variation will be irrelevant unless you need microsecond accuracy in the timing for your sensor readings - which I suspect isn't required.

A description of the overall project would be useful. What sort of sensors are you using and for what?

...R

This is a MicroMouse for navigating a maze autonomously. So the main algorithm is flood fill. However the flood fill algorithm can have varying times for each pass since you might just be updating a single value; or discovering some specific wall cascades to updating many many values multiple times. However, I haven't gotten a clock on each passes speed yet (since I can't yet navigate) so I took the assumption that each iteration had the potential to take perhaps a significant amount of time.

ahadik: Upon further thought, I'm not actually sure how the Blink Without Delay method could be leveraged here. My algorithm consists of a main while loop, and each pass through it might take more or less time. Therefor, I don't see how I could get a consistent time step using the Blink Without Delay strategy.

If you design the sketch using a non-blocking approach then the only time taken will be the time needed to check for possible events, and then do any processing that needs to be done as a result of those events. Typically the time needed to perform pure computation will be small (there simply isn't space on an Arduino for much code or data) so I wouldn't expect a sketch to be tied up for long periods if it was well designed. I don't know what your 'flood fill' algorithm entails or how long it will take to execute, but I would start on the assumption that the non-blocking approach can be made to work without interrupts and only fall back to the interrupt based approach if and when it proves necessary.

ahadik: I need to query sensors while running an algorithm simultaneously. The sensor querying updates an array that is referenced by the algorithm. That is, I need the algorithm to access values in the array and know that they are the most recent values observed. I have a function for querying the sensors attached to an interrupt, which I believe means the sensors will be queried at a consistent time step.

If the individual values take up more than one byte of RAM then you'll need to guard access to them in your main program using noInterrupts() and interrupts() around the accesses so you see consistent values.

Also find out about the volatile keyword.

Is this possible to use the interrupt() and noInterrupt() functions outside the main program? In this case what file would have to be included?

You can use them wherever you like. No need to include anything, they are part of the core.


Rob