Циклы в Ардуино

Циклы Arduino IDE

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

В каждом скетче Arduino есть как минимум один цикл — это основной цикл или ,по-другому, раздел void loop(). Но при проектировании реальных устройств может быть очень полезно иметь другие циклы в коде, работающие внутри основного цикла.

В этой статье мы обсудим циклы while, циклы do-while и циклы for. Мы увидим, как использовать эти циклы в программе Arduino. Для этого соберем пример проекта, который мигает светодиодом только при нажатии кнопки. Мы также увидим, как выполнять такие операции, как одновременная установка режимов нескольких контактов с помощью цикла for.

Цикл WHILE в Ардуино

Код для цикла while выглядит следующим образом:

while(условие){
    // тело цикла while
}

Если условие истинно, программа войдет в тело цикла while и будет выполнять код тела в цикле до тех пор, пока условие остается истинным. Если условие ложно, программа пропустит цикл while и перейдет к следующей строке кода.

В качестве примера того, как использовать цикл while, давайте создадим схему, которая будет мигать светодиодом при нажатии кнопки.

Для создания этого проекта понадобятся следующие компоненты:

  • Arduino Uno
  • Соединительные провода
  • Макетная плата
  • Резистор 1 Ком
  • Тактильная кнопка

Соберем следующую электрическую схему:

Электрическая схема для демонстрации работы цикла while в Ардуино
К Arduino UNO подключены светодиод и тактильная кнопка. При нажатии на кнопку светодиод должен начать мигать, при отпускании — погаснуть.

После сборки схемы можно загрузить сам код в плату:

int buttonPin = 2; // Контакт для кнопки
int ledPin = 8;    // Контакт для светодиода

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);  // Настройка режима - на вход с подтягивающим резистором
  pinMode(ledPin, OUTPUT);           // Настройка режима - на выход
}

void loop() {
  int buttonState = digitalRead(buttonPin);   // Получаем значение с кнопки

  while (buttonState == LOW) {                // Условие цикла while
    digitalWrite(ledPin, HIGH);               // Включаем светодиод
    delay(200);                               // Пауза 200 миллисекунд
    digitalWrite(ledPin, LOW);                // Выключаем светодиод
    delay(200);                               // Пауза 200 миллисекунд
    buttonState = digitalRead(buttonPin);     // Обновляем состояние кнопки
  }
}

В верхней части скетча мы объявляем переменную для контакта, подключенного к кнопке, с именем buttonPin, и переменную для контакта, подключенного к светодиоду, с именем ledPin.

В разделе setup() мы установили buttonPin как вход с внутренним подтягивающим резистором. Затем мы устанавливаем ledPin в качестве выхода.

В разделе loop() мы объявляем переменную с именем buttonState и присваиваем ей значение digitalRead(buttonPin). Это считывает состояние напряжения на контакте кнопки (контакт 2), и сохраняет результат в переменной buttonState.

Мы хотим, чтобы программа входила в цикл while при нажатии кнопки. Нажатие кнопки приводит к тому, что контакт 2 переходит в  низкое состояние. Другими словами, когда кнопка нажата, то buttonState становится равным LOW, что делает условие истинным. Таким образом, Arduino войдет в цикл while и будет выполнять основной код, пока условие не станет ложным. А условие будет ложным только при высоком значении buttonState. Поэтому, пока кнопка нажата, светодиод будет продолжать мигать.

В конце тела цикла while необходимо обновлять состояние кнопки, так как мы рискуем заполучить бесконечный цикл. Без обновления состояния после первого нажатия кнопки программа войдет в цикл и будет выполнять ее снова и снова. Потому что переменная buttonState всегда будет хранить значение LOW.

Чтобы этого избежать, считывание состояния кнопки можно вставить прямо в условие цикла while.

void loop() {
  while (!digitalRead(buttonPin)) {
    digitalWrite(ledPin, HIGH);
    delay(200);
    digitalWrite(ledPin, LOW);
    delay(200);
  }
}
Цикл while arduino
Симуляция примера цикла while в Ардуино

Цикл DO WHILE в Ардуино

Циклы do-while работают так же, как и обычные циклы while, за исключением того, что основной код выполняется до того, как происходит проверка условия. Таким образом, даже если условие ложно, код в теле будет выполнен хотя бы один раз. Код цикла do while выглядит следующим образом:

do {
    // Тело цикла do-while
} while(условие);

Сначала Arduino вводит блок do и выполняет основной код. Затем он переходит к оператору while и оценивает условие. Если условие равно false, тогда Arduino перейдет к остальной части скетча. Но если условие равно true, код в теле будет выполняться снова и снова, пока условие не станет ложным.

Цикл FOR в Ардуино

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

for(инициализация; условие; итерация) {
   // Тело цикла for
}

Значение инициализации определяет переменную управления циклом, обычно называемую i или j. Условие определяет, когда скетч выйдет из цикла for. Значение итерации определяет, как переменная управления циклом изменяется при каждой итерации цикла.

Пример использования цикла for

Одним из полезных применений циклов for является одновременная инициализация нескольких контактов.

Например, взгляните на этот код, который можно использовать для установки десяти контактов (от 0 до 9) Arduino в качестве выходов:

void setup() { 
    pinMode(0, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
}

Используя цикл for, вы можете сделать то же самое всего тремя строками кода:

void setup(){
    for(i=0; i<10; i++) {
       pinMode(i, OUTPUT);
    }
}

Здесь мы объявляем переменную управления циклом с именем i и устанавливаем ее равной нулю. Переменная управления циклом содержит количество циклов, которое будет увеличиваться на единицу при каждой итерации цикла.

Затем мы ставим условие. Цикл for будет продолжаться до тех пор, пока условие истинно. В этом случае условием является количество выводов, которые мы хотим инициализировать. Каждый контакт с нуля по девятый будет установлен как выход (10 контактов), поэтому условие i < 10.

Мы хотим, чтобы управляющая переменная цикла i увеличивалась на единицу каждый раз в цикле, поэтому мы используем i++ в качестве значения итерации.

В первой итерации цикла i будет установлено в ноль. Ноль меньше десяти, поэтому условие истинно, и код в теле будет выполнен. В функции pinMode() первым параметром будет номер вывода, который мы хотим инициализировать. Но вместо этого мы можем использовать переменную управления циклом i, поэтому в качестве выхода будет установлен нулевой цифровой вывод.

В следующий раз при выполнении цикла значение итерации i++ увеличит управляющую переменную цикла на единицу. Так что теперь i будет равняться единице. Один меньше десяти, поэтому Arduino входит в тело цикла for. Поскольку i теперь равно единице, первый вывод будет установлен как выход.

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

Оператор прерывания BREAK в Arduino

Вы можете заставить программу выйти из цикла, даже если условие истинно, с помощью ключевого слова break. Ключевое слово break приводит к немедленному выходу программы из цикла. Он работает с циклами while, циклами do-while и циклами for. Это еще один способ контролировать поведение цикла.

Например, вы можете использовать break для выхода из цикла при возникновении определенного события:

int x = 3;

for(i=0; i<10; i++) {
    if(x == 3){
       break;
    }
    Serial.print("Привет"); 
}
Serial.print("Пока");

В этом примере break; помещается внутри оператора if. Если x равно трем, Arduino войдет в тело инструкции if и выполнит команду break. Это приведет к выходу из цикла for, поэтому “Привет” не будет выведен на последовательный монитор. Но поскольку Serial.print("Пока"); находится вне цикла for, “Пока” будет выведено на последовательный монитор.

Оператор пропуска текущей итерации CONTINUE

Ключевое слово continue позволяет еще больше контролировать действие циклов. Этот оператор заставляет скетч останавливать текущую итерацию цикла и приступать к следующему циклу.

for(i=0; i<10; i++) {
    if(x == 3){
       continue;
    }
    Serial.print("Привет"); 
}

Пока x не равно трем, «Привет» будет напечатано один раз для каждой итерации цикла for. Но когда x равен трем, Arduino войдет в тело оператора if и встретит оператор continue. Это заставит Arduino остановить текущую итерацию цикла for и начать новый цикл.

При использовании команды continue скетч не выходит из цикла for, он просто переходит к началу следующей итерации. Переменная управления циклом сохраняет свое значение, поэтому счет не теряется. Ключевое слово continue — это способ сократить итерацию цикла, когда происходит определенное событие.

Понимание того, как работают различные типы циклов, — важно. Если вы хотите иметь полный контроль над тем, как работает ваш программный код. Это непростая тема для освоения. Но немного попрактиковавшись и немного поэкспериментировав, вы сможете использовать их, чтобы получить полный контроль над вашими скетчами.

Не стесняйтесь оставлять комментарии ниже, если у вас есть какие-либо вопросы!

Документация

5 3 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Леонид
Леонид
3 месяцев назад

Спасибо. очень познавательно. А как сделать так, чтобы например я нажал и держал кнопку, светодион включился на 5 секунд и сам погас, при этом кнопку я не держу нажатой?