Arduino - instrucțiuni de control. Arduino face loop Arduino în timp ce bucla iese

Astăzi vom studia o parte la fel de importantă a limbajului de programare, cum ar fi buclele. Pentru ce sunt necesare. De exemplu, să ne stabilim un obiectiv. Trebuie să aprindeți șase LED-uri pe rând cu o perioadă de 50 ms, apoi să le stingeți pe rând cu același interval. Ei bine, ce poate fi mai simplu? Scriem următorul cod:
void setup() ( pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); ) bucla void () (digitalWrite(2, HIGH); delay(50); digitalWrite(3, HIGH); delay(50); digitalWrite(4, HIGH); delay(50); digitalWrite(5, HIGH); delay(50) ; digitalWrite(6, HIGH); delay(50); digitalWrite(7, HIGH); delay(50); digitalWrite(2, LOW); delay(50); digitalWrite(3, LOW); delay(50); digitalWrite (4, LOW); delay(50); digitalWrite(5, LOW); delay(50); digitalWrite(6, LOW); delay(50); digitalWrite(7, LOW); delay(50); ) În primul rând, Am inițializat șase pini digitali de la al doilea la al șaptelea ca ieșiri, iar în programul principal am scris alternativ aprinderea LED-ului, o întârziere și așa mai departe de șase ori. După aceea același lucru, dar de fiecare dată LED-ul a fost stins. Acum îl încărcăm în Arduino și ne bucurăm de lucru. Dar totuși, ceva nu este în regulă aici. Dacă te uiți cu atenție la codul programului, vei observa că există părți ale codului care se repetă pe tot parcursul programului. De exemplu, repetarea pauzei ar trebui să-ți atragă imediat atenția. Și atunci când inițializați un pin, doar numărul acestuia se schimbă. Când îl porniți și îl opriți, se schimbă doar numărul. Pentru un program atât de mic, desigur, îl puteți lăsa așa, controlerul îl va mânca și nu se va sufoca, dar dacă trebuie să executați cod repetat, de exemplu, de 1000 de ori. Cred că am destulă răbdare să-l umplu, dar MK are suficientă memorie? Desigur, vă puteți întreba, de ce naiba avem nevoie de 1000 de operații identice? Ei bine, da, este greu de imaginat.) Dar nu aceasta este problema, dar dacă avem o serie de 1000 de celule. Acest lucru se întâmplă adesea, de exemplu, mai mulți senzori scriu parametri într-o matrice și cum îți dai seama cum să rezolvi această mizerie. Ar fi necesar să-l analizăm cumva în funcție de niște parametri. Pentru astfel de incidente au fost inventate ciclurile. O buclă este o bucată de cod care este executată de un anumit număr de ori. O parte executată a unui program într-o buclă se numește iterație. Numărul de iterații poate fi de la 0 la infinit. Pentru a executa bucle în limbajul de programare, există până la trei opțiuni de bucle. Crede-mă, este suficient pentru orice codare sofisticată. Să ne uităm la toate acestea mai în detaliu.
  • în timp ce (condiție) ()
  • do() în timp ce(condiție);
  • pentru (variabila de numărare; condiție; creșterea variabilă de numărare) ()
Primul ciclu în timp ce (condiție) (). Cum lucrează. După cuvânt in timp ce trebuie să existe o condiție între paranteze. Condiția poate fi orice, atâta timp cât este adevărată. De îndată ce condiția devine falsă, bucla se va opri și programul va continua să ruleze de la următoarea linie după buclă. Să folosim un exemplu.
char i = 0; in timp ce eu De fapt, ce scrie aici. Mai întâi inițializam variabila de numărare iși resetați-l. Apoi, intrăm în buclă și începem să verificăm starea dintre paranteze. Dacă valoarea i este mai mic de 10, apoi executați corpul buclei. În corpul buclei în sine, creștem pur și simplu valoarea variabilei de numărare cu una și verificăm din nou condiția. În cazul nostru, bucla va fi executată de 10 ori. Adică mai întâi sensul i este egal cu zero. Zero este mai puțin de zece. Apoi, am mărit variabila cu unu și am comparat, unul este mai mic de zece și așa mai departe. De îndată ce variabila de numărare devine egală cu zece, atunci verificăm, zece este mai mic decât zece? Bineînțeles că nu, iar după verificare, ciclul va înceta să funcționeze. Așa funcționează acest ciclu. Ce ar trebui să faceți dacă trebuie să executați codul din corpul buclei o singură dată, chiar dacă nu satisface condiția? Există un alt ciclu pentru asta numit face() în timp ce(condiție). Funcționează exact la fel ca și ciclul anterior, cu excepția unui singur lucru. În această buclă, corpul buclei este executat mai întâi și apoi are loc testul. Să vedem cum arată în cod.
char i = 0; face ( i++; ) while((i > 0) & (i Uite ce interesant este. Mai întâi, ca și data trecută, inițializam variabila de numărare la zero, dar în condiția scriem asta i a fost mai mult de zero și mai puțin de zece. Adică, valoarea variabilei trebuie să se situeze în intervalul de la unu la nouă. Dacă l-am fi scris în acest fel folosind bucla anterioară, nu ar fi fost niciodată executat. Dar avem un cuvânt magic do. Adică ce se va întâmpla. În primul rând, în corpul buclei, valoarea variabilei de numărare va crește și va deveni una, iar aceasta este mai mare decât zero, condiția va deveni adevărată. În consecință, bucla va continua să se execute până când variabila de numărare este egală cu zece. Și în sfârșit, a treia versiune a ciclului. Cum lucrează:
char i; pentru(i = 0; i Cum functioneaza. Mai întâi, inițiam din nou variabila de numărare, dar fără o valoare specifică. Apoi scriem cuvântul pentru, dar între paranteze scriem mai întâi variabila noastră de numărare și îi atribuim o valoare inițială. Apoi verificăm condiția și dacă este adevărată, atunci executăm corpul buclei și creștem valoarea variabilei de numărare. În esență, acesta este același cu in timp ce()() deci ce ciclu să folosești depinde de tine. Câteva cuvinte despre unele puncte. De exemplu, dacă scrii în timp ce(1);, atunci bucla va rula pentru totdeauna. Sau dacă cu pentru, atunci va arăta așa pentru(;;);. Atenție. Uneori, atunci când executați un ciclu, doriți doar să lăsați totul și să părăsiți el, dar condiția nu vă permite. Ce ar trebuii să fac? Există o altă comandă pentru asta pauză;. De îndată ce MK întâlnește această comandă în corpul buclei, va ieși imediat din buclă și va continua să execute programul din următoarea linie după buclă. Dar dacă, în timpul funcționării buclei, apare o condiție care nu satisface condiția sau, de exemplu, un moment în care nu trebuie să continuăm să executăm sfârșitul corpului buclei? Echipa ne va ajuta aici continua;. De îndată ce MK întâlnește această comandă, renunță la totul și trece la următoarea iterație a buclei. Sper că am explicat totul clar. Acum, după ce am primit aceste cunoștințe, să ne rescriem programul, dar folosind bucle.
void setup() (octetul i = 2; // Variabilă de numărare while(i // Dacă i este mai mic de 8, atunci executați corpul buclei ( pinMode(i, OUTPUT); // Inițializați pinii începând de la 2 i++; //Măriți variabila de numărare cu una) ) bucla void() ( octet i = 2; while(i Să aruncăm o privire mai atentă. Mai întâi am inițializat variabila de numărare iși i-a atribuit o valoare de doi. De ce doi? Dar pentru că am selectat în mod special pini de la al doilea până la al șaptelea, pentru a mă asigura că valoarea inițială nu contează deloc. S-a dovedit a fi un fel de joc de cuvinte) Ei bine, desigur, da. Apoi scriem condiția buclei. Trebuie să facem șase iterații, deoarece avem șase LED-uri. Grozav, credem că doi plus șase sunt egal cu opt. Da, deci trebuie să verificăm variabila de numărare până când este mai mică de opt. Asta au scris ei while(i . Acum bucla noastră va rula de șase ori. Ce trebuie să facem în corpul buclei? Nimic complicat, trebuie doar să introduceți funcția de inițializare a ieșirii pe ieșire, doar să înlocuiți o variabilă de numărare în loc de numărul de ieșire. Ce este truc.De îndată ce MK intră în bucla de corp, înainte de a executa funcția de inițializare a ieșirii, să ne uităm la argumentele care sunt transmise.Unul dintre ele ar trebui să aibă numărul de ieșire și avem acolo o variabilă de numărare.Ce ar trebui să avem face? Dar nimic, un MK inteligent se va uita la ce variabilă este acolo și va scoate cu mândrie numărul. Și avem un doi acolo. Ei bine, grozav, să inițializam a doua ieșire. După aceea, vom crește valoarea lui variabila de numărare cu o alta și verificați condiția. Da, trei este mai puțin de opt, să facem totul din nou, doar variabila acum are trei. Asta înseamnă că vom inițializa ieșirea pentru a treia oară și apoi vom crește numărarea variabilă câte una.În acest fel, parcurgând bucla, vom seta toate ieșirile de care avem nevoie.Mai mult, creșterea variabilei de numărare cu una nu este o condiție strictă. Nimeni nu te deranjează să scrii așa ceva: i = ((127*i)/31) & 0xF4;Și acest lucru va funcționa și dacă condiția este adevărată după execuție. Pentru buclă, nu contează ce se întâmplă în organism; este interesat dacă condiția este adevărată sau nu. Asta e tot. În lecția următoare ne vom uita la funcții, de ce sunt necesare și vom încerca să le scriem pe ale noastre.

Să vedem cum funcționează operatorii de bucle for, while și do while în Arduino IDE, cum să folosiți corect buclele în schițe și ce greșeli trebuie evitate. Folosind exemple simple, vom demonstra cum puteți opri o buclă sau puteți trece de la o buclă la alta. Pentru a înțelege corectitudinea ciclurilor de scriere, în primul rând, ar trebui să studiați tipurile și proprietățile algoritmilor în robotică.

Cum funcționează buclele în IDE-ul Arduino

Orice buclă din C++ și limbajul de programare Arduino este o acțiune care se repetă de mai multe ori sau de un număr infinit de ori. Niciun program pentru microcontrolerul Arduino nu este complet fără o buclă, de exemplu, o buclă goală este numită într-o buclă infinită. Există trei tipuri de operatori de buclă: for, while și do while - să ne uităm la fiecare operator și să vedem cum funcționează folosind exemple.

Principiul de funcționare al for și while poate fi explicat cu următoarele exemple simple. Bucla for este executată de un număr finit de ori (indicat în condiția operatorului); este folosită atunci când programul, de exemplu, necesită ca LED-ul să clipească de mai multe ori. Bucla while poate rula la nesfârșit, de exemplu, când LED-ul de pe Arduino clipește până când datele de la senzor se schimbă.

Descrierea buclei for din Arduino cu un exemplu

Construcția for din Arduino este definită după cum urmează:

pentru (inițializare; condiție; modificare)( )

O buclă for este folosită pentru a repeta anumite comenzi cuprinse între acolade. Acest ciclu este potrivit pentru efectuarea oricăror acțiuni repetitive.
La initializare se creează o variabilă și se atribuie o valoare inițială.
ÎN condiție se înregistrează valoarea variabilei la care se va executa bucla.
ÎN Schimbare indică modul în care variabila se va schimba la fiecare pas al buclei.

pentru (octetul i=0; i<=5; i++){ digitalWrite (13, HIGH ); delay (500); digitalWrite (13, LOW ); delay (500); }

În schița exemplu, este setată o variabilă cu o valoare inițială i=0, condiția spune că bucla va rula până când variabila este egală sau mai mare de cinci i<=5 . Modificarea afirmă că variabila va fi incrementată cu una la fiecare pas al buclei. În cele din urmă, bucla for iese atunci când variabila este egală cu cinci, așa că LED-ul va clipi de cinci ori înainte ca bucla să se încheie.

Pasul variabil (modificarea) poate fi orice. Dacă este necesar să creșteți o variabilă cu două unități simultan, atunci modificarea contorului ar trebui să fie scrisă după cum urmează: i=i+2. Bucla for poate fi utilizată în cadrul procedurii de configurare a golului, de exemplu, pentru a indica modul de funcționare a mai multor pini simultan. Și, de asemenea, în procedura buclei goale, de exemplu, în programul de pornire secvențială a LED-urilor pe Arduino.



Descrierea programului Arduino cu bucle for și while

Descrierea buclei Arduino while cu un exemplu

Construcția while din Arduino este definită după cum urmează:

în timp ce (condiție)( // comenzi care vor fi repetate }

Bucla while va rula continuu și la nesfârșit atâta timp cât condiția dintre paranteze este adevărată. Ieșirea buclei va fi atinsă atunci când variabila din condiția while se schimbă, așa că ceva trebuie să își schimbe valoarea. Variabila poate fi modificată în codul programului în interiorul unei bucle sau la citirea valorilor de la orice senzor, de exemplu, de la un telemetru cu ultrasunete HC-SR04.

octet i=0; // trebuie să creăm o variabilă înaintea buclei in timp ce eu<5){ // bucla rulează atâta timp cât i este mai mic de 5 digitalWrite(13, HIGH); întârziere (500); digitalWrite(13, LOW); întârziere (500); i++; // schimba variabila }

Când utilizați funcția while, variabila trebuie creată înainte de a începe bucla. În schița exemplu, LED-ul va clipi de cinci ori înainte ca ciclul să se încheie. Dacă nu modificați variabila în interiorul acoladelor i++, apoi ciclul se va repeta la nesfârșit. A doua modalitate de a ieși din bucla while a Arduino Uno este să citiți datele de la senzor și să utilizați o instrucțiune if pentru a schimba variabila.

O altă buclă care poate fi utilizată în IDE-ul Arduino este bucla de postcondiție. face în timp ce. Când se utilizează această construcție, comenzile dintr-o buclă vor fi executate cel puțin o dată, indiferent de condiție, deoarece condiția este verificată după ce corpul buclei este executat. În următorul exemplu de cod, LED-ul se va aprinde indiferent de citirile senzorului și abia apoi se va verifica postcondiția.

în apă; // creează o variabilă înaintea buclei do ( digitalWrite (13, HIGH ); water = analogRead (AO); ) while (apă<5) // verifica senzorul digitalWrite(13, LOW);

Cum să ieși dintr-un timp sau pentru buclă

În cazul în care este necesară ieșirea din corpul buclei, indiferent de condițiile specificate, se folosește operatorul pauză sau mergi la. Declarația break vă permite să părăsiți bucla și programul va continua să execute următoarele comenzi. Declarația goto vă permite nu numai să ieșiți din buclă, ci și să continuați executarea programului din punctul dorit de-a lungul etichetei, de exemplu, puteți merge la o altă buclă în Arduino.

Bucle folosind instrucțiuni pentruȘi in timp ce sunt una dintre cele mai importante constructe ale limbajului C++ care stă la baza Arduino. Se găsesc în absolut fiecare schiță, chiar dacă nu o știi. În acest articol, vom arunca o privire mai atentă asupra buclelor, vom afla care este diferența dintre for și while, cum puteți simplifica scrierea unui program cu ajutorul lor și ce greșeli ar trebui evitate.

Dacă sunteți încă un programator începător și doriți să înțelegeți ce este o buclă și de ce este necesară, priviți următoarea secțiune a acestui articol cu ​​o descriere detaliată.

Operatorul WHILE este folosit în C++ și Arduino pentru a repeta aceleași comenzi de un număr arbitrar de ori. În comparație cu bucla FOR, bucla WHILE pare mai simplă; este de obicei folosită acolo unde nu trebuie să numărăm numărul de iterații dintr-o variabilă, ci pur și simplu trebuie să repetăm ​​codul până când ceva se schimbă sau are loc un eveniment.

sintaxa WHILE

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

Orice construct de limbaj care returnează o valoare booleană poate fi folosit ca condiții. Condițiile pot fi operații de comparare, funcții, constante, variabile. Ca și în cazul oricărei alte operații logice din Arduino, orice valoare, alta decât zero, va fi percepută ca adevărată, zero – falsă.

// O buclă fără sfârșit while(true)( Serial.println("În așteptare..."); ) // O buclă care rulează până când valoarea funcției checkSignal() se schimbă while(!checkSignal())( Serial.println ("Așteptăm..."); )

Rețineți că instrucțiunea while poate fi folosită fără a bloca blocul cu acolade, caz în care prima comandă întâlnită după buclă va fi repetată. Nu este recomandat să folosiți fără bretele, deoarece in acest caz este foarte usor sa gresesti. Exemplu:

While(true) Serial.print("Se așteaptă întrerupere"); întârziere (1000);

În acest caz, inscripția va fi afișată într-o buclă nesfârșită fără pauze, deoarece comanda delay(1000) nu se va repeta. Puteți petrece mult timp prind astfel de erori - este mult mai ușor să folosiți o breteză.

Exemplu de utilizare a unei bucle while

Cel mai adesea, while este folosit pentru a aștepta un eveniment. De exemplu, pregătirea obiectului Serial pentru lucru.

Serial.begin(9600); în timp ce (!Serial) ( ; // Unele plăci Arduino vă cer să așteptați până când portul serial este liber)

Un exemplu de așteptare a sosirii unui personaj de pe dispozitive externe prin UART:

While(Serial.available())( int byteInput = Seria.read(); // Alte acțiuni)

În acest caz, vom citi valorile atâta timp cât Serial.available() returnează o valoare diferită de zero. Odată ce toate datele din buffer se epuizează, bucla se va opri.

bucla FOR în Arduino

În bucla FOR, avem ocazia nu numai să setăm condiții la limită, ci și să definim imediat o variabilă pentru contor și să indicăm cum se vor schimba valorile acesteia la fiecare iterație.

Sintaxa buclei FOR

Aici designul va fi puțin mai complicat:
pentru (<начальное значение счетчика>;<условие продолжения выполнения цикла>;<изменение значения счетчика на каждом шаге>){
<список_команд>
}

Cel mai simplu exemplu:

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

Am creat imediat o variabilă, am inițializat-o și am indicat că la sfârșitul fiecărui ciclu valoarea contorului ar trebui să crească cu unu. Și asta este tot - acum poți folosi variabila în interiorul buclei.

Pasul variabil poate fi diferit. Iată exemple:

  • 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–) // Înapoi – de la 10 la 1

face bucla while

În unele cazuri, trebuie să organizăm bucla în așa fel încât instrucțiunile blocului să fie executate cel puțin o dată, iar apoi să fie efectuată verificarea. Pentru astfel de algoritmi, puteți utiliza construcția do while. Exemplu:

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

Această versiune a buclei nu prezintă dificultăți - pur și simplu am mutat blocul cu condițiile în jos, astfel încât tot conținutul din interiorul acoladelor după operatorul do va fi executat înainte de prima verificare.

Continuați și întrerupeți declarațiile

Există situații în care trebuie să întrerupeți urgent execuția unei bucle în interiorul unui bloc de bucle, fără a aștepta să treceți la blocul de verificare a stării. Pentru a face acest lucru, puteți folosi operatorul pauză:

În timp ce (adevărat) ( ​​dacă (bifează Ceva ()) ( pauză; ) )

Dacă vrem pur și simplu să oprim progresul iterației curente, dar nu să ieșim din buclă, ci să mergem la blocul de verificare a condiției, atunci trebuie să folosim operatorul continua:

În timp ce (adevărat) ( ​​dacă (bifați Ceva()) (continuați; ))

Instrucțiunile continue și break pot fi folosite cu toate variantele buclelor FOR și WHILE.

Bucle imbricate în Arduino

Orice variante de bucle pot fi ușor combinate între ele, realizând structuri imbricate. Variabilele definite în blocul buclei „supraiacente” vor fi disponibile în cea interioară. Cel mai obișnuit exemplu de acest tip de buclă este traversarea matricelor bidimensionale. În exemplul următor, folosim o buclă dublă: prima va itera prin rânduri (variabila i), a doua, imbricată, va trece prin coloanele (variabila j) ale tabloului, pe care am definit-o în variabila arr.

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

Mai multe despre cicluri

Dacă nu ați lucrat niciodată cu bucle, să ne aruncăm puțin în lumea teoriei și să ne dăm seama ce sunt buclele și de ce avem nevoie de aceste construcții de limbaj misterioase.

De ce avem nevoie de o buclă?

De fapt, sarcina principală a buclei este de a repeta aceleași construcții de limbaj de mai multe ori. Această nevoie apare în aproape fiecare program și, cu siguranță, nicio schiță Arduino nu poate face fără o buclă - funcția loop() este numită și într-o buclă infinită.

Să ne uităm la următorul exemplu. Trebuie să alimentați simultan 5 LED-uri conectate la placa Arduino de la pinii 5 la 9. Cea mai evidentă opțiune pentru aceasta ar fi să plasați cinci instrucțiuni la rând:

digitalWrite(5, HIGH);

digitalWrite(6, HIGH);

digitalWrite(7, HIGH);

digitalWrite(8, HIGH);

digitalWrite(9, HIGH);

Să ignorăm deocamdată problema riscului unei astfel de acțiuni, deoarece includerea simultană a unui astfel de număr de LED-uri creează o sarcină crescută pe circuitul de alimentare al plăcii. Principalul lucru pentru noi acum este că am creat cinci linii de cod, fiecare dintre ele diferită de celelalte printr-o singură cifră. Această abordare are următoarele dezavantaje:

  • Cu orice modificare, va trebui să faceți modificări la mai multe linii simultan. De exemplu, dacă trebuie să comutăm LED-urile la pinii 2 la 6 sau să oprim tensiunea în loc să o pornim, va trebui să facem 5 modificări în cod. Ce se întâmplă dacă există mai multe instrucțiuni și modificări?
  • Codul mare cu un număr mare de instrucțiuni similare este incomod și neplăcut de citit. Cinci rânduri identice nu sunt foarte înfricoșătoare. Dar obiceiul de a folosi coduri murdare va duce în cele din urmă la zeci și sute de pagini în plus în listă, ceea ce vă va face atât pe dvs., cât și pe colegii tăi descurajați.
  • În procesul de „copiere și lipire” instrucțiuni aproape identice, puteți face cu ușurință o greșeală, de exemplu, uitați să schimbați numărul PIN: digitalWrite(5, HIGH); digitalWrite(5, HIGH);
  • Puteți eșua cu ușurință la un interviu la orice companie obișnuită de software, arătând intervievatorului acest cod.

Din toate acestea, putem concluziona că reutilizarea acelorași șiruri din nou și din nou ar trebui aproape întotdeauna evitată și înlocuită cu bucle. Mai mult, în multe situații este imposibil să faci fără cicluri; nimic nu le poate înlocui. Nu puteți modifica de câte ori se repetă codul în timp ce programul rulează. De exemplu, trebuie să procesați fiecare element matrice de date, primit de la dispozitive externe. Nu veți prezice niciodată câte date vor exista, de câte ori se va repeta prelucrarea și, prin urmare, nu veți putea introduce numărul necesar de instrucțiuni în momentul scrierii articolului.

Și aici ciclurile ne vin în ajutor.

Reguli de sintaxă

Buclă în Arduino este un bloc de program special care va fi apelat de un anumit număr de ori în timpul execuției programului. În cadrul acestui bloc, descriem comenzile în sine care vor fi apelate și regulile prin care controlerul va determina de câte ori trebuie să fie apelate.

În exemplul nostru de mai sus, i-am putea spune controlerului următoarele:

Repetați comanda digitalScrie de 5 ori

Într-o lume ideală cu programatori de roboți, acest lucru ar fi probabil suficient, dar deoarece vorbim cu computerul în C++, trebuie să traducem această frază în acest limbaj:

Repetați comanda – trebuie să folosiți instrucțiuni speciale care îi spun controlerului că ceva interesant este pe cale să înceapă cu while sau for loops

digitalWrite – lăsați-l așa cum este, dar scrieți-l o dată și închideți-l între acolade. Ce să faci cu numerele PIN - chiar mai jos.

de 5 ori – folosiți un contor pentru aceasta, care va crește cu fiecare repetare. La începutul (sau la sfârșitul) unui bloc, puteți compara valoarea acestui contor cu o valoare limită (în acest caz 5) folosind o operație de comparare.

Să ne uităm la un exemplu de astfel de comandă buclă „tradusă” cu o instrucțiune while:

Contor int = 0; // O variabilă care va stoca valoarea contorului // Cerem procesorului să repete construcția în acolade până când condiția din paranteze revine adevărată. // În cazul nostru, contorul este contorul nostru, 5 este valoarea limită, condiția este ca valoarea contorului să fie mai mică de 5. // Dar putem specifica operatori logici complet diferiți în timp ce (contorul< 5) { digitaWrite(5, HIGH); // Будем включать светодиод counter++; // Увеличиваем значение счетчика } // Дойдя до сюда, исполняющий процессор переместится в начало блока и опять займется проверкой условий. Если условия вернут истину, команды в блоке между { и } выполнятся еще раз. Если условие не выполнится - процессор переместится к концу блока и пойдет дальше. Этот цикл больше его не заинтересует.

Pentru cei care au observat o eroare în codul dat, dăm un cinci și scriem blocul buclă diferit:

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

Același rezultat poate fi obținut folosind o buclă FOR:

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

După cum puteți vedea, în acest caz plasăm imediat toate operațiunile necesare cu contorul într-o singură instrucțiune FOR - aceasta este mult mai convenabilă dacă trebuie să numărați suma necesară.

Puteți obține informații detaliate despre regulile de utilizare a buclelor în secțiunile relevante ale acestui articol.

Concluzie

În acest articol, ne-am uitat la constructe foarte importante ale limbajului Arduino: bucle FOR și WHILE. Puteți găsi acești operatori în aproape orice schiță mai mult sau mai puțin complexă, deoarece fără bucle multe operații asupra datelor ar fi imposibile. Nu este nimic complicat în sintaxa buclelor - vă puteți obișnui cu ele cu ușurință și le puteți utiliza activ în proiectele dvs.

Fiecare limbaj de programare are un set de instrucțiuni de control care permit aceluiași cod să fie executat în mod repetat (o buclă), selectarea unei bucăți de cod adecvate (condiții) și instrucțiuni pentru ieșirea din porțiunea curentă de cod.

Arduino IDE împrumută majoritatea controalelor necesare din C/C++. Sintaxa lor este identică cu C. Mai jos vom descrie pe scurt sintaxa lor.

declarația dacă

Instrucțiunea if vă permite să executați un anumit fragment al unui program în funcție de rezultatul verificării unei anumite condiții. Dacă condiția este îndeplinită, atunci codul programului va fi executat, dar dacă condiția nu este îndeplinită, atunci codul programului va fi omis. Sintaxa pentru comanda if este următoarea:

Dacă(condiție) ( instrucțiune1; instrucțiune2; )

Condiția poate fi orice comparație a unei variabile sau a unei valori returnate de o funcție. Principalul criteriu pentru o condiție dacă este că răspunsul trebuie să fie întotdeauna adevărat sau fals. Exemple de condiții pentru o declarație if:

Dacă(a!=2) ( ) dacă(x<10) { } if(znak==’B’) { }

În parantezele care sunt scrise în interiorul condiției, puteți executa codul.

Oamenii care încep să învețe programarea fac adesea greșeala de a echivala valoarea unei variabile specificate folosind un singur semn „=". O astfel de notație indică în mod clar atribuirea unei valori variabile și, prin urmare, condiția va fi întotdeauna „adevărată”, adică îndeplinită. Testarea că o variabilă este egală cu o anumită valoare este întotdeauna indicată printr-un semn dublu egal (==).

Puteți utiliza starea funcției ca o condiție, de exemplu:

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

Exemplul de mai sus ar fi executat după cum urmează: În primul pas, funcția init() este apelată. Această funcție returnează o valoare care va fi interpretată ca „adevărat” sau „fals”. În funcție de rezultatul comparației, se va trimite un text „ok” sau nu se va trimite nimic.

Dacă... altfel afirmație

O instrucțiune if extinsă este instrucțiunea if….else. Acesta asigură că o bucată de cod este executată atunci când o condiție este adevărată (adevărată), iar o a doua bucată de cod este executată atunci când condiția nu este îndeplinită (fals). Sintaxa instrucțiunii f if….else este următoarea:

Dacă (condiție) ( // comanda A ) else ( // comanda B )

Comenzile „A” vor fi executate numai când condiția este îndeplinită, comanda „B” va fi executată atunci când condiția nu este îndeplinită. Executarea simultană a comenzii „A” și „B” nu este posibilă. Următorul exemplu arată cum se utilizează sintaxa if...else:

Dacă (init()) ( Serial.print("ok"); ) else ( Serial.print("eroare"); )

În acest fel, puteți verifica execuția corectă a funcției și puteți informa utilizatorul despre aceasta.

O practică comună este negarea afecțiunii. Acest lucru se datorează faptului că o funcție care a fost executată corect returnează valoarea 0, iar o funcție care a fost executată incorect din anumite motive returnează o valoare diferită de zero.

Explicația pentru această „complicație a vieții” este simplă. Dacă funcția este executată corect, atunci aceasta este singura informație de care avem nevoie. În cazul unei erori, uneori merită să înțelegeți ce a mers prost și de ce funcția nu a fost efectuată corect. Și aici alte numere decât zero vin în ajutor, adică folosind coduri digitale putem determina tipul de eroare. De exemplu, 1 - o problemă cu citirea unei valori, 2 - nu există spațiu în memorie sau pe disc etc.

Ultimul exemplu modificat arată cum să apelați o funcție care returnează zero atunci când este executată corect:

Dacă (!init()) ( Serial.print("ok"); ) else ( Serial.print("eroare"); )

Declarație de schimbare a cazului

Declarația if vă permite să testați o singură condiție. Uneori este necesar să efectuați una dintre acțiuni în funcție de valoarea returnată sau citită. Operatorul cu alegere multiplă este ideal pentru aceasta. Sintaxa comenzii de comutare este prezentată mai jos:

Comutare (var) (cazul 1: //instrucțiune pentru var=1 pauză; cazul 2: //instrucțiune pentru var=2 pauză; implicit: //instrucțiune implicită (dacă var este diferită de 1 și 2) )

În funcție de valoarea variabilei var, sunt executate instrucțiuni în blocuri specifice. Eticheta cazului indică începutul unui bloc pentru valoarea specificată. De exemplu, cazul 1: înseamnă că acest bloc va fi executat pentru valoarea lui var egală cu unu.

Fiecare bloc trebuie terminat cu o comandă de pauză. Întrerupe execuția ulterioară a instrucțiunii switch. Dacă comanda break este omisă, atunci instrucțiunile vor fi executate în blocurile ulterioare înainte de comanda break. Eticheta implicită este opțională, la fel ca altfel într-o declarație if. Instrucțiunile situate în blocul implicit sunt executate numai atunci când valoarea variabilei var nu se potrivește cu niciun model.

Se întâmplă adesea ca aceleași instrucțiuni să fie executate pentru una dintre mai multe valori. Acest lucru se poate realiza după cum urmează:

Comutator (x) ( cazul 1: //instrucțiune pentru x=1 pauză; cazul 2: cazul 3: cazul 5: //instrucțiune pentru x=2 sau 3 sau 4 pauză; cazul 4: //instrucțiune pentru x=4 pauză ; cazul 6: // instrucțiune pentru x=6 pauză; implicit: // instrucțiune implicită (dacă x este diferit de 1,2,3,4,5,6) )

În funcție de valoarea variabilei x, se va executa blocul de instrucțiuni corespunzător. Repetarea cazului 2: cazul 3: cazul 5: informează compilatorul că dacă variabila x are valoarea 2 sau 3 sau 5, atunci aceeași bucată de cod va fi executată.

pentru declarație

Instrucțiunea for este folosită pentru a executa același cod din nou și din nou. Adesea este necesar să se execute aceleași instrucțiuni, schimbând doar valoarea unei variabile. O buclă for este ideală pentru asta. Sintaxa comenzii este următoarea:

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

Primul parametru dat într-o instrucțiune for este valoarea inițială a variabilei. Un alt element este verificarea condiției pentru continuarea execuției buclei. Bucla rulează atâta timp cât condiția este îndeplinită. Ultimul element este modificarea valorii variabilei. Cel mai adesea ii crestem sau scadem valoarea (dupa caz). În acest exemplu, instrucțiunile conținute în buclă vor fi executate la i=0...9.

Adesea, o variabilă utilizată într-o buclă este declarată acolo:

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

O variabilă care este folosită pentru a număra pașii următori ai buclei poate fi utilizată în cadrul acesteia pentru a apela o funcție cu parametrii corespunzători.

For(int i=10;i>0;i—) ( Serial.print(i); // vor fi trimise numerele 10,9,8,7,6,5,4,3,2,1)

în timp ce declarația

Bucla for este ideală acolo unde vrem să facem o numărătoare. Într-o situație în care trebuie să efectuăm anumite acțiuni ca urmare a unui eveniment care nu este neapărat previzibil (de exemplu, așteptăm să fie apăsat un buton), atunci putem folosi instrucțiunea while, care execută blocul de instrucțiuni ca atâta timp cât condiția este îndeplinită. Sintaxa instrucțiunii while este următoarea:

While(condiție) ( // bloc de instrucțiuni de executat)

Este important ca verificarea stării să aibă loc la începutul ciclului. Se poate întâmpla ca instrucțiunile din bucla while să nu fie executate niciodată. De asemenea, este posibil să creați o buclă infinită. Să ne uităm la două exemple:

Int x=2; while(x>5) ( Serial.print(x); ) —————————————- int y=5; while(y>0) ( Serial.print(y); )

Primul bloc de instrucțiuni aflat în interiorul while nu va fi niciodată executat. Variabila x are valoarea doi și nu va deveni mai mare de 5. În al doilea exemplu avem de-a face cu o buclă infinită. Variabila „y” are valoarea 5, adică mai mare decât zero. Nu există nicio modificare a variabilei „y” în interiorul buclei, așa că bucla nu se va finaliza niciodată.

Aceasta este o greșeală comună când uităm să modificăm un parametru care determină terminarea buclei. Mai jos sunt două exemple corecte de utilizare a unei bucle while:

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

În primul exemplu, ne-am ocupat de modificarea valorii variabilei care este verificată în condiție. Ca urmare, ciclul se va încheia în cele din urmă. În al doilea exemplu, a fost creată în mod intenționat o buclă infinită. Această buclă este echivalentă cu funcția loop() din IDE-ul Arduino. În plus, în interiorul buclei a fost introdusă o verificare a stării, după care bucla se termină cu comanda break.

fă... în timp ce declarație

O variație a buclei while este bucla do...while. Pe lângă sintaxă, diferă în locul în care este verificată condiția. În cazul do...while, condiția este verificată după executarea blocului de instrucțiuni. Aceasta înseamnă că blocul de instrucțiuni din corpul buclei va fi executat cel puțin o dată. Mai jos este sintaxa comenzii do...while:

Do ( // bloc de instrucțiuni ) while(condiție)

Tot ceea ce este scris despre operatorul while se aplică și pentru a face...while. Mai jos este un exemplu de utilizare a unei bucle do...while:

Int x=10; do ( // bloc de instrucțiuni x—; ) while(x>0); —————————————- do ( // bloc de instrucțiuni dacă (condiția) se rupe; ) în timp ce (adevărat);

declarație de pauză

Declarația break vă permite să părăsiți bucla (do...while, for, while) și să părăsiți opțiunea switch. În exemplul următor, luați în considerare execuția comenzii break:

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

Bucla trebuie executată pentru numerele de la 0 la 9, dar pentru numărul 5 este îndeplinită o condiție care declanșează instrucțiunea break. Aceasta va ieși din buclă. Ca urmare, numai numerele 0,1,2,3,4 vor fi trimise către portul serial (Serial.print).

Continuați operatorul

Operatorul continue face ca instrucțiunile buclei (do...while, for, while) să se oprească din execuție pentru valoarea curentă și să treacă la următorul pas al buclei. Următorul exemplu arată cum funcționează instrucțiunea continue:

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

Așa cum nu este greu de observat, bucla va fi executată pentru valori de la 0 la 9. Pentru valoarea 5, comanda de continuare va fi executată, drept urmare instrucțiunile de după această comandă nu vor fi executate. Ca urmare, numerele 0,1,2,3,4,6,7,8,9 vor fi trimise la portul serial (Serial.print).

declarație de returnare

Instrucțiunea return încheie execuția funcției apelate și returnează o valoare de un anumit tip. Puteți specifica un număr, un simbol sau o variabilă de un anumit tip ca parametru de comandă. Este important ca valoarea returnată să se potrivească cu tipul funcției declarate. Următorul exemplu arată cum se utilizează instrucțiunea return:

Int checkSensor())( dacă (analogRead(0) > 400) ( // citirea intrării analogice returnează 1; // Pentru valori mai mari de 400, 1 este returnat altfel ( return 0; // pentru altele, 0 este întors) )

După cum puteți vedea, puteți utiliza mai multe instrucțiuni return într-o singură funcție, dar numai una dintre ele va funcționa întotdeauna. Este acceptabilă utilizarea operatorului de retur fără parametri. Acest lucru vă permite să opriți prematur o funcție care nu returnează nicio valoare.

Void function_name() ( instrucțiune1; if(x==0) return; instrucțiune2; instrucțiune3; )

În exemplul de mai sus, instrucțiunea1 se va executa ori de câte ori funcția este apelată. Execuția instrucțiunii2 și instrucțiunii3 depinde de rezultatul comenzii if. Dacă condiția este adevărată (adevărată), comanda return va fi executată și funcția va ieși.

În cazul în care condiția nu este îndeplinită, nici comanda de returnare nu este executată, dar instrucțiunile instruction2 și instruction3 sunt executate, iar după aceea funcția își finalizează activitatea.

Goto declarație

Din motive ideologice, este necesar să săriți peste această descriere... Instrucția goto este o comandă care nu ar trebui folosită în programarea normală. Determină complexitatea codului și este un obicei prost de programare. Vă recomandăm insistent să nu utilizați această comandă în programele dumneavoastră. Deoarece goto este inclus în documentația oficială de pe site-ul web arduino.cc, iată o scurtă descriere a acestuia. sintaxa comenzii du-te:

…. du-te la marca; // mergeți la linia etichetată „metka” ..... .... …. metka: // etichetă cu care programul va continua să lucreze...

Comanda vă permite să mergeți la marcajul desemnat, adică într-un loc din program.