SAMD21 Hardware timer interrupts not working

Hi

Not sure whether this is the correct subforum so please feel free to move it.

I am using the SAMD21 microcontroller and need to use the hardware timer interrupt. For convenience, I am using this library.

I have tested a very basic example - just printing out micros() value. This works perfectly in my function at 100 microsecond interrupt duration.

However, in my substantive code which is considerably more complex it doesn't seem to work properly. The timer does trigger but at 10x or 100x more slowly.

I cannot figure out why. Things I have thought about:

  • Length of the interrupt function. This is only 25 microseconds so shouldn't cause any overlapping issues.
  • Functions in the main loop. There is some code in the main loop but this only triggers very infrequently and the problem occurs before it is triggered.
  • I am using a WiFi module but not calling any wifi functions during the interrupt function (the code collects sensor values and then sends via wifi).
  • I wondered if printing out using Serial was causing problems but I don't think so given my basic test code where it worked fine.

The below is the printout of micros() called at the start of each interrupt. You can see this is orders of magnitude greater than 100 microseconds.

17594076 us
17604076 us
17614076 us
17624076 us
17634076 us
17644076 us

Does anyone have any ideas about what is going wrong? I can post my code if that would help (approx 300 lines).

Thanks

Hi @sbaratheon

Which SAMD_TimerInterrupt function are you calling, to set up the interrupt period?

Hi @MartinL

In the linked library I am using the attachInterrupt function. My code reads as follows:

            // attach the sampling ISR
            if (ITimer.attachInterrupt(SAMPLE_FREQ_MICROSEC, ISR_sample)){
                Serial.println("Attached sampling ISR");
            }
            else{
                Serial.println("Failed to attach sampling ISR");
            }

where SAMPLE_FREQ_MICROSEC is defined as 100. There is also attachInterrupt_MS function in the library but Im pretty sure this is for milliseconds (the library's documentation isn't great).

Edit: Also the ITimer object is declared globally as:

SAMDTimer ITimer(TIMER_TC3); // used for hardware interrupts

Hi @sbaratheon

Taking a look at the library code, I think that the attachInterrupt() function's first parameter takes a frequency in Hz.

100Hz is equivalent to a period of 10000µs, which is period you're seeing on your output.

@sbaratheon

To pass the interval in microseconds (µs) as an argument, I believe requires the attachInterruptInterval() function instead.

@MartinL

Ah, this is very embarrassing! Many thanks. Looks much better now:

17964309 us
17964469 us
17964628 us
17964856 us
17964045 us
17964230 us
17964393 us
17964549 us

Any idea why it isn't exactly 100 microseconds? I am printing micros() at the very start of the interrupt. Does the interrupt timer only reset at the end of the interrupt function?

Don't even try to print from within an ISR. On many processors, that causes a system crash.

Store the value of micros() in a global variable and print that in the main loop.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.