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

delay_until #1

Open
sinurb opened this issue Jan 23, 2018 · 3 comments
Open

delay_until #1

sinurb opened this issue Jan 23, 2018 · 3 comments

Comments

@sinurb
Copy link

sinurb commented Jan 23, 2018

Hi,

What does the delay_until do? And why did you use "5" as argument?

Thanks

@trainman419
Copy link
Owner

unsigned long t = 0;

void delay_until(unsigned long ms) {
  unsigned long end = t + (1000 * ms);
  unsigned long d = end - micros();

  // crazy long delay; probably negative wrap-around
  // just return
  if ( d > 1000000 ) {
    t = micros();
    return;
  }
  
  if (d > 15000) {
    unsigned long d2 = (d-15000)/1000;
    delay(d2);
    d = end - micros();
  }
  delayMicroseconds(d);
  t = end;
}

delay_until() and the associated global t is used to wait the specified amount of time since the previous call to delay_until(). This allows me to run the same sequence of code on a schedule, even if individual function calls take a slightly different amount of time each time.

The argument to delay_until is the number of milliseconds to delay (since the previous call to delay_until)

For example, if I have a function foo() that takes 1-2 milliseconds to execute, if I my loop is:

void loop() {
    foo(); // 1-2 mS
    delay(5); // 5 mS
}

The total loop time will be between 6 and 7 milliseconds, instead of the desired 5 milliseconds. Since I cannot predict exactly how long foo() will take, I cannot just adjust the delay.

With delay_until(), this loop always takes 5 milliseconds:

void loop() {
    foo(); // 1-2 mS
    delay_until(5); // wait until 5mS have passed
}

This is particularly important for LIN because the protocol requires that the first set of messages be sent every 5 milliseconds (5mS * 10 messages = 50 mS), and the entire set of messages repeats every 200mS, so at the end of the loop I delay for the remaining 150mS:

bekant/bekant.ino

Lines 264 to 265 in f3733f8

// Wait the remaining 150 ms in the cycle
delay_until(150);

Again, the important thing to note here is that if I used a normal delay() between messages or at the end of the main loop, the amount of time that it takes to handle WiFi clients would increase the loop time, and the other LIN devices would probably time out.

@sinurb
Copy link
Author

sinurb commented Jan 23, 2018 via email

@trainman419
Copy link
Owner

The 5mS and 200mS loop rates are for this specific application. I measured these timings with my oscilloscope when I was reverse-engineering the protocol for the desk.

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

2 participants