11

I've noticed most example snippets always have a delay in the loop even if it's not needed for proper execution of the program.

I can only assume this is added because people copy and paste without understanding what's going on but it got me thinking if adding a delay could possible save power too.

If I have a loop that checks some inputs for changes could it be possible that adding a delay(10) saves some cycles and thus power?

gre_gor
  • 1,682
  • 4
  • 18
  • 28
Ryan Detzel
  • 305
  • 5
  • 10

7 Answers7

17

No, it burns energy by doing nothing.

You definitively should send your MCU to sleep and wake up on events or use the watchdog timer to wake up after a predefined period of time.

Kwasmich
  • 1,523
  • 12
  • 18
8

The delay function doesn't do anything special. It basically just counts down milliseconds inside a while loop and times it with micros().

void delay(unsigned long ms)
{
    uint32_t start = micros();

    while (ms > 0) {
        yield();
        while ( ms > 0 && (micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}
gre_gor
  • 1,682
  • 4
  • 18
  • 28
5

No, a short delay (up to 100 millis) is usually inserted in a void loop() when you are attached to an external sensor, in order to stabilize the readings. But it has nothing to do with power consumption. As an example, here are lines 49-52 from the example sketch "AnalogInSerialOut":

      // wait 2 milliseconds before the next loop
      // for the analog-to-digital converter to settle
      // after the last reading:
      delay(2);
Arducode
  • 51
  • 2
5

The answers above are wrong, at least for NodeMCU 0.9 (ESP-12 board) ESP8266 and I also tested with Firebeetle ESP8266 board. Since I have a USB tester I can check that if the loop method is empty, the boards consume about 70mA-80mA but during delay(ms) they consume about 20mA-30mA.

This is the delay function for the boards commented:

void __delay(unsigned long ms) {
    if(ms) {
        os_timer_setfn(&delay_timer, (os_timer_func_t*) &delay_end, 0);
        os_timer_arm(&delay_timer, ms, ONCE);
    } else {
        esp_schedule();
    }
    esp_yield();
    if(ms) {
        os_timer_disarm(&delay_timer);
    }
}

I have not investigate further why delay function saves so much power consumption.

MABC
  • 151
  • 1
  • 1
1

could it be possible that adding a delay(10) saves some cycles and thus power?

No, the delay() function just pauses the code for the time specified. It's stil running and consuming energy for counting the time and waiting it to finish.

If you need to conserve power, you could adjust your circuit components in a fashion that will save energy, or if you want to save energy on your Arduino, you could use a breadboard setup(Instructions here and here) or make use of the internal watchdog timer to sleep and wake at certain time intervals. More tutorial about watchdog timer is explained here.

Cheers!

EngrAbbas
  • 176
  • 1
  • 1
  • 11
1

I suspect the answer depends on the kind of Arduino you're using.

The ESP8266 is ARM based, and I believe ARM chips include power management circuits, where subsystems are automatically put in low power state when they are not being used. An ARM-based Arduino will likely use a lot less power while executing a delay than while doing other things.

I don't think AVR chips have any sort of power management, so they have all their silicon "lit up" at all times. That said, CMOS logic circuits do use more power when switching states than when idle, so even an AVR-based Arduino will probably use slightly less power while in a delay() function that it will when it's running instructions that use the arithmetic unit, UARTs, and other subsystems of the chip.

You'll get much better power savings by putting your Arduino into sleep mode.

Duncan C
  • 5,752
  • 3
  • 19
  • 30
1

As stated in previous answers, at least on the AVR version of the Arduino core, delay() is a busy wait that keeps the CPU running. In his answer, Duncan C correctly states that “CMOS logic circuits do use more power when switching states than when idle”. It is then expected that instructions that switch a large number of gates or flip-flops consume more power than instructions that only switch a few ones.

Out of curiosity, I disassembled a call to delay() to see what kind of instructions it executes. I found that the “hot path” is a loop that executes 44 instructions per iteration:

  • 23 of them do arithmetic or logic (add, subtract, compare, XOR)
  • 13 move data around (register load, register copy, I/O, read RAM)
  • 7 alter the program flow (function call, return, jump, conditional branches, conditional skip)
  • 1 alters a bit in a status register

I do not know how this compares with “typical” code, but the large proportion of instructions that do arithmetic and logic computations suggests that delay() should be way more energy hungry than, say, a long sequence of nop instructions. In the end, the only way to know for sure whether delay() changes anything to the power consumption of a specific program would be to measure it.

As a side note, an easy way to save some power on AVR boards is to #include <avr/sleep.h> and insert a call to sleep_mode() at the end of loop(). The sleep with not last for long though, as the Arduino core sets Timer 0 to interrupt the CPU every 1024 µs.

Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81