Olaf van der Kaa
Olaf van der Kaa

Reputation: 53

Arduino - millis() - value getting value of other variable

i am trying to have a function fire every x amount without blocking the main loop, i saw some example code to do this, see code below:

// Interval is how long we wait
// add const if this should never change
int interval=1000;
// Tracks the time since last event fired
unsigned long previousMillis=0;


void loop() { 
  // Get snapshot of time
  unsigned long currentMillis = millis();

  Serial.print("TIMING: ");
  Serial.print(currentMillis);
  Serial.print(" - ");
  Serial.print(previousMillis);
  Serial.print(" (");
  Serial.print((unsigned long)(currentMillis - previousMillis));
  Serial.print(") >= ");
  Serial.println(interval);

  if ((unsigned long)(currentMillis - previousMillis) >= interval) {
      previousMillis = currentMillis;
  }

}

Now the following happens:

TIMING: 3076 - 2067 (1009) >= 1000
TIMING: 4080 - 3076 (1004) >= 1000
TIMING: 5084 - 4080 (1004) >= 1000
TIMING: 6087 - 5084 (1003) >= 1000
TIMING: 7091 - 6087 (1004) >= 1000

Why is the currentMillis getting so much higher every loop? It looks like it is sharing a pointer or something like that, because it adds the interval value everytime. I am confused!

Upvotes: 2

Views: 501

Answers (2)

zmo
zmo

Reputation: 24812

To expand on @patrick-trentin's answer, it's looking very likely that your code is not the only thing you run on your Arduino. The code you see in your sketches is never the only code that the arduino runs. It handles for you the Serial data incoming, and if you use some other modules (like SPI or network) it's having some other code that runs in ISP, which are functions run regularly using a timer.

But the arduino CPU cannot run code in parallel. To mimic parallel behaviour, it's actually stopping your main loop, to run a subroutine (the ISP), which will read a byte coming in through Serial (for example), buffer it to then make it available to you using a nice method on the Serial object.

So the more things you do in those interrupt based subroutines, the less often you'll iterate your main loop, having it pass less often over the millis() comparaison you do.

Upvotes: 2

Patrick Trentin
Patrick Trentin

Reputation: 7342

I think that the code you presented us is an incomplete picture of what you have uploaded on the Arduino, since on my device I obtain the following sequence

TIMING: 0 - 0 (0) >= 1000
TIMING: 0 - 0 (0) >= 1000
TIMING: 1 - 0 (1) >= 1000
TIMING: 32 - 0 (32) >= 1000
TIMING: 93 - 0 (93) >= 1000
TIMING: 153 - 0 (153) >= 1000
TIMING: 218 - 0 (218) >= 1000
TIMING: 283 - 0 (283) >= 1000
TIMING: 348 - 0 (348) >= 1000
TIMING: 412 - 0 (412) >= 1000
TIMING: 477 - 0 (477) >= 1000
TIMING: 541 - 0 (541) >= 1000
TIMING: 606 - 0 (606) >= 1000
TIMING: 670 - 0 (670) >= 1000
TIMING: 735 - 0 (735) >= 1000
TIMING: 799 - 0 (799) >= 1000
TIMING: 865 - 0 (865) >= 1000
TIMING: 929 - 0 (929) >= 1000
TIMING: 994 - 0 (994) >= 1000
TIMING: 1058 - 0 (1058) >= 1000
TIMING: 1127 - 1058 (69) >= 1000
TIMING: 1198 - 1058 (140) >= 1000
TIMING: 1271 - 1058 (213) >= 1000
TIMING: 1344 - 1058 (286) >= 1000

and it sounds correct given the code you provided.


Are you sure there isn't any sleep() call in your original source code?

(perhaps you didn't upload the updated code on the device?)

Upvotes: 3

Related Questions