1. Let us try to understand the difference between a blocking code and a non-blocking code.
2. A blocking code is a code in which the MCU is blocked for certain amount of time is and prevented from doing any other task during that blocking period. For example:
Turn ON the built-in LED (L, Fig-1) of UNO and let it be at this ON-state for 1 sec time. After that turn OFF the LED and let it be at this OFF-state for 1 sec time. Repeat the process again. The blocking codes are given below Fig-1:
Figure-1:
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
digitalWrite(13, HIGH); //LED is ON
delay(1000); //LED remains ON for 1 sec time
digitalWrite(13, LOW); //LED is OFF
delay(1000); //LED remains OFF for 1 sec
}
3. while delay(1000) function (in Section-2) is being executed, the MCU remains totally blocked, and it cannot do any other task. Here, we see a wastage of 1 sec valuable time of the MCU; but, it is alright as long as there is no other task for the MCU to do.
4. Let us see how we can turn ON and turn OFF the LED (L) of Fig-1 at 1 sec interval without using the delay() function. Because, we are not using delay() function, the MCU will not be blocked any more. Anyway, there is still only one task (ON and OFF the LED) for the MCU; so, there is not much utilization of MCU's time/ability keeping it unblocked.
byte ledState = HIGH;
byte ledPin = 13;
unsigned long int currMillis = millis(); //recording time t0
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH); // L is turned ON
}
void loop()//MCU checks if 1 sec has elapsed without being blocked
{
if (millis() - currMillis >= 1000)//checkingif 1 sec is elspased
{
//ledState = !ledState; //1 sec has gone; invert ledState from ON ---> OFF
if (ledState == HIGH)
{
ledState = LOW;
}
else
{
ledState = HIGH;
}
digitalWrite(ledPin, ledState); //L is OFF --> ON ----> OFF....
currMillis = millis(); //recording t1, t2, .....
}
}
5. In this example, we will assign two tasks to the MCU which it will perform simultaneously without using delay() function, but it will be using millis() function to assign slots for their execution. the tasks are:
(1) LED (L) of Fig-2 will be turned ON/OFF at 1 sec interval.
(2) Smoke Detector will be checked if it is active (smoke has erupted from a hazardous point) in order to activate Alarm.
Figure-2:
byte ledState = HIGH;
#define ledPin 13
#define alarmLed 5
#define smokeSwitch 4
unsigned long int currMillis = millis(); //recording time t0
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(smokeSwitch, INPUT_PULLUP);
pinMode(alarmLed, OUTPUT);
digitalWrite(ledPin, HIGH); // L is turned ON
}
void loop()//MCU checks if 1 sec has elapsed without being blocked
{
if (millis() - currMillis >= 1000)//checkingif 1 sec is elspased
{
//edit ; ledState = !ledState; //1 sec has gone; invert ledState from ON ---> OFF
if (ledState == HIGH)
{
ledState = LOW;
}
else
{
ledState = HIGH;
}
digitalWrite(ledPin, ledState); //L is OFF --> ON ----> OFF....
currMillis = millis(); //recording t1, t2, .....
}
else
{
if (digitalRead(smokeSwitch) == LOW)
{
Serial.println("Smoke Dectected");
digitalWrite(alarmLed, HIGH); //alarm is activated
while (1); //wait to see the preventive action
}
}
}
Flow Chart Representation of the above sketch:
Figure-2:
6. Present the solution of the job of Section-5 using FSM (Finite State Machine) approach of post #81 @J-M-L of the following thread.
https://forum.arduino.cc/t/how-to-get-rid-of-goto-statement/1140656