ISR best practices in Arduino - Time & Space Complexity
When using Interrupt Service Routines (ISRs) in Arduino, it's important to understand how their execution time affects your program.
We want to know how the time spent inside an ISR grows as the code inside it changes.
Analyze the time complexity of this simple ISR example.
volatile int count = 0;
void ISR_example() {
count++; // increment counter
for (int i = 0; i < 10; i++) {
// small fixed loop
}
}
void setup() {
attachInterrupt(digitalPinToInterrupt(2), ISR_example, RISING);
}
void loop() {
// main code
}
This ISR increments a counter and runs a small fixed loop each time it is triggered.
Look at what repeats inside the ISR.
- Primary operation: Incrementing the counter and running a loop 10 times.
- How many times: The loop runs 10 times every time the ISR is called.
Here, the loop inside the ISR runs a fixed 10 times, no matter what.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | ~1 increment + 10 loop steps |
| 100 | ~1 increment + 10 loop steps |
| 1000 | ~1 increment + 10 loop steps |
Pattern observation: The work inside the ISR stays the same each time it runs, so execution time per call does not grow with input size.
Time Complexity: O(1)
This means the ISR runs in constant time, no matter how many times it is triggered.
[X] Wrong: "Adding a loop inside the ISR will make the ISR time grow with the number of interrupts."
[OK] Correct: The loop inside the ISR runs a fixed number of times each call, so the time per interrupt stays constant, not growing with the number of interrupts.
Understanding ISR time complexity helps you write responsive Arduino programs that handle interrupts efficiently without slowing down the main code.
"What if the loop inside the ISR ran 'n' times instead of a fixed 10? How would the time complexity change?"