kempa662 Napisano Grudzień 10, 2018 Udostępnij Napisano Grudzień 10, 2018 (edytowany) Witam, Od dwóch dni "bawię się w Arduino" staram się robić przykłady zawarte w Kursie Arduino z Forbota i między innymi znalazłem sygnalizację świetlną, którą postanowiłem zrobić. Wszystko wyszło ok i postanowiłem utrudnić sobie zadanie i dodać możliwość sterowania dwoma przyciskami, które będą zmieniały działanie programu z świateł drogowych na światła wyłączone (czyli mruga tylko żółta dioda, tak jak w miastach po wyłączeniu świateł) i z tym mam problem... Kombinowałem na różne sposoby i mi nie wychodzi Dwa przypadki: 1) mogę sterować przyciskami, lecz pętla if wykonuje kod tylko raz i się nie zapętla (jest to dla mnie wiadome) void setup() { pinMode(10, OUTPUT); //Dioda czerwona pinMode(9, OUTPUT); //Dioda żółta pinMode(8, OUTPUT); //Dioda zielona pinMode(7, INPUT_PULLUP); //przycisk włączenie pinMode(6, INPUT_PULLUP); //przycisk wyłączenie digitalWrite(10, LOW); //Wyłączenie diod digitalWrite(9, LOW); digitalWrite(8, LOW); int a=0; int b=0; } void loop() { int przycisk1 = digitalRead(7); int przycisk2 = digitalRead(6); int a = 0; int b = 0; if (przycisk1 == LOW){ a = 1; b = 0; } if (przycisk2 == LOW) { a = 0; b = 1; } if(a == 1){ // normalne działanie świateł digitalWrite(10, LOW); //Czerwona digitalWrite(9, LOW); //Pomarańczowa digitalWrite(8, HIGH); //Zielona delay(2000); digitalWrite(10, LOW); //Czerwona digitalWrite(9, HIGH); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(1000); digitalWrite(10, HIGH); //Czerwona digitalWrite(9, LOW); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(2000); digitalWrite(10, HIGH); //Czerwona digitalWrite(9, HIGH); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(1000); } if (b == 1) { // światła wyłączone digitalWrite(10, LOW); digitalWrite(9, HIGH); digitalWrite(8, LOW); delay (1000); digitalWrite(10, LOW); digitalWrite(9, LOW); digitalWrite(8, LOW); delay (1000); } } 2) kod wykonuje się w pętli, lecz nie mogę zmienić działania przyciskami, muszę resetować arduino i nacisnąć drugi przycisk void setup() { pinMode(10, OUTPUT); //Dioda czerwona pinMode(9, OUTPUT); //Dioda żółta pinMode(8, OUTPUT); //Dioda zielona pinMode(7, INPUT_PULLUP); //przycisk włączenie pinMode(6, INPUT_PULLUP); //przycisk wyłączenie digitalWrite(10, LOW); //Wyłączenie diod digitalWrite(9, LOW); digitalWrite(8, LOW); int a=0; int b=0; } void loop() { int przycisk1 = digitalRead(7); int przycisk2 = digitalRead(6); int a = 0; int b = 0; if (przycisk1 == LOW){ a = 1; b = 0; } if (przycisk2 == LOW) { a = 0; b = 1; } while(a == 1){ // normalne działanie świateł digitalWrite(10, LOW); //Czerwona digitalWrite(9, LOW); //Pomarańczowa digitalWrite(8, HIGH); //Zielona delay(2000); digitalWrite(10, LOW); //Czerwona digitalWrite(9, HIGH); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(1000); digitalWrite(10, HIGH); //Czerwona digitalWrite(9, LOW); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(2000); digitalWrite(10, HIGH); //Czerwona digitalWrite(9, HIGH); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(1000); } while (b == 1) { // światła wyłączone digitalWrite(10, LOW); digitalWrite(9, HIGH); digitalWrite(8, LOW); delay (1000); digitalWrite(10, LOW); digitalWrite(9, LOW); digitalWrite(8, LOW); delay (1000); } } Kombinowałem z łączeniem pętli w różny sposób, oraz z do-while ale nic to nie daje... Może ktoś ma jakąś radę? Edytowano Grudzień 10, 2018 przez kempa662
Zero Grudzień 10, 2018 Udostępnij Grudzień 10, 2018 (edytowany) Wywal (dlatego pierwszy program nie zapętla się). int a = 0; int b = 0; z funkcji loop, zamiast WHILE użyj IF. lub dodaj odczyt stanu przycisków w pętlach while lub pobaw się przerwaniami Tak rzucam pomysłami, bo nie chcę narzucać jednego rozwiązania. Te delaye sprawią, że program będzie miał pewną bezwładność, ale powinno działać. Pamiętaj, że funkcja setup() wykonuje się raz, a loop() działa na okrągło. A co się stanie, gdy będą wciśnięte oba przyciski? Edytowano Grudzień 10, 2018 przez Zero
kempa662 Grudzień 10, 2018 Autor tematu Udostępnij Grudzień 10, 2018 Dzięki za podpowiedzi, zobaczę co mi wyjdzie ;)
Belferek Grudzień 10, 2018 Udostępnij Grudzień 10, 2018 29 minut temu, kempa662 napisał: 1) mogę sterować przyciskami, lecz pętla if wykonuje kod tylko raz Bo gdy loopy() wróci do początku zmienne a i b są inicjowane i zerowane od nowa. Tak na marginesie taki fragment znajduję i w setup() i w loop(). Po co? int a=0; int b=0; Takie zmienne możesz zadeklarować poza setup() i poza loop(). Będą one miały zasięg globalny i będą "widoczne" w każdym miejscu i w każdej funkcji programu. 32 minuty temu, kempa662 napisał: 2) kod wykonuje się w pętli, lecz nie mogę zmienić działania przyciskami, muszę resetować arduino i nacisnąć drugi przycisk Bo Twój program wchodzi w pętlę while(a == 1).... i nie może z niej wyjść gdyż w pętli a się nie zmienia i zawsze będzie równe 1. Twój program "zawiesił" się wewnątrz tej pętli i dlatego tylko reset przywraca UNO do życia.
kempa662 Grudzień 10, 2018 Autor tematu Udostępnij Grudzień 10, 2018 (edytowany) Wyrzuciłem inty przed setup() oraz loop() i z if-ami działa powiedzmy dobrze, tylko jak nacisnę przycisk1 program zaczyna działać jak normalne światła, ale żeby przełączył się na drugi tryb muszę trzymać przycisk2 do momentu jak pierwsza pętla if się zakończy (albo dobrze celować pod koniec ). Czy jest możliwe, żeby od razu po naciśnięciu przycisku, niezależnie od momentu, w którym znajduje się program następowała zmiana z jednego wariantu na drugi? Chyba, że zbyt dużo wymagam od tak prostego programu Tak to teraz wygląda: int a = 0; int b = 0; void setup() { pinMode(10, OUTPUT); //Dioda czerwona pinMode(9, OUTPUT); //Dioda żółta pinMode(8, OUTPUT); //Dioda zielona pinMode(7, INPUT_PULLUP); //przycisk włączenie pinMode(6, INPUT_PULLUP); //przycisk wyłączenie digitalWrite(10, LOW); //Wyłączenie diod digitalWrite(9, LOW); digitalWrite(8, LOW); } void loop() { int przycisk1 = digitalRead(7); int przycisk2 = digitalRead(6); if (przycisk1 == LOW){ a = 1; b = 0; } if (przycisk2 == LOW) { a = 0; b = 1; } if(a == 1){ // normalne działanie świateł digitalWrite(10, LOW); //Czerwona digitalWrite(9, LOW); //Pomarańczowa digitalWrite(8, HIGH); //Zielona delay(2000); digitalWrite(10, LOW); //Czerwona digitalWrite(9, HIGH); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(1000); digitalWrite(10, HIGH); //Czerwona digitalWrite(9, LOW); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(2000); digitalWrite(10, HIGH); //Czerwona digitalWrite(9, HIGH); //Pomarańczowa digitalWrite(8, LOW); //Zielona delay(1000); } if (b == 1) { // światła wyłączone digitalWrite(10, LOW); digitalWrite(9, HIGH); digitalWrite(8, LOW); delay (1000); digitalWrite(10, LOW); digitalWrite(9, LOW); digitalWrite(8, LOW); delay (1000); } } Edytowano Grudzień 10, 2018 przez kempa662
Zero Grudzień 10, 2018 Udostępnij Grudzień 10, 2018 (edytowany) Szybko łapiesz. Teraz pewnie ktoś wyskoczy, że delaye() to samo zło (to akurat prawda ). Generalnie po dodaniu jeszcze kliku zmiennych typu bool (a może int jedna lub dwie) i użycia do sterowania millis() lub przerwań można by się pokusić o to, by program nie miał tej bezwładności. Na twoim miejscu zapisałbym sobie ten projekt do zrobienia później i leciałbym dalej przez kurs (millis() jest w II części kursu zad.9 - jeśli jednak postanowisz trochę pokrążyć dookoła tego tematu). Edytowano Grudzień 10, 2018 przez Zero
Belferek Grudzień 10, 2018 Udostępnij Grudzień 10, 2018 (edytowany) 37 minut temu, kempa662 napisał: muszę trzymać przycisk2 do momentu jak pierwsza pętla if się zakończy No to sam widzisz, że stosowanie delay() nie jest najlepszym pomysłem jak wcześniej zauważył Zero. Próbujesz w ten sposób sterować czasem. Wspomniane przerwania to chyba na razie porywanie się z motyką na słońce, ale może takie narzędzie jak tu - zobacz bibliotekę Timers byłoby prostsze? Korzystałem z tej biblioteki i działa nawet zgrabnie. By ją móc wykorzystać ja bym stworzył sobie zmienną np. int program której przypisywałbym wartości odpowiadające sekwencji diód LED. Po odmierzeniu zadanego czasu przez Timers odczytywałbym (modyfikował) zawartość tej zmiennej i zapalał odpowiednią sekwencję LED. Mam nadzieję, że rozumiesz o co mi chodzi. Chociaż Ty lepiej wiesz jak program ma działać i może znajdziesz inne zastosowanie Timers.h. Dzięki tej bibliotece Twój loop() może bez przestojów odczytywać klawisze, a ustawiony stan LED do czasu zmiany jest przecież stabilny i nie wymaga ciągłego "podtrzymania". To taki jeden z pomysłów na gorąco. Edytowano Grudzień 10, 2018 przez Belferek
kempa662 Grudzień 10, 2018 Autor tematu Udostępnij Grudzień 10, 2018 Chyba zrobię najpierw cały kurs, żeby wiedzieć trochę więcej o Arduino i dopiero będę kombinował jak poprawić to co mam teraz. O delay-ach już poczytałem i wiedzę, że w większości przypadków można to lepiej rozwiązać 1
SOYER Grudzień 10, 2018 Udostępnij Grudzień 10, 2018 He, he, pozdrawiam nowego kolegę, jakbym siebie czytał rok temu. Powodzenia życzę 1
Treker (Damian Szymański) Grudzień 11, 2018 Udostępnij Grudzień 11, 2018 @kempa662, witam na forum Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start: Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników. Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć? Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości. Dnia 10.12.2018 o 21:43, kempa662 napisał: Chyba zrobię najpierw cały kurs, żeby wiedzieć trochę więcej o Arduino i dopiero będę kombinował jak poprawić to co mam teraz. Jeśli żadne terminy Cie nie gonią to faktycznie najlepiej przejdź spokojnie przez cały kurs, a najlepiej przez dwa. Zobaczysz jak wiele spraw się uprości. O wymianie delay() na lepsze rozwiązanie z millis() też znajdziesz coś w dalszej części kursu
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »