(Yet another) millis replacing delay confusion

I really have read (and reread) many explanations, tutorials and forum threads on this and I just get stuck at one thing:

If I use millis as a replacement for delay (that is, I just need to pause the program for 2 seconds, in my case, to wait until the wifi client connects), how do I do that with millis?

Specifically, if I use a greater than comparison between actual elapsed time with a desired amount of elapsed time (e.g., 2 seconds), and the comparison fails (i.e., 2 seconds has not yet elapsed), the program continues on to the next lines in loop. This is not what I want to happen. I want the program to just wait a couple of seconds.

How would I do that?

Thank you!

I want the program to just wait a couple of seconds.

Then use delay()

You could use a while loop that waits until millis() increases by the desired amount, but that would not provide any advantage over delay() unless you want to do something else during the waiting period

This is a demonstration of what UKHeliBob said.

unsigned long last_time, now_time;

void setup()
{
  Serial.begin(115200);
  last_time = millis();
}

void loop()
{
  now_time = millis();
  if (now_time - last_time >= 2000)
  {
    // anything placed in here runs once every 2 seconds
    Serial.println("2 Sec");
    last_time = now_time;
  }

  // anything placed here runs on every loop
}

If I use millis as a replacement for delay (that is, I just need to pause the program for 2 seconds, in my case, to wait until the wifi client connects), how do I do that with millis?

Am I correct to assume you mean as part of setup()? Delay is ok in setup as it is only waiting once for things that never happen again, so it does not get in the way of the general running of the code.

Here is some wifi set up code I used with an ESP8266:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define STASSID "YourSSID"
#define STAPSK  "YourPassword"
const char * ssid = STASSID;
const char * pass = STAPSK;
void setup_wifi() {
  uint8_t wait = 0;
  while (WiFi.status() != WL_CONNECTED) {
    if (wait) {
      --wait;
    }
    else {
      wait = 40;
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, pass);
    }
    delay(500);
    display.setCursor(0,0);
    display.clearDisplay();
    display.print(wait);
    display.display();
  }
}

The display in this case is an OLED, but you can replace the display prints with whatever you need, such as prints to the serial monitor or whatever you have.

UKHeliBob: Then use delay()

You could use a while loop that waits until millis() increases by the desired amount, but that would not provide any advantage over delay() unless you want to do something else during the waiting period

Everywhere I read I am advised to not use delay, so I was trying to improve my code and learn.

But, if delay in my case is the smartest way to go (and happens to be the easiest), then I'm fine with that.

I also explored the while loop, but my understanding is that a while-millis loop is no better than delay as far as the blocking nature, except insofar as other things can be done within the while loop (which would not then serve as a simple waiting (delay) period. Correct (or am I as confused as I think I am)?

Thank you!

I also explored the while loop, but my understanding is that a while-millis loop is no better than delay as far as the blocking nature, except insofar as other things can be done within the while loop (which would not then serve as a simple waiting (delay) period. Correct (or am I as confused as I think I am)?

Your understanding is correct

As far as delay() [u]always[/u] being a bad idea, that is not true, as in the case of your stated requirement

Everywhere I read I am advised to not use delay, so I was trying to improve my code and learn.

Yes, and the advice is good. I wish delay() wasn’t in the tutorials but it is. Mostly I hate delay() because of the number of times I see questions on here along the lines of “why is my code slow and unresponsive?” The answer being that the code is full of delays everywhere. The problem is that a little bit of delay() often doesn’t cause a problem in a simple program, so people get used to using it. Then they write something complex and delay() completely screws it up. In general I discourage using delay(), as you will see if you read some of my posts, however, in a few very limited situations is it OK. It’s OK in setup().

Is there any other advice you want about delay? I generally point people at these 2 tutorials (there are others if you search)
Using millis for timing
Demonstration for several things at the same time
Apologies if you are already aware of those.

OTOH if what you have is a simple requirement there is really no point in messing with the additional complexities of millis() timing. I have a number of projects I built for people which needed nothing other than delay() and other blocking methods and which are working really well for them!

It certainly is worth learning about millis() because there are many times when non-blocking code will be necessary when/if you move on to more complex systems. But it is pointless to dismiss the simpler alternatives just because they might not work well for some other programs in your maybe distant future.

I've been doing this stuff for a while but I still get confused every time I need to code what should be a simple for loop in a non-blocking fashion. But that's probably just me getting old.

Steve

PickyBiker: This is a demonstration of what UKHeliBob said.

unsigned long last_time, now_time;

void setup() {  Serial.begin(115200);  last_time = millis(); }

void loop() {  now_time = millis();  if (now_time - last_time >= 2000)  {    // anything placed in here runs once every 2 seconds    Serial.println("2 Sec");    last_time = now_time;  }

 // anything placed here runs on every loop }

Thank you for this example. I think I understand that this code checks if 2 seconds has passed and if so, executed the code in the first remarks line. Otherwise, executed the code in the second remarks line and continues on to any code that follows within loop().

PerryBebbington: Yes, and the advice is good. I wish delay() wasn't in the tutorials but it is. Mostly I hate delay() because of the number of times I see questions on here along the lines of "why is my code slow and unresponsive?" The answer being that the code is full of delays everywhere. The problem is that a little bit of delay() often doesn't cause a problem in a simple program, so people get used to using it. Then they write something complex and delay() completely screws it up. In general I discourage using delay(), as you will see if you read some of my posts, however, in a few very limited situations is it OK. It's OK in setup().

Is there any other advice you want about delay? I generally point people at these 2 tutorials (there are others if you search) Using millis for timing Demonstration for several things at the same time Apologies if you are already aware of those.

I have indeed seen these tutorials -- and very much appreciate pointing them out to me nonetheless.

I have read other posts of yours (and other very knowledgeable people here). Funny (in a sad kind of way) that the solution to making one's code faster is to remove delays.

I'm going to stick with the couple of delays in my code, as all here have indicated it's just fine (possibly even the best way) in my case.

Thank you!

UKHeliBob: Your understanding is correct

As far as delay() [u]always[/u] being a bad idea, that is not true, as in the case of your stated requirement

Thank you for the confirmation of my understand and for confirming that delay is not always a bad idea -- I know it's weird but it was a subtle nag on me that my code could be better (which I'm sure it can be, but in ways I don't yet know about).

slipstick: OTOH if what you have is a simple requirement there is really no point in messing with the additional complexities of millis() timing. I have a number of projects I built for people which needed nothing other than delay() and other blocking methods and which are working really well for them!

It certainly is worth learning about millis() because there are many times when non-blocking code will be necessary when/if you move on to more complex systems. But it is pointless to dismiss the simpler alternatives just because they might not work well for some other programs in your maybe distant future.

I've been doing this stuff for a while but I still get confused every time I need to code what should be a simple for loop in a non-blocking fashion. But that's probably just me getting old.

Steve

That is great advice -- Thank you!

I do want to learn, but I am much better at it in a goal-oriented, problem-solving situation.

Thanks for sharing about the confusion -- I'm feeling it more and more also.

I know it's weird but it was a subtle nag on me that my code could be better

Your code could be better. My code could be better. I doubt there is any who's code could not be better.

In a year or so look at the code you wrote today and you will be amazed at how many things you can see that 'obviously' (obvious in a year's time, not obvious now) could be improved.