# Arduino Tutorial: Avoiding the Overflow Issue When Using millis() and micros()

One of our most popular blog posts right now this is called Arduino Tutorial: Using millis() Instead of delay(). Here we discuss how to use `millis()` and `micros()` and their major advantages compared to `delay()`.

We mentioned one caveat with these functions, and that is that `millis()` and `micros()` overflow after around 50 days and 70 minutes, respectively. This potential issue can very easily be avoided with a small alteration to the code from last time.

The use of `millis()` throughout this post is interchangeable with `micros()`.

## The Easy Fix

Let’s look at the simple non-blocking example we included in the previous blog post:

```int period = 1000;
unsigned long time_now = 0;

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

void loop() {
if(millis() > time_now + period){
time_now = millis();
Serial.println("Hello");
}

//Run other code
}
```

Here we will get a buggy behavior after approximately 50 days when `millis()` will go from returning a very high number (close to (2^32)-1) to a very low number. This is known as overflow or rollover.

Now, let’s see how we can fix this:

```int period = 1000;
unsigned long time_now = 0;

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

void loop() {
if(millis() - time_now > period){
time_now = millis();
Serial.println("Hello");
}

//Run other code
}
```

We basically just move `time_now` to the other side of the inequality operator. For the equation to still make sense we then have to change the sign of the variable, hence the subtraction. You can look at this as comparing a duration to a our `period` variable instead of working with time stamps.

## Hold Your Horses!

“How would this even work?”, you might wonder. This is not a stupid question. This can easily look like as we’re merely moving the problem rather than fixing it.

Looking at this mathematically it doesn’t make much sense since the left side will become negative when the `millis()` overflow occur (the result of a very small integer minus a very large integer).

#### The Reason This Works

What’s nice is that we don’t have to worry about this at all. Since both inputs to the calculation are of the `unsigned long` data type, the answer will also be an `unsigned long`, and thus the result will overflow in line with the return value of `millis()`. Remember that both `millis()` and `micros()` return `unsigned long`.

###### Example/Proof
```void setup() {
Serial.begin(115200);

unsigned long a = 1;
unsigned long b = 4294967295; //unsigned long maximum value

Serial.println(a-b);
}

void loop() {
}
```

This will print `2` to the serial monitor. The `Serial.print()` function does not modify the answer in any way in this case.

To be sure that this works across multiple platforms and architectures you can explicitly cast the result of the calculation to the correct data type like this:

```int period = 1000;
unsigned long time_now = 0;

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

void loop() {
if((unsigned long)(millis() - time_now) > period){
time_now = millis();
Serial.println("Hello");
}

//Run other code
}
```

#### Different Data Types

On Arduino Uno (and equivalent) you have to explicitly cast the calculation when dealing with `uint8_t` for this to work. If you don’t, the result of the subtraction will become negative if given the right input.

`uint16_t` and `uint32_t` (the same as `unsigned long` on Arduino Uno and equivalent) have behavior such that explicit casting isn’t necessary. Other data types than `unsigned long` (`uint32_t`) is not relevant when dealing with `millis()` or `micros()`.

## Summary

As mentioned, this is a really easy “fix” to a potential problem when dealing with `millis()` or `micros()` (we don’t really fix the problem, we just avoid it). For more information about this topic, read this nice and comprehensive post on Stack Exchange.

If you’re feeling unsure about data types and overflows, we recommend you play around with this and see what happens in different edge-cases with different data types. Make sure your print function doesn’t influence your results in any way (sometimes it can). Remember that this behavior may vary across different platforms, compilers and/or architectures.