Skocz do zawartości

Arduino sterowanie przyciskiem


kempa662

Pomocna odpowiedź

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 przez kempa662
Link do komentarza
Share on other sites

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 przez Zero
Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

(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 przez kempa662
Link do komentarza
Share on other sites

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 przez Zero
Link do komentarza
Share on other sites

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 przez Belferek
Link do komentarza
Share on other sites

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ć 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

@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 😉

Link do komentarza
Share on other sites

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!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.