Difference between revisions of "Safe millis with rollover compensation"

From Public Wiki
Jump to navigation Jump to search
(Created page with "==Synopsis== Demonstrate safe delays with millis() or micros() that has rollover compensation. ==Notes== ==Code== <syntaxhighlight lang="C++" line='line'> // Interval is h...")
 
 
Line 7: Line 7:
 
==Code==
 
==Code==
 
<syntaxhighlight lang="C++" line='line'>
 
<syntaxhighlight lang="C++" line='line'>
 
 
// Interval is how long we wait
 
// Interval is how long we wait
 
// add const if this should never change
 
// add const if this should never change
int interval=1000;
+
int timer1_period=1000;
 +
int timer2_period=3333;
 +
int timer3_period=5000;
 +
int special_period=7000;
 +
 
 
// Tracks the time since last event fired
 
// Tracks the time since last event fired
unsigned long previousMillis=0;
+
unsigned long timer1_etime=0;
+
unsigned long timer2_etime=0;
 +
unsigned long timer3_etime=0;
 +
bool          special_status=LOW;
 +
unsigned long special_etime=0;
 
void setup() {
 
void setup() {
  pinMode(13, OUTPUT);
+
    Serial.begin(9600);
 +
    delay(1000);
 +
    Serial.println("Timer start.");
 
}
 
}
 
   
 
   
Line 21: Line 29:
 
   // Get snapshot of time
 
   // Get snapshot of time
 
   unsigned long currentMillis = millis();
 
   unsigned long currentMillis = millis();
+
 
   // How much time has passed, accounting for rollover with subtraction!
+
   //Every 1000
   if ((unsigned long)(currentMillis - previousMillis) >= interval) {
+
   if ((unsigned long)(currentMillis - timer1_etime) >= timer1_period) {
       // It's time to do something!
+
       Serial.println("Every Second.");
       digitalWrite(13, !digitalRead(13)); // Toggle the LED on Pin 13
+
      timer1_etime = currentMillis;
+
  }
      // Use the snapshot to set track time until next event
+
 
       previousMillis = currentMillis;
+
  //Every 3333
 +
  if ((unsigned long)(currentMillis - timer2_etime) >= timer2_period) {
 +
      Serial.println("                Every 3.333 Seconds.");
 +
       timer2_etime = currentMillis;
 +
  }
 +
 
 +
  //Every 5000
 +
  if ((unsigned long)(currentMillis - timer3_etime) >= timer3_period) {
 +
      Serial.println("                                      Every 5 Seconds.");
 +
      timer3_etime = currentMillis;
 +
  }
 +
 
 +
 
 +
  //Rare occasions 1:16384 probabilty per loop tick
 +
  //Set Condition
 +
  if(currentMillis%16384==1 && !special_status)
 +
  {
 +
    special_status=HIGH;
 +
    Serial.println("SPECIAL OCCASION FLAG SET!!!!.");
 +
    special_etime = currentMillis;
 +
  }
 +
 
 +
  //Reset Condition
 +
  if ((unsigned long)(currentMillis - special_etime) >= special_period && special_status) {
 +
      Serial.println("SPECIAL OCCASION EXPIRES!");
 +
      special_status = LOW;
 +
       special_etime = currentMillis;
 
   }
 
   }
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 19:10, 9 December 2020

Synopsis

Demonstrate safe delays with millis() or micros() that has rollover compensation.

Notes

Code

 1 // Interval is how long we wait
 2 // add const if this should never change
 3 int timer1_period=1000;
 4 int timer2_period=3333;
 5 int timer3_period=5000;
 6 int special_period=7000;
 7 
 8 // Tracks the time since last event fired
 9 unsigned long timer1_etime=0;
10 unsigned long timer2_etime=0;
11 unsigned long timer3_etime=0;
12 bool          special_status=LOW;
13 unsigned long special_etime=0;
14 void setup() {
15     Serial.begin(9600);
16     delay(1000);
17     Serial.println("Timer start.");
18 }
19  
20 void loop() {
21    // Get snapshot of time
22    unsigned long currentMillis = millis();
23 
24    //Every 1000
25    if ((unsigned long)(currentMillis - timer1_etime) >= timer1_period) {
26       Serial.println("Every Second.");
27       timer1_etime = currentMillis;
28    }
29 
30    //Every 3333
31    if ((unsigned long)(currentMillis - timer2_etime) >= timer2_period) {
32       Serial.println("                Every 3.333 Seconds.");
33       timer2_etime = currentMillis;
34    }
35    
36    //Every 5000
37    if ((unsigned long)(currentMillis - timer3_etime) >= timer3_period) {
38       Serial.println("                                      Every 5 Seconds.");
39       timer3_etime = currentMillis;
40    }
41 
42 
43    //Rare occasions 1:16384 probabilty per loop tick
44    //Set Condition
45    if(currentMillis%16384==1 && !special_status)
46    {
47      special_status=HIGH;
48      Serial.println("SPECIAL OCCASION FLAG SET!!!!.");
49      special_etime = currentMillis;
50    }
51 
52    //Reset Condition
53    if ((unsigned long)(currentMillis - special_etime) >= special_period && special_status) {
54       Serial.println("SPECIAL OCCASION EXPIRES!");
55       special_status = LOW;
56       special_etime = currentMillis;
57    }
58 }