Цикл for в некоторых случаях может блокировать выполнение кода. В данном материале мы расскажем о том, как реализовать неблокирующий цикл for и одновременно управлять большим количеством процессов.

Представьте, что вы хотите управлять своим шаговым двигателем через Bluetooth и отдаете приказ сделать 14000 шагов. Новичок напишет код следующим образом:
for (int i = 0; i < 14000; i++) {
motor.step(1);
}
Но что, если вы хотите остановить этот процесс посередине, потому что что-то пошло не так? Или если вы хотите запустить 2 двигателя одновременно? Цикл for блокирует код, и этот код не будет реагировать на ваши новые заказы, пока цикл for для 1 двигателя не завершится.
Решение простое – не используйте циклы for, если вы хотите управлять большим количеством процессов одновременно. Замените его на if. Далее приведена общая структура кода, когда можно управлять сколько угодно процессов и не блокировать их.
Сначала мы объявляем некоторые переменные:
bool moveMotor1 = false;
bool moveMotor2 = false;
int motor1StepsNum, motor2StepsNum;
Наш бесконечный цикл будет легким:
void loop() {
ReceiveBTData();
if (moveMotor1) MoveMotor1();
if (moveMotor2) MoveMotor2();
}
Мы создаем функции для движущихся двигателей с «if»:
void MoveMotor1() {
if (motor1StepsNum > 0) {
motor1.step(1);
motor1StepsNum--;
}
else moveMotor1 = false;
}
void MoveMotor2() {
if (motor2StepsNum > 0) {
motor2.step(1);
motor2StepsNum--;
}
else moveMotor2 = false;
}
И, наконец, мы обрабатываем Bluetooth-соединение, где мы инициализируем или останавливаем процессы:
#define moveMotor1Value 81
#define moveMotor2Value 82
#define stopMotor1Value 91
#define stopMotor2Value 92
#define cancelValue 99
void ReceiveBTData() {
if(Serial.available() > 0) {
byte receivedValue = Serial.read();
if (receivedValue == moveMotor1Value) {
motor1StepsNum = Serial.read() + (Serial.read() << 8);
moveMotor1 = true;
}
if (receivedValue == moveMotor2Value) {
motor2StepsNum = Serial.read() + (Serial.read() << 8);
moveMotor2 = true;
}
if (receivedValue == stopMotor1Value) {
moveMotor1 = false;
}
if (receivedValue == stopMotor2Value) {
moveMotor2 = false;
}
if (receivedValue == cancelValue) {
moveMotor1 = false;
moveMotor2 = false;
}
}
}