Skocz do zawartości

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


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

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

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);
     
  }
}

 

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();

     

  • 2 miesiące później...

Zadanie 7.1

IMG_20250118_182430.thumb.jpg.26cb45cead0a7a2ae7df733d9bd498d2.jpg

Zadanie 7.4

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

void setup() {
  lcd.begin(16, 2); //Deklaracja typu
  lcd.clear(); // czyscimy wyswietlacz
  pinMode(8, INPUT_PULLUP); //Wyjście przycisku
  pinMode(9, INPUT_PULLUP); //Wyjście przycisku

}
void loop(){
 if (digitalRead(9) == LOW) { //jeżeli wcisniemy przycisk 9
  lcd.clear(); //czyszczenie ekranu
  licznik=true;} 

if (digitalRead(8) == LOW) {
  czas = 0; //zerujemy licznik tak by przy kazdym wcisnieciu zaczynalo liczyc od 0
  lcd.clear(); //czyszczenie ekranu
  licznik=false;}

  if (licznik == false){ //jeżeli wcisniemy przycisk 8
  czas = czas+1; // dodajemy sekunde do zmiennej czas
  lcd.setCursor(0, 0); //Ustawienie kursora
  lcd.print("CZAS START"); // wyswietlenie napisu CZAS START
  lcd.setCursor(0,1); //Ustawienie kursora w odpowiednim miejscu
  lcd.print(czas); //Wyświetlenie czasu z zmiennej czas
  lcd.setCursor(5, 1); //Ustawienie kursora
  lcd.print("sekund"); // wyswietlenie napisu sekund po zmiennej czas
  delay(1000); // opóźnienie 1sek by licznik dzialał prawidłowo
  }

 
  if (licznik == true){ //jeżeli wcisniemy przycisk 9
  lcd.setCursor(0,0); //ustawienie kursora
  lcd.print("WYNIK"); // wyswietlenie napisu WYNIK
  lcd.setCursor(3,1); //ustawienie kursora
  lcd.print(czas); //Wyświetlenie czasu z int=czas
   lcd.setCursor(7, 1); //Ustawienie kursora
  lcd.print("sekund"); // wyswietlenie sekund
  delay(100);
}}

Ogólnie licznik działa fajnie liczy czas, fajnie wygląda. Jest tylko jeden problem w moim wykonaniu. Po wciśnięciu przycisku start czas leci ale żeby zatrzymać liczenie trzeba przycisk stop przytrzymać do ok 1 sekundy w zależności w którym etapie jest aktualnie pętla. Nie wiem jak to ulepszyć. Pewnie trzeba by użyć jakiś zmiennych których jeszcze nie znam. Coś w stylu kontrolowanie stanu przycisku co 20ms a nie raz na sekundę.

Proszę o uwagi 🙂 Dodaje jeszcze 2 zdjęcia licznika

 

IMG_20250119_092840.thumb.jpg.228d0c190f6c3853836908a082857178.jpgIMG_20250119_092901.thumb.jpg.6c682d246500ec58e88e2463e6719ce1.jpg

  • Lubię! 2
(edytowany)
57 minut temu, PanMajster napisał:

Ogólnie licznik działa fajnie liczy czas, fajnie wygląda. Jest tylko jeden problem w moim wykonaniu. Po wciśnięciu przycisku start czas leci ale żeby zatrzymać liczenie trzeba przycisk stop przytrzymać do ok 1 sekundy w zależności w którym etapie jest aktualnie pętla. Nie wiem jak to ulepszyć. Pewnie trzeba by użyć jakiś zmiennych których jeszcze nie znam. Coś w stylu kontrolowanie stanu przycisku co 20ms a nie raz na sekundę.

Polecam zapoznać się z funkcją millis(), jest cięższa w użyciu, ale nie blokuje kodu. 🙂 Jest omawiana w kursie arduinio poziom II

Edytowano przez BeeKeyPro
  • Lubię! 1
  • 2 miesiące później...
(edytowany)

Witam,

podłączyłem wyświetlacz, działa!

Wyświetlacz jak i diodę podświetlającą zasilam z baterii 9v przez stabilizator liniowy, i zauważyłem, że po odłączeniu baterii dioda cały czas świeci, tylko słabiej.

Czy to jest normalne?

Wydedukowałem, że napięcie z pinów sterujących przebija się na vcc wyświetlacza i zasila diodę podświetlającą. Są one podpięte do tej samej szyny zasilającej na płytce stykowej. Efekt nie występuje gdy podpinam vcc wyświetlacza przez diodę prostowniczą (katoda od strony wyświetlacza).

Tutaj zdjęcie arduino (podpięte tylko gnd i piny sterujące).

arduino.thumb.jpg.d696874a84769affaa2f2f0410bf4fef.jpg

Tutaj zasilanie włączone (wszystko działa znakomicie).

196140094_wczony.thumb.jpg.9555197b8307fffbb295d0c037d258b4.jpg

Tutaj zasilanie odłączone (dioda podświetlająca świeci (słabiej), jestem w stanie dostrzec napis, lecz nie widać go na zdjęciu).

1494774384_wyczony.thumb.jpg.84ab29992d66ad24cf1815629da17d23.jpg

Co wy na to?:)

Edytowano przez migdas

Zadanie 7.4

#include <Arduino.h>
#include <LiquidCrystal.h>
#include <Bounce2.h>

#define START_B 2 //przycisk start
#define STOP_B 3 //przycisk stop

//Konfiguracja LCD
LiquidCrystal lcd(A8, A9, A10, A11, A12, A13);

//Inicjalizacja obiektu Bounce dla eliminacji drgań
Bounce startButton = Bounce();
Bounce stopButton = Bounce();

unsigned long previousMillis;
unsigned long elapsedSec;
unsigned long elapsedMiliSec;

void setup() {
  //Konfiguracja przycisków i ustawienie 25ms dla eliminacji drgań
  startButton.attach(START_B, INPUT_PULLUP);
  startButton.interval(25);
  stopButton.attach(STOP_B, INPUT_PULLUP);
  stopButton.interval(25);
  
  lcd.begin(16 ,2);
  lcd.print("Press Start!");
    
}



void loop() {
   // Aktualizacja stanu przycisków
  startButton.update();
  stopButton.update();
  
  //Sprawdzenie czy start został wciśniety
  if (startButton.fell()){
    lcd.clear();
    previousMillis = millis();

     // Pętla do pomiaru czasu aż do wciśnięcia przycisku STOP
    while(!stopButton.fell()){
      stopButton.update();
      elapsedSec = (millis() - previousMillis) / 1000;
      elapsedMiliSec = ((millis() - previousMillis) % 1000) / 10;
      
      // Wyświetlanie zmierzonego czasu na LCD
      lcd.setCursor(0, 0);
      lcd.print("Elapsed time:");
      lcd.setCursor(0, 1);
      lcd.print(elapsedSec);
      lcd.print(",");
      if (elapsedMiliSec < 10) lcd.print("0"); //dodanie "0" przed milisekundy 0-9
      lcd.print(elapsedMiliSec);
      lcd.print(" s ");
      
    }
    // Po wciśnięciu STOP wyświetl wynik końcowy
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Finish!");
    lcd.setCursor(0, 1);
    lcd.print(elapsedSec);
    lcd.print(",");
    if (elapsedMiliSec < 10) lcd.print("0"); //dodanie "0" przed milisekundy 0-9
    lcd.print(elapsedMiliSec);
    lcd.print(" s ");
  
  }
}

 

  • 4 tygodnie później...

Cześć, mam problem z HD44780, pół wyświetlacza wyświetla śmieci, niezależnie od kontrastu. Goldpiny lutowałem sam, ale kiedyś ten wyświetlacz działał cały, a luty wyglądają normalnie. Pytanie do bardziej wprawionych - czy to wygląda jak uszkodzenie samego wyświetlacza czy problem z brakiem jakiś sygnałów?

20250425_163154.thumb.jpg.172ca6f6b14614b92a1e4aed72fda124.jpg20250425_163208.thumb.jpg.73435133fac8dbca228eb31ec2f819c2.jpg

Dnia 25.04.2025 o 16:36, Saalin napisał:

Pytanie do bardziej wprawionych - czy to wygląda jak uszkodzenie samego wyświetlacza czy problem z brakiem jakiś sygnałów?

To wygląda raczej na uszkodzenie wyświetlacza. A jaka jest różnica między pierwszym, a drugim zdjęciem? Co się zmieniło, że nagle cały wyświetlacz przestał działać?

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...