Skocz do zawartości

Implementacja przycisku on/off w programie


HexXxaN

Pomocna odpowiedź

Jestem tutaj nowy a jedyne co do tej pory programowałem to PLC w technikum. Robię sobie ćwiczenie, w którym 4 diody zapalają się i gasną jedna po drugiej. Gdy ostatnia dioda gaśnie zapala się pierwsza i tak w nieskończoność. Problem polega na tym, że za rozpoczęcie i zakończenie pracy układu odpowiada jeden tact switch. Z zainicjowaniem pętli nie mam żadnego problemu. Problem jest z jej przerwaniem. Założenie jest takie, że przyciśnięcie przycisku drugi raz w jakimkolwiek miejscu pętli natychmiastowo ją łamie i z niej wychodzi nawet wtedy, gdy nie wypełniła się do końca. Wszystkie diody mają zgasnąć, a program ma wrócić na swój początek. Jak pewnie się domyślacie pętla ta w ogóle się nie przerywa bez względu na to ile razy wciskam przycisk. Szukałem rozwiązania tego problemu w kursie z Forbota, ale to rozwiązanie nie sprawdza się w moim programie. Moglibyście mi doradzić jak rozwiązać ten problem? Może istnieje jakaś komenda, która jest w stanie wykonać to w elegancki sposób? Ta funkcja będzie mi potrzebna w przyszłości w bardziej zaawansowanych projektach. Z góry dziękuję za pomoc.

Link do komentarza
Share on other sites

@HexXxaN, 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.

10 godzin temu, HexXxaN napisał:

Założenie jest takie, że przyciśnięcie przycisku drugi raz w jakimkolwiek miejscu pętli natychmiastowo ją łamie i z niej wychodzi nawet wtedy, gdy nie wypełniła się do końca.

Jeśli do migania diodami wykorzystujesz opóźnienia delay to natychmiastowe zatrzymanie pętli będzie trudne - trzeba byłoby trochę pokombinować. Lepiej zastąpić delay za pomocą funkcji millis lub wykorzystać przerwania. Informacje na ten temat znajdziesz w tych artykułach:

Pamiętaj, że delay całkowicie zatrzymuje działania programu, nie możesz się więc dziwić, że Arduino "w między czasie" nie sprawdza stanu przycisku 😉

  • Pomogłeś! 1
Link do komentarza
Share on other sites

@Treker Dzięki, bardzo mi pomogłeś 😄 Program działa prawidłowo, natomiast pojawił się inny problem. Nie wiem jak programowo pozbyć się drgań przycisku bez funkcji delay w attachInterrupt oraz nie wiem jak ustawić "miganie" diod w moim programie. Próbowałem wstawić funkcję while(roznicaCzasu<=1000) ale nie zadziałała. Oto kod:

int przycisk = 2; 
volatile boolean stan = 0;
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long roznicaCzasu = 0;

void setup() 
 {
  for(int i=4;i<=7;i++)
  {
  pinMode(i,OUTPUT);
  }
pinMode(przycisk,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(przycisk), wcisniecie, FALLING);
}

void wcisniecie()
  {
    stan=!stan;
  }
  
void loop() 
{
aktualnyCzas = millis();
roznicaCzasu = aktualnyCzas - zapamietanyCzas;
  if(stan==0)
    {
      for(int i=4;i<=7;i++)
        {
          if(i==7||i==5||i==6)
            {
              digitalWrite(i,HIGH);     //tu sie zapala
              digitalWrite(i-1,LOW);    //tu gaśnie
            }
          else
            {
              digitalWrite(4,HIGH);    //tu sie zapala
              digitalWrite(7,LOW);     //tu gaśnie
            }
        }
    }
  else
    {
        digitalWrite(4,LOW);
        digitalWrite(5,LOW);
        digitalWrite(6,LOW);
        digitalWrite(7,LOW);
    }

}

 

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

@Belferek ten zapamiętany czas wyglądał tak:

              while(aktualnyCzas-zapamietanyCzas<=1000UL)
                {
                digitalWrite(i,HIGH);     //tu sie zapala
                digitalWrite(i-1,LOW);    //tu gaśnie
                }
              zapamietanyCzas=aktualnyCzas;
            }
          else
            {
              while(aktualnyCzas-zapamietanyCzas<=1000UL)
                {
                digitalWrite(4,HIGH);    //tu sie zapala
                digitalWrite(7,LOW);     //tu gaśnie
                }
              zapamietanyCzas=aktualnyCzas;
            }

 

Link do komentarza
Share on other sites

przecież to nie ma sensu...

sprawdzasz, czy zmienna a jest mniejsza lub równa b. jeśli tak, robisz hakieś machlojki z diodami i podstawiasz wartość b do a, a potem dalej sprawdzasz... i żeby nie wiem co się stało, cały czas w pętli będziesz miał a == b, czyli kolejny obrót pętli, kolejne podstawienie i tak w kółko... bo b się przecież sama nie zmieni.

na pewno o to ci chodziło?

Link do komentarza
Share on other sites

Dnia 30.04.2019 o 03:57, HexXxaN napisał:

Jestem tutaj nowy a jedyne co do tej pory programowałem to PLC w technikum. Robię sobie ćwiczenie, w którym 4 diody zapalają się i gasną jedna po drugiej. Gdy ostatnia dioda gaśnie zapala się pierwsza i tak w nieskończoność. Problem polega na tym, że za rozpoczęcie i zakończenie pracy układu odpowiada jeden tact switch. Z zainicjowaniem pętli nie mam żadnego problemu. Problem jest z jej przerwaniem. Założenie jest takie, że przyciśnięcie przycisku drugi raz w jakimkolwiek miejscu pętli natychmiastowo ją łamie i z niej wychodzi nawet wtedy, gdy nie wypełniła się do końca. Wszystkie diody mają zgasnąć, a program ma wrócić na swój początek. Jak pewnie się domyślacie pętla ta w ogóle się nie przerywa bez względu na to ile razy wciskam przycisk. Szukałem rozwiązania tego problemu w kursie z Forbota, ale to rozwiązanie nie sprawdza się w moim programie. Moglibyście mi doradzić jak rozwiązać ten problem? Może istnieje jakaś komenda, która jest w stanie wykonać to w elegancki sposób? Ta funkcja będzie mi potrzebna w przyszłości w bardziej zaawansowanych projektach. Z góry dziękuję za pomoc.

Użyj while(button == false) w loop

Link do komentarza
Share on other sites

18 godzin temu, HexXxaN napisał:

  while(aktualnyCzas-zapamietanyCzas<=1000UL)
                {
                digitalWrite(i,HIGH);     //tu sie zapala
                digitalWrite(i-1,LOW);    //tu gaśnie
                }

Zauważ, że jeśli warunek while jest prawdziwy to pętla zacznie się wykonywać i w Twoim programie .... nigdy się nie skończy gdyż w pętli zmienne warunku się nie zmieniają! Co do drgania styków to zobacz tutaj: https://github.com/thomasfredericks/Bounce2

 

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.