Timer interrupt (precision)

hey,

I'm using a timer interrupt on my adafruit feather m0 (with ATSAMD21G18 @ 48MHz). My code ist based on this version SAMD21 Arduino Timer Example · GitHub. My code: see appendix "timerInterrupt_A6.ino"

In order to get to know the real timer interrupt frequency I added some time recording via micros().

Looking at this time data one can see that the frequency, at which the timer interrupt works, is pretty unstable. I added some evaluation grafics done with matlab (see appendix "timer interrupt").
The frequency is calculated by this little sketch:

t_0 = t_raw(start:stop,1) - t_raw(start,1);
for i = 1:length(t_0)-1
    T_sample(i,1) = (t_0(i+1) - t_0(i));
end
T_sec = T_sample./1000000;
f = 1./T_sec;

Do you know what could be the reason of this unstable frequency? Is it just the precision of micros()?

Second issue is the fact, that the adjusted frequency (of 10kHz) for the timer interrupt differs quite a lot from the acutal (reached) frequncy, which is about 9375Hz. What could be the reason?

Thanks!

timerInterrupt_A6.ino (5.3 KB)

micros()

On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution of eight microseconds.

I've no idea what precision it has on Adafruit Feather M0 (with ATSAMD21G18 @ 48MHz).

10kHz = 100us

What is the actual fluctuation of recorded micros() values?
Minimum value and maximum value recorded?

pcbbc:
micros()
I've no idea what precision it has on Adafruit Feather M0 (with ATSAMD21G18 @ 48MHz).

10kHz = 100us

What is the actual fluctuation of recorded micros() values?
Minimum value and maximum value recorded?

Thanks for your response!

In most of the cases the time between two interrupts vary between 104 and 108 microseconds.

pcbbc:
10kHz = 100us

10kHz = 1/100us

PerryBebbington:
10kHz = 1/100us

Err no.

1 s / 10k = 0.0001 s = 0.1ms = 100us

@ottooo:
104 and 108 doesn't seem unreasonable to me if the micros() granularity is 4ms.

pcbbc:
@ottooo:
104 and 108 doesn't seem unreasonable to me if the micros() granularity is 4ms.

Again, thanks for your response!

Is there any proof (just to be safe), that the micros() granularity is 4ms for the ATSAMD21G18 @ 48MHz? Since your original post was related to 16 MHz Arduino boards.

ottooo:
Is there any proof (just to be safe), that the micros() granularity is 4ms for the ATSAMD21G18 @ 48MHz? Since your original post was related to 16 MHz Arduino boards.

I don't have any. Just guessing based on your 104/108 values which are multiples of 4.
No doubt the info is out the somewhere, or by looking at the core libraries. But I don't have the time to investigate myself - Sorry.

Write sketch that repeatedly reads two values of micros() and compares them.
If there's a difference, output it.
See what values you get out.
If you only output the difference if it less than the previous difference, this should give you a lower bound on clock granularity.

If it's 4 you have your answer.

pcbbc:
Err no.

1 s / 10k = 0.0001 s = 0.1ms = 100us

@ottooo:
104 and 108 doesn't seem unreasonable to me if the micros() granularity is 4ms.

:slight_smile:
I'm on holiday, too much wine :slight_smile:
(OK, so there is no such thing as too much wine!)

10kHz = 1/100us looks correct to me. 10kHz = 100us doesn't; not even the same unit.

To quote MartinL: "The SAMD21's micros() function is based on the microcontroller's system ticker that has a resolution of 1µs."

ocrdu:
10kHz = 1/100us looks correct to me. 10kHz = 100us doesn't; not even the same unit.

This really doesn't go well with French wine :o

ocrdu:
10kHz = 1/100us looks correct to me. 10kHz = 100us doesn't; not even the same unit.

To quote MartinL: "The SAMD21's micros() function is based on the microcontroller's system ticker that has a resolution of 1µs."

Okay, at best it's ambiguous...
(1/100)us
1/(100 us)

Probably I shouldn't have used equals.

pcbbc:
Write sketch that repeatedly reads two values of micros() and compares them.

That's it. Thanks!

It was
t1 = micros();
t2 = micros();

t1-t2 = [4 3 4 4 3 4 4..]

So I think there is no real granularity, it's more a low accuracy of micros()

It's documented for heaven's sake. In the second sentence.