Best emtpy loop()

Hello.

I'm a bit experienced programmer, but this is my first Arduino project. I've created a Arduino program just with timer events. I don't need the "void loop(){..}". But the compiler requires one. How to fill the loop function best so it won't disturb the running program? Leave it empty? AFAIK will this lead this to an repeated call of this function (The explanation I found everywhere is, that the main of Arduino looks like "this: for (;;) loop();" ). I've add a "delay(100000);" in the loop hoping this will put the CPU to sleep - not wasting energy.

Is there a better solution? I searched for it but I did not found anything near this question. Maybe my Google Fu is not good enough?

delay(anything); does not put the processor to sleep. Sleep libraries are available for most types of MCUs.

Since the loop function is required, most people do this:

void loop () {}

1 Like

So all your code is in the setup function and it never exits. In that case simply use the

void loop() {}

IF that is not the situation, post your code in code tags so we can see it.

No.

Presumably setup(), um, sets up all these alleged timer events; there must be code that handles them.

Which code I would love to read.

a7

The compiler will see an empty function and remove it / optimize it to minimal code

Which board is this ? If it is for example an RTOS board (ESP32 etc.) then you can disable the loop() task or simply put a small delay of a few milliseconds in it.

Thanks for all of your answers. But this raises questions...

@alto777: I'm glad to share the code - but first when my project is finished. The HW wirering is complete, but neither the software (As everybody knows: Experimental code is nothing to show.. :slight_smile: ) nor the positioning of all of the modules, etc.

Hmm. Than: what is the program doing? Nothing? This is what I want.

As far as I see a cheap copy of an mini pro. Can you tell my how to disable? Then I can read the manual and maybe got other ideas. The Idea with delay .. I've done this.

Post a link to the product page.

The Arduino IDE (and its predecessor "Processing") are made for simplicity of programming.

In (most of) your projects you will (1) configure hardware, (2) configure software, and (3) run a program continuously. setup() allows you to configure hardware and software one time (runs once), and loop() allows you to continuously run your program (runs forever) without creating you own "loop".

I like to use setup() as a "run once" program to see specific items. I also call other functions from setup() so those other functions "run once" and do not "loop forever" in loop().

1 Like

That’s correct: When setup() completes, it calls loop(). loop() is recursive in that when it’s code is completed, it calls itself.

No it doesn't. It returns to main() which then calls loop() again.
If loop() called itself recursively, the program would soon crash due to running out of stack space.

5 Likes

I forgot about the built in main() function, thanks. So, main() calls setup() first and then loop()?

main.cpp for AVR boards:

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
	init();

	initVariant();

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

You could always leave loop() empty and end setup() with an endless loop of your own, such as

while (true);

So you are happy that we will only provide support when it is done.

4 Likes

You can define your own function main(), and it works. You will need to remember that millis(), micros(), pwm, ADC and more have not been set up.

1 Like

Just gonna say that. main is a weak symbol overridden by a strong definition at link time.

It’s marked as

_attribute_((weak))

(in GCC / AVR-GCC)

Just copy the existing main() and… don't call loop().

But… you still have to spin a wheel somewhere, and I don't see it mattering too much if you make such spinning one step different.

a7

What is your reason for wanting the processor to do "nothing"? Typically, we use interrupts sparingly, very few reasonable codes do all their work within the interrupts. Instead, flags are set or variables toyed with, and the code within loop() deals with the results.

I think a much more detailed description of your needs/intent is warranted.

The code to show is usually a minimal example that proves/disproves/illustrates the problem, error or stated goal. Such an example is inevitably experimental.

I doesn't. But most microcontrollers use so little power anyway, it is often not worth saving.

If your circuit is battery powered then you might want to absolutely minimise the power consumption to maximise the battery life. This isn't as easy as you might imagine, for example:

  • You have to choose the right board and use sleep libraries as mentioned already.
  • Many boards have a power led and other components on them, and these may use more power than the microcontroller itself, when it is in a sleep mode.
  • It's also possible that the battery's natural self-discharge rate is higher than the microcontroller's power consumption, so choice of battery is also important.