Skocz do zawartości

Kurs Arduino - #7 - Wyświetlacz tekstowy, LCD 2x16


Komentator

Pomocna odpowiedź

I to jest prawda, pin sprawdzany jest po delay(), ale pomiędzy oboma`sprawdzaniami upływa tak dużo czasu, że sygnał może się z łatwością w międzyczasie zmienić - w tym sensie "ma szansę". Przycisk trzeba przytrzymać odpowiednio długo, by zadziałał.

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

Już to sobie zwizualizowałem.

 

362141118_Wykreswhile_3.thumb.png.a93e60c30df4ad1c4067d893abeedd46.png

Na niebiesko zaznaczyłem stan while(digitalRead(10) != LOW), a na różowo działanie delay(1000). Stanie 1 uruchamia wyświetlenie stanu licznika counter, a następnie delay(1000) i nic się nie dzieje przez 1000 ms chociaż w międzyczasie stan pin 10 zmienił się. Po upływie 1000 ms digitalRead(10) != LOW więc counter zwiększa wartość o 1 i kończy się intrukcja while() bez wykonania instrukcji if(). W kolejnej pętli digitalRead(10) != LOW więc ponownie wyświetlany jest stan licznika, następnie uruchamia się delay(1000). Tym razem po upływie 1000 ms stan digitalRead(10) == LOW więc po zwiększeniu licznika o 1 jest wykonywana instrukcja if(), która wyświetla napis KONIEC oraz powiększony o 1 stan licznika i kończy się pętla. Przy kolejnym obiegu pętli while() nie jest wykonywane ponieważ digitalRead(10) == LOW. Dopiero przy następnym obiegu pętli gdy digitalRead(10) != LOW instrukcja while zostanie uruchomiona i będzie działo się to, co wcześniej opisałem.

Reasumując, wynik stanu licznika jest wyświetlany raz lub dwa razy w każdej pętli i nie odzwierciedla ani ilości wykonanych pętli, ani ilości stanów digitalRead(10) != LOW.  Wyświetlanie napisu KONIEC jest przypadkowe.

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

Faktycznie w programie funkcja delay() powoduje problemy ponieważ podczas trwania delay(1000) program nie sprawdza stanu przycisków. Czyli w sumie jeśli ktoś by bardzo szybko wciskał przycisk to nigdy by się ta pętla nie zakończyła chyba. Trochę poprawiłem ten kod używając innej funkcji milis(). 

Dnia 8.11.2024 o 20:25, Sylba napisał:

Reasumując, wynik stanu licznika jest wyświetlany raz lub dwa razy w każdej pętli i nie odzwierciedla ani ilości wykonanych pętli, ani ilości stanów digitalRead(10) != LOW.  Wyświetlanie napisu KONIEC jest przypadkowe.

 "nie odzwierciedla ani ilości wykonanych pętli, ani ilości stanów digitalRead(10) != LOW" A to nie to samo? Dwa razy zostanie wyświetlony w przypadku kiedy spełni się warunek if wewnątrz pętli?

 

Dnia 8.11.2024 o 20:25, Sylba napisał:

Dopiero przy następnym obiegu pętli gdy digitalRead(10) != LOW instrukcja while zostanie uruchomiona i będzie działo się to, co wcześniej opisałem.

 

Ale wewnątrz if jest jeszcze instrukcja break. Czy może się zdarzyć sytuacja, że po naciśnięciu przycisku wyświetli się "Koniec", ale instrukcja break zostanie pominięta? W sumie jest jeden blok kodu ale nie jestem pewien.

#include <LiquidCrystal.h> //Dołączenie bilbioteki
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Informacja o podłączeniu nowego wyświetlacza

double counter = 0;
double poprzedniCzas = 0;
double aktualnyCzas = 0;
 
void setup() {
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  lcd.begin(16, 2); //Deklaracja typu
  lcd.clear();
  lcd.setCursor(0, 0); //Ustawienie kursora

}
 
 
void loop()
{
  
  if(digitalRead(9) == LOW) {
    
    aktualnyCzas = milis();


    while(digitalRead(10) != LOW) {

      if(aktualnyCzas - poprzedniCzas >= 1000) {
         poprzedniCzas = aktualnyCzas;
         counter = counter + 1;
         lcd.clear();
         lcd.setCursor(0, 1);
         lcd.print(counter);
         
      }
    }
    
     lcd.clear();
     lcd.print("Koniec");
     lcd.setCursor(0, 1);
     lcd.print(counter);
     
  }
}

 

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

Zamierzałem zadać to samo pytanie co Santiago.

Poza tym mam jeszcze takie uwagi:

  1. Nie jest nie poprawnym użycie zmiennej aktualnyCzas przechowującej wartość millis(), ale zamiast niej można użyć po prostu samo millis().
  2.  if(aktualnyCzas - poprzedniCzas >= 1000) {
             poprzedniCzas = aktualnyCzas;

    to fragment kodu, który może służyć do odczytania stanu przycisku (patrz gotowy przykład Denounce z IDE Arduino. Pytanie po co aż 1000?

  3. Skoro zacytowany powyżej fragment kodu ma służyć jako zabezpieczenie odczytu stanu przycisku, to powinien być użyty luż przy pierwszym odczycie stanu przycisku

     

    void loop()
    {
      
      if(digitalRead(9) == LOW) {
        
        aktualnyCzas = milis();

     

Link do komentarza
Share on other sites

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ę »
×
×
  • 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.