Nie jestem ekspertem od Arduinomimo posiadania płyty przez długi czas prawie nie badałem. Używałem go jako narzędzia do kopiowania i wklejania już stworzonego kodu, ale bez większego zainteresowania uczeniem się, jak to działa, ale po prostu z zamiarem, aby działało i było dla mnie przydatne. W te święta trochę dostroiłem szopkę za pomocą kilku diod LED i czujnika ultradźwiękowego HC-SR04. I przestałem obserwować, co trzeba zrobić.
Chciałem po prostu zrobić różne rzeczy z dwoma diodami LED z tego samego sygnału. Ups. Szybko natknąłem się na to, co myślę, że będzie jedno z pierwszych ograniczeń, które napotykasz, gdy zaczynasz bawić się Arduino. I nie musisz tego zbytnio komplikować. Mówię tylko o niektórych diodach LED, zdajesz sobie sprawę, że nie możesz zrobić tego, co chcesz poprawnie.
Wyjaśnijmy to od samego początku wielozadaniowość nie istnieje w Arduino, dwa zadania nie mogą być przetwarzane równolegle. Istnieją jednak techniki wykonywania połączeń tak szybko, że wydają się one działać w tym samym czasie.
Opiszę sprawę bardziej szczegółowo. Na Boże Narodzenie ustawiłem szopkę i chciałem, aby niektóre lampki do szopki zapaliły się, gdy zbliżają się moje córki. Nic skomplikowanego. Chciałem tylko, aby dwie gałęzie diod LED działały inaczej niż wartości czujnika zbliżeniowego.
Chciałem, żeby ktoś podszedł bliżej niż 10 cm
- Jedna z gałęzi świateł, które trafiłyby do gwiazd, świeciłaby się przez 10 sekund
- Że drugi, który wejdzie do domów, pozostanie włączony przez 10 sekund, ale ponieważ oddzielili się od szopki.
Proste, nie? ponieważ może to spowodować duże problemy. Ponieważ Arduino nie jest w stanie wykonywać wielu zadań jednocześnie, wykonuje jedno polecenie po drugim.
Zrobiłem montaż za pomocą czujnika ultradźwiękowego HC-SR04 i 2 diody LED, każda z nich byłaby odpowiednikiem gałęzi Betlejem. Pierwsza część nie jest zbyt zabawna, ponieważ dotyczy konfiguracji i obsługi czujnika ultradźwiękowego w pętli LOOP, ale można to znaleźć w tysiącach miejsc. Jak innego dnia, jeśli zbadam więcej, robię coś specjalnego, na razie tutaj jesteś (przepraszam, że nie umieszczam kredytów, ale nie pamiętam, skąd to mam)
Kod HC-SR04 na Arduino
int ledPin1 = 8; int ledPin2 = 7; długi dystans; długi czas; długi czas prądu; długi okres czasu; void setup () {// zainicjuj cyfrowy pin LED_BUILTIN jako wyjście. pinMode (ledPin1, OUTPUT); pinMode (ledPin2, OUTPUT); Serial.begin (9600); pinMode (3, WYJŚCIE); / * aktywacja pinu 9 jako wyjścia: dla impulsu ultradźwiękowego * / pinMode (2, INPUT); / * aktywacja pinu 8 jako wejście: czas odbijania ultradźwięków * /} // funkcja pętli działa w kółko na zawsze void loop () {digitalWrite (3, LOW); / * Ze względu na stabilizację czujnika * / delayMicroseconds (5); digitalWrite (3, WYSOKI); / * wysyłanie impulsu ultradźwiękowego * / delayMicroseconds (10); time = pulseIn (2, HIGH); / * Funkcja pomiaru długości przychodzącego impulsu. Mierzy czas, jaki upływa od wysłania impulsu ultradźwiękowego do momentu, w którym czujnik odbierze odbicie, czyli: od momentu, gdy pin 12 zaczyna odbierać odbicie, WYSOKI, aż do zatrzymania, NISKI, długość przychodzącego impulsu * / odległość = int (0.017 * czas); / * wzór do obliczania odległości w celu uzyskania wartości całkowitej * / / * Monitorowanie w centymetrach przez monitor szeregowy * / Serial.println ("Odległość"); Serial.println (odległość); Serial.println ("cm"); opóźnienie (1000);
Dzięki temu odległość zmierzona przez czujnik ultradźwiękowy zostanie sprawdzona i zapisana
Rozwiązanie operacyjne LEDS
Pierwsza rzecz, która przychodzi na myśl, to zacząć wprowadzać opóźnienia. Nie wiem dlaczego, ale wszyscy początkujący myślą o delay (), co znacznie ogranicza opcje, ponieważ podczas korzystania z delay () deska nie działa dalej i dlatego nie możesz zrobić nic więcej w tym czasie zawieszenia. Rozwiązaniem jest użycie millis ()
Tutaj znalazłem proste rozwiązanie oparte na if i counters. Jak mawiał mój nauczyciel, wszystko można zaprogramować z wieloma „if” pod rząd. Ale oczywiście prawda nie jest zbyt elegancka.
// jeśli odległość jest mniejsza niż 10, włączamy dwie diody lub gałęzie i zaczynamy odliczać czas za pomocą millis () if (odległość <10) {digitalWrite (ledPin1, HIGH); digitalWrite (ledPin2, HIGH); currenttime = millis (); } // jeśli odległość jest większa niż 10, sprawdzimy czas, który upłynął od włączenia, a jeśli jest większy niż wskazany, wyłączymy diodę LED1 if (odległość> 10) {timepast = millis () - aktualny czas ; digitalWrite (ledPin1, LOW); // jeśli odległość jest większa niż 10000 wyłączymy LED2 if (timepast> 10000) {digitalWrite (ledPin2, LOW); }}}
Ten kod ma na celu to, że Arduino nieustannie wykonuje te trzy ifs, aby przejść przez nie tak szybko, że wydaje się, że robi kilka rzeczy jednocześnie. Ale jak już wiemy, kontynuuje wykonywanie zdań jeden po drugim.
Po zmierzeniu odległości i zapisaniu jej w zmiennej dystans, jeśli zostaną ocenione:
- Pierwsza sprawdza, czy odległość jest mniejsza niż pożądane 10 cm. Jeśli tak, to włączamy dwie diody i zaczynamy odliczać czas za pomocą millis ()
- i poszlibyśmy do drugiego, jeśli na odległość większą niż 10 cm. Jeśli się zgadza, obliczamy upływający czas i dezaktywujemy diodę 1, która zależy tylko od odległości.
- Poszlibyśmy do trzeciego, jeśli sprawdzimy, czy minęło więcej niż 10 sekund od aktywacji licznika, a jeśli tak, wyłącz pin 2
- I tak pętla trwa. I znowu.
W końcu i chociaż rozwiązanie zadziałało, było dla mnie jasne, że wiele osób musiało doświadczyć tego problemu i że musi istnieć bardziej ortodoksyjne rozwiązanie. Zacząłem szukać i znalazłem dobry (z pewnością nie jedyny) u chłopców Programowanie adafruitowe i obiektowe. Polega na tworzeniu obiektów ze zdefiniowanymi klasami, aby wykonywać szybkie wywołania i nie muszą setki razy powtarzać kodu w naszym programie.
Ostatecznie jest to „to samo”, co moje rozwiązanie z licznikami if +, ale jest o wiele bardziej eleganckie i zapewnia znacznie bardziej czytelny i wydajniejszy kod.
Zarządzanie wielozadaniowością nieuchronnie prowadzi do zarządzania czasem w Arduino. Początkowo nie było tego zawarte w artykule, ale myślę, że jest bardzo interesujące.
Funkcje Arduino i czasu
Jak już skomentowałem Myślę, że istnieje duża zależność z opóźnieniem () , być może dlatego, że ludzie zaczynający widzą tę funkcję we wszystkich przykładach, które są zwykle umieszczane od mrugnięcia po dowolną sygnalizację świetlną lub jakąkolwiek manipulację włączaniem i wyłączaniem diod LED.
Opóźnienie ma bardzo duży problem, a mianowicie, gdy wywołujemy delay() przez pewien czas, wszystko się zatrzymuje. Tablica nie odczytuje żadnego czujnika, ani nie kontynuuje wykonywania zdań, ani w ogóle nic nie robi, po prostu czeka na czas, który każemy Ci przejść i oczywiście jeśli chcemy użyć tablicy do więcej niż jednej rzeczy jednocześnie nie jest to opłacalne.
Będziemy musieli się przyjrzeć millis () nawet do delayMicroseconds() Mamy też micros(), która zwraca liczbę mikrosekund od rozpoczęcia wykonywania programu
Mrugaj natychmiast
Fajny przykład, aby zobaczyć, jak to działa uruchom mityczne Blink, ale bez zwłoki. Główna różnica polega na tym, że zapominamy o funkcji delay () i używamy millis (), aby móc liczyć czas między operacjami.
Wiedza o istnieniu „przerwań” w arduino może pomóc we wdrażaniu programów z pewnym stopniem wielozadaniowości.
Cześć Leandro, bardzo dziękuję. Nie znam tematu przerw. Zbadam, żeby zobaczyć :)
ISTNIEJE FUNKCJA HARMONOGRAMU, KTÓRA POZWALA NA KILKA PĘTLI W JEDNYM CZASIE