# Using mills correctly as a timer

**URL:** <https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064>\
**Category:** Programming\
**Created:** [March 5, 2022, 2:05pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064 "2022-03-05T14:05:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 5, 2022, 2:05pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/1 "2022-03-05T14:05:34Z")

</div>

I seems to be always asking questions, but I am trying to improve the methods I use in my programming

Timing. I tend to use millis() to time events in my main loop, however someone recently questioned my implementation and I would like advice on why my method is 'wrong' and a better way to achieve the same result.

Is there a library dedicated to simple millis() timing events? I will look.

An example of my method (typed from memory...)

```cpp
I will declare:

unsigned long PiezoBeep;

Just before the main loop:

PiezoBeep = millis();

**main loop:**

    if (millis() - PiezoBeep > 5000) {

      Freq = 800;
      Duration = 100;
      SFX ();
      PiezoBeep = millis();
    }

```

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 5, 2022, 2:10pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/2 "2022-03-05T14:10:04Z")

</div>

That looks OK as far as it goes but without a complete sketch there is no context

One small improvement would be to call millis() only once to get the current value at the start of loop() then use that value when needed rather than calling millis() multiple times

---

<div class="post-metadata">

**Author:** ![Coding\_Badly](https://avatars.discourse-cdn.com/v4/letter/c/f14d63/32.png) [@Coding\_Badly](https://forum.arduino.cc/u/Coding_Badly)\
**Post date:** [March 5, 2022, 2:29pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/3 "2022-03-05T14:29:40Z")

</div>

> [@phoneystark20201](#):
>
> Is there a library dedicated to simple millis() timing events?

There's this...

`#define runEvery(t) for (static uint16_t _lasttime; millis() - _lasttime >= (t); _lasttime += (t)) `

Used like this...

```cpp
void loop(void)
{
    runEvery(125) {
        Serial.println(F("125 ms tick"));
    }
}

```

> [@phoneystark20201](#):
>
> `if (millis() - PiezoBeep > 5000) {`

Make that greater than or equal.

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 5, 2022, 3:21pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/4 "2022-03-05T15:21:50Z")

</div>

Thanks

Does calling millis() multiple times incur a penalty then (memory wise), or is it just better practice.

I will try that other method Coding\_Badly and see how I get on

Thanks all

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 5, 2022, 4:16pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/5 "2022-03-05T16:16:23Z")

</div>

The compiler may well reduce the number of calls to millis() when optimising the code but it is good practice to do it explicitly

For one thing it removes the chance that the value may change between calls thus possibly producing inconsistent results. For another it means that you can use a meaningful name for the value such as currentTime so that you can write code that is easily understood such as

```cpp
if (currentTime - previousRunTime >= requiredPeriod)
{
  previousRunTime = currentTime;
  //time to do something
}

```

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 6, 2022, 2:04pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/6 "2022-03-06T14:04:20Z")

</div>

This is absolutely doing my head in.

I have a situation where I wish to trigger certain events in a timeline using millis();

I used the method I mentioned in my original post and it just does not want to work.  
Can someone advise on a better method. I don't know how to adjust that code in post 3 to be relevant to my requirements.

My code is horrific now... all over the place and I am starting again. I'll type out my base idea and you can tell me why it's terrible:

```cpp
uint8_t Event_1 = 15; // Event 1 trigger point in seconds                     
uint8_t Event_2 = 25; // Event 2 trigger point in seconds               
unsigned long Event_length; // millis timer of entire event   

void loop(void)
{

   do {} while (digitalRead(Button)); // Wait here for start button

   Event_length = millis();

  do{

     if ((millis() - Event_length) > (Event_1 * 100) { // Event 1 at 15 seconds
          // Do something
          break;
     }

  } while ((millis() - Event_length) < (30000);

  do{

     if ((millis() - Event_length) > (Event_2 * 100) { // Event 2 at 25 seconds
          // Do something
          break;
     }

   } while ((millis() - Event_length) < (30000);

}

```

This is an off the top of my head example, but how I have it laid out. I realise the do loop exit statements are a bit pointless.

My problem is the timing is all way off.  
Even if I change the uint8\_t statements to unsigned\_long, it still doesn't work (what is the uint statement for unsigned long?)

Feeling incredibly thick

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 6, 2022, 2:14pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/7 "2022-03-06T14:14:39Z")

</div>

static uint32\_t is unsigned long?

I had some Fastleds library commands in the main loop.... is that what is messing up my timing?

---

<div class="post-metadata">

**Author:** ![david\_2018](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/david_2018/32/1013044_2.png) [@david\_2018](https://forum.arduino.cc/u/david_2018)\
**Post date:** [March 6, 2022, 2:23pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/8 "2022-03-06T14:23:16Z")

</div>

The method you are using is no better than using delay()

FastLED will mess things up a bit, while sending data to the LEDs the millis interrupt is disabled. FastLED attempts to adjust for the lost millis count, but is not very precise.

The test code you posted works properly, but all the timed events are based off Event\_length, so Event\_1 will occur 1500mS later, then Event\_2 will occur (25 - 15) \* 100, or 1000mS after that. To get a 2500mS delay between Event\_1 and Event\_2 you would need to set Event\_length to millis() after Event\_1 completes.

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 6, 2022, 2:25pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/9 "2022-03-06T14:25:38Z")

</div>

Start by eliminating all of the do/while loops. You need the code to be free running and not blocked

An example

```cpp

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

void loop()
{
  unsigned long currentTime = millis();
  static unsigned long startTime1 = currentTime;
  static unsigned long startTime2 = currentTime;
  unsigned long period1 = 2000; //adjust to suit your needs
  unsigned long period2 = 2500;
  if (currentTime - startTime1 >= period1)
  {
    Serial.println("end of period 1");
    startTime1 = currentTime;
  }
  if (currentTime - startTime2 >= period2)
  {
    Serial.println("end of period 2");
    startTime2 = currentTime;
  }
}
```

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 6, 2022, 2:26pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/10 "2022-03-06T14:26:58Z")

</div>

No that is fine. I am taking into account the fact that they operate in real time based on Event\_length.

Event 1 is 15000ms isn't it? (you have 1500ms). So I entirely realise that Event 2 is 10 seconds after Event 1.

The reason for this method is there is other stuff going on within the loops (LED control for instance). So I don't want to stop the process using delay.

---

<div class="post-metadata">

**Author:** ![david\_2018](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/david_2018/32/1013044_2.png) [@david\_2018](https://forum.arduino.cc/u/david_2018)\
**Post date:** [March 6, 2022, 2:30pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/11 "2022-03-06T14:30:58Z")

</div>

> [@phoneystark20201](#):
>
> Event 1 is 15000ms isn't it? (you have 1500ms).

15 \* 100 = 1500

> [@phoneystark20201](#):
>
> The reason for this method is there is other stuff going on within the loops (LED control for instance). So I don't want to stop the process using delay.

Your do...while loop is blocking, so is no different from delay, unless you have some additional code within the do...while that implements your additional processing (and that would have to be in every do...while loop if you wanted it to run contenuously). See UKHeliBob's post for a better method, although that has problem with the two timers running independently of each other.

You may want to look into using a state machine, that may be a more appropriate method.

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 6, 2022, 2:39pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/12 "2022-03-06T14:39:57Z")

</div>

> [@david\_2018](#):
>
> that has problem with the two timers running independently of each other

It is intended as an example of non blocking timing, not a solution to the requirements of @phoneystark20201

If the two timing periods are to be run consecutively then it is easy to change the code to do that as you and I both know

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 6, 2022, 2:47pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/13 "2022-03-06T14:47:19Z")

</div>

Sorry... brain is fried. Yes, my milliseconds math is correct in my code, and wrong here... derr.

There are other things within the do loop. The events are configurable at the start, so you can actually specify event 2 to operate before event 1 (if that makes sense).

The reason for this method was so default things can be updated (like the Leds) within that do loop, and certain events can be triggered exactly when required.  
These events are very short (relay operations etc).

I have commented out the FASTLED commands and the timing works. I need to control the LEDS another way.

---

<div class="post-metadata">

**Author:** ![GoForSmoke](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/goforsmoke/32/1127097_2.png) [@GoForSmoke](https://forum.arduino.cc/u/GoForSmoke)\
**Post date:** [March 6, 2022, 2:56pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/14 "2022-03-06T14:56:10Z")

</div>

> [@phoneystark20201](#):
>
> ```arduino
> PiezoBeep = millis();
> 
> ```

```arduino
      PiezoBeep += 5000; // the tone plays for 100ms every 5 secs this way, not 5.1 secs.

```

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 6, 2022, 2:59pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/15 "2022-03-06T14:59:24Z")

</div>

Same project.....

```cpp
void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[random16(NUM_LEDS)] += CRGB::White;
  }
}

```

What does the random8() and random16 mean? Can't find that anywhere.  
I know random(8) is a random number.

A random number that is 8 bit or 16 bit?

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [March 6, 2022, 3:07pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/16 "2022-03-06T15:07:31Z")

</div>

> [@UKHeliBob](#):
>
> The compiler may well reduce the number of calls to millis() when optimising the code but it is good practice to do it explicitly

I hope not, or the compiler is way smarter than I think possible, or it would only be able to do in the narrowest of circumstances and still should not.

And it would def be wrong in the case of functions that aren't like _millis_(). I do not know if the compiler has any special knowledge about _millis_() that would allow it to do any optimising.

Calls to _millis_() separated by any code might return different numbers, and might be what is intended - but probably not. Unless it is a test of _millis_() to see it tick up or something.

So I agree, in a nice free running loop that "takes no time", _millis_() should be called once, ppl like

```arduino
// unsigned long currentMillis() = millis(); // Oops, thx @Coding_Badly

    unsigned long currentMillis = millis();

```

At the top. I use _now_ as the variable name, just me doing me.

On the same hand, I usually _digitalRead_() anything I will need multiple times in the same time slice. That eliminates any problems a bouncing switch or glitchy signal might introduce. And leaves one place only to fix an upside down logic mistake, the kind I never make. 😑

a7

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 6, 2022, 3:12pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/17 "2022-03-06T15:12:03Z")

</div>

random8() and random16() are functions in the FastLed library if that library is used by the sketch that you found them in

```cpp
/// Generate an 8-bit random number
LIB8STATIC uint8_t random8()
{
    rand16seed = APPLY_FASTLED_RAND16_2053(rand16seed) + FASTLED_RAND16_13849;
    // return the sum of the high and low bytes, for better
    // mixing and non-sequential correlation
    return (uint8_t)(((uint8_t)(rand16seed & 0xFF)) +
                     ((uint8_t)(rand16seed >> 8)));
}

/// Generate a 16 bit random number
LIB8STATIC uint16_t random16()
{
    rand16seed = APPLY_FASTLED_RAND16_2053(rand16seed) + FASTLED_RAND16_13849;
    return rand16seed;
}

/// Generate an 8-bit random number between 0 and lim
/// @param lim the upper bound for the result
LIB8STATIC uint8_t random8(uint8_t lim)
{
    uint8_t r = random8();
    r = (r*lim) >> 8;
    return r;
}

/// Generate an 8-bit random number in the given range
/// @param min the lower bound for the random number
/// @param lim the upper bound for the random number
LIB8STATIC uint8_t random8(uint8_t min, uint8_t lim)
{
    uint8_t delta = lim - min;
    uint8_t r = random8(delta) + min;
    return r;
}

/// Generate an 16-bit random number between 0 and lim
/// @param lim the upper bound for the result
LIB8STATIC uint16_t random16( uint16_t lim)
{
    uint16_t r = random16();
    uint32_t p = (uint32_t)lim * (uint32_t)r;
    r = p >> 16;
    return r;
}

/// Generate an 16-bit random number in the given range
/// @param min the lower bound for the random number
/// @param lim the upper bound for the random number
LIB8STATIC uint16_t random16( uint16_t min, uint16_t lim)
{
    uint16_t delta = lim - min;
    uint16_t r = random16( delta) + min;
    return r;
}

```

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 6, 2022, 3:14pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/18 "2022-03-06T15:14:42Z")

</div>

> [@alto777](#):
>
> the compiler is way smarter than I think possible

Agreed. It is unlikely in practice that the compiler would reduce the number calls to millis() but it does get up to some tricks behind the scenes

---

<div class="post-metadata">

**Author:** ![phoneystark20201](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/phoneystark20201/32/749209_2.png) [@phoneystark20201](https://forum.arduino.cc/u/phoneystark20201)\
**Post date:** [March 6, 2022, 3:16pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/19 "2022-03-06T15:16:21Z")

</div>

Overflow. Now I know the millis() resets/rolls over something like every 49 days or something.

But, my routine will run for years (I hope), and there is the remote, tiny possibility that someone initiates the routine right at the end of the millis() counter.  
When it rolls over to zero, my loop would fail.

So, is it so horrific that I reset the millis()?

It basically sits there waiting for a button press. Why would resetting millis() at the start of the routine, immediately after a button press break the code or be such a forbidden thing?

---

<div class="post-metadata">

**Author:** ![UKHeliBob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ukhelibob/32/215663_2.png) [@UKHeliBob](https://forum.arduino.cc/u/UKHeliBob)\
**Post date:** [March 6, 2022, 3:20pm UTC](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064/20 "2022-03-06T15:20:45Z")

</div>

If you write your code using subtraction to determine whether a timing period has ended and use unsigned variables (see post #9) then millis() rollover will not cause a problem unless the timing period is greater than 49 days. There is no need to reset millis()

[Next page](https://forum.arduino.cc/t/using-mills-correctly-as-a-timer/966064.md?page=2)
