Skocz do zawartości

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


Komentator

Pomocna odpowiedź

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define START 12
#define STOP 4

LiquidCrystal_I2C lcd(0x20, 16, 2);

void setup() {
pinMode(START, INPUT_PULLUP);
pinMode(STOP, INPUT_PULLUP);

lcd.begin();
lcd.clear();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Stoper");
lcd.setCursor(0,1);
}

void loop() {
  int stan1 = digitalRead(START);
  int stan2 = digitalRead(STOP);
  int godzina = 0;
  int minuta = 0;
  int sekunda = 0;
  
if(digitalRead(START) == LOW) {
  lcd.setCursor(0,0); 
  lcd.print("START:");
  lcd.setCursor(0,1);

  for(int i = 0; i >= 0; i++) {  
    delay(10);
    sekunda = sekunda + 1;
    lcd.print(godzina);
    lcd.print("gdz ");
    lcd.print(minuta);
    lcd.print("min ");
    
    
     if (sekunda >= 28){
    lcd.print(sekunda / 28);
    }
     else {
      lcd.print("0");
      } 
    lcd.print("sec ");
    if (sekunda / 28 > 60) {
      sekunda = 0;
      minuta = minuta + 1;
    }
    if (minuta > 60) {
      minuta = 0;
      godzina = godzina + 1;
    }
      
    lcd.setCursor(0,1);
    
    if(digitalRead(STOP) == LOW) {
      i = -2;
      lcd.setCursor(0,0);
      lcd.print("STOP: ");
      lcd.setCursor(0,1);
    }
  }
}
if(digitalRead(STOP) == LOW) {
  
  }
  delay(200);
}

zad 7.4 tylko miałem problem że nie mogę ustawić stopera dokładnie, mija się trochę i przy pomiarze np. 10 minut rozjeżdża się o około 10 sekund nie wiem jak to naprawić aby dokładniej mierzył będę wdzięczny za wskazówkę jak to zrobić.

image.thumb.png.8563e1f08b8b1396bbd939f7e5d78b11.png

Link do komentarza
Share on other sites

Nic nie poradzisz na niedokładność czasu...sam kwarc ma pewnie dosyć duże wachania więc liczenie delay'em wprowadza błąd, dodatkowo wykonywanie kodu też zajmuję jakiś czas który nie jest uwzględniany podczas obliczeń więc duży błąd nie jest zaskoczeniem... jeśli zależy Ci na dokładnym odmierzaniu czasu to poczytaj o RTC...

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

@solowkidamian, widzę tu trochę "dziwnych" obliczeń, jak to dzielenie sekund przez 28. Czyżby to były próby wprowadzania poprawek do oszacowanego błędu? Nie znam się na tyle na I2C, by mieć pewność, ale mam pewne podejrzenia, że czas spędzony w odwołaniach do ekranu może być różny, również przez to, że zmienia się liczba znaków. Przejrzałem strony kursu i widzę, że do tego momentu nie była wspomniana funkcja millis(). Ta powinna pomóc Ci uzyskać większą dokładność, bez specjalnych poprawek. Tj. zamiast samemu zliczać jakieś ułamki sekund, spróbuj odczytywać każdorazowo wartość millis().

PS Mam inne zdanie niż @farmaceuta, co do RTC. Jego funkcją nie jest raczej dokładne mierzenie czasu, a pamiętanie i odmierzanie ludzkiej koncepcji bieżącej daty i godziny również, gdy komputer nie pracuje. A dokładność bywa umiarkowana. Nic niezbędnego dla stopera.

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

9 minut temu, trainee napisał:

@solowkidamian

PS Mam inne zdanie niż @farmaceuta, co do RTC. Jego funkcją nie jest raczej dokładne mierzenie czasu, a pamiętanie i odmierzanie ludzkiej koncepcji bieżącej daty i godziny również, gdy komputer nie pracuje. A dokładność bywa umiarkowana. Nic niezbędnego dla stopera.

No i ja się z tym zgadzam😉 to że RTC to jeszcze nie znaczy że będzie super dokładny ten czas bo i tu występują rozbieżności...z punktu widzenia kompa to bez znaczenia jakiej jednostki czasu użyjemy, choć często chodzi nam właśnie o ten "normalny" czas który postrzegamy jako ludzie i chcemy coś tam co jedną  np. sekundę...ii zgadzam się z tym że millis() tu w zupełności wystarczy😉 (jak i do 99,9% innych rzeczy)

  • Pomogłeś! 1
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

A co do innych kwestii, masz w kodzie:

2 godziny temu, solowkidamian napisał:

  for(int i = 0; i >= 0; i++) {  

    ...    
    
    if(digitalRead(STOP) == LOW) {
      i = -2;
      lcd.setCursor(0,0);
      lcd.print("STOP: ");
      lcd.setCursor(0,1);
    }
  }

 

Wygląda to na próbę stworzenia nieskończonej pętli, z której wydostajesz się po naciśnięciu przycisku. Ta pętla ma pewne problemy. Będzie się wykonywała tak długo, jak długo i będzie większe lub równe 0. Formalnie je tylko zwiększasz, więc w teorii zawsze, ale niestety nie w praktyce. Maksymalna wartość int na Arduino to 32767 i gdy ją zwiększy się o 1, to się "obróci" i osiągnie wartość minimalną, czyli -32768. Przy Twoich wyliczeniach, tak jak je czytam, że ta pętla wykonuje się mniej więcej 28 razy na sekundę, pętla skończy się po 32767 / 28 / 60 = 19 minutach.

Jedno, czego Ci na pewno zabrakło, patrząc na to i = -2, to wiedza o istnieniu słowa kluczowego break. Drugie, którego zastosowanie może trudniej na pierwszy rzut oka zrozumieć z dokumentacji for w Arduino, to to, że każde z tych wyrażeń w for można pominąć i ma to w różnych przypadkach sens. Np. jeżeli się pominie środkowe, warunek, to pętla nigdy sama się nie skończy. Prowadzi to do popularnego w C idiomu:

for (;;) {
  /* to jest pętla nieskończona */
}

I z takiej uciec możesz właśnie wspomnianym break.

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

@trainee dzięki wielkie, nie wiedziałem że zmienna int ma swoje granice warto wiedzieć, zapamiętam też sobie tom nieskończoną pętle. Robiłem gdzieś rok temu kurs C++ z YT i tez było na pewno o tej pętli, niestety skleroza. co do tego dzielenia przez 28  to tak właśnie z tego co sprawdzałem w tedy najdokładniej stoper podawał sekundy. Sprawdzę też tą funkcje millis()

 

Edytowano przez solowkidamian
Link do komentarza
Share on other sites

2 godziny temu, solowkidamian napisał:

@trainee 

Sprawdzę też tą funkcje millis()

 

A to akurat proste... 

// zła wersja! nie używać! dalej kumuluje błąd! 
unsigned long czas = 0;
unsigned long last = 0;

loop() { 
  czas = millis(); 
  

if (czas - last >= 1000UL) { 
  sekunda++; 
  last = czas;
  } 
  
}

Wrzucasz to u siebie zamiast tych wynalazków na delay() i śmiga...

Edytowano przez farmaceuta
  • Nie zgadzam się! 1
Link do komentarza
Share on other sites

5 minut temu, ethanak napisał:

Chyba jednak nie...


czas = millis();
sekunda = czas / 1000UL;

 

A to już zależy kto jak liczy bo oba przykłady robią to samo tylko w inny sposób...😉 W moim przykładzie trzeba sobie albo liczyć tak jak napisałeś, albo gdy sekunda = 60 to zmienną resetować i liczyć od nowa a zwiększyć minuty o jeden...

No fakt... twój przykład mniej zamotany 😜

  • Nie zgadzam się! 1
Link do komentarza
Share on other sites

@farmaceuta, Twoja propozycja jest karkołomna.

10 godzin temu, trainee napisał:

Tj. zamiast samemu zliczać jakieś ułamki sekund, spróbuj odczytywać każdorazowo wartość millis().

Miałem tu dokładnie na myśli to, co napisał @ethanak. Oczywiście dla stopera trzeba jeszcze zapamiętać moment naciśnięcia "Start".

Poprawka. Nie karkołomna. Jest po prostu niepoprawna. Bo bierzesz jedynie, że większe niż 1000 ms (co jeżeli coś tam dłużej się zablokuje między wierszami, przecież tu ma być obsługa guzików i wyświetlacza) i liczysz to jako sekunda, a mogło być to 1,1 s np.

PS O wiele bardziej pomocne byłoby dać @solowkidamian jakąkolwiek szansę na pomyślenie nad użyciem samemu.

Edytowano przez trainee
Link do komentarza
Share on other sites

Mam wyświetlacz LCD 2x16 z zestawu z arduino uno kursu 1, ale chciałbym zaoszczędzić pinów czy jak dokupię

Konwerter I2C dla wyświetlacza LCD HD44780 na przykład taki:

https://botland.com.pl/konwertery-pozostale/2352-konwerter-i2c-dla-wyswietlacza-lcd-hd44780-5903351248693.html

połączę przewodami z żeńskimi końcówkami,

oraz zastosuje ten poradnik https://botland.com.pl/content/81-lcd-2x16-przy-pomocy-arduino-i-lcm1602-po-i2c-

to będzie to działać, dobry ten konwerter do tego wyświetlacza?

 

Link do komentarza
Share on other sites

Dwa zadanka.

Zad. 7.1
1663951963733.thumb.jpg.dd27cb918f08dd7d079e6cd28584f18f.jpg

 

Zad. 7.4
 

#include <LiquidCrystal.h> //Dołączenie bilbioteki
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Informacja o podłączeniu nowego wyświetlacza
// polskie znaki na wyswietlacz - start
byte ll[8] = {
  0b01100,
  0b00100,
  0b00110,
  0b01100,
  0b00100,
  0b00100,
  0b01110,
  0b00000
};
byte ee[8] =  {
  0b00000,
  0b00000,
  0b01110,
  0b10001,
  0b11110,
  0b10000,
  0b01110,
  0b00011
};
//Polskie znaki na wyswietlacz - koniec
#define StartGuzik 8
#define StopGuzik 9
float sekundy = 0;
 
void setup() {
  pinMode(StartGuzik, INPUT_PULLUP);
  pinMode(StopGuzik, INPUT_PULLUP);
  lcd.createChar(1, ll);
  lcd.createChar(2, ee);
  lcd.begin(16, 2); //Deklaracja typu
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Sekundnik: Czekam");
  lcd.setCursor(0, 1);
  lcd.print("Min" + String(char(2)) + String(char(1)) + "o:" + String(sekundy) + " Sek");
  delay(100);
}
 
void loop() {
  while (digitalRead(StartGuzik) == LOW) { //Wcisniecie przycisku
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Sekundnik: Start");

    while (digitalRead(StopGuzik) == HIGH) { //Petla wykonoywana do momentu wicsniecia przycisku stop
     lcd.setCursor(0, 1);
     lcd.print("Min" + String(char(2)) + String(char(1)) + "o:" + String(sekundy) + " Sek");
     sekundy = sekundy + 0.2; //Przyrost sekund
     delay(200); //Opoznienie dla przyrostu sekund
    }
    //Po wcisnieciu przycisku stop:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Sekundnik: Stop");
    lcd.setCursor(0, 1);
    lcd.print("Min" + String(char(2)) + String(char(1)) + "o:" + String(sekundy) + " Sek");
    delay(50);
    
  while (digitalRead(StartGuzik) == LOW && digitalRead(StopGuzik) == LOW) { //Jednoczesne wcisniecie przyciskow stop i start
  sekundy = 0; //Wyzerowanie zmiennej
  lcd.clear();
  lcd.setCursor(0, 0); //Ustawienie kursora
  lcd.print("Sekudnik: Czekam");
  lcd.setCursor(0,1);
  lcd.print("Min" + String(char(2)) + String(char(1)) + "o:" + String(sekundy) + " Sek");
  delay(50);
  }
 }
}

 

Edytowano przez Danyeru
  • Lubię! 1
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.