Hi Everybody,
I'm using a self-written function for non-blocking periodic-delayed code-execution.
The most simplest example is switching an LED ON / off. Which could be called toggle the LED
If LED is off => switch LED ON
.
If LED is ON => switch LED off
void toggleLED_OnOff(byte myLED_Pin) {
if ( digitalRead(myLED_Pin) == LOW) { // if LED is off
digitalWrite(myLED_Pin,HIGH); // switch LED ON
}
else { // if LED is ON
digitalWrite(myLED_Pin,LOW); // switch LED off
}
}
example to switch on / off a LED periodically and continiously once every 5 seconds (5000 milliseconds)
as a time-table
actual|
time | state of LED
00:00 | switch LED ON
00:05 | switch LED off
00:10 | switch LED ON
00:15 | switch LED off
00:20 | switch LED ON
00:25 | switch LED off
00:30 | switch LED ON
00:35 | switch LED off
...
most basic example:
const byte LED_Pin = 13;
unsigned long StartTime;
void toggleLED_OnOff(byte myLED_Pin) {
if ( digitalRead(myLED_Pin) == LOW) { // if LED is off
digitalWrite(myLED_Pin,HIGH); // switch LED ON
}
else { // if LED is ON
digitalWrite(myLED_Pin,LOW); // switch LED off
}
}
void setup() {
pinMode(LED_Pin,OUTPUT);
digitalWrite(LED_Pin,HIGH); // switch ON LED
StartTime = millis(); // initialise variable StartTime with actual value of function millis()
}
void loop() {
// code that shall be executed all the time
// check if more or less then 5000 milliseconds have passed by
if ( TimePeriodIsOver(StartTime,5000) ) {
// if 5000 milliseconds HAVE passed by automatically update variable StartTime
toggleLED_OnOff(LED_Pin); // toggle LED
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
to demonstrate the non-blocking character of this timing-function the code-version below uses the serial monitor in a special way similar to a LC-Display
The effect will be that you see just one single line with text in the serial monitor that shows a fast upcounting number and the state of the LED beeing ON or off
you see 5 seconds long
counting fast 2524740 LED is switched ON
then 5 seconds long
counting fast 2558332 LED is switched off
and so on
the fast counting up number shows how many times per second loop is iterating the lines of code
const byte LED_Pin = 13;
unsigned long StartTime;
unsigned long myCounter;
unsigned long PrintTimer;
void toggleLED_OnOff(byte myLED_Pin) {
if ( digitalRead(myLED_Pin) == LOW) { // if LED is off
digitalWrite(myLED_Pin, HIGH); // switch LED ON
}
else { // if LED is ON
digitalWrite(myLED_Pin, LOW); // switch LED off
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_Pin, OUTPUT);
digitalWrite(LED_Pin, HIGH); // switch ON LED
StartTime = millis(); // initialise variable StartTime with actual value of function millis()
myCounter = 0;
}
void loop() {
// code that shall be executed all the time
myCounter++; // increment variable myCounter by 1 with each iteration of loop()
PrintCounter_and_LEDState();
// check if more or less then 5000 milliseconds have passed by
if ( TimePeriodIsOver(StartTime, 5000) ) {
// if 5000 milliseconds HAVE passed by automatically update variable StartTime
toggleLED_OnOff(LED_Pin); // toggle LED
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void ClearSerialMonitor() {
for (byte i = 0; i < 40; i++) {
Serial.println();
}
}
void PrintCounter_and_LEDState() {
// to create a steady-looking text print 40 empty lines
// that scroll the last printed text out of sight
if ( TimePeriodIsOver(PrintTimer, 200) ) { // once every 200 milliseconds
ClearSerialMonitor();
Serial.print("counting fast ");
Serial.print(myCounter);
Serial.print(" LED is switched ");
if ( digitalRead(LED_Pin) == HIGH) {
Serial.println("ON");
}
else {
Serial.println("off");
}
}
}