Ардуино цикли. Цикли FOR и WHILE в Arduino Вложени цикли в Arduino

Днес ще изучаваме също толкова важна част от езика за програмиране, като циклите. За какво са нужни. Например, нека си поставим цел. Трябва да запалите шест светодиода последователно с период от 50 ms и след това да ги изключите последователно със същия интервал. Е, какво може да бъде по-просто? Пишем следния код:
void setup() ( pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); ) празен цикъл () ( digitalWrite(2, HIGH); delay(50); digitalWrite(3, HIGH); delay(50); digitalWrite(4, HIGH); delay(50); digitalWrite(5, HIGH); delay(50) ; digitalWrite (7, HIGH); digitalWrite (5, LOW); digitalWrite (50); цифрови изводи от втория до седмия като изходи, а в основната програма написахме алтернативно включване на светодиода, забавяне и така нататък шест пъти. След това същото, но всеки път, когато светодиодът беше изключен. Сега го качваме в Arduino и се наслаждаваме на работата. Но все пак тук нещо не е наред. Ако се вгледате внимателно в програмния код, ще забележите, че има части от кода, които се повтарят в цялата програма. Например, повторението на паузата трябва веднага да хване окото ви. А при инициализиране на пин се променя само номерът му. Когато го включите и изключите, само номерът се променя. За такава малка програма, разбира се, можете да я оставите така, контролерът ще я изяде и няма да се задави, но ако трябва да изпълните повторен код, например 1000 пъти. Мисля, че имам достатъчно търпение да го напълня, но МК има ли достатъчно памет? Разбира се, можете да попитате защо, по дяволите, имаме нужда от 1000 еднакви операции? Е, да, трудно е да си го представим.) Но това не е проблемът, но ако имаме масив от 1000 клетки. Това често се случва, например няколко сензора записват параметри в масив и как да разберете как да оправите тази бъркотия. Би било необходимо по някакъв начин да го анализираме според някои параметри. Именно за такива инциденти са изобретени циклите. Цикълът е част от кода, който се изпълнява определен брой пъти. Една изпълнена част от програма в цикъл се нарича итерация. Броят на повторенията може да бъде от 0 до безкрайност. За да изпълните цикли на езика за програмиране, има до три опции за цикъл. Повярвайте ми, това е достатъчно за всяко сложно кодиране. Нека разгледаме всичко това по-подробно.
  • докато (условие) ()
  • do() докато (условие);
  • за (променлива за броене; условие; променлива за увеличаване на броя) ()
Първи цикъл докато (условие) (). Как работи той. След словото докатотрябва да има условие в скоби. Условието може да бъде всяко, стига да е вярно. Веднага щом условието стане невярно, цикълът ще спре да се изпълнява и програмата ще продължи да се изпълнява от следващия ред след цикъла. Нека използваме пример.
char i = 0; докато азВсъщност това, което е написано тук. Първо инициализираме променливата count iи го нулирайте. След това влизаме в цикъла и започваме да проверяваме условието в скоби. Ако стойността iе по-малко от 10, тогава изпълнете тялото на цикъла. В тялото на самия цикъл ние просто увеличаваме стойността на променливата за броене с единица и проверяваме условието отново. В нашия случай цикълът ще бъде изпълнен 10 пъти. Тоест първо смисълът iе равно на нула. Нула е по-малко от десет. След това увеличихме променливата с едно и сравнихме, едно е по-малко от десет и т.н. Веднага след като променливата за броене стане равна на десет, тогава проверяваме дали десет е по-малко от десет? Разбира се, че не и след проверка цикълът ще спре да работи. Ето как работи този цикъл. Какво трябва да направите, ако трябва да изпълните кода в тялото на цикъла само веднъж, дори и да не отговаря на условието? Има друг цикъл за това, т.нар do() докато (условие). Работи точно както предишния цикъл, с изключение на едно нещо. В този цикъл първо се изпълнява тялото на цикъла и след това се извършва тестът. Нека да видим как изглежда в кода.
char i = 0; do ( i++; ) while((i > 0) & (iВижте колко е интересно. Първо, както миналия път, инициализираме променливата за броене на нула, но в условието записваме това iбеше повече от нула и по-малко от десет. Тоест стойността на променливата трябва да е в диапазона от едно до девет. Ако го бяхме написали по този начин, използвайки предишния цикъл, той никога нямаше да бъде изпълнен. Но ние имаме вълшебна дума направи. Тоест какво ще стане. Първо, в тялото на цикъла стойността на променливата за броене ще се увеличи и ще стане единица, а това е повече от нула, условието ще стане вярно. Съответно, цикълът ще продължи да се изпълнява, докато променливата за броене стане десет. И накрая, третата версия на цикъла. Как работи той:
char i; за (i = 0; iКак работи. Първо инициираме отново променливата за броене, но без конкретна стойност. След това пишем думата за, но в скоби първо записваме нашата променлива за броене и я присвояваме първоначална стойност. След това проверяваме условието и ако е вярно, тогава изпълняваме тялото на цикъла и увеличаваме стойността на променливата за броене. По същество това е същото като докато()()така че кой цикъл да използвате зависи от вас. Няколко думи за някои точки. Например, ако пишете докато (1);, тогава цикълът ще работи вечно. Или ако със за, тогава ще изглежда така за(;;);. Бъди внимателен. Понякога, когато изпълнявате цикъл, просто наистина искате да пуснете всичко и да излезете от него, но условието не го позволява. Какво трябва да направя? Има друга команда за това прекъсване;. Веднага щом MK срещне тази команда в тялото на цикъла, той незабавно ще излезе от цикъла и ще продължи да изпълнява програмата от следващия ред след цикъла. Но какво ще стане, ако по време на работа на цикъла възникне условие, което не удовлетворява условието или например момент, в който не е необходимо да продължим да изпълняваме края на тялото на цикъла? Екипът ще ни помогне тук продължи;. Веднага щом MK се натъкне на тази команда, той зарязва всичко и продължава с изпълнението следваща итерацияцикъл. Надявам се, че обясних всичко ясно. След като получихме това знание, нека пренапишем нашата програма, но използвайки цикли.
void setup() (байт i = 2; // Променлива за броене while(i // Ако i е по-малко от 8, тогава се изпълнява тялото на цикъла ( pinMode(i, OUTPUT); // Инициализиране на пинове, започващи от 2 i++; //Увеличаване на променливата за броене с едно) ) void loop() ( byte i = 2; while(iНека да разгледаме по-отблизо. Първо инициализирахме променливата за броене iи му присвои стойност две. Защо две? Но тъй като специално избрах пинове от втори до седми, за да съм сигурен, че първоначалната стойност изобщо няма значение. Оказа се някаква игра на думи) Е, разбира се, да. След това записваме условието за цикъл. Трябва да направим шест итерации, тъй като имаме шест светодиода. Страхотно, мислим, че две плюс шест е равно на осем. Да, така че трябва да проверим променливата за броене, докато стане по-малко от осем. Това са го написали while(i . Сега нашият цикъл ще се изпълнява шест пъти. Какво трябва да направим вътре в тялото на цикъла? Нищо сложно, просто въведете функцията за инициализация на изхода на изхода, просто заменете променлива за броене вместо изходния номер. Какво е Веднага след като MK влезе в цикъла на тялото, нека да разгледаме подадените аргументи и да имаме променлива за отчитане интелигентният MK ще погледне каква е променливата и гордо ще я извади. Е, чудесно, нека инициализираме втория изход и ще увеличим стойността на променливата за броене проверете условието. Да, три е по-малко от осем, нека направим всичко отново, само че променливата вече има три чрез цикъла ще настроим всички изходи, от които се нуждаем. Освен това увеличаването на променливата за броене с единица не е строго условие. Никой не ви пречи да напишете нещо подобно: i = ((127*i)/31) & 0xF4;И това също ще работи, ако условието е вярно след изпълнение. За цикъла няма значение какво се случва в тялото; той се интересува дали условието е вярно или не. Това е всичко. В следващия урок ще разгледаме функциите, защо са необходими и ще се опитаме да напишем наши собствени.

Всеки език за програмиране има набор от контролни инструкции, които позволяват един и същ код да се изпълнява многократно (цикъл), избор на подходяща част от кода (условия) и инструкции за излизане от текущата част от кода.

Arduino IDE заимства повечето от необходимите контроли от C/C++. Техният синтаксис е идентичен с C. По-долу ще опишем накратко синтаксиса им.

оператор if

Инструкцията if ви позволява да изпълните определен фрагмент от програма в зависимост от резултата от проверката на определено условие. Ако условието е изпълнено, тогава програмният код ще бъде изпълнен, но ако условието не е изпълнено, тогава програмният код ще бъде пропуснат. Синтаксисът на командата if е както следва:

Ако (условие) ( инструкция1; инструкция2; )

Условието може да бъде всяко сравнение на променлива или стойност, върната от функция. Основният критерий за условие if е, че отговорът винаги трябва да бъде или вярно, или невярно. Примери за условия за оператор if:

If(a!=2) ( ) if(x<10) { } if(znak==’B’) { }

Вътре в скобите, които са написани в условието, можете да изпълните кода.

Хората, които започват да учат програмиране, често правят грешката да приравняват стойността на определена променлива с помощта на един знак "=". Такава нотация ясно показва присвояването на стойност на променлива и следователно условието винаги ще бъде „вярно“, тоест изпълнено. Проверката дали дадена променлива е равна на определена стойност винаги се обозначава с двоен знак за равенство (==).

Можете да използвате състоянието на функцията като условие, например:

If(init()) ( Serial.print("ok"); )

Горният пример ще бъде изпълнен по следния начин: В първата стъпка се извиква функцията init(). Тази функция връща стойност, която ще се тълкува като "true" или "false". В зависимост от резултата от сравнението ще бъде изпратен текст „ок“ или няма да бъде изпратено нищо.

Изявление If… else

Разширен оператор if е операторът if….else. Той гарантира, че една част от кода се изпълнява, когато дадено условие е вярно (true), а втората част от кода се изпълнява, когато условието не е изпълнено (false). Синтаксисът на оператора f if….else е както следва:

If (условие) ( // команда A ) else ( // команда B )

Командите "A" ще бъдат изпълнени само когато условието е изпълнено, командата "B" ще бъде изпълнена, когато условието не е изпълнено. Едновременното изпълнение на командата “A” и “B” не е възможно. Следният пример показва как да използвате синтаксиса if...else:

If (init()) ( Serial.print("ok"); ) else ( Serial.print("error"); )

По този начин можете да проверите правилното изпълнение на функцията и да информирате потребителя за това.

Често срещана практика е състоянието да се отрича. Това се дължи на факта, че функция, която е изпълнена правилно, връща стойността 0, а функция, която е изпълнена неправилно по някаква причина, връща ненулева стойност.

Обяснението за това „усложнение на живота“ е просто. Ако функцията се изпълнява правилно, тогава това е единствената информация, от която се нуждаем. В случай на грешка, понякога си струва да разберете какво се е объркало и защо функцията не е била изпълнена правилно. И тук на помощ идват числа, различни от нула, т.е. с помощта на цифрови кодове можем да определим вида на грешката. Например 1 - проблем с четенето на някаква стойност, 2 - няма място в паметта или на диска и т.н.

Последният модифициран пример показва как да се извика функция, която връща нула, когато се изпълнява правилно:

If (!init()) ( Serial.print("ok"); ) else ( Serial.print("error"); )

Изявление за превключване на регистъра

Инструкцията if ви позволява да тествате само едно условие. Понякога е необходимо да се извърши едно от действията в зависимост от върнатата или прочетена стойност. Операторът за множествен избор на switch е идеален за това. Синтаксисът на командата switch е показан по-долу:

Switch (var) ( case 1: //инструкция за var=1 прекъсване; case 2: //инструкция за var=2 break; default: //инструкция по подразбиране (ако var е различна от 1 и 2) )

В зависимост от стойността на променливата var се изпълняват инструкции в конкретни блокове. Етикетът case показва началото на блок за определената стойност. Например случай 1: означава, че този блок ще бъде изпълнен за стойност на var равна на едно.

Всеки блок трябва да бъде прекратен с команда за прекъсване. Той прекъсва по-нататъшното изпълнение на командата switch. Ако командата за прекъсване е пропусната, тогава инструкциите ще бъдат изпълнени в следващите блокове преди командата за прекъсване. Етикетът по подразбиране не е задължителен, точно както в оператор if. Инструкциите, разположени в блока по подразбиране, се изпълняват само когато стойността на променливата var не съответства на нито един шаблон.

Често се случва едни и същи инструкции да бъдат изпълнени за една от няколко стойности. Това може да се постигне по следния начин:

Превключвател (x) ( случай 1: //инструкция за прекъсване x=1; случай 2: случай 3: случай 5: //инструкция за прекъсване x=2 или 3 или 4; случай 4: //инструкция за прекъсване x=4 случай 6: // инструкция за x=6 прекъсване по подразбиране: // инструкция по подразбиране (ако x е различно от 1,2,3,4,5,6)

В зависимост от стойността на променливата x ще бъде изпълнен съответният блок от инструкции. Повтарянето на случай 2: случай 3: случай 5: информира компилатора, че ако променлива x има стойност 2, 3 или 5, тогава ще бъде изпълнена същата част от кода.

за изявление

Операторът for се използва за изпълнение на един и същ код отново и отново. Често е необходимо да се изпълняват едни и същи инструкции, като се променя само стойността на някоя променлива. Цикълът for е идеален за това. Синтаксисът на командата е както следва:

Int i; за (i=0;i<10;i++) { // инструкции для выполнения в цикле }

Първият параметър, даден в оператор for, е началната стойност на променливата. Друг елемент е проверка на условието за продължаване на цикъла. Цикълът се изпълнява, докато условието е изпълнено. Последният елемент е промяната в стойността на променливата. Най-често увеличаваме или намаляваме стойността му (според необходимостта). В този пример инструкциите, съдържащи се в цикъла, ще бъдат изпълнени при i=0...9.

Често там се декларира променлива, използвана в цикъл:

For(int i=0;i<10;i++) { // инструкции для выполнения в цикле }

Променлива, която се използва за преброяване на следващите стъпки на цикъла, може да се използва в него за извикване на функция със съответните параметри.

For(int i=10;i>0;i—) ( Serial.print(i); // ще бъдат изпратени числа 10,9,8,7,6,5,4,3,2,1)

декларация while

Цикълът for е идеален, когато искаме да направим броене. В ситуация, в която трябва да извършим определени действия в резултат на някакво събитие, което не е непременно предвидимо (например чакаме да бъде натиснат бутон), тогава можем да използваме оператора while, който изпълнява блока с оператори като стига условието да е изпълнено. Синтаксисът на оператора while е както следва:

Докато (условие) ( // блок от инструкции за изпълнение)

Важно е проверката на състоянието да се извършва в началото на цикъла. Може да се случи така, че инструкциите вътре в цикъла while никога да не бъдат изпълнени. Също така е възможно да се създаде безкраен цикъл. Нека да разгледаме два примера:

Int x=2; while(x>5) ( Serial.print(x); ) —————————————— int y=5; докато (y>0) ( Serial.print (y); )

Първият блок от изрази, намиращ се вътре в while, никога няма да бъде изпълнен. Променливата x има стойност две и няма да стане по-голяма от 5. Във втория пример имаме работа с безкраен цикъл. Променливата "y" има стойност 5, т.е. по-голяма от нула. Няма промяна в променливата "y" вътре в цикъла, така че цикълът никога няма да завърши.

Това е често срещана грешка, когато забравим да променим параметър, който причинява прекратяване на цикъла. По-долу са два правилни примера за използване на цикъл while:

Int x=0; докато (x<10) { //блок инструкций x++; } —————————————- while(true) { if(условие) break; // блок инструкций }

В първия пример се погрижихме да променим стойността на променливата, която се проверява в условието. В резултат на това цикълът в крайна сметка ще приключи. Във втория пример умишлено е създаден безкраен цикъл. Този цикъл е еквивалентен на функцията loop() в Arduino IDE. Освен това вътре в цикъла е въведена проверка на условието, след което цикълът завършва с командата break.

do…while оператор

Разновидност на цикъла while е цикълът do...while. Освен по синтаксис, той се различава и по мястото, където се проверява условието. В случай на do...while, условието се проверява след изпълнение на блока от инструкции. Това означава, че блокът от инструкции в тялото на цикъла ще бъде изпълнен поне веднъж. По-долу е синтаксисът на командата do...while:

Do ( // блок от инструкции ) докато (условие)

Всичко, което е написано за оператора while важи и за do...while. По-долу е даден пример за използване на do...while цикъл:

Int x=10; do ( // блок от инструкции x—; ) while(x>0); —————————————- do ( // блок от инструкции if (условие) break; ) while(true);

изявление за прекъсване

Командата break ви позволява да излезете от цикъла (do...while, for, while) и да излезете от опцията switch. В следния пример разгледайте изпълнението на командата break:

За(i=0;i<10;i++) { if(i==5) break; Serial.print(i); }

Цикълът трябва да се изпълни за числата от 0 до 9, но за числото 5 е изпълнено условие, което задейства командата break. Това ще излезе от цикъла. В резултат само числата 0,1,2,3,4 ще бъдат изпратени към серийния порт (Serial.print).

Продължи оператор

Операторът за продължаване кара инструкциите на цикъла (do...while, for, while) да спрат изпълнението за текущата стойност и да продължат към следващата стъпка на цикъла. Следният пример показва как работи операторът за продължаване:

За(i=0;i<10;i++) { if(i==5) continue; Serial.print(i); }

Както не е трудно да се забележи, цикълът ще бъде изпълнен за стойности от 0 до 9. За стойност 5 ще бъде изпълнена командата за продължаване, в резултат на което инструкциите след тази команда няма да бъдат изпълнени. В резултат на това числата 0,1,2,3,4,6,7,8,9 ще бъдат изпратени към серийния порт (Serial.print).

изявление за връщане

Операторът return завършва изпълнението на извиканата функция и връща стойност от определен тип. Можете да посочите число, символ или променлива от определен тип като параметър на командата. Важно е връщаната стойност да съответства на типа на декларираната функция. Следният пример показва как да използвате израза return:

Int checkSensor())( if (analogRead(0) > 400) ( // четене на аналоговия вход връща 1; // За стойности, по-големи от 400, 1 се връща else( return 0; // за други, 0 е се завърна) )

Както можете да видите, можете да използвате множество оператори за връщане в една функция, но само един от тях винаги ще работи. Приемливо е да се използва оператор за връщане без параметри. Това ви позволява да прекратите преждевременно функция, която не връща никаква стойност.

Void function_name() ( инструкция1; ако(x==0) връщане; инструкция2; инструкция3; )

В примера по-горе инструкция1 ще се изпълнява при всяко извикване на функцията. Изпълнението на инструкция2 и инструкция3 зависи от резултата от командата if. Ако условието е вярно (вярно), командата за връщане ще бъде изпълнена и функцията ще излезе.

В случай, че условието не е изпълнено, командата return също не се изпълнява, но се изпълняват инструкциите instruction2 и instruction3, след което функцията приключва работата си.

изявление goto

Поради идеологически причини е необходимо да пропуснете това описание... Операторът goto е команда, която не трябва да се използва в нормалното програмиране. Това причинява сложност на кода и е лош навик за програмиране. Силно препоръчваме да не използвате тази команда във вашите програми. Тъй като goto е включен в официалната документация на уебсайта arduino.cc, ето кратко описание за него. синтаксис на командата goto:

…. goto mark; // отидете на реда с надпис 'metka' ..... .... …. metka: // етикет, с който програмата ще продължи да работи...

Командата ви позволява да отидете до определения знак, т.е. до място в програмата.

Цикли, използващи оператори заИ докатоса една от най-важните конструкции на езика C++, който е в основата на Arduino. Срещат се в абсолютно всяка скица, дори и да не го знаете. В тази статия ще разгледаме по-подробно циклите, ще разберем каква е разликата между for и while, как можете да опростите писането на програма с тяхна помощ и какви грешки трябва да се избягват.

Ако все още сте начинаещ програмист и искате да разберете какво е цикъл и защо е необходим, разгледайте следващия раздел на тази статия с подробно описание.

Операторът WHILE се използва в C++ и Arduino за повтаряне на едни и същи команди произволен брой пъти. В сравнение с цикъла FOR, цикълът WHILE изглежда по-прост; той обикновено се използва, когато не е необходимо да броим броя на повторенията в променлива, а просто трябва да повтаряме кода, докато нещо се промени или настъпи някакво събитие.

WHILE синтаксис

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

Всяка езикова конструкция, която връща булева стойност, може да се използва като условия. Условията могат да бъдат операции за сравнение, функции, константи, променливи. Както при всички други логически операции в Arduino, всяка стойност, различна от нула, ще се възприема като истина, а нула – като невярна.

// Безкраен цикъл while(true)( Serial.println("Waiting..."); ) // Цикъл, който работи, докато стойността на функцията checkSignal() се промени while(!checkSignal())( Serial.println ("Очакване..."); )

Обърнете внимание, че операторът while може да се използва без блокиране на блока с фигурни скоби, в който случай ще се повтори първата срещана команда след цикъла. Силно не се препоръчва да се използва без фигурни скоби, т.к в този случай е много лесно да се направи грешка. Пример:

While(true) Serial.print("Изчакване за прекъсване"); забавяне (1000);

В този случай надписът ще се показва в безкраен цикъл без паузи, тъй като командата delay(1000) няма да бъде повторена. Можете да прекарате много време в хващане на такива грешки - много по-лесно е да използвате къдрава скоба.

Пример за използване на цикъл while

Най-често докато се използва за изчакване на някакво събитие. Например, готовността на серийния обект за работа.

Serial.begin(9600); while (!Serial) ( ; // Някои платки Arduino изискват да изчакате, докато серийният порт се освободи)

Пример за изчакване на знак да пристигне от външни устройства чрез UART:

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

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

FOR цикъл в Arduino

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

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

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

Най-простият пример:

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

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

Променливата стъпка може да е различна. Ето примери:

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

do while цикъл

В някои случаи трябва да организираме цикъла по такъв начин, че инструкциите на блока да се изпълняват поне веднъж и след това да се извърши проверката. За такива алгоритми можете да използвате конструкцията do while. Пример:

Направете ( Serial.println("Работи"); ) докато (checkSomething());

Тази версия на цикъла не представлява никакви затруднения - просто преместихме блока с условията надолу, така че цялото съдържание във фигурните скоби след оператора do ще бъде изпълнено преди първата проверка.

Продължете и прекъснете твърденията

Има ситуации, когато трябва спешно да прекъснете изпълнението на цикъл вътре в блок за цикъл, без да чакате да преминете към блока за проверка на условието. За да направите това, можете да използвате оператора прекъсвам:

Докато (true) ( ​​​​if (checkSomething()) ( прекъсване; ) )

Ако просто искаме да спрем напредъка на текущата итерация, но не и да излезем от цикъла, а да отидем до блока за проверка на условието, тогава трябва да използваме оператора продължи:

Докато (вярно) ( ​​if (проверете нещо()) ( продължи; ) )

Операторите continue и break могат да се използват с всички варианти на цикли FOR и WHILE.

Вложени цикли в Arduino

Всички варианти на цикли могат лесно да се комбинират един с друг, създавайки вложени структури. Променливите, дефинирани в блока на „надлежащия“ цикъл, ще бъдат налични във вътрешния. Най-често срещаният пример за този вид цикъл е преминаването през двумерни масиви. В следващия пример използваме двоен цикъл: първият ще премине през редовете (променлива 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]); } } }

Повече за циклите

Ако никога не сте работили с цикли, нека се потопим малко в света на теорията и да разберем какво представляват циклите и защо имаме нужда от тези мистериозни езикови конструкции.

Защо се нуждаем от цикъл?

Всъщност основната задача на цикъла е да повтаря едни и същи езикови конструкции няколко пъти. Тази необходимост възниква в почти всяка програма и със сигурност нито една скица на Arduino не може да мине без цикъл - функцията 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);
  • Можете лесно да се провалите на интервю във всяка нормална софтуерна компания, като покажете на интервюиращия този код.

От всичко това можем да заключим, че повторното използване на едни и същи низове отново и отново трябва почти винаги да се избягва и да се заменя с цикли. Освен това в много ситуации е невъзможно да се направи без цикли; нищо не може да ги замени. Не можете да промените броя на повторенията на кода, докато програмата работи. Например, трябва да обработите всеки елемент масив от данни, получени от външни устройства. Никога няма да предвидите колко данни ще има, колко пъти ще се повтори обработката и следователно няма да можете да вмъкнете необходимия брой инструкции към момента на писане на статията.

И тук на помощ идват циклите.

Синтаксични правила

Цикъл в Arduinoе специален програмен блок, който ще бъде извикан определен брой пъти по време на изпълнение на програмата. В рамките на този блок ние описваме самите команди, които ще бъдат извикани, и правилата, по които контролерът ще определи колко пъти трябва да бъдат извикани.

В нашия пример по-горе можем да кажем на контролера следното:

Повторете командата digitalWrite 5 пъти

В един идеален свят с програмисти-роботи това вероятно би било достатъчно, но тъй като говорим с компютъра на C++, трябва да преведем тази фраза на този език:

Повторете командата – трябва да използвате специални инструкции, които казват на контролера, че нещо интересно предстои да започне с цикли while или for

digitalWrite – оставете го както е, но го напишете веднъж и го оградете във фигурни скоби. Какво да правим с пин номерата - точно отдолу.

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

Нека да разгледаме пример за такава "преведена" команда за цикъл с оператор while:

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

За тези, които са забелязали грешка в дадения код, даваме пет и записваме блока на цикъла по различен начин:

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

Същият резултат може да се постигне с помощта на FOR цикъл:

For(int брояч =0; брояч<5; counter ++){ digitalWrite(counter+5, HIGH); }

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

Можете да получите подробна информация за правилата за използване на цикли в съответните раздели на тази статия.

Заключение

В тази статия разгледахме много важни конструкции на езика Arduino: цикли FOR и WHILE. Можете да намерите тези оператори в почти всяка повече или по-малко сложна скица, защото без цикли много операции с данни биха били невъзможни. Няма нищо сложно в синтаксиса на циклите - можете лесно да свикнете с тях и да ги използвате активно в проектите си.

Нека да разгледаме как работят операторите за цикли for, while и do while в Arduino IDE, как правилно да използвате цикли в скици и какви грешки да избягвате. Използвайки прости примери, ще демонстрираме как можете да спрете цикъл или да преминете от един цикъл към друг. За да разберете правилността на писане на цикли, първо трябва да проучите видовете и свойствата на алгоритмите в роботиката.

Как работят циклите в Arduino IDE

Всеки цикъл в C++ и езика за програмиране Arduino е действие, което се повтаря много или безкраен брой пъти. Нито една програма за микроконтролера Arduino не е завършена без цикъл, например празен цикъл се извиква в безкраен цикъл. Има три вида оператори за цикъл: for, while и do while - нека да разгледаме всеки оператор и да видим как работят с примери.

Принципът на работа на for и while може да бъде обяснен със следните прости примери. Цикълът for се изпълнява краен брой пъти (посочено в условието на оператора); той се използва, когато програмата, например, изисква светодиодът да мига няколко пъти. Цикълът while може да работи безкрайно, например, когато светодиодът на Arduino мига, докато данните от сензора се променят.

Описание на for цикъла в Arduino с пример

Конструкцията for в Arduino се дефинира, както следва:

за (инициализация; условие; промяна)( )

Цикъл for се използва за повтаряне на специфични команди, затворени във фигурни скоби. Този цикъл е подходящ за извършване на всякакви повтарящи се действия.
При инициализациясъздава се променлива и се присвоява начална стойност.
IN състояниезаписва се стойността на променливата, при която ще се изпълни цикълът.
IN промянапоказва как променливата ще се промени на всяка стъпка от цикъла.

за (байт i=0; i<=5; i++){ digitalWrite (13, HIGH ); delay (500); digitalWrite (13, LOW ); delay (500); }

В примерната скица е зададена променлива с начална стойност i=0, условието гласи, че цикълът ще работи, докато променливата стане равна или по-голяма от пет аз<=5 . Промяната гласи, че променливата ще се увеличава с единица на всяка стъпка от цикъла. И накрая, for цикълът излиза, когато променливата е равна на пет, така че светодиодът ще мига пет пъти, преди цикълът да приключи.

Променливата стъпка (промяна) може да бъде всякаква. Ако е необходимо да се увеличи променлива с две единици наведнъж, тогава промяната в брояча трябва да бъде написана, както следва: i=i+2. Цикълът for може да се използва в процедурата за настройка на void, например, за да посочи работния режим на няколко пина наведнъж. А също и в процедурата за void loop, например в програмата за последователно включване на светодиоди на Arduino.



Описание на програмата Arduino с цикли for и while

Описание на Arduino while цикъл с пример

Конструкцията while в Arduino се дефинира, както следва:

докато (условие)( // команди, които ще се повтарят }

Цикълът while ще работи непрекъснато и безкрайно, докато условието в скобите е вярно. Изходът от цикъла ще бъде достигнат, когато променливата в условието while се промени, така че нещо трябва да променя стойността си. Променливата може да бъде променена в програмния код вътре в цикъл или при четене на стойности от всеки сензор, например от ултразвуков далекомер HC-SR04.

байт i=0; // трябва да създадем променлива преди цикъладокато аз<5){ // цикълът се изпълнява, докато i е по-малко от 5 digitalWrite(13, HIGH); забавяне (500); digitalWrite(13, LOW); забавяне (500); i++; // промяна на променлива }

Когато използвате функцията while, променливата трябва да бъде създадена преди началото на цикъла. В примерната скица светодиодът ще мига пет пъти преди цикълът да приключи. Ако не промените променливата във фигурните скоби i++, тогава цикълът ще се повтаря безкрайно. Вторият начин за излизане от цикъла while на Arduino Uno е да се прочетат данни от сензора и да се използва оператор if за промяна на променливата.

Друг цикъл, който може да се използва в Arduino IDE, е цикълът на постусловието. направете...докато. Когато използвате тази конструкция, командите в цикъл ще бъдат изпълнени поне веднъж, независимо от условието, тъй като условието се проверява след изпълнение на тялото на цикъла. В следния пример на код светодиодът ще се включи независимо от показанията на сензора и едва тогава ще провери постусловието.

int вода; // създаване на променлива преди цикъла do ( digitalWrite (13, HIGH ); water = analogRead (AO); ) while (water<5) // проверка на сензора digitalWrite(13, LOW);

Как да излезете от цикъла while или for

В случай, че е необходимо да се излезе от тялото на цикъла, независимо от зададените условия, се използва операторът прекъсвамили гото. Командата break ви позволява да излезете от цикъла и програмата ще продължи да изпълнява следните команди. Операторът goto ви позволява не само да излезете от цикъла, но и да продължите да изпълнявате програмата от желаната точка по етикета, например можете да отидете до друг цикъл в Arduino.