[SOLVED] How to correctly use millis() for delay

Hello, I'm wondering if i'm doing this right. I'm trying to use the millis() function to delay another function precisely. I want to know if I'm declaring the variables right, if I'm fetching the potentiometer value right and if I really need floating points to do this.

Here's my code:

uint16_t delayTime = 1000;
uint64_t time;

void setup(){

}

void loop() {
    while (millis() < time + analogRead(pot) * (delayTime / 1023)) {}
    thatOtherFunction();
    time = millis();
}

I would greatly appreciate your help!

─ ArduMasterPro44 ─

Try to avoid the use of while( ) loops as they are blocking.

Search this site for non-blocking TIMER, or BWD.

example:


    //****************************************               h e a r t b e a t L E D   T I M E R
    //is it time to toggle the heartbeatLED ?
    if (millis() - heartbeatMillis >= 500)
    {
      //restart this TIMER
      heartbeatMillis = millis();

      //Toggle the heartbeatLED
      digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
    }

But that's what I want, I want it to wait until the time is appropriate.

The example attached above is non blocking and still makes the LED function at the appropriate time that it is supposed to.

Are you suggesting like this:

uint16_t delayTime = 1000;
uint64_t time;

void setup(){

}

void loop() {
    if (millis() >= time + analogRead(pot) * (delayTime / 1023)) {
      thatOtherFunction();
    }
    time = millis();
}

You're missing the point, using millis() correctly allows you to wait until the time is appropriate while freeing up the processor to do other things. Using while() like that you might as well just use delay(), you've just re-created delay() in a different way.

This: Flashing multiple LEDs at the same time
Shows you several different ways to use millis() to flash LEDs while leaving the processor free to do other things. Follow the example that makes most sense to you.


uint16_t delayTime = 1000;
uint64_t time;

void setup()
{

}

void loop() 
{
    if (millis() - time >= analogRead(pot) * (delayTime / 1023)) 
    {
      //restart this TIMER
      time = millis();

      thatOtherFunction();
    }

}

Make sure this does what you think it does


analogRead(pot) * (delayTime / 1023)

Could I also do it like this:

uint16_t delayTime = 1000;
uint64_t time;

void setup()
{

}

void loop() 
{
    if (millis() - time >= analogRead(pot) * (delayTime / 1023)) 
    {
      
      thatOtherFunction();

      //restart this TIMER
      time = millis();
    }

}

analogRead(pot) * (delayTime / 1023) converts a potentiometer reading to a 0 - 1000 value. Also, another thing that I want to know, is if I would need floating points to do it?

That should work the same.


Floating point is not needed.

uint64_t time; goes up to 4 billion milli seconds


The same method can time events in days, weeks . . .

What happens when you try?

My habit is to always put the

time = millis();

bit right after the if() bit.
It doesn't matter, but be consistent so you always know where to look for it in your code.

I just realised that I need a blocking Timer because it is in a for loop which is after that in the void loop!

This doesn’t make sense.

Because it runs a certain amount of times and if it skips a go because of the non-blocking timer, it will skip some instructions.

I'm seeing the proof right now!

You absolutely do not, ever, need a blocking timer. Never, ever ever. Ever. No.

Put the code that needs to run at a certain time into a new function then call that function from the timer.

We need to see what you are referring to comment.

99.9% of the time, you do not need to use blocking code.

Only in an instance where you need tight timing in micro seconds.

So it goes more like this:

uint16_t delayTime = 1000;
uint64_t time;

void setup()
{

}

void loop() 
{
  for (uint8_t i = 0; i < 8; i++){
    if (millis() - time >= analogRead(pot) * (delayTime / 1023)) 
    {
      
      thatOtherFunction();

      //restart this TIMER
      time = millis();
    }
  }
}

That example is an aberration.

We need more information.

look this over

const byte PinPot = A0;

const unsigned long MaxDelay = 10000;
      unsigned long msecLst;
      unsigned long msec;

void
action (
    int val)
{
    Serial.print   ("action: ");
    Serial.println (val);
}

void loop() {
    int pot = analogRead (PinPot);
    unsigned long msec = millis ();
    if (msec - msecLst >= MaxDelay * pot / 1024)  {
        action (pot);
        msecLst = msec;
    }
}

void setup(){
    Serial.begin (9600);
}

The result of that division is zero.

Also, where did you come up with the magic number 1023?