loop() speed ?

Does anybody know how fast the loop() function is running ? Is it based on a timer interrupt ?

Cheers!

It runs as fast as it can. So the less you do, the more often it will run. In the absence of any other instructions, roughly every microsecond.

No it's not based on a timer interrupt. loop() just gets called over and over nonstop. If you know C, the main routine looks more or less like this:

main() {
    setup();
    for (;;) {
        loop();
        }
    }

So the time loop() itself uses is the return statement at the end (2 bytes) plus the empty for loop takes 6 bytes …

==> so 8 bytes used in total, think that is done in 4 clock cycles => 1/4 microSecond.

I did a minimal sketch

volatile int i =0;
void setup(){}
void loop() { i++; }

Some raw dissasembly

C:\Users\Rob\AppData\Local\Temp\build1002766541878677201.tmp>"\Program Files (x86)\arduino-0022\hardware\tools\avr\bin\avr-objdump.exe" -S sketch_feb11a.cpp.o

Disassembly of section .text.setup:

00000000 <setup>:
   0:   08 95           ret

Disassembly of section .text.loop:

00000000 <loop>:
   0:   80 91 00 00     lds     r24, 0x0000
   4:   90 91 00 00     lds     r25, 0x0000
   8:   01 96           adiw    r24, 0x01       ; 1
   a:   90 93 00 00     sts     0x0000, r25
   e:   80 93 00 00     sts     0x0000, r24
  12:   08 95           ret

C:\Users\Rob\AppData\Local\Temp\build1002766541878677201.tmp>"\Program Files (x86)\arduino-0022\hardware\tools\avr\bin\avr-objdump.exe" -S main.cpp.o

int main(void)
{
        init();
   0:   0e 94 00 00     call    0       ; 0x0 <main>

        setup();
   4:   0e 94 00 00     call    0       ; 0x0 <main>

        for (;;)
                loop();
   8:   0e 94 00 00     call    0       ; 0x0 <main>
   c:   00 c0           rjmp    .+0             ; 0xe <__zero_reg__+0xd>

To call loop:

call   : 4 cycles
rjmp   : 2 cycles

Inside loop:

lds x 2: 4 cycles
sts x 2: 4 cycles
adiw   : 2 cycles
ret    : 4 cycles

Total: 20 cycles. Predicated time: 20 x 62.5 nS = 1.1250 uS.

It's not the "bytes used" it is the clock cycles from the data sheet.

PeterLuke: Does anybody know how fast the loop() function is running ? Is it based on a timer interrupt ?

It's not a useful thing to know, per se. As soon as you add instructions it will run more slowly. So you need to design so that the rate at which loop() is called is not particularly important.

Total: 20 cycles. Predicated time: 20 x 62.5 nS = 1.1250 uS.

But half of it are the i++ ==> so 10 cycles is the overhead of loop()

This raises the question if

loop() { // some functionality }

is faster/slower/equal

than

loop() { while(true) { // same functionality } }

:)

The “while” inside “loop” will be quicker because you save the RET and CALL but still have the RJMP.

However I should warn you that Version 1.0 of the IDE does a little extra:

#include <Arduino.h>

int main(void)
{
	init();

#if defined(USBCON)
	USB.attach();
#endif
	
	setup();    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}        
	return 0;
}

So if you don’t let loop() exit you miss out on serialEventRun. Perhaps that’s a good thing. Personally I don’t like extra function calls being added behind my back.

Yeah, it would be better to have a callback function, something like : Serial.attachIRQ( bool (*callback)(char c) );

(0.22) HardwareSerial.cpp - not tested !!

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  bool b = true; 
  if (callback != null) b = callback(c);
  if (b)
  {
    int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;

    // if we should be storing the received character into the location
    // just before the tail (meaning that the head would advance to the
    // current location of the tail), we're about to overflow the buffer
    // and so we don't write the character or advance the head.
    if (i != rx_buffer->tail) {
      rx_buffer->buffer[rx_buffer->head] = c;
      rx_buffer->head = i;
    } else rx_buffer->lost++;
  }
}

Then I would get the char c before it is entered in the queue and my returnvalue determins if it will be added to the rRX queue or not ...

This way you could implement out of band commands in a serial interface, e.g. an XON/XOFF protocol. But as said not tried yet...