That is a documented approach to compare the drift of two millis()based methods to generate an event more or less exactly every second.

The first (and usual) method stores the initial() millis value and waits in a loop until the new millis() value has reached the requested time.

```
unsigned long millisNow;
unsigned long millisCurrent;
unsigned long millisMemory = 0;
int loopcount = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop()
{
// put your main code here, to run repeatedly:
millisCurrent = millis();
while ((millis() - millisCurrent) <= 1000UL)
{
delay(39);
if (loopcount < 1)
{
Serial.print (" MillisNow: ");
Serial.print (millisNow);
Serial.print (" | MillisCurrent: ");
Serial.print (millisCurrent);
Serial.print (" | MillisMemory: ");
Serial.print (millisMemory);
Serial.print (" | loopcount: ");
Serial.print (loopcount);
Serial.println ();
millisMemory = millis();
}
millisNow = millis();
loopcount++;
}
loopcount = 0;
}
```

That method accrues also the errors due to the processing time and the low defnintion of millis():

As you can see in the serial output the millisNow value is always more than the preceeding value +1000. by about 25mS

MillisNow: 16418 | MillisCurrent: 16418 | MillisMemory: 15442 | loopcount: 0

MillisNow: 17446 | MillisCurrent: 17446 | MillisMemory: 16472 | loopcount: 0

MillisNow: 18476 | MillisCurrent: 18476 | MillisMemory: 17501 | loopcount: 0

MillisNow: 19505 | MillisCurrent: 19505 | MillisMemory: 18530 | loopcount: 0

MillisNow: 20534 | MillisCurrent: 20534 | MillisMemory: 19558 | loopcount: 0

MillisNow: 21563 | MillisCurrent: 21563 | MillisMemory: 20587 | loopcount: 0

MillisNow: 22591 | MillisCurrent: 22591 | MillisMemory: 21616 | loopcount: 0

MillisNow: 23620 | MillisCurrent: 23620 | MillisMemory: 22645 | loopcount: 0

MillisNow: 24649 | MillisCurrent: 24649 | MillisMemory: 23674 | loopcount: 0

MillisNow: 25678 | MillisCurrent: 25678 | MillisMemory: 24702 | loopcount: 0

MillisNow: 26707 | MillisCurrent: 26707 | MillisMemory: 25732 | loopcount: 0

MillisNow: 27736 | MillisCurrent: 27736 | MillisMemory: 26761 | loopcount: 0

MillisNow: 28765 | MillisCurrent: 28765 | MillisMemory: 27790 | loopcount: 0

MillisNow: 29794 | MillisCurrent: 29794 | MillisMemory: 28819 | loopcount: 0

MillisNow: 30823 | MillisCurrent: 30823 | MillisMemory: 29847 | loopcount: 0

MillisNow: 31852 | MillisCurrent: 31852 | MillisMemory: 30876 | loopcount: 0

MillisNow: 32880 | MillisCurrent: 32880 | MillisMemory: 31905 | loopcount: 0

MillisNow: 33909 | MillisCurrent: 33909 | MillisMemory: 32934 | loopcount: 0

MillisNow: 34938 | MillisCurrent: 34938 | MillisMemory: 33964 | loopcount: 0

MillisNow: 35968 | MillisCurrent: 35968 | MillisMemory: 34992 | loopcount: 0

MillisNow: 36997 | MillisCurrent: 36997 | MillisMemory: 36021 | loopcount: 0

MillisNow: 38025 | MillisCurrent: 38025 | MillisMemory: 37050 | loopcount: 0

MillisNow: 39054 | MillisCurrent: 39054 | MillisMemory: 38079 | loopcount: 0

MillisNow: 40083 | MillisCurrent: 40083 | MillisMemory: 39108 | loopcount: 0

MillisNow: 41112 | MillisCurrent: 41112 | MillisMemory: 40136 | loopcount: 0

MillisNow: 42141 | MillisCurrent: 42141 | MillisMemory: 41165 | loopcount: 0

MillisNow: 43169 | MillisCurrent: 43169 | MillisMemory: 42194 | loopcount: 0

MillisNow: 44198 | MillisCurrent: 44198 | MillisMemory: 43224 | loopcount: 0

MillisNow: 45228 | MillisCurrent: 45228 | MillisMemory: 44252 | loopcount: 0

The following method appears to give better results:

```
unsigned long millisNow;
int millisCurrent;
int millisMemory = 0;
int loopcount = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop()
{
// put your main code here, to run repeatedly:
millisCurrent = millis() % 1000UL;
delay(39);
millisNow = millis();
if (millisMemory > millisCurrent)
{
Serial.print (" MillisNow: ");
Serial.print (millisNow);
Serial.print (" | MillisCurrent: ");
Serial.print (millisCurrent);
Serial.print (" | MillisMemory: ");
Serial.print (millisMemory);
Serial.print (" | loopcount: ");
Serial.print (loopcount);
Serial.println ();
loopcount = 0;
}
++loopcount;
millisMemory = millisCurrent;
}
```

The serial monitor returns a millisNow value with a strong jitter, but the mean distance between two values keeps being 1000.

MillisNow: 631045 | MillisCurrent: 6 | MillisMemory: 967 | loopcount: 25

MillisNow: 632071 | MillisCurrent: 32 | MillisMemory: 992 | loopcount: 26

MillisNow: 633058 | MillisCurrent: 19 | MillisMemory: 980 | loopcount: 25

MillisNow: 634046 | MillisCurrent: 7 | MillisMemory: 968 | loopcount: 25

MillisNow: 635072 | MillisCurrent: 33 | MillisMemory: 993 | loopcount: 26

MillisNow: 636059 | MillisCurrent: 20 | MillisMemory: 981 | loopcount: 25

MillisNow: 637047 | MillisCurrent: 8 | MillisMemory: 969 | loopcount: 25

MillisNow: 638073 | MillisCurrent: 33 | MillisMemory: 995 | loopcount: 26

MillisNow: 639060 | MillisCurrent: 22 | MillisMemory: 983 | loopcount: 25

MillisNow: 640049 | MillisCurrent: 10 | MillisMemory: 971 | loopcount: 25

MillisNow: 641075 | MillisCurrent: 36 | MillisMemory: 997 | loopcount: 26

MillisNow: 642063 | MillisCurrent: 24 | MillisMemory: 985 | loopcount: 25

MillisNow: 643051 | MillisCurrent: 11 | MillisMemory: 972 | loopcount: 25

MillisNow: 644077 | MillisCurrent: 38 | MillisMemory: 999 | loopcount: 26

MillisNow: 645065 | MillisCurrent: 26 | MillisMemory: 987 | loopcount: 25

MillisNow: 646053 | MillisCurrent: 13 | MillisMemory: 975 | loopcount: 25

MillisNow: 647041 | MillisCurrent: 2 | MillisMemory: 963 | loopcount: 25

MillisNow: 648067 | MillisCurrent: 28 | MillisMemory: 989 | loopcount: 26

MillisNow: 649054 | MillisCurrent: 15 | MillisMemory: 976 | loopcount: 25

MillisNow: 650042 | MillisCurrent: 3 | MillisMemory: 964 | loopcount: 25

MillisNow: 651068 | MillisCurrent: 28 | MillisMemory: 989 | loopcount: 26

MillisNow: 652055 | MillisCurrent: 16 | MillisMemory: 977 | loopcount: 25

MillisNow: 653043 | MillisCurrent: 4 | MillisMemory: 965 | loopcount: 25

MillisNow: 654069 | MillisCurrent: 29 | MillisMemory: 990 | loopcount: 26

MillisNow: 655056 | MillisCurrent: 17 | MillisMemory: 979 | loopcount: 25

MillisNow: 656045 | MillisCurrent: 6 | MillisMemory: 966 | loopcount: 25

MillisNow: 657070 | MillisCurrent: 31 | MillisMemory: 992 | loopcount: 26

MillisNow: 658058 | MillisCurrent: 19 | MillisMemory: 980 | loopcount: 25

MillisNow: 659046 | MillisCurrent: 6 | MillisMemory: 967 | loopcount: 25

MillisNow: 660071 | MillisCurrent: 32 | MillisMemory: 993 | loopcount: 26

MillisNow: 661059 | MillisCurrent: 20 | MillisMemory: 981 | loopcount: 25

MillisNow: 662046 | MillisCurrent: 7 | MillisMemory: 968 | loopcount: 25

MillisNow: 663072 | MillisCurrent: 33 | MillisMemory: 994 | loopcount: 26

MillisNow: 664060 | MillisCurrent: 22 | MillisMemory: 983 | loopcount: 25

MillisNow: 665048 | MillisCurrent: 9 | MillisMemory: 970 | loopcount: 25

MillisNow: 666074 | MillisCurrent: 35 | MillisMemory: 996 | loopcount: 26

MillisNow: 667062 | MillisCurrent: 23 | MillisMemory: 983 | loopcount: 25

MillisNow: 668049 | MillisCurrent: 10 | MillisMemory: 971 | loopcount: 25

MillisNow: 669076 | MillisCurrent: 37 | MillisMemory: 998 | loopcount: 26

MillisNow: 670064 | MillisCurrent: 24 | MillisMemory: 985 | loopcount: 25

MillisNow: 671051 | MillisCurrent: 12 | MillisMemory: 973 | loopcount: 25

MillisNow: 672039 | MillisCurrent: 1 | MillisMemory: 962 | loopcount: 25

MillisNow: 673064 | MillisCurrent: 26 | MillisMemory: 987 | loopcount: 26

MillisNow: 674053 | MillisCurrent: 14 | MillisMemory: 975 | loopcount: 25

MillisNow: 675041 | MillisCurrent: 2 | MillisMemory: 962 | loopcount: 25

MillisNow: 676066 | MillisCurrent: 27 | MillisMemory: 988 | loopcount: 26

MillisNow: 677054 | MillisCurrent: 15 | MillisMemory: 976 | loopcount: 25

MillisNow: 678042 | MillisCurrent: 2 | MillisMemory: 963 | loopcount: 25

MillisNow: 679067 | MillisCurrent: 28 | MillisMemory: 989 | loopcount: 26

MillisNow: 680055 | MillisCurrent: 16 | MillisMemory: 977 | loopcount: 25

Maybe I have a bug in the first sketch, but i tried to avoid having much code outside the loop to minimize the drift, which i never could get smaller.

I cannot explain, why the drift in the first version is so strong. It is about 29 mS per second.

That is extreme and makes the code useless!

What is your analysis?

Regards

Laszlo