Skocz do zawartości

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


Pomocna odpowiedź

@Danyeru dobra robota! Zwróć tylko uwagę na wcięcia w kodzie, bo coś tam się z czasem rozjechało (m.in. brak wcięcia wewnątrz ostatniego while). To drobiazgi, ale warto wyrabiać sobie taki nawyk 🙂

  • Lubię! 1
  • 2 miesiące później...

Z każdą kolejną lekcją omawiane tematy są coraz bardziej ciekawsze 👍

Gdyby ktoś potrzebował pomocy, poniżej podrzucam własne spostrzeżenia oraz działający kod programu do zadania domowego 😉

1️⃣ Zadanie domowe 7.1

obraz.thumb.png.3643ab5f8f2a5809af57cbf461a79ebf.png

2️⃣ Zadanie domowe 7.4

Proste rozwiązanie, aby stworzyć swój pierwszy, w pełni działający stoper ⏱️

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

#define start 10
#define koniec 11

int odczyt = 0;

void setup() {
  pinMode(start, INPUT_PULLUP);
  pinMode(koniec, INPUT_PULLUP);
  
  lcd.begin(16, 2);
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("Wcisnij przycisk");
  lcd.setCursor(0, 1);
  lcd.print("START");

  while (digitalRead(start) == HIGH) {}
}

void loop() {
  int odczyt = 0;
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Czas [s]");
  lcd.setCursor(0, 1);
  lcd.print("0");
  
  while (digitalRead(koniec) == HIGH) {
    odczyt = odczyt + 1;
    lcd.setCursor(0, 1);
    lcd.print(odczyt);
    delay(1000);
  }

  while (digitalRead(koniec) == LOW) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Koniec [s]");
    lcd.setCursor(0, 1);
    lcd.print(odczyt);
    
    delay(5000);

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Wcisnij przycisk");
    lcd.setCursor(0, 1);
    lcd.print("START");
    
    delay(1000);
  }
  while (digitalRead(start) == HIGH) {}
}
  • Lubię! 2
3 godziny temu, Wejmon napisał:

Z każdą kolejną lekcją omawiane tematy są coraz bardziej ciekawsze 👍

Super, dobra robota. Cieszę się, że kurs jest ciekawy. Mam nadzieję, że kolejne ćwiczenia też Ci się spodobają. Powodzenia!

  • Lubię! 1
  • 5 tygodnie później...

zadanie 7.4

Program działa prawie że bez zarzutów, tylko jeżeli chce zatrzymać stoper drugim przyciskiem muszę go trzymać wciśniętego przez momencik i go puścić aby program się skończył szybkie naciśniecie przycisku nie działa na program. Jeżeli program się skończy przyciśniecie szybko pierwszego przycisku bez problemu resetuje program. Pytanie czy da się coś w programie jeszcze zmienić? 

#include <LiquidCrystal.h>//biblioteka odpowiedzialna za lcd
#define przyciskStart 8
#define przyciskKoniec 9
LiquidCrystal lcd(2,3,4,5,6,7);//podlaczenie lcd
boolean Start=false;
boolean Koniec=false;
int time=0;
void setup() {
  // put your setup code here, to run once:
  pinMode(przyciskStart,INPUT_PULLUP);
  pinMode(przyciskKoniec,INPUT_PULLUP);
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Stoper:");
}
void loop() {
  // put your main code here, to run repeatedly:
 if(digitalRead(przyciskStart)==LOW && Start==false){  
    Start=true; 
 }
 if(digitalRead(przyciskStart)==HIGH && Start==true){
  time++;
    delay(1000);
    lcd.clear();
    lcd.begin(16,2);
    lcd.setCursor(0,0);
    lcd.write("Stoper:");
    lcd.setCursor(8,0);
    lcd.print(time);
    lcd.print("sec.");
 }
 if(digitalRead(przyciskKoniec)==LOW && Start==true && Koniec==false){
Koniec=true;
 }
 if(digitalRead(przyciskKoniec)==HIGH && Start==true && Koniec==true){
  lcd.clear();
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("Koniec:");
  lcd.print(time);
  lcd.print("sec.");
  time=0;
  Start=false;
  Koniec=false;
 }
 delay(100);
}

 

Może zadziała...

 if(digitalRead(przyciskKoniec)==HIGH && Start==true && Koniec==true){
  Start=false;
  Koniec=false;
  lcd.clear();
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("Koniec:");
  lcd.print(time);
  lcd.print("sec.");
  time=0;
  
 }

 

@lukasz957 w swoim kodzie masz opóźnienie delay, która trwa aż jedną sekundę - to zatrzymuje działanie programu na ten czas, więc wciśnięcie przycisku nie jest rejestrowane. Jest wiele metod rozwiązania tego problemu, ale najprościej zacząć zwyczajnie od skrócenia tego czasu. Pomyśl co można zrobić w programie, aby stoper działał oprawnie, przy opóźnieniu, które będzie np. 100 razy mniejsze.

@lukasz957 jeśli korzystasz ze zmiennych, które mogą przyjmować wartości całkowite to nie możesz do nich dodawać liczb typu 0.01. Idziesz w dobrą stronę, ale musisz albo zmienić typ zmiennych, albo (lepiej) zmienić wartości, na których działasz.

  • 4 tygodnie później...
  • 4 tygodnie później...

Bardzo ciekawa lekcja. Po jej wykonaniu sprawdziłem jeszcze bibliotekę liquidCrystal.h, żeby się dowiedzieć co można jeszcze zrobić.

A więc do zadań:

Zadanie 7.1

Zdjęcie mojego wyświetlacza. Jeszcze bawiłem się funkcją createChar(), by przyozdobić wyświetlacz:

20230321_165340.thumb.jpg.40af17adb6e0c130f2a8875d1917a8f1.jpg

Zadanie 7.2

Zauważyłem, że piksele wygaszają się dość wolno to utrudnia czytelność.

Zadanie 7.3

W sumie to nic nie zauważyłem. Zniknął mi tekst przy dodaniu funkcji .clear, ale to wynika z tego że tekst był drukowany w setupie...

Zadanie 7.4

Mój kod działającego programu. Posiada też możliwość resetowania licznika, ale przyciski trzeba trzymać wciśnięte przez sekundę za względu na delay():

#include <LiquidCrystal.h> //biblioteka do wyswietlaczy
LiquidCrystal elcd(2, 3, 4, 5, 6, 7); //nowy obiekt wyswietlacza i obsługiwane piny

#define swstart 12
#define swstop 13

void setup() {
  elcd.begin(16,2); //deklaracja typu wyswietlacza

  elcd.clear(); //wyczysc ekran
  elcd.setCursor(0,0); //ustawienie kursora
  elcd.print("Press the button"); //wyswietl tekst
  elcd.setCursor(0,1); //ustawienie kursora
  elcd.print("Time: 0 [sec]"); //wyswietl tekst

  pinMode(swstart, INPUT_PULLUP); // przycisk START
  pinMode(swstop, INPUT_PULLUP); // przycisk STOP
}
int timerRead = 0;

bool timerStart = false;
bool timerStop = true;

void loop() {

  if(digitalRead(swstart) == LOW)
  { 
    timerStart = true;  //zmiana flag
    timerStop = false;
    elcd.setCursor(0,0);
    elcd.print("START           "); //spacje, aby wyczyscic poprzedni tekst
  }

  while(timerStart == true) 
  {
    delay(1000); //opoznienie 1 sekunda
    timerRead++; //inkrementacja zmiennej
    elcd.setCursor(6, 1);  //Ustawienie kursora w odpowiednim miejscu
    elcd.print(timerRead); //wypisanie aktualnej wartosci
    elcd.print(" [sec]");  //jednostka po wartosci

    if(digitalRead(swstop) == LOW) //warunek do wyjscia z petli while
    {
      timerStart = false;  //zmiana flag
      timerStop = true;
      elcd.setCursor(0,0);
      elcd.print("STOP "); //spacje, aby wyczyscic poprzedni tekst
    }  
  }
  delay(1000); // opoznienie by zapobiec przypadkowemu resetowi
  if  (digitalRead(swstop) == LOW && timerStop == true) //gdy sie wcisnie stop i jest zatrzymane...
  {
    timerRead = 0; //resetowanie licznika
    elcd.setCursor(6, 1);  //Ustawienie kursora w odpowiednim miejscu
    elcd.print("          "); //wyczyszczenie czesci ekranu
    elcd.setCursor(6, 1);
    elcd.print(timerRead);  //wypisanie wartosci
    elcd.print(" [sec]");
  }
}

Prócz tego bawiłem się scrollowaniem tekstu w obie strony. Zastanawia mnie jak długi ciąg znaków można przedstawić na wyświetlaczu z jego pomocą. Jest jakiś limit pamięci? Efekt mojej zabawy(scrolling w lewo, w prawo i miganie):

action.thumb.gif.370a5763eca0cc98de1f4bb947266de2.gif

  • Lubię! 1

@Maciek_S dobra robota 😉 Ciekawe testy!

17 godzin temu, Maciek_S napisał:

Zastanawia mnie jak długi ciąg znaków można przedstawić na wyświetlaczu z jego pomocą. Jest jakiś limit pamięci?

Limit oczywiście jest 😉 A jaki? Albo poszukaj w ramach zadania domowego, albo w ramach testu możesz zobaczyć co dzieje się, gdy zwiększasz ten tekst. Zobacz co pojawia się w logach Arduino podczas kompilacji/wgrywania. Obserwuj parametr informujący o tym ile procent pamięci zajmuje Twój program.

  • 4 tygodnie później...

Witam wszystkich po krótkiej przerwie o to moja dzisiejsza zabawa, lecimy dalej

7.1

image.thumb.png.c03c16960d4146cd369dcac3693531c4.png

7.4

#include <LiquidCrystal.h> //Dołączenie biblioteki
LiquidCrystal lcd(2,3,4,5,6,7); //Informacja o podłączeniu nowego wyświetlacza
#define button 8 //Definicja pinów
#define button2 9
float czas = 0.00; //Deklaracja zmiennych
bool status = false;
void setup() {
  pinMode(button, INPUT_PULLUP); //Uruchomienie pinów do pracy pod przycisk
  pinMode(button2, INPUT_PULLUP);
  lcd.begin(16,2); //Deklaracja typu
  lcd.clear();
  lcd.setCursor(0,0); //Ustawienie kursora
  lcd.print("Wciśnij przycisk");
}

void loop() {
  if(digitalRead(button)== LOW){ //Jeżeli przycisk wciśnięto zmień status do pracy
    status = true;
  } 
  if(status == true){ //Jeśli przycisk wciśnięto rozpocznij odliczanie
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Start");
    lcd.setCursor(0,1);
    lcd.print(czas);
    czas = czas + 0.01;
    delay(10);

  }
  if(digitalRead(button2) == LOW){ //Jeżeli wciśnięto 2 przycisk pokaż wynik
    status = false;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("KONIEC");
    lcd.setCursor(0,1);
    lcd.print(czas);
    delay(500); //Opóźnienie pomiędzy wyświetleniem wyniku, a ponownym odliczaniem
    czas = 0; //Zresetowanie zmiennej do ponownego liczenia
  }
}

Aktualnie stoper pracuje jak prawdziwy stoper licząc sekundy i mili sekundy, jednakże teraz doczytałem, że ma być w sekundach więc wystarczy zmienić typ zmiennej czas na int oraz linijkę:
 

    czas = czas + 0.01;
    delay(10);

Na:
 

    czas = czas + 1;
    delay(1000);

 

  • Lubię! 1
  • 4 miesiące później...

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