Kurs Arduino – #10 – wykresy, liczby losowe, warunki cd.

Kurs Arduino – #10 – wykresy, liczby losowe, warunki cd.

Pora na obiecaną, dodatkową część naszego kursu Arduino. Tym razem zajmiemy się kilkoma rzeczami, które usprawnią programowanie.

Mowa między innymi o łączeniu warunków oraz losowaniu liczb. Sprawdzimy również, jak łatwo informacje, które trafiają do PC przedstawić w formie wykresu!

Arduino - rysowanie wykresów

Oczywiście Arduino IDE z czasem się zmienia. Niedawno pojawiła się tam bardzo wygodna opcja, która pozwala na szybkie rysowanie wykresów z informacji  przesyłanych przez UART.

Aby móc korzystać z tego narzędzia potrzebujemy nowej wersji Arduino IDE, jeśli instalowałeś je niedawno i w menu narzędzia widzisz dwie opcje: "Szeregowy monitor" oraz "Monitor portu szeregowego", to nie musisz już nic robić.

Nowe pozycje w menu Arduino IDE.

Nowe pozycje w menu Arduino IDE.

Jeśli widzisz tylko jedną opcję tego typu, to zaktualizuj swoje IDE. Najnowsza wersja dostępna jest oczywiście za darmo na stronie projektu.

Aby rysować wykres musimy, najlepiej w regularnych, odstępach wysyłać do komputera liczby w nowej linii. Na początku stwórzmy układ, który będzie rysował wykres napięcia mierzonego na wejściu A5, do którego podłączymy potencjometr w roli dzielnika napięcia.

Zestaw elementów do kursu

Gwarancja pomocy na forum Błyskawiczna wysyłka

Teraz możesz kupić zestaw ponad 70 elementów niezbędnych do przeprowadzenia ćwiczeń z kursu u naszych dystrybutorów!

Kup w Botland.com.pl

Schemat podłączenia układu wygląda następująco:

Potencjometr podłączony do A5.

Potencjometr podłączony do A5.

Standardowa wersja programu wysyłającego dane do terminala wyglądałaby następująco:

Korzystając z opcji "Szeregowy monitor", podczas kręcenia potencjometrem, zobaczymy taki efekt:

Zmiany napięcia na A5.

Zmiany napięcia na A5.

Mało czytelnie prawda? Wystarczy jednak włączyć drugą opcję, czyli "Monitor portu szeregowego", a naszym oczom ukaże się znacznie bardziej czytelniejszy efekt. Będzie to wykres, przykład dla pomiarów, gdy zmieniałem ręcznie ustawienia potencjometru:

Pomiar napięcia na A5, wykres w Arduino.

Pomiar napięcia na A5, wykres w Arduino.

Prawda, że znacznie czytelniej? Kiedy w praktyce przydają się takie opcje? Oczywiście wtedy, gdy korzystamy z czujników (odległości, temperatury itd.). Tak się składa, że w poprzedniej części kursu Arduino omówiliśmy obsługę czujnika odległości HC-SR04. Spróbujmy narysować więc wykres mierzonej odległości!

Arduino - wykres odległości od przeszkody

W tym celu wracamy do schematu montażowego z poprzedniego artykułu:

Schemat podłączenia czujnika odległości.

Schemat podłączenia czujnika odległości.

Uruchamiamy również kod napisany podczas poprzedniej lekcji. Należy wprowadzić tylko dwie zmiany. Pierwsza, to wyświetlanie wyniku w nowej linii bez jednostki. Druga, to odrobina większa częstotliwość pomiarów - dzięki temu wykres będzie bardziej płynny.

Gotowe? Pora uruchomić narzędzie do rysowania wykresów. Tutaj może być różnie - czasami zadziała, a czasami nie. Dlaczego?

W przypadku tego czujnika odległości zakłócenie może spowodować, że wyślemy do komputera informację o błędnym pomiarze. Na poniższym zrzucie ekranu widać, że jeden z pierwszych pomiarów wskazał odległość wynoszącą 2000 cm.

Błędny odczyt z czujnika.

Błędny odczyt z czujnika.

Spowodowało to automatyczne dobranie skali na wykresie, które utrudnia odczytanie późniejszych, poprawnych wyników. Jak temu zaradzić? Najlepiej programowo. Dodajmy prosty warunek, który będzie sprawdzał jaką wartość wysyłamy do komputera. Może on wyglądać np. tak:

Dzięki temu nigdy nie wyślemy do komputera wartości, która wykracza za zakres czujnika. Zmienna dystans została zadeklarowana jako liczba dodatnia, więc wystarczy sprawdzać górny zakres. Nie musimy kontrolować dolnego. Cały program po zmianach wygląda tak:

Teraz wykres za każdym razem będzie wyglądał poprawnie:

Wykres odległości - wersja poprawna.

Wykres odległości - wersja poprawna.

Podczas nagrywania pomiarów przesuwałem szybko przeszkodę przed czujnikiem. Jak widać, kilka razy nasze ograniczenie uchroniło nas przed błędnymi pomiarami. Przy okazji warto zwrócić uwagę, jak rysowanie wykresu ułatwia zauważenie problemów z jakością odczytów z sensora! Tutaj np.: widać stosunkowo duże szumy wartości, odczyty nie są stabilne.

Arduino - wykres kilku wartości

Opisana funkcja rysowania wykresów pozwala również na jednoczesne rysowanie kilku wartości na jednej planszy. Aby wykorzystać tę opcję należy wysłać liczby w tej samej linii oddzielonych znakiem tabulatora, a na ich końcu powinien pojawić się znak nowej linii.

W praktyce kod będzie wyglądał tak:

Natomiast wykres po podstawieniu wartości losowych wyjdzie przykładowo taki:

Różne dane na jednym wykresie.

Różne dane na jednym wykresie.

 

Rysowanie wykresów może być również szczególnie przydatne, gdy wykorzystujemy czujniki przyspieszenia lub położenia. Zachęcam do przeczytania mojego artykułu, w którym pokazałem jak wykorzystać najnowsze Genuino 101 do obrazowania jego położenia!

Tam właśnie wykorzystałem jednoczesne rysowanie wykresu dla kilku wartości:

Wizualizacja zmiany położenia układu.

Wizualizacja zmiany położenia układu.

Zadanie domowe 10.1

Wykorzystaj w praktyce możliwość rysowania jednocześnie kilku wykresów. Do Arduino podłącz dwa fotorezystory - robiliśmy to już w innych lekcjach.  Następnie mierz napięcie odzwierciedlające poziom światła padającego na każdy z czujników. Obie wartości zaprezentuj na jednym wykresie. Pochwal się w komentarzu zrzutem ekranu przedstawiającym Twój wykres!

Arduino - liczby losowe

Czasami oczekujemy, aby program działał w sposób "nieprzewidywalny". Praktyczny przykład? Robot, który po wykryciu przeszkody obraca się o losowy kąt lub prosta gra, w której komputer wykonuje swój ruch z nieprzewidywalnym opóźnieniem. W poprzednim przykładzie użyłem właśnie takich wartości, aby zademonstrować jednoczesne rysowanie wykresów dla różnych danych.

Arduino niestety nie może rzucić kośćmi do gry...

Arduino niestety nie może rzucić kośćmi do gry...

W tym miejscu przydaje się funkcja zwracająca losową wartość. Jednak mówiąc szczerze, liczba ta nie będzie zupełnie nieprzewidywalna. Dlatego w przypadku komputerów/mikrokontrolerów mówimy o liczbach pseudolosowych. Jest to temat dość rozbudowany i nie będziemy się tutaj nim zajmować.

Za zwracanie losowej wartości odpowiedzialna jest funkcja random();, która może przyjąć dwa argumenty. Dzięki nim kształtujemy zakres, z jakiego losowane są liczby. W praktyce funkcję najczęściej wykorzystujemy na jeden z dwóch sposobów. Z podaniem wyłącznie górnego zakresu:

Wtedy zwrócona wartość będzie liczbą z zakresu od 0 do liczby o jeden mniejszej od tej wpisanej w nawiasie. Możemy również wpłynąć na dolne ograniczenie zakresu.  W tym celu wystarczy dodać drugi argument:

Pora sprawdzić działanie tej funkcji w praktyce. W tym celu napiszmy najbanalniejszy program, jaki tylko można wykonać. Jego zadaniem jest losowanie liczb w odstępach 1 sekundy i wyświetlanie ich w terminalu (opcja "Szeregowy monitor" w menu "Narzędzia"):

Zgodnie z zapowiedzią w terminalu oczekujemy losowych wartości. Sprawdźmy:

Wynik pierwszego uruchomienia programu.

Wynik pierwszego uruchomienia programu.

Chcieliśmy losowe dane i mamy. Teraz uruchommy wgrany program kilka kolejnych razy. Zgodnie z oczekiwaniami za każdym razem liczby losowe powinny być inne, prawda?

Niestety, za każdym razem otrzymujemy identyczny ciąg. Tak jak pisałem "losowość" zwracanych liczb jest trochę oszukana. Mikrokontroler na pokładzie Arduino, to bardzo precyzyjny układ, który wykonuje kolejne, zaprogramowane operacje. W jego świecie nie istnieją wartości losowe.

Jak można się domyślać Arduino losowe liczby generuje wykonując pewne określone operacje na poprzednio wylosowanej wartości.

Aby poprawić działanie algorytmu losującego najlepiej byłby przed każdym jego startem zaczynać od podania innej wartości jako tej pierwszej, początkowej.

Ta liczba, na podstawie której generowane są następne nosi nazwę ziarna/zarodka, w języku angielskim określona jest ona jako random seed. Więcej na ten temat znaleźć można na Wikipedii (hasło: generator liczb pseudolosowych). Dla nas najważniejsze jest, że w języku Arduino występuje również takie pojęcie - mamy wpływ na owe ziarno. Służy do tego funkcja:

W jej argumencie, zaznaczonym tutaj jako wartosc_poczatkowa, należy podać za każdym razem... losową wartość. Ale namieszałem, prawda? Aby losować liczby, potrzebujemy losowej wartości. Macie pomysł jak to uzyskać? Jeśli nie, to zerknijcie to lekcji o przetworniku ADC w Arduino.

Co dzieje się, gdy do odczytywanego wejście nie podłączymy żadnego sygnału? Wtedy zbieramy "śmieci" z otoczenia, które są... właśnie losowe. Do tej pory było to dla nas problemem. Jednak tutaj wykorzystamy te wartości w słusznym celu.

Aby nasze Arduino korzystało z "bardziej losowych" liczb możemy na początku zrobić tak:

Dzięki temu, przy każdym starcie programu zmierzymy losowe napięcie panujące na wejściu A0. Dalej wartość ta zostanie podana jako ziarno do generatora liczb pseudolosowych.

Poprawmy szybko nasz program i sprawdźmy go w praktyce:

Od teraz, po każdym uruchomieniu otrzymamy inne wartości:

Oczywiście nadal nie jest to idealny generator liczb losowych, jednak w takiej formie wystarczy on do wykorzystania w zdecydowanej większości projektów tworzonych na bazie Arduino.

Zadanie domowe 10.2

Sprawdź, co stanie się, jeśli zamiast ziarna odczytywanego z wejścia analogowego wpiszemy tam stałą wartość. Jak wtedy zachowa się generator liczb pseudolosowych?

Zadanie domowe 10.3

Napisz program, który działa jak elektroniczna kostka do gry. Do Arduino podłącz przycisk. Każde jego wciśnięcie powinno wysyłać do komputera (prze UART) wylosowaną wartość - oczywiście z zakresu od 1 do 6.


Losowe miganie diodą

Wykorzystajmy zdobytą wiedzą do napisania programu, który będzie migał diodą wbudowaną w Arduino w sposób losowy. Załóżmy, że długość świecenia ma wahać się od około 100ms do 990ms. Natomiast czas, gdy dioda jest wyłączona będzie w granicach 50-490ms. Obie wartości powinny zmieniać się w odstępach, co 10 ms.

W tym celu potrzebować będziemy dwóch wartości losowych:

Tak wylosowane wartości moglibyśmy wstawić do funkcji opóźniającej delay, jednak wtedy opóźnienie mogłoby przyjmować wartości np.: od 100 do 999, czyli nie zachowalibyśmy założonych odstępów o 10ms. Jak to naprawić?

Wystarczy, że będziemy losować wartości 10 razy mniejsze, które pomnożymy razy 10 przed podstawieniem ich do funkcji opóźniającej:

Teraz wartości te można podstawić już do programu:

W praktyce dioda miga, tak jak chcieliśmy, czyli zupełnie losowo!

Łączenie instrukcji warunkowych

Już na samym początku kursu Arduino zajęliśmy się instrukcjami warunkowymi, które są używane do sterowania pracą programu w zależności od pewnych informacji. Najczęściej sprawdzaliśmy tylko jeden warunek, np.: "Czy przycisk został wciśnięty?". W programie wyglądało to następująco:

W praktyce często może się zdarzyć, że będziemy chcieli sprawdzić jednocześnie dwa warunki. Najprostszym przykładem będzie sprawdzenie, czy użytkownik wcisnął więcej niż jeden przycisk.

Oczywiście można to zrobić tradycyjnie:

Rozwiązanie jest skuteczne, jednak pojawią się pewne problemy z czytelnością takie zapisu, gdy będziemy chcieli sprawdzić jednocześnie jeszcze więcej warunków. Dlatego zdecydowanie łatwiej będzie, gdy poznamy dwa operatory logiczne:

  1. Iloczyn logiczny -  &&
  2. Suma logiczna -  ||

Pierwszy z nich wykorzystamy, gdy będziemy chcieli sprawdzić, czy:

warunek pierwszy i warunek drugi został spełniony
if (warunek1 == 1 && warunek2 == 1)

Drugi z nich służy natomiast do sprawdzania, czy:

spełniony został warunek pierwszy lub warunek drugi (lub oba)
if (warunek1 == 1 || warunek2 == 1)

Łączenie warunków w praktyce

W tym celu podłączmy do Arduino dwie diody (zieloną i czerwoną) oraz dwa przyciski. Schemat montażowy wygląda następująco:

Schemat montażowy do przykładu z operatorami logicznymi.

Schemat montażowy do przykładu z operatorami logicznymi.

Teraz napiszmy program, który będzie włączał diodę zieloną, gdy wciśniemy jeden z dwóch przycisków. Kod może wyglądać np. tak:

W praktyce najważniejsza część tego programu ogranicza się do jednej linijki. Konkretnie warunku, w którym za jednym razem sprawdzamy stany dwóch przycisków. Jeśli przynajmniej jeden z nich został wciśnięty, to dioda zostanie włączona.

Rozbudujmy trochę program i dodajmy osobny warunek, który będzie włączał diodę czerwoną, tylko gdy jednocześnie wciśniemy oba przyciski:

Działanie ostatecznej wersji programu widoczne jest na poniższym filmie:

Praktyczny przykład - czujnik odległości

Powyższe przykłady pokazywały, że układ działa, ale nie były zbyt użyteczne. Spróbujmy teraz zrobić coś bardziej praktycznego. Podłączmy do Arduino przycisk, czujnik odległości oraz buzzer. Układ będzie miał piszczeć brzęczykiem, jeśli przeszkoda znajdzie się w odległości między 20, a 40 cm lub, gdy wciśniemy przycisk.

Do dzieła, najpierw łączymy potrzebny obwód. Aby było trochę trudniej, tym razem zamiast schematu montażowego podaję listę połączeń + pomocnicze zdjęcie. Na tym etapie kursie wszyscy powinni już dać radę złożyć taki układ samodzielnie:

  • trigPin czujnika odległości do pinu nr 12
  • echoPin czujnika odległości do pinu nr 9
  • buzzer do pinu nr 11
  • przycisk do pinu nr 10

Oczywiście dodatkowo należy podłączyć odpowiednio zasilanie Vcc (szynę dodatnią) do czujnika odległości, natomiast masę do buzzera, przycisku oraz oczywiście również do czujnika. U mnie w praktyce wyglądało to tak:

Kurs Arduino - układ do testowania łączenia warunków w praktyce.

Kurs Arduino - układ do testowania łączenia warunków w praktyce.

Pora na napisanie programu. Odczytywać odległość już potrafimy, tak samo sprawdzanie stanu przycisku nie stanowi już dla nas żadnego problemu. Dlatego skupimy się na przeanalizowaniu warunku. Tak jak napisałem, zależy nam na włączenie buzzera, gdy odczytana odległość znajduje się w zakresie od 20 do 40 cm.

W tym celu musimy sprawdzić, czy odczytana wartość jest większa od 20 i jednocześnie mniejsza od 40 cm. Zrobimy to oczywiście w jednym warunku:

Teraz pora na obsłużenie przycisku. Oczywiście moglibyśmy rozbić to na dwa osobne warunki:

Tylko po co? Nie powinniśmy powielać tych samych fragmentów kody, gdy tego nie musimy. W tym wypadku zbędne jest ponowne sterowanie włączeniem i wyłączeniem buzzera. Czy nie możemy warunku połączyć w jeden? Oczywiście, że możemy!

Sprawdzimy czy:

(zmierzony dystans jest większy od 20 i mniejszy od 40) lub (czy wciśnięto przycisk)

Przekładając to na język zrozumiały dla komputera będzie to:

Tym samym cały program prezentuje się następująco:

W praktyce program działa dokładnie tak jak przewidywaliśmy. Na poniższym filmie widać, że buzzer wydaje dźwięk, gdy przeszkoda znajduje się w odpowiedniej odległości lub, gdy wciśniemy przycisk:

Wykorzystanie operatorów logicznych do łączenia warunków jest bardzo proste, a ich odpowiednie użycie pozwala na rozwiązywanie naprawdę zawiłych problemów. Polecam potrenować we własnym zakresie rozbudowane warunki, chociażby rozwiązując poniższe zadanie domowe.

Zadanie domowe 10.4

Napisz programy, które losują liczbę z zakresu 0-100, a następnie sprawdzają, czy wylosowana wartość jest:

  1. mniejsza od 10 lub  większa od 90
  2. większa od 50, ale nie mieści się w przedziale 70-85
  3. równa 50, 40, 30 lub 20
  4. mieści się w zakresie od 10 do 40 lub od 60 do 100

W każdym przypadku wyświetl na PC wylosowaną liczbę oraz informację, czy spełnia warunek.

Podsumowanie

Mam nadzieję, że wiedza, którą zdobyłeś podczas wykonywania ćwiczeń z tego odcinka kursu pomoże Ci w pisaniu jeszcze ciekawszych programów. Bardzo często, dla własnej wygody, będziesz korzystał z łączenia warunków oraz rysowania wykresów.

W kolejnym artykule na zajmiemy się... sprawdzeniem zdobytej tu wiedzy! Tak, pora na mały QUIZ, który pozwoli na ocenę swoich umiejętności. Będzie to sygnał dla Was, czy możecie iść już dalej, czy warto wrócić do niektórych lekcji. Pojawią się również konkretne informacje dotyczące kontynuacji kursu Arduino, czyli poziomu II.

Nawigacja kursu

Nie chcecie przeoczyć kolejnych odcinków? Korzystając z poniższego formularza możecie zapisać się na powiadomienia o nowych publikacjach!

Damian (Treker) Szymański

Arduino, kurs, kursArduino, losowanie, programowanie, wykres

Komentarze

Dodaj komentarz