user62646: I have this code:


The output looks like this:

Why are there non-periodically some extremely large values?
Thanks

user60070: There are be several "tasks" and interrupts that run in the background and they influence how often the loop() function is called.
For example timer, usart ...
They all need some attention from time to time. If the need some really fixed execution time you must use something like a hardware timer.
and by the way: a maximum of ~1.1ms is not bad for such a small controller. :-)
And as a addition to your question in your comments: I don't think there is a way to make the loop faster. As long as you need the other tasks, you have do give them some time.

user7508: As explained by theSealion in his answer, this may be due to the
different background tasks performed by the microcontroller. However, I
personally find that 1 ms looks excessive. My guess is that the
main culprit is the USB stack pushing all those bytes down the wire.
In order to check this, I wrote the following program. It measures a
histogram of the loop execution times and then prints it through the
serial port. Since the data is only printed after the measurements are
done, the serial port does not do any work while the timings are being
measured.
const int HISTOGRAM_LENGTH = 512;

uint16_t histogram[HISTOGRAM_LENGTH];

void print_histogram() {
    Serial.println(F("t (us)  count"));
    Serial.println(F("-------------"));
    for (int i = 0; i < HISTOGRAM_LENGTH; i++) {
        if (histogram[i] == 0) continue;  // skip zeros
        Serial.print(i * 4);
        Serial.print('\t');
        Serial.println(histogram[i]);
    }
    Serial.println(F("-------------"));
    Serial.flush();
}

void setup() {
    Serial.begin(9600);
}

void loop() {
    static uint32_t last_time;
    uint32_t now = micros();
    uint32_t dt = now - last_time;
    uint32_t bin = dt / 4;  // resolution of micros() is 4 us
    if (bin >= HISTOGRAM_LENGTH)
        bin = HISTOGRAM_LENGTH - 1;
    if (++histogram[bin] == UINT16_MAX) {
        print_histogram();
        exit(0);
    }
    last_time = now;
}

These are the results when run on an Arduino Uno:
t (us)  count
-------------
8       21888
12      65535
16      632
20      323
56      1
-------------

This shows that most loop iterations take 8–12 µs. Those iterations
that were interrupted took 16–20 µs. The outlier at 56 µs is
most likely the time between the program starting and the very first
iteration of loop().
Here, the only interrupt source that affects the measurements is the
timer interrupt. It fired exactly 955 times during the measurement
period, which is consistent with the number of samples recorded at
16–20 µs. We can see from this data that the timer interrupt takes
roughly 8 µs to run, which is quite reasonable. Again, I would not
consider a 1 ms delay as reasonable.

62646: <p>I have this code:</p>

<p><a href="https://i.stack.imgur.com/p0XtM.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/p0XtM.png" alt="enter image description here"></a></p>

<hr>

<p>The output looks like this:</p>

<p><a href="https://i.stack.imgur.com/mGbnf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mGbnf.png" alt="output"></a></p>

<p>Why are there non-periodically some extremely large values?</p>

<p>Thanks</p>
 60070: <p>There are be several "tasks" and interrupts that run in the background and they influence how often the loop() function is called.</p>

<p>For example timer, usart ...</p>

<p>They all need some attention from time to time. If the need some really fixed execution time you must use something like a hardware timer.</p>

<p>and by the way: a maximum of ~1.1ms is not bad for such a small controller. :-)</p>

<p>And as a addition to your question in your comments: I don't think there is a way to make the loop faster. As long as you need the other tasks, you have do give them some time.</p>
 7508: <p>As explained by theSealion in his answer, this may be due to the
different background tasks performed by the microcontroller. However, I
personally find that 1&nbsp;ms looks excessive. My guess is that the
main culprit is the USB stack pushing all those bytes down the wire.</p>

<p>In order to check this, I wrote the following program. It measures a
histogram of the loop execution times and then prints it through the
serial port. Since the data is only printed <em>after</em> the measurements are
done, the serial port does not do any work while the timings are being
measured.</p>

<pre class="lang-cpp prettyprint-override"><code>const int HISTOGRAM_LENGTH = 512;

uint16_t histogram[HISTOGRAM_LENGTH];

void print_histogram() {
    Serial.println(F("t (us)  count"));
    Serial.println(F("-------------"));
    for (int i = 0; i &lt; HISTOGRAM_LENGTH; i++) {
        if (histogram[i] == 0) continue;  // skip zeros
        Serial.print(i * 4);
        Serial.print('\t');
        Serial.println(histogram[i]);
    }
    Serial.println(F("-------------"));
    Serial.flush();
}

void setup() {
    Serial.begin(9600);
}

void loop() {
    static uint32_t last_time;
    uint32_t now = micros();
    uint32_t dt = now - last_time;
    uint32_t bin = dt / 4;  // resolution of micros() is 4 us
    if (bin &gt;= HISTOGRAM_LENGTH)
        bin = HISTOGRAM_LENGTH - 1;
    if (++histogram[bin] == UINT16_MAX) {
        print_histogram();
        exit(0);
    }
    last_time = now;
}
</code></pre>

<p>These are the results when run on an Arduino Uno:</p>

<pre><code>t (us)  count
-------------
8       21888
12      65535
16      632
20      323
56      1
-------------
</code></pre>

<p>This shows that most loop iterations take 8–12&nbsp;µs. Those iterations
that were interrupted took 16–20&nbsp;µs. The outlier at 56&nbsp;µs is
most likely the time between the program starting and the very first
iteration of <code>loop()</code>.</p>

<p>Here, the only interrupt source that affects the measurements is the
timer interrupt. It fired exactly 955&nbsp;times during the measurement
period, which is consistent with the number of samples recorded at
16–20&nbsp;µs. We can see from this data that the timer interrupt takes
roughly 8&nbsp;µs to run, which is quite reasonable. Again, I would not
consider a 1&nbsp;ms delay as reasonable.</p>
