Pętle w Arduino



Pętla FOR


Pętla (instrukcja) for: jest stosowana do wielokrotnego wykonania zestawu instrukcji zawartych w nawiasach klamrowych. Typowo wykorzystuje się ją z licznikiem, który służy do sterowania ilością iteracji pętli poprzez jego inkrementację lub dekrementację. Instrukcja for znajduje zastosowanie w różnorodnych sytuacjach wymagających powtarzania określonych czynności, często w kontekście pracy z tablicami, co pozwala na efektywne przetwarzanie zbiorów danych lub manipulację stanem wielu wejść/wyjść.

Podstawowa składnia pętli for w Arduino wygląda następująco (Kod_001):

Kod_001

Inicjalizacja: Ustawia początkowy stan pętli, zwykle przez zadeklarowanie i przypisanie wartości początkowej do zmiennej licznika.

Warunek: Określa warunek kontynuowania pętli. Pętla wykonuje się dopóki warunek jest spełniony (dopóki zwraca wartość “prawda” czyli true).

Inkrementacja: Modyfikuje stan zmiennej licznika na końcu każdego cyklu pętli, zazwyczaj przez inkrementację (zwiększenie) lub dekrementację (zmniejszenie).

Załóżmy, że naszym celem jest wyświetlenie na konsoli szeregowej serii numerów od 0 do 10, wraz ze słowem ‘Numer:‘ na początku każdej linii.

Symulacja_1

W powyższej symulacji, pętla skonfigurowana jest do wykonywania iteracji od wartości początkowej i = 0 do wartości końcowej i = 10 włącznie, zwiększając zmienną i o jeden (i=i+1) po każdej iteracji.

Składniki pętli for opisane są poniżej:

  • Inicjalizacja: int i = 0 ustanawia zmienną lokalną i jako licznik pętli i inicjalizuje ją wartością 0 przed pierwszą iteracją pętli.
  • Warunek kontynuacji: i <= 10 to warunek, który jest sprawdzany przed każdą iteracją pętli. Dopóki wartość i jest mniejsza lub równa 10, pętla będzie kontynuowana.
  • Inkrementacja: i=i+1 zwiększa wartość i o jeden po każdej iteracji pętli. To samo można osiągnąć za pomocą bardziej zwięzłej formy i++ (szczegóły o operatorach inkrementacji takich jak ++ przeczytacie w innym wydaniu EduBox). Instrukcja dekrementację i=i-1 jest równoważna z i–.



Poniżej znajdziesz przykład wykorzystania instrukcji switch…case w Arduino, który drukuje nam informacje na którym schodku się znajdujemy (zakładając, że wchodzimy po schodach). W zależności od numeru schodka, na którym znajduje się użytkownik, program wyśle przez port szeregowy odpowiedni komunikat (Symulacja_1):

W tym przykładzie zmienna numerSchodka reprezentuje numer schodka, na którym aktualnie znajduje się użytkownik. Instrukcja switch analizuje tę zmienną i w zależności od jej wartości wyświetla odpowiedni komunikat przez port szeregowy. Każdy przypadek (case) odpowiada jednemu z czterech schodków. Jeśli wartość numerSchodka nie mieści się w zakresie od 0 do 4, program wypisze komunikat informujący, że taki schodek nie istnieje.

Przykład ten pokazuje, jak za pomocą instrukcji switch…case można obsługiwać różne scenariusze w zależności od wartości zmiennej, umożliwiając przejrzyste zarządzanie wieloma opcjami w programie.




Alternatywnie, zamiast instrukcji switch…case, można użyć struktury if…else if…else, która pozwala na osiągnięcie tego samego efektu poprzez sekwencyjne sprawdzanie warunków. Poniżej przedstawiono taki sposób realizacji (Symulacja_2):

Symulacja_2

Porównanie:

  • switch…case jest bardziej przejrzysty, gdy porównujemy jedną zmienną z wieloma wartościami, ponieważ eliminuje powtarzanie zmiennej (numerSchodka == …).
  • if…else if…else daje większą elastyczność, ponieważ pozwala na bardziej złożone warunki, np. if (numerSchodka > 4).

Dla tego konkretnego przypadku switch…case jest bardziej czytelny, ale jeśli warunki miałyby być bardziej skomplikowane (np. numerSchodka > 0 && numerSchodka < 5), if…else byłoby lepszym wyborem.




ENUM – typ wyliczeniowy

Enum to skrót od “enumerated type“, czyli wyliczenia. Jest to specjalna konstrukcja, która pozwala programiście określić zmienną mogącą przyjmować jedną z kilku wcześniej zdefiniowanych wartości. Dzięki enum kod staje się bardziej czytelny i łatwiejszy w utrzymaniu, ponieważ zamiast używać bezpośrednio liczb lub ciągów znaków do reprezentowania stanów czy typów, można korzystać z intuicyjnych nazwanych stałych.

Enum o nazwie “moja_nazwa”, który składa się z trzech wyliczeń definiuje się w taki sposób (Kod_002):

Kod_002

Uwaga: Nazwy w enum nie mogą zawierać polskich znaków.

Przykład użycia enum w instrukcji switch…case można zobaczyć w symulacji zamieszczonej poniżej.

Aby sprawdzić działanie programu, należy zmienić wartość zmiennej dzis w linijce 8 na dowolny inny dzień tygodnia, na przykład zamiast Sroda ustawić Niedziela (Symulacja_3):

Symulacja_3

W tym przykładzie enum pozwala w czytelny sposób reprezentować dni tygodnia jako nazwy zamiast liczb. Dzięki temu kod jest bardziej intuicyjny i łatwiejszy w utrzymaniu – zamiast zastanawiać się, co oznacza liczba 3, możemy bezpośrednio użyć Sroda. To sprawia, że kod jest przejrzysty, a dodanie nowych dni lub modyfikacja wartości nie wymaga pamiętania konkretnych liczb, tylko użycia zrozumiałych nazw.




Operator warunkowy (?:) – skrócona wersja if…else

Operator warunkowy, zwany również operatorem trójargumentowym (ternary operator), jest uproszczoną formą instrukcji if…else, pozwalającą na zapis warunku w jednej linii. Jest przydatny, gdy chcemy przypisać wartość do zmiennej lub wykonać prostą operację na podstawie warunku (Kod_003).

Kod_003
  • Jeśli warunek jest prawdziwy (true), zwracana jest pierwsza wartość (po ?).
  • Jeśli warunek jest fałszywy (false), zwracana jest druga wartość (po :).



Przykłady:

  1. Przypisanie wartości do zmiennej na podstawie warunku (Symulacja_4):
Symulacja_4

Jeśli temperatura jest większa niż 30, do status przypisywane jest “Goraco“, w przeciwnym razie “Chlodno“.




2. Znalezienie większej liczby (Symulacja_5):

Symulacja_5

Jeśli a jest większe od b, zmienna wieksza przyjmie wartość a, w przeciwnym razie b.




3. Sprawdzenie, czy liczba jest parzysta (Symulacja_6):

Symulacja_6

Jeśli liczba x jest parzysta, wypisuje “jest parzysta“, w przeciwnym razie “jest nieparzysta“.




Użycie operatora warunkowego (?:)

Dobre zastosowania:

  • Proste przypisania wartości na podstawie warunku.
  • Skrócenie kodu, gdy warunek jest prosty i czytelny.
  • Oszczędność miejsca w pamięci programu (flash) w Arduino.

Kiedy lepiej użyć if…else?

  • Jeśli kod warunkowy jest bardziej złożony (np. kilka linii kodu w każdym przypadku).
  • Gdy wymagana jest większa czytelność i łatwiejsze debugowanie1.

Operator warunkowy sprawdza się świetnie w prostych decyzjach, ale w bardziej skomplikowanych przypadkach lepiej korzystać z klasycznych instrukcji warunkowych.




  1. Debugowanie to proces wykrywania i usuwania błędów w programie, który polega na analizie działania kodu oraz testowaniu poprawek. W praktyce odbywa się to poprzez używanie narzędzi takich jak Serial.println() w Arduino, debuggera w IDE lub analizatora stanów logicznych, aby śledzić wartości zmiennych i sprawdzać, czy program działa zgodnie z oczekiwaniami. ↩︎



Asystent Arduinowo_AI

Asystent Arduinowo_AI zgłębił powyższy zakres wiedzy i z przyjemnością wszystko Ci wyjaśni.