Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

micros() rollover does not work for computing delta times. #25

Open
KurtE opened this issue Dec 26, 2024 · 1 comment
Open

micros() rollover does not work for computing delta times. #25

KurtE opened this issue Dec 26, 2024 · 1 comment

Comments

@KurtE
Copy link

KurtE commented Dec 26, 2024

Describe the bug
There is a lot of code, that tries to compute how much time has expired using code like:

uint32_t start_time = micros();
<do something>
uint32_t delta_time = micros() - start_time;

This is not working correctly when the micros rolls over. i.e. the call to micros() returns a smaller number than the previous call.

Example sketch

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial && millis() < 5000) {}
  Serial.println("\nTest millis and Micros");
  Serial.println(micros());

}

void loop() {
  unsigned long start_us = micros();
  unsigned long start_ms = millis();
  delay(1000); 

  unsigned long end_us = micros();
  unsigned long end_ms = millis();

  unsigned long delta_us = end_us - start_us;
  unsigned long delta_ms = end_ms - start_ms;

  Serial.print("US: ");
  Serial.print(start_us);
  Serial.print(" ");
  Serial.print(end_us);
  Serial.print(" ");
  Serial.print(delta_us);

  Serial.print("\tMS: ");
  Serial.print(start_ms);
  Serial.print(" ");
  Serial.print(end_ms);
  Serial.print(" ");
  Serial.println(delta_ms);

  if (Serial.available()) {
    Serial.println("Paused");
    while (Serial.read() != -1) {}
    while (Serial.read() == -1) {}
    while (Serial.read() != -1) {}
  }
}

Output from the sketch:

Test millis and Micros
1619447
US: 1619450 2619503 1000053	MS: 1619 2619 1000
US: 2619555 3619603 1000048	MS: 2619 3619 1000
US: 3619632 4619702 1000070	MS: 3619 4619 1000
US: 4619732 5619802 1000070	MS: 4619 5619 1000
US: 5619832 6619902 1000070	MS: 5619 6619 1000
US: 6619933 7620002 1000069	MS: 6619 7620 1001
US: 7620032 8620102 1000070	MS: 7620 8620 1000
US: 8620154 672354 4287019496	MS: 8620 9620 1000
US: 672384 1672454 1000070	MS: 9620 10620 1000
US: 1672484 2672554 1000070	MS: 10620 11620 1000
US: 2672584 3672654 1000070	MS: 11620 12620 1000
US: 3672705 4672754 1000049	MS: 12620 13620 1000
US: 4672784 5672854 1000070	MS: 13620 14620 1000
US: 5672883 6672954 1000071	MS: 14620 15620 1000
US: 6672983 7673054 1000071	MS: 15620 16620 1000
US: 7673084 8673154 1000070	MS: 16620 17621 1001
US: 8673184 725405 4287019517	MS: 17621 18621 1000
US: 725457 1725505 1000048	MS: 18621 19621 1000
US: 1725535 2725605 1000070	MS: 19621 20621 1000
US: 2725657 3725705 1000048	MS: 20621 21621 1000
US: 3725735 4725805 1000070	MS: 21621 22621 1000
US: 4725835 5725905 1000070	MS: 22621 23621 1000
US: 5725935 6726005 1000070	MS: 23621 24621 1000
US: 6726057 7726105 1000048	MS: 24621 25621 1000
US: 7726135 8726205 1000070	MS: 25621 26621 1000
US: 8726235 778457 4287019518	MS: 26621 27622 1001
US: 778487 1778557 1000070	MS: 27622 28622 1000
Paused

Notice the lines like: US: 8620154 672354 4287019496

Additional context
I have not waited long enough on millis() to know if it has similar issue or not.

@KurtE
Copy link
Author

KurtE commented Dec 26, 2024

Some more quick comments on the micros:
I ran a simple loop()

void loop() {
  uint32_t millis_start = millis();
  uint32_t usPrev = 0;
  uint32_t us;

  while ((us = micros()) >= usPrev) {
    usPrev = us;
  }
  uint32_t delta_ms = millis() - millis_start;
  Serial.print(us);
  Serial.print(" ");
  Serial.print(usPrev);
  Serial.print(" ");
  Serial.println(delta_ms);
}

And the rollover is about every 9 seconds.

0 8947848 7282
0 8947848 8948
0 8947848 8948
0 8947848 8948
0 8947848 8948
0 8947848 8948

Guessing, that the micros is rolling over at when some internal value goes to a max 32 bit value of: 4294967295
and dividing it by something:

4294967295 / 8947848 = 480.0000284984725 guessing clock speed in MHZ.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant