Grzegorz1397 Napisano Luty 28, 2020 Udostępnij Napisano Luty 28, 2020 Cześć, mam problem z przerwaniem na arduino. W pętli loop wykonuje się pętla for. Chciałbym żeby wciśnięcie jednego przycisku monostabilnego wywoływało zatrzymanie pętli do czasu wciśnięcia kolejnego przycisku. Czyli program ma zatrzymać petle for na czas od wciśnięcia jednego przycisku do wciśnięcia drugiego. Program obsługuje elektrozawory. Jeśli w instrukcji przerwania wpisywałem digitalWrite(dol=LOW): podobnie dla góra, lewo i prawo to faktycznie w momencie wciśnięcia przycisku zawory się wyłączały, ale pętla działała zwiększając na wyświetlaczu ilosc wykonanych cykli mimo, że zawory nie działały. Jeśli chcę do wywoływania pauzy programu użyć przycisku monostabilnego to pewnie będę musiał też w funkcji przerwania uwzględnić jakąś pętlę while i zmienną typu logicznego żeby przerwanie wykonywało się do czasu wciśnięcia kolejnego przycisku? Chciałbym prosić o pomoc w napisaniu samego środka funkcji przerwania. Nie do końca wiem też jaka jest praktyczna różnica w wywoływaniu przerwania stanem niskim, a zboczem opadającym. for(ilosc_wykonanych; ilosc_wykonanych<liczba_cykli; ilosc_wykonanych) { lcd.setCursor(3, 0); lcd.print("WYKONANE CYKLE"); lcd.setCursor(8, 1); lcd.print(ilosc_wykonanych); lcd.setCursor(0, 2); lcd.print("ILOSC CYKLI"); lcd.setCursor(11, 2); lcd.print("="); lcd.setCursor(12, 2); lcd.print(liczba_cykli); lcd.setCursor(0, 3); lcd.print("CZAS ZANURZENIA"); lcd.setCursor(15, 3); lcd.print("="); lcd.setCursor(16, 3); lcd.print(t); lcd.setCursor(19, 3); lcd.print("S"); delay(300); delay(oczekiwanie); digitalWrite(gora, LOW); digitalWrite(dol, HIGH); delay(czas_zanurzenia); digitalWrite(dol, LOW); digitalWrite(gora, HIGH); delay(oczekiwanie); digitalWrite(prawo, LOW); digitalWrite(lewo, HIGH); delay(oczekiwanie); digitalWrite(dol, HIGH); digitalWrite(gora, LOW); delay(czas_zanurzenia); digitalWrite(dol, LOW); digitalWrite(gora, HIGH); delay(oczekiwanie); digitalWrite(lewo, LOW); digitalWrite(prawo, HIGH); lcd.clear(); ilosc_wykonanych = ilosc_wykonanych + 1; } lcd.clear(); lcd.setCursor(3, 1); lcd.print("KONIEC PROGRAMU"); delay(500); } Cytuj Link do komentarza Share on other sites More sharing options...
Belferek Luty 28, 2020 Udostępnij Luty 28, 2020 (edytowany) for(ilosc_wykonanych; ilosc_wykonanych<liczba_cykli; ilosc_wykonanych++) { .... //ilosc_wykonanych=ilosc_wykonanych+1 TO JEST ZBĘDNE | Taka konstrukcja tej pętli jest lepsza. Edytowano Luty 28, 2020 przez Belferek Cytuj Link do komentarza Share on other sites More sharing options...
Belferek Luty 28, 2020 Udostępnij Luty 28, 2020 (edytowany) 4 godziny temu, Grzegorz1397 napisał: Jeśli w instrukcji przerwania wpisywałem digitalWrite(dol=LOW): To niestety ale źle wpisywałeś. Poprawna składnia tego polecenia to digitalWrite(NR_PINU, STAN); Więc jak to działało nie wiem. Może zanim użyjesz przerwań zainteresuj się biblioteką Bounce2 i przykładami jej użycia. Biblioteka dostępna jest z poziomu menadżera bibliotek: CTRL+SHIFT+I Dzięki tej bibliotece wykryjesz zmiany stanu przycisków. Edytowano Luty 28, 2020 przez Belferek Cytuj Link do komentarza Share on other sites More sharing options...
Grzegorz1397 Marzec 25, 2020 Autor tematu Udostępnij Marzec 25, 2020 (edytowany) #include <LiquidCrystal.h> #define dol 1 #define gora 0 #define lewo 5 #define prawo 4 #define LM35 A0 long liczba_cykli; int ilosc_wykonanych; int czas_zanurzenia; int t; int oczekiwanie=1500; int oczekiwanie1=400; float temperatura=0; #define RS 7 #define EN 15 //A1 #define D4 16 //A2 #define D5 17 //A3 #define D6 18 //A4 #define D7 19 //A5 LiquidCrystal lcd(RS,EN,D4,D5,D6,D7); void setup() { int czas=czas_zanurzenia/1000; pinMode(0, OUTPUT); pinMode(2, INPUT_PULLUP); pinMode(1, OUTPUT); pinMode(3, INPUT_PULLUP); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, INPUT_PULLUP); pinMode(8, INPUT_PULLUP); pinMode(7, INPUT_PULLUP); pinMode(9, INPUT_PULLUP); pinMode(10, INPUT_PULLUP); pinMode(11, INPUT_PULLUP); pinMode(12, INPUT_PULLUP); pinMode(13, INPUT_PULLUP); lcd.begin(20, 4); lcd.setCursor(6, 0); lcd.print("WITAJ"); delay(3000); lcd.clear(); lcd.begin(20, 4); bool cykle = true; while(cykle == true){ lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI"); lcd.setCursor(8, 1); lcd.print(liczba_cykli); delay(300); if(digitalRead(10) == LOW){ delay(500); liczba_cykli=liczba_cykli+1; lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI ="); lcd.setCursor(8, 1); lcd.print(liczba_cykli); } if(digitalRead(9) == LOW){ delay(500); liczba_cykli=liczba_cykli+10; lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI ="); lcd.setCursor(8, 1); lcd.print(liczba_cykli); } if(digitalRead(11) == LOW){ delay(500); liczba_cykli=liczba_cykli+100; lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI ="); lcd.setCursor(8, 1); lcd.print(liczba_cykli); } if(digitalRead(13) == LOW){ delay(500); liczba_cykli=liczba_cykli+1000; lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI ="); lcd.setCursor(8, 1); lcd.print(liczba_cykli); } if(digitalRead(8) == LOW){ delay(500); liczba_cykli=liczba_cykli+10000; lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI ="); lcd.setCursor(8, 1); lcd.print(liczba_cykli); } if(digitalRead(12) == LOW){ delay(500); liczba_cykli=liczba_cykli+100000; lcd.clear(); lcd.setCursor(4, 0); lcd.print("ILOSC CYKLI ="); lcd.setCursor(8, 1); lcd.print(liczba_cykli); } if(digitalRead(6) == LOW){ delay(300); cykle = false; } } bool zanurzenie = true; while(zanurzenie == true){ lcd.clear(); lcd.setCursor(2, 0); lcd.print("CZAS ZANURZENIA"); lcd.setCursor(8, 1); lcd.print(t); lcd.setCursor(12, 1); lcd.print("S"); delay(300); if(digitalRead(10) == LOW){ delay(500); czas_zanurzenia=czas_zanurzenia+1000; t=czas_zanurzenia/1000; lcd.clear(); lcd.setCursor(2, 0); lcd.print("CZAS ZANURZENIA ="); lcd.setCursor(8, 1); lcd.print(t); lcd.setCursor(12, 1); lcd.print("S"); } if(digitalRead(9) == LOW){ delay(500); czas_zanurzenia=czas_zanurzenia+10000; t=czas_zanurzenia/1000; lcd.clear(); lcd.setCursor(2, 0); lcd.print("CZAS ZANURZENIA ="); lcd.setCursor(8, 1); lcd.print(t); lcd.setCursor(12, 1); lcd.print("S"); } if(digitalRead(6) == LOW){ delay(300); zanurzenie = false; } } lcd.clear(); lcd.setCursor(4, 0); lcd.print("URUCHAMIANIE"); lcd.setCursor(6, 1); lcd.print("PROGRAMU"); delay(3000); for(int i=5;i>0;i--){ lcd.clear(); lcd.setCursor(9,2); lcd.print(i); delay(1000); } lcd.clear(); digitalWrite(prawo, HIGH); digitalWrite(gora, HIGH); } void loop(){ temperatura = ((analogRead(LM35) * 5.0) / 1024.0) * 100; lcd.begin(20, 4); lcd.noCursor(); lcd.noBlink(); for(ilosc_wykonanych; ilosc_wykonanych<liczba_cykli; ilosc_wykonanych++) { lcd.setCursor(0, 0); lcd.print("WYK. CYKLE"); lcd.setCursor(10, 0); lcd.print("="); lcd.setCursor(11, 0); lcd.print(ilosc_wykonanych); lcd.setCursor(0, 1); lcd.print("TEMPERATURA"); lcd.setCursor(11, 1); lcd.print("="); temperatura = ((analogRead(LM35) * 5.0) / 1024.0) * 100; lcd.setCursor(12, 1); lcd.print(temperatura); lcd.setCursor(17, 1); lcd.print("C"); lcd.setCursor(0, 2); lcd.print("ILOSC CYKLI"); lcd.setCursor(11, 2); lcd.print("="); lcd.setCursor(12, 2); lcd.print(liczba_cykli); lcd.setCursor(0, 3); lcd.print("CZAS ZANURZENIA"); lcd.setCursor(15, 3); lcd.print("="); lcd.setCursor(16, 3); lcd.print(t); lcd.setCursor(19, 3); lcd.print("S"); delay(300); delay(oczekiwanie); digitalWrite(gora, LOW); digitalWrite(dol, HIGH); delay(czas_zanurzenia); digitalWrite(dol, LOW); digitalWrite(gora, HIGH); delay(oczekiwanie1); digitalWrite(prawo, LOW); digitalWrite(lewo, HIGH); delay(oczekiwanie); digitalWrite(dol, HIGH); digitalWrite(gora, LOW); delay(czas_zanurzenia); digitalWrite(dol, LOW); digitalWrite(gora, HIGH); delay(oczekiwanie1); digitalWrite(lewo, LOW); digitalWrite(prawo, HIGH); lcd.clear(); } lcd.clear(); lcd.setCursor(3, 1); lcd.print("KONIEC PROGRAMU"); delay(500); } Odświeżam nieco temat, wstawiam cały kod. Program działa tak jak powinien, natomiast nie wiem jak dorobić do niego dwie kwestie: 1. W skrzynce sterowniczej zamontowane są dwa wentylatory. Chciałbym, żeby wentylatory uruchamiały się kiedy czujnik temperatury wskaże powyżej określonej temperatury, załóżmy 30 stopni. 2. Wciśnięciem jednego przycisku (obojętnie czy monostabliny czy bistabilny) chciałbym wywoływać zastopowanie wykonywania programu. Elektrozawory mają się po prostu zatrzymać, odliczanie w pętli for również do czasu wciśnięcia przycisku kolejny raz. Nie wiem jak te dwa problemy poprawnie zrealizować pod względem programowym. Będę wdzięczny za wszelkie sugestie. Edytowano Marzec 25, 2020 przez Grzegorz1397 zapomniałem wstawić kod programu Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
ethanak Marzec 25, 2020 Udostępnij Marzec 25, 2020 1 minutę temu, Grzegorz1397 napisał: wstawiam cały kod Z ciekawości: gdzie go wstawiasz? Cytuj Link do komentarza Share on other sites More sharing options...
Grzegorz1397 Marzec 25, 2020 Autor tematu Udostępnij Marzec 25, 2020 1 minutę temu, ethanak napisał: Z ciekawości: gdzie go wstawiasz? Już dodałem, poranna nieuwaga 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Marzec 25, 2020 Udostępnij Marzec 25, 2020 7 minut temu, Grzegorz1397 napisał: Będę wdzięczny za wszelkie sugestie. Wywalić pętlę for w loop() Wywalić delay Wiesz jak się do tego zabrać? Poza tym: wszelkie inicjalizacje lcd (begin, noBlink i tym podobne) mają siedzieć w setup, a nie być wykonywane za każdym obrotem pętli. Cytuj Link do komentarza Share on other sites More sharing options...
Grzegorz1397 Marzec 25, 2020 Autor tematu Udostępnij Marzec 25, 2020 2 minuty temu, ethanak napisał: Wiesz jak się do tego zabrać? Niestety nie, nie jestem programistą i wszystko robiłem intuicyjnie. Nie wiem czym zastąpić pętle for i delay. Przy każdym uruchomieniu urządzenia muszę mieć możliwość ustawienia ilości cykli, czasu zanurzenia i właśnie delay ustalam jak długo. Wstawiam zdjęcie urządzenia, żeby ułatwić wyobrażenie co to właściwie ma robić. Czas zanurzenia to czas kiedy siłownik pionowy jest wysunięty. Nie mam pojęcia w jaki sposób sterować tam czasami jeśli nie za pomocą delay. Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Marzec 25, 2020 Udostępnij Marzec 25, 2020 5 minut temu, Grzegorz1397 napisał: Nie wiem czym zastąpić pętle for i delay. Przykład na zastąpienie for Zamiast: void loop() { int n; for (n=0; n< 10; n++) { rób_coś(); } rób_jeszcze_cos(); } robisz: void loop() { static int n=0; if (n < 10) { rób_coś(); n++; } else { rób_coś_innego(); n=0; } } Wygląda na bardziej skomplikowane, ale pozostaje tylko jedna główna pętla której już nie trzeba przerywać. Co do zastąpienia delay czymś bardziej strawnym - o millis() napisano już gigabajty różnych poradników, np. taki: https://forbot.pl/blog/kurs-arduino-ii-wielozadaniowosc-opoznienia-z-millis-id18418 Do tego jak wpiszesz do forumowej wyszukiwarki "delay millis" to parę sensownych wyników dostaniesz. Cytuj Link do komentarza Share on other sites More sharing options...
Grzegorz1397 Marzec 26, 2020 Autor tematu Udostępnij Marzec 26, 2020 Już samo wyeliminowanie pętli for i zastąpienie jej if-ami wyeliminowało wszystkie problemy. Na if-ach dodałem też pauzę i uruchomienie wentylatorów, wszystko działa, dziękuję za pomoc. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!