1.5 Kurs „Arduino Łopatologicznie” Pętle for, while oraz do while. Cykliczne wykonywanie instrukcji.

Na dzisiejszej lekcji pokażę Wam jak wykonać powtarzający się kod bez potrzeby kopiowania go konkretną ilość razy. W programowaniu pomagają nam w tym pętle. Dzięki nim kod jest bardziej czytelny i zajmuje mniej pamięci. Pętle są rodzajem bardziej rozbudowanych instrukcji warunkowych poznanych na poprzednich lekcjach.

Rodzaje pętli

Dzisiaj omówimy pętle for, while oraz do while.

1.Pętla  for pozwala nam wykonać program określoną ilość razy. Jej składnia wygląda następująco:

for ( int i=0 ; i<10 ; i++) {

//kod wykonywany w pętli w nawiasach klamrowych

}; 

Pętla for potrzebuje od nas 3 argumenty, które podajemy w nawiasie

  • pierwszy argument pętli int i=0 tworzy nam zmienną wewnętrzną o wartości 0, można ją nazwać licznikiem.
  • Kolejno wpisujemy warunek trwania pętli i<10, kiedy i jest mniejsze od 10 pętla się wykonuje, jeśli osiągnie wartość 10 pętla zakończy działanie.
  • Następnie podajemy jak ma się zmienić wartość naszego licznika. wyrażenie i++ oznacza to samo co i = i + 1; zwiększa wartość o 1 z każdym przebiegiem pętli.

Dość teorii – zastosujemy to w praktyce. Napiszmy kod mrugający naszą diodą połączoną na pinie13 arduino sygnał SOS. SOS składa się z 3 krótkich sygnałów, 3 długich i znów 3 krótkich.

int ledPin = 13; //tworzymy zmienną globalną ledPin o wartości 13 

void setup() {
 pinMode(ledPin, OUTPUT); //ustawiamy działanie pin13 jako wyjście

}

void loop() {
// literka S - trzy krótkie mrugnięcia
digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200);  

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

// literka O - trzy długie mrugnięcia

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(1000);                  // czekamy 1 sekunde
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(300);  

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(1000);                  // czekamy 1 sekunde
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(300); 

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(1000);                  // czekamy 1 sekunde
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(300); 

// literka S - trzy krótkie mrugnięcia
digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200);  

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

}

Wyobraźmy sobie teraz, że chcemy nadać sygnał SOS 10 razy… Koszmar kopiowania powtarzającego się kodu może raz na zawsze wymazać z naszej pamięci. Otrzymaliśmy narzędzie, które skutecznie pomaga wygodnie realizować powtarzające czynności.

Dzięki pętlom można uniknąć kopiowania tego kodu x10.

Wystarczy , że zapiszemy to następująco:

int ledPin = 13; //tworzymy zmienną globalną ledPin o wartości 13 

void setup() {
 pinMode(ledPin, OUTPUT); //ustawiamy działanie pin13 jako wyjście


 for (int i=0 ; i < 10 ; i++) {
// literka S - trzy krótkie mrugnięcia
digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200);  

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

// literka O - trzy długie mrugnięcia

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(1000);                  // czekamy 1 sekunde
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(300);  

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(1000);                  // czekamy 1 sekunde
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(300); 

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(1000);                  // czekamy 1 sekunde
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(300); 

// literka S - trzy krótkie mrugnięcia
digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200);  

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 

digitalWrite(ledPin, HIGH);   // ustawiamy stan wysoki (podajemy napięcie)
delay(500);                  // czekamy 0,5 sekundy
digitalWrite(ledPin, LOW);    // ustawiamy stan niski (odłączamy napięcie)
delay(200); 
};

}

void loop() {


}

Aby sobie prześledzić dokładniej działanie pętli for zróbmy proste ćwiczenie. Wypiszemy kolejno w Serial Monitorze liczby od 1 do 20.

Robienie tego ręcznie było by bardzo mozolne, dzięki pętli łatwo będzie to zautomatyzować.

Kod będzie wyglądał następująco:

int licznik = 1; //tworzymy zmienną o wartości początkowej 1

void setup() {
Serial.begin(9600);

for (int i = 0 ; i<20 ; i++){
  Serial.println(licznik);
  licznik = licznik + 1;  //możemy łatwiej to zapisać licznik++;
  }
}
void loop() {

}

W ramach praktyki wykonajmy teraz pętle, w której będziemy zmniejszać licznik o 2 z każdą iteracją. Oraz wypiszemy cyfry w kolejności malejącej od 30 do 10 – ale tylko parzyste. Oczywiście można takie wypisanie zrealizować prościej przy pomocy pętli for, ale te dziwne argumenty przyjmujemy na potrzeby ćwiczeń.

Przykładowy sposób rozwiązania:

int liczba = 30;

void setup() {
Serial.begin(9600);

for (int i = 20 ; i>=0 ; i=i-2){
  Serial.println(liczba);
  liczba = liczba - 2;
  
  }

}

void loop() {


}

Ustalamy wartość początkową licznika pętli na 20, i z każdym przejściem pętli zmniejszamy jego wartość o 2, skoro od 30 do 10 jest 10 liczb parzystych to musimy pętle uruchomić x10. Jeśli warunkiem wyjścia z pętli było by i>0 to pętla wykonała by się tylko 10 razy zatem ustawiamy warunek i>=0

Lepsze zrozumienie działania pętli wymaga chwili czasu i samodzielnym wykonaniu paru ćwiczeń. Proponuję w ramach praktyki wypisać sobie liczby od 1 do 10, wypisać co drugą liczbę od 5 do 15, wypisać sumę kolejnych liczb od 1 do 5.

Pętla while i do while

Kolejny typ pętli to while oraz do while. Różnica polega na tym, że pętla while wykona się tylko jeśli warunek wejścia do pętli zostanie spełniony jest on sprawdzany na samym początku. Pętla do while zawsze wykona się przynajmniej raz ponieważ warunek zostaje sprawdzony dopiero na końcu.

W przeciwieństwie do pętli for tutaj nie musimy wiedzieć z góry ile razy pętla ma się powtórzyć – decyduje o tym spełnienie postawionych warunków.

Składnia pętli while wygląda następująco:

//pętla while
while ( wykonuj dopóki warunek spełniony ){
//zapętlony kod
};

//przykład:
while ( liczba < 5){
liczba++;
// kod wykonuje się aż liczba nie osiągnie wartości 5
}

//

do {
// wykonujemy kod bez sprawdzenia warunku

} while ( wykonuj dopóki warunek spełniony)
// jeśli warunek spełniony pętla wykonywana jest jeszcze raz

//przykład 2:

do {
liczba ++
//kod wykonuje się i kolejno sprawdzamy warunek
}while (liczba <=5) // pętla wykonuje się aż wartość liczba nie //przekroczy wartości 5, warunek musi być spełniony

W ramach ćwiczenia możemy napisać program, który wykonuje się póki nie wpiszemy na klawiaturze liczby większej od 30 i zlicza ilość prób.

int podanaLiczba = 0;
int licznikProb = 0;

void setup() {
Serial.begin(9600);

do{
  Serial.println("Podaj liczbę z przedziału od 1 do 100");
  delay(3000);
  podanaLiczba = Serial.parseInt();
  licznikProb++;
  Serial.println("Ilość prób: ");
  Serial.println(licznikProb);
  }while (podanaLiczba<30); //sprawdzamy warunek, jeśli poprawny pętla wykonuje się kolejny raz

}

void loop() {


}

W ramach ćwiczeń zmodyfikuj tą pętlę tak aby przestała się wykonywać jeśli poda się liczbę z przedziału od 20 do 30, w przeciwnym wypadku ma się wykonywać od nowa przy okazji zliczając ilość prób. Rozwiązanie napisz w komentarzu. Zadanie jest z pozoru proste ale można popełnić tu łatwo błąd logiczny.

Podsumowując mamy do dyspozycji 2 rodzaje pętli for oraz while, pętla while może też przybierać zmodyfikowaną postać do while – w tej wersji wiemy, że kod wykona się przynajmniej raz zanim sprawdzimy warunek. Pętli for używamy w przypadku jeśli jest nam znana ilość iteracji. Pętle while wykorzystujemy do działań mających się powtarzać, aż nie zostanie spełniony określony warunek – pętla wykonuje się póki warunek zwraca logiczną prawdę.

ZADANIE DOMOWE:

  • 1. jeśli dalej nie obserwujesz naszego facebooka zrób to -> KLIK
  • 2. napisz pętle for wypisującą na ekranie tak wyglądający ciąg cyfr:
zadanie 2

podpowiedź : pętla w pętli

  • 3. Zadanie dodatkowe dla tych, którzy poradzili sobie z poprzednim zadaniem, należy wyświetlić X w 10 rzędach w każdym kolejnym o 1 więcej jak na poniższym screenie:
zadanie 3

Czekamy na wasze pytania i udzielone odpowiedzi do lekcji w komentarzach tutaj albo na fejsie, powodzenia!

<—- Lekcja 4 Lekcja 6 —->

4 Comments

Zostaw komentarz

  1. Paweł
    Odpowiedz

    //zadanie 1 wykonane 🙂

    int liczba = 1;
    void setup() {

    Serial.begin(9600);

    while (liczba < 6 ){

    for (int i = 1 ; i < 6 ; i ++) {
    Serial.print(liczba);
    delay(500);
    }
    liczba ++;
    Serial.println("");
    }

    }

    void loop() {
    }

    1. admin
      Odpowiedz

      Dzięki za komentarz, zapraszamy do śledzenia kolejnej części kursu w maju.

  2. Paweł
    Odpowiedz

    Jak to skrócić?

    int liczba = 1;
    void setup() {

    Serial.begin(9600);

    while (liczba < 11 ){

    for (int i = 1 ; i < 2 ; i ++) {
    char ch = 'X';
    Serial.print(ch);
    delay(500);
    }
    liczba ++;
    Serial.println("");

    for (int i = 1 ; i < 3 ; i ++) {
    char ch = 'X';
    Serial.print(ch);
    delay(500);
    }
    liczba ++;
    Serial.println("");
    }

    }

    void loop() {

Odpowiedz

Twój adres e-mail nie zostanie opublikowany