Arduino переход в начало программы по условию. Arduino циклы. Условие и ветвление в тексте программы

Конструкция for используется для повторения блока операторов, заключенных в фигурные скобки. Счетчик приращений обычно используется для приращения и завершения цикла. Оператор for подходит для любых повторяющихся действий и часто используется в сочетании с массивами коллекций данных/выводов.

Заголовок цикла for состоит из трех частей:

for (initialization ; condition ; increment ) {операторы выполняющиеся в цикле}

Инициализация (Initialization) выполняется самой первой и один раз. Каждый раз в цикле проверяется условие (condition), если оно верно, выполняется блок операторов и приращение (increment), затем условие проверяется вновь. Когда логическое значение условия становится ложным, цикл завершается.

Пример

// Затемнение светодиода с использованием ШИМ-вывода int PWMpin = 10; // Светодиод последовательно с резистором 470 ом на 10 выводов void setup() { // настройка не нужна } void loop() { for (int i=0; i <= 255; i++){ analogWrite(PWMpin, i); delay(10); } }

Цикл for в Си гораздо более гибкий, чем циклы for в других языках программирования, например, в Бейсике. Любой из трех или все три элемента заголовка могут быть опущены, хотя точки с запятой обязательны. Также операторы для инициализации, условия и приращения цикла могут быть любым допустимым в Си операторами с независимыми переменными, и использовать любой тип данных Си, включая данные с плавающей точкой (floats). Эти необычные для цикла for типы операторов позволяют обеспечить программное решение некоторых нестандартных проблем.

Например, использование умножения в операторе счетчика цикла позволяет создавать логарифмическую прогрессию:

For(int x = 2; x < 100; x = x * 1.5){ println(x); }

Генерируется: 2,3,4,6,9,13,19,28,42,63,94

Другой пример, плавное уменьшение или увеличение уровня сигнала на светодиод с помощью одного цикла for :

Void loop(){ int x = 1; for (int i = 0; i > -1; i = i + x){ analogWrite(PWMpin, i); if (i == 255) x = -1; // переключение управления на максимуме delay(10); } }

Конструкция for используется для повторения блока операторов, заключенных в фигурные скобки. Счетчик приращений обычно используется для приращения и завершения цикла. Оператор for подходит для любых повторяющихся действий и часто используется в сочетании с массивами коллекций данных/выводов.

Заголовок цикла for состоит из трех частей:

for (initialization ; condition ; increment ) {операторы выполняющиеся в цикле}

Инициализация (Initialization) выполняется самой первой и один раз. Каждый раз в цикле проверяется условие (condition), если оно верно, выполняется блок операторов и приращение (increment), затем условие проверяется вновь. Когда логическое значение условия становится ложным, цикл завершается.

Пример
// Затемнение светодиода с использованием ШИМ-вывода int PWMpin = 10; // Светодиод последовательно с резистором 470 ом на 10 выводов void setup() { // настройка не нужна } void loop() { for (int i=0; i <= 255; i++){ analogWrite(PWMpin, i); delay(10); } }

Цикл for в Си гораздо более гибкий, чем циклы for в других языках программирования, например, в Бейсике. Любой из трех или все три элемента заголовка могут быть опущены, хотя точки с запятой обязательны. Также операторы для инициализации, условия и приращения цикла могут быть любым допустимым в Си операторами с независимыми переменными, и использовать любой тип данных Си, включая данные с плавающей точкой (floats). Эти необычные для цикла for типы операторов позволяют обеспечить программное решение некоторых нестандартных проблем.

Например, использование умножения в операторе счетчика цикла позволяет создавать логарифмическую прогрессию:

For(int x = 2; x < 100; x = x * 1.5){ println(x); }

Генерируется: 2,3,4,6,9,13,19,28,42,63,94

Другой пример, плавное уменьшение или увеличение уровня сигнала на светодиод с помощью одного цикла for :

Void loop() { int x = 1; for (int i = 0; i > -1; i = i + x){ analogWrite(PWMpin, i); if (i == 255) x = -1; // переключение управления на максимуме delay(10); } }

», мы узнали, как использовать цикл «for» для организации работы контроллера. Этот тип цикла используется повсеместно и с лихвой перекрывает «потребность в зацикленных операциях». Однако существует еще один тип цикла — «while». ничем не лучше, чем цикл for, просто он использует в работе другие принципы.

В большинстве случаем можно выбирать, какой из двух типов циклов использовать. В мы использовали «while» для приостановки программы, до момента введения пользователем требуемых данных. В этом уроке мы более подробно рассмотрим, как работают этот цикл на примере платформы Arduino.

Продолжим работу со схемой, состоящую из 2-х светодиодов.

Кроме того, мы продолжим работать с кодом, который мы дорабатывали в 14 уроке.

Назад в прошлое: контроллер запрашивает у пользователя данные, ожидает ввода, а затем присваивает полученные значения переменным blinkNumberGreen и blinkNumberRed . Это позволяет пользователю управлять количество миганий каждого из 2-х светодиодов.

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

Давайте разбираться, как это работает:

int z = 1 ; // объявляем переменную и присваиваем ей значение 1

while (z <=10) { //запускаем цикл while

Serial . println (z ); //выводим текущее значение переменной z через последовательный порт

z = z +1 // увеличиваем значение переменной z на 1

} // завершаем цикл

Цикл while будет продолжать выполнять команды до тех пор, пока «условие», описанное в круглых скобках, истинно. В приведенном выше примере, цикл будет продолжать выполнять команды пока z меньше или равно 10. В теле цикла отрабатываются 2 команды:

  • Выведение значения переменной через последовательный порт;
  • Увеличение значение переменной на 1 (по-научному – инкрементирование).

Благодаря увеличению значения переменной, в конечном итоге, программа выйдет из цикла. Если, представить на секунду, что мы забыли указать эту строку или произойдёт, какой-то сбой, то программа благополучно зациклится (иными словами зависнет).

Цикл начинает свою работу с того, что проверяет истинность условия. Если, z меньше или равно 10, то программа отрабатывает цикл. Затем следует повторная проверка условия и т.д. Когда значение переменной достигнет z = 11 , условие больше не будет истинным. Программа не отработает цикл и перейдёт в следующую строку, идущую сразу после фигурной скобки цикла.

Достаточно теории, переходим к практике. Заменим циклы for в исходном коде, на циклы while.

Мигалка в исполнении цикла FOR:

for (int i = 1; i <= blinkNumberGreen; i++) // запускаем цикл for

{

Serial . print (» Зелёный мигнул «);

Serial.println (i);

digitalWrite (greenLed, HIGH); // включаем зелёный светодиод

delay (timeOnGreenLed); // ждём

digitalWrite (greenLed, LOW); // выключаем зелёный светодиод

delay (timeOffGreenLed); // ждём

}

Мигалка в исполнении цикла WHILE:

int i =1; //объявляем переменную и присваиваем ей значение 1

while (i <= blinkNumberGreen)

{ // запускаем цикл while

Serial.print (» Зелёный мигнул «);

Serial.println(i);

digitalWrite(greenLed,HIGH); // включаем зелёный светодиод

delay(timeOnGreenLed); // ждём

digitalWrite(greenLed,LOW); // выключаем зелёный светодиод

delay(timeOffGreenLed); // ждём

i = i +1 //увеличиваем значение переменной на 1

}

Сохраняем программу и загружаем прошивку в контроллер. Смотрим на результат.

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

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

Оператор WHILE используется в C++ и Ардуино для организации повтора одних и тех команд произвольное количества раз. По сравнению с FOR цикл WHILE выглядит проще, он обычно используется там, где нам не нужен подсчет числа итераций в переменной, а просто требуется повторять код, пока что-то не изменится, не наступит какие-то событие.

Синтаксис WHILE

while(<условие или список условий>)
{
<программный блок, который будет повторяться>
}

В качестве условий может использоваться любая конструкция языка, возвращающая логическое значение. Условиями могут быть операции сравнения, функции, константы, переменные. Как и при любых других логических операциях в Ардуино любое значение, кроме нуля будет восприниматься как истина (true), ноль – ложь (false).

// Бесконечный цикл while(true){ Serial.println("Waiting…"); } // Цикл, выполняющийся до изменения значения функции checkSignal() while(!checkSignal()){ Serial.println("Waiting…"); }

Обратите внимание, что оператор while может использоваться без выделения блока фигурными скобками, в этом случае повторяться будет первая команда, встреченная после цикла. Крайне не рекомендуется использовать while без фигурных скобок, т.к. в этом случае можно очень легко допустить ошибку. Пример:

While(true) Serial.print("Waiting for interruption"); delay(1000);

В данном случае надпись будет выводиться в бесконечном цикле без пауз, потому что команда delay(1000) повторяться не будет. Вы можете потратить много времени, выявляя такие ошибки – гораздо проще использовать фигурную скобку.

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

Чаще всего while используется для ожидания какого-либо события. Например, готовности объекта Serial к работе.

Serial.begin(9600); while (!Serial) { ; // Для некоторых плат ардуино требуется ждать, пока не освободится последовательный порт }

Пример ожидания прихода символа от внешних устройств по UART:

While(Serial.available()){ int byteInput = Seria.read(); // Какие-то другие действия }

В данном случае мы будем считывать значения до тех пор, пока Serial.available() будет возвращать не нулевое значение. Как только все данные в буфере закончатся, цикл остановится.

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

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

Синтаксис цикла FOR

Здесь конструкция будет немного сложнее:
for (<начальное значение счетчика>;<условие продолжения выполнения цикла>;<изменение значения счетчика на каждом шаге>){
<список_команд>
}

Самый простой пример:

For(int i=5;i<10;i++){ // Конструкция «3 в одном» pinMode(i, OUTPUT); }

Мы сразу создали переменную, инициализировали ее, указали, что в конце каждого цикла значение счетчика нужно увеличивать на единицу. И все – теперь можно использовать переменную внутри цикла.

Шаг переменной может быть иным. Вот примеры:

  • for(int i=0; i<10; i=i+2) // Шаг 2
  • for(int i=0; i<10; i+=2) // Аналогичен предыдущему
  • for(int i=10; i>0; i–) // Идем обратно – от 10 до 1

Цикл do while

В некоторых случаях нам нужно организовать цикл таким образом, чтобы инструкции блока выполнялись хотя бы один раз, а затем уже осуществлялась проверка. Для таких алгоритмов можно использовать конструкцию do while. Пример:

Do { Serial.println("Working"); } while (checkSomething());

Никаких сложностей этот вариант цикла не представляет – мы просто перенесли блок с условиями вниз, поэтому все содержимое внутри фигурных скобок после оператора do выполнится до первой проверки.

Операторы continue и break

Бывают ситуации, когда вам нужно экстренно прервать выполнение цикла внутри блока цикла, не дожидаясь до перехода к блоку проверки условий. Для этого можно использовать оператор break :

While (true) { if (checkSomething()) { break; } }

Если мы просто хотим остановить ход выполнения текущей итерации, но не выйти из цикла, а перейти к блоку проверки условий, то должны использовать оператор continue :

While (true) { if (checkSomething()) { continue; } }

Операторы continue и break могут использоваться со всеми вариантами циклов FOR и WHILE.

Вложенные циклы в Ардуино

Любые варианты циклов можно спокойно совмещать друг с другом, делая вложенные конструкции. Переменные, определенные в блоке «вышележащего» цикла будут доступны во внутреннем. Самый часто встречаемый пример такого рода циклов – обход двумерных массивов. В следующем примере мы используем двойной цикл: первый будет перебирать строчки (переменная i), второй, вложенный – столбцы (переменная j) массива, который мы определили в переменно arr.

Int arr; void setup() { for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { arr[i][j] = i * j; Serial.println(arr[i][j]); } } }

Подробнее о циклах

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

Зачем нужен цикл

На самом деле, главная задача цикла – повторить одни и те же конструкции языка несколько раз. Такая потребность возникает практически в каждой программе и уж точно без цикла не обходится ни один скетч Ардуино – функция loop() тоже вызывается в бесконечном цикле.

Давайте рассмотрим следующий пример. Вам нужно подать питание одновременно на 5 светодиодов, подключенных к плате Arduino с 5 по 9 пины. Самым очевидным вариантом для этого будет размещение пяти инструкций подряд:

digitalWrite(5, HIGH);

digitalWrite(6, HIGH);

digitalWrite(7, HIGH);

digitalWrite(8, HIGH);

digitalWrite(9, HIGH);

Опустим пока вопрос рискованности такого действия, ведь одновременное включение такого числа светодиодов создает повышенную нагрузку на схему питания платы. Главное для нас сейчас то, что мы создали пять строк кода, каждая из которых отличается от других всего лишь на одну цифру. Такой подход имеет следующие недостатки:

  • При любом изменении придется вносить правки одновременно во множество строк. Например, если нам понадобится переключить светодиоды на пины со 2 по 6 или не включить, а выключить напряжение, то придется сделать 5 изменений в коде. А если инструкций и изменений будет больше?
  • Объемный код с большим количеством однотипных инструкций неудобно и неприятно читать. Пять одинаковых строчек – не сильно страшно. Но привычка к грязному коду со временем приведет к десяткам и сотням лишних страниц в листинге, что повергнет в уныние и вас, и ваших коллег.
  • В процессе «копипастинга» почти одинаковых инструкций можно легко совершить ошибку, например, забыв поменять номер пинов: digitalWrite(5, HIGH); digitalWrite(5, HIGH);
  • Вы с легкостью провалите собеседование в любую нормальную софтверную компанию, показав интервьюеру такой код.

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

И тут нам на помощь приходят циклы.

Правила синтаксиса

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

В нашем описанном выше примере мы могли бы сказать контроллеру следующее:

Повтори команду digitalWrite 5 раз

В идеальном мире с роботами-программистами этого бы, наверное, хватило, но так как мы разговариваем с компьютером на языке C++, нам нужно перевести эту фразу на этот язык:

Повтори команду – нужно использовать специальные инструкции, говорящие контроллеру, что сейчас начинается что-то интересное с циклами while или for

digitalWrite – оставляем как есть, но пишем один раз и заключаем в фигурные скобки. Как быть с номерами пинов – чуть ниже.

5 раз – использовать для этого счетчик, который будет увеличиваться при каждом повторении. В начале (или конце) блока можно сравнивать значение этого счетчика с предельным значением (в данном случае 5) с помощью операции сравнения.

Давайте посмотрим на пример такой «переведенной» команды цикла с инструкцией while:

Int counter = 0; // Переменная, в которой будет храниться значение счетчика // Мы просим процессор повторять конструкцию в фигурных скобках до тех пор, пока условие в круглых скобках будет возвращать истину. // В нашем случае counter – наш счетчик, 5 – предельное значение, условие значение счетчика меньше 5. // Но мы можем указывать совершенно разные логические операторы while (counter < 5) { digitaWrite(5, HIGH); // Будем включать светодиод counter++; // Увеличиваем значение счетчика } // Дойдя до сюда, исполняющий процессор переместится в начало блока и опять займется проверкой условий. Если условия вернут истину, команды в блоке между { и } выполнятся еще раз. Если условие не выполнится - процессор переместится к концу блока и пойдет дальше. Этот цикл больше его не заинтересует.

Тем, кто заметил в приведенном коде ошибку, ставим пятерку и пишем блок цикла по-другому:

While (counter < 5) { // Вот теперь мы будем включать разные светодиоды, с 5 (0+5) по 9 (4+5) digitalWrite(counter + 5, HIGH); counter++; }

Такого же результата можно добиться с использованием цикла FOR:

For(int counter =0; counter<5; counter ++){ digitalWrite(counter+5, HIGH); }

Как видим, в данном случае мы сразу помещаем все необходимые операции со счетчиком в одну инструкцию FOR – это гораздо удобнее, если вам нужно подсчитывать нужное количество.

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

Заключение

В этой статье мы рассмотрели очень важные конструкции языка Ардуино: циклы FOR и WHILE. Вы сможете встретить эти операторы практически в любом более-менее сложном скетче, потому что без циклов многие операции над данными были бы невозможны. Ничего сложного в синтаксисе циклов нет – вы без труда к ним привыкните и сможете активно использовать в своих проектах.

/ /

Оператор For

Конструкция for используется для повторения блока операторов, заключенных в фигурные скобки. Счетчик приращений обычно используется для приращения и завершения цикла. Оператор for подходит для любых повторяющихся действий и часто используется в сочетании с массивами коллекций данных/выводов.

Заголовок цикла for состоит из трех частей:

for (initialization ; condition ; increment ) {операторы выполняющиеся в цикле}

Инициализация (Initialization) выполняется самой первой и один раз. Каждый раз в цикле проверяется условие (condition), если оно верно, выполняется блок операторов и приращение (increment), затем условие проверяется вновь. Когда логическое значение условия становится ложным, цикл завершается.

Пример

// Затемнение светодиода с использованием ШИМ-вывода int PWMpin = 10; // Светодиод последовательно с резистором 470 ом на 10 выводов void setup() { // настройка не нужна } void loop() { for (int i=0; i <= 255; i++){ analogWrite(PWMpin, i); delay(10); } }

Цикл for в Си гораздо более гибкий, чем циклы for в других языках программирования, например, в Бейсике. Любой из трех или все три элемента заголовка могут быть опущены, хотя точки с запятой обязательны. Также операторы для инициализации, условия и приращения цикла могут быть любым допустимым в Си операторами с независимыми переменными, и использовать любой тип данных Си, включая данные с плавающей точкой (floats). Эти необычные для цикла for типы операторов позволяют обеспечить программное решение некоторых нестандартных проблем.

Например, использование умножения в операторе счетчика цикла позволяет создавать логарифмическую прогрессию:

For(int x = 2; x < 100; x = x * 1.5){ println(x); }

Генерируется: 2,3,4,6,9,13,19,28,42,63,94

Другой пример, плавное уменьшение или увеличение уровня сигнала на светодиод с помощью одного цикла for :

Void loop(){ int x = 1; for (int i = 0; i > -1; i = i + x){ analogWrite(PWMpin, i); if (i == 255) x = -1; // переключение управления на максимуме delay(10); } }