Arduino Uno Rev 3. IDE running on Windows 10 (Acer) laptop
My simple timed loop is:
unsigned long Oldmillis = 0;
const long DELAY = 10; // 10 ms
void setup() {
}
void loop() {
unsigned long newmillis = millis();
if (newmillis - Oldmillis >= DELAY) {
Oldmillis = newmillis;
// Tasks to be repeated are placed here.
}
}
I noticed that the loop was being repeated usually every 10 ms but occasionally every 11ms. I tried different values of delay and found that where DELAY is a multiple of 4 the loop repeats every DELAY ms, but for other values it occasionally repeats after DELAY+1 ms.
I wrote code to test it, which you may find below with some results at the end. When the delay is a multiple of 4 there is no serial output.
Many thanks for reading so far. I would be most grateful if anyone can shed a light on this. I can get around the problem, but am unlikely to sleep well until I find out what I did wrong!
/*
* The TIMED LOOP loop is intended to run once every Delay_ms ms, using millis() .
* It appears that with some values of Delay_ms it runs 1 ms late
* The code is intended to detect the late occurrences and count them.
* When there have been a sufficient number, LATE_COUNT,
* of late occurrences, it prints out the results.
*
*/
unsigned long Oldtime = 0;
unsigned long Timestamp;
int Latecounter = 0;
int Changecounter = 0;
int Delay_ms;
const int START_DELAY_MS = 10;
const int LATE_COUNT = 10;
const int NUMSAMPLES = 4;
void setup(){
Delay_ms = START_DELAY_MS;
}
void loop() {
unsigned long currenttime = millis();
int pastime = currenttime - Oldtime;
// TIMED LOOP
if (pastime >= Delay_ms){ // should trigger when = Delay_ms, and usually does!
if (pastime > Delay_ms) { // but sometimes it gets to more than Delay_ms
++Latecounter; // Up the counter when it got over Delay_ms
if (Latecounter >= LATE_COUNT){ // when there are sufficient errors, print the results
long elapsedtime = currenttime - Timestamp;
Timestamp = currenttime;
// PRINT RESULTS
Serial.begin(250000);
Serial.print("With Delay_ms set to: ");
Serial.print(Delay_ms);
Serial.print(" we get ");
Serial.print(Latecounter);
Serial.print(" late occurences in ");
Serial.print(elapsedtime);
Serial.print(" ms. That's about 1 in ");
Serial.print(elapsedtime/Latecounter);
Serial.println(" ms.");
Serial.print(" The most recent loop started at ");
Serial.print(currenttime);
Serial.println(" ms.");
Serial.print(" The previous loop started at ");
Serial.print(Oldtime);
Serial.println(" ms.");
Serial.print(" The most recent delay was ");
Serial.print(pastime);
Serial.println(" ms.");
Serial.end();
Latecounter = 0;
++Changecounter;
if (Changecounter >= NUMSAMPLES){ // Is it time to change the delay?
Changecounter = 0;
++Delay_ms;
}
}
}
Oldtime = currenttime;
}
}
Here are some typical results from the serial output:
14:14:52.305 -> With Delay_ms set to: 10 we get 10 late occurences in 2390 ms. That's about 1 in 239 ms.
14:14:52.305 -> The most recent loop started at 2390 ms.
14:14:52.305 -> The previous loop started at 2379 ms.
14:14:52.305 -> The most recent delay was 11 ms.
14:14:54.875 -> With Delay_ms set to: 10 we get 10 late occurences in 2560 ms. That's about 1 in 256 ms.
14:14:54.875 -> The most recent loop started at 4950 ms.
14:14:54.875 -> The previous loop started at 4939 ms.
14:14:54.875 -> The most recent delay was 11 ms.
14:14:57.418 -> With Delay_ms set to: 10 we get 10 late occurences in 2560 ms. That's about 1 in 256 ms.
14:14:57.418 -> The most recent loop started at 7510 ms.
14:14:57.418 -> The previous loop started at 7499 ms.
14:14:57.418 -> The most recent delay was 11 ms.
14:14:59.976 -> With Delay_ms set to: 10 we get 10 late occurences in 2560 ms. That's about 1 in 256 ms.
14:14:59.976 -> The most recent loop started at 10070 ms.
14:14:59.976 -> The previous loop started at 10059 ms.
14:14:59.976 -> The most recent delay was 11 ms.
14:15:03.177 -> With Delay_ms set to: 11 we get 10 late occurences in 3200 ms. That's about 1 in 320 ms.
14:15:03.177 -> The most recent loop started at 13270 ms.
14:15:03.177 -> The previous loop started at 13258 ms.
14:15:03.177 -> The most recent delay was 12 ms.
14:15:06.381 -> With Delay_ms set to: 11 we get 10 late occurences in 3200 ms. That's about 1 in 320 ms.
14:15:06.381 -> The most recent loop started at 16470 ms.
14:15:06.381 -> The previous loop started at 16458 ms.
14:15:06.381 -> The most recent delay was 12 ms.
14:15:09.580 -> With Delay_ms set to: 11 we get 10 late occurences in 3200 ms. That's about 1 in 320 ms.
14:15:09.580 -> The most recent loop started at 19670 ms.
14:15:09.580 -> The previous loop started at 19658 ms.
14:15:09.580 -> The most recent delay was 12 ms.
14:15:12.800 -> With Delay_ms set to: 11 we get 10 late occurences in 3200 ms. That's about 1 in 320 ms.
14:15:12.800 -> The most recent loop started at 22870 ms.
14:15:12.800 -> The previous loop started at 22858 ms.
14:15:12.800 -> The most recent delay was 12 ms.