Циклы в ардуино используются для управления потоком программы. В цикле блок кода выполняется снова и снова. Каждый цикл цикла называется итерацией цикла. В зависимости от определенных условий, которые определяются в коде, вы можете контролировать, входит ли программа в цикл или нет.
В каждом скетче Arduino есть как минимум один цикл — это основной цикл или ,по-другому, раздел void loop()
. Но при проектировании реальных устройств может быть очень полезно иметь другие циклы в коде, работающие внутри основного цикла.
В этой статье мы обсудим циклы while
, циклы do-while
и циклы for
. Мы увидим, как использовать эти циклы в программе Arduino. Для этого соберем пример проекта, который мигает светодиодом только при нажатии кнопки. Мы также увидим, как выполнять такие операции, как одновременная установка режимов нескольких контактов с помощью цикла for
.
Цикл WHILE в Ардуино
Код для цикла while
выглядит следующим образом:
while(условие){ // тело цикла while }
Если условие истинно, программа войдет в тело цикла while
и будет выполнять код тела в цикле до тех пор, пока условие остается истинным. Если условие ложно, программа пропустит цикл while
и перейдет к следующей строке кода.
В качестве примера того, как использовать цикл while
, давайте создадим схему, которая будет мигать светодиодом при нажатии кнопки.
Для создания этого проекта понадобятся следующие компоненты:
- Arduino Uno
- Соединительные провода
- Макетная плата
- Резистор 1 Ком
- Тактильная кнопка
Соберем следующую электрическую схему:
После сборки схемы можно загрузить сам код в плату:
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); } }
Цикл 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 секунд и сам погас, при этом кнопку я не держу нажатой?
Здравствуйте. Один из способов это использовать функцию millis() для сохранения значения времени, когда была нажата кнопка. А далее отслеживать прошедшее время и если оно >= 5 секундам, отключать светодиод.
Например, если схема подключения как на картинке, то код будет следующий: