Line Robot - Basic lessons - While
"While" is one of 2 loops in C++. The other one, "for", we already know. It has even a simpler form. For example:
void RobotLine::loop() {
static uint32_t startMs = millis();
while(millis() - startMs < 10000)
print("%i\n\r", millis());
}
First line declares a variable that will be retained between successive executions of loop(), named "startMs", which immediately stores number of milliseconds since microcontroller power-up. Now, "while": in the brackets is a logical expression (evaluates either true or false). As long as it is true (for 10 sec.), the next instruction will execute, printing milliseconds.
Can You find a subtle error in the code? Hint: it will run only once. If You try to execute it the second time, nothing will be displayed. Here is the corrected version:
void RobotLine::loop() {
static uint32_t startMs;
if (setup())
startMs = millis();
while(millis() - startMs < 1000)
print("%i\n\r", millis());
}
The previous one initialized "startMs" only when loop() started the first time.
Note that this task could have been programmed without "while".
Task: stop and go.
Let the robot follow a line. If an obstacle is detected, the robot must stop for 10 sec. If the obstacle is removed within this interval, the robot should continue following the line. If not, the program should end. Line-following algorithm is here:
void RobotLine::loop() {
if (line(5))
go(10, 80);
else if (line(3))
go(80, 10);
else
go(60, 60);
}
Solution
void RobotLine::loop() {
if (line(5))
go(10, 80);
else if (line(3))
go(80, 10);
else
go(60, 60);
if (frontLeft() < 60){
stop();
uint32_t startMs = millis();
bool timeout = true;
while (millis() - startMs < 10000 && timeout){
delayMs(1);
if (frontLeft() > 60)
timeout = false;
}
if (timeout)
end();
}
}
Second block starts with "if" that checks distance ahead. If there is an obstacle, the motors will stop. Timer "startMs" will start. "timeout" is set to a default value, "true", if the obstacle is not removed. Now, "while" starts, and will continue to run for the next 10 sec. (when millis() - startMs becomes bigger than 10000) and while "timeout" is still "true". It will be "true" as long as the "if" inside "while" instruction doesn't notice that the obstacle is gone (distance > 60). So, the loop will end either after 10 sec. or if the obstacle is removed. In the former case, the next "if" will evaluate true and the program will end.