Skocz do zawartości

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


Komentator

Pomocna odpowiedź

Cześć,

poniżej mój program stopera:
 

#include <LiquidCrystal.h>

#define startBtn 11
#define stopBtn 10

const unsigned long secondInMillis = 1000;
const unsigned long minuteInMillis = 60 * secondInMillis;
const unsigned long hourInMillis = 60 * minuteInMillis;

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
unsigned long timer = 0; // czas ktory uplynal w milisekundach
int dt = 97; // krok czasowy stopera - licba pierwsza, zeby ladnie dziesiate i setne czesci sekundy sie zmienialy
bool isRunning = false;

void setup() {
  pinMode(startBtn, INPUT_PULLUP);
  pinMode(stopBtn, INPUT_PULLUP);

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
}

void loop() {
  if (isRunning) {
    handleStopButton();
    timer += dt;
    updateDisplay();
  }
  else {
    handleStartButton();
  }
  delay(dt);
}

void handleStartButton() {
  if (digitalRead(startBtn) == LOW) {
    timer = 0;
    isRunning = true;
    lcd.clear();
  }
}

void handleStopButton() {
  if (digitalRead(stopBtn) == LOW) {
    isRunning = false;
    lcd.setCursor(0, 1);
    lcd.print("Koniec");
  }
}

void updateDisplay() {
  int hours = timer / hourInMillis;
  int minutes = (timer % hourInMillis) / minuteInMillis;
  int seconds = (timer % minuteInMillis) / secondInMillis;
  int hundredths = (timer % secondInMillis) / 10;
  
  String toPrint = formatTime(hours, minutes, seconds, hundredths);
  lcd.setCursor(16 - toPrint.length(), 0);
  lcd.print(toPrint);
}

//format czasu HH:MM:ss.SS
String formatTime(int hours, int minutes, int seconds, int hundredths) {
  String leadingZeroHours = hours < 10 ? "0" : "";
  String hoursStr = hours == 0 ? "" : leadingZeroHours + String(hours) + ":" ;
  String leadingZeroMinutes = minutes < 10 ? "0" : "";
  String minutesStr = minutes == 0 ? "" : leadingZeroMinutes + String(minutes) + ":" ;
  String leadingZeroSeconds = seconds < 10 ? "0" : "";
  String secondsStr =  leadingZeroSeconds + String(seconds) + ".";
  String leadingZeroHundredths = hundredths < 10 ? "0" : "";
  String hundredthsStr =  leadingZeroHundredths + String(hundredths);
  return  hoursStr + minutesStr + secondsStr + hundredthsStr;
}

Co mnie zaskoczyło?

  • 16-bitowe int-y na arduino - przy mierzeniu czasu w milisekundach (przyzwyczajenia z Javy) po ok. 32 sekundach następowało przepełnienie licznika 
  • dziwne wyniki przy liczeniu reszty z dzielenia unsigned long przez int - stąd stałe xxxInMillis też są typu unsigned long

Skomplikowana metoda formatowania czasu ma za zadanie wyświetlanie jak najmniejszej (no prawie ) ilości informacji na ekranie, tzn:

  • dla czasów poniżej sekundy wyświetla 00.SS
  • dla czasów poniżej minuty nadal ss.SS - z potencjalnym '0' poprzedzającym liczbę sekund
  • dla czasów poniżej godziny mm:ss.SS - z potencjalnym '0' poprzedzającym liczbę sekund i minut
  • dla czasów powyżej godziny hh:mm:ss.SS - z potencjalnym '0' poprzedzającym liczbę sekund i minut i godzin

gdzie SS  -setne sekundy, ss- sekundy, mm - minuty a hh - godziny.

I jako dodatkowy smaczek - przyjęcie dt = 97 powoduje, że na ostatnim miejscu tzn. setnych częściach sekundy będą się pojawiać wszystkie cyfry - będzie wyglądać jakby stoper działał z większa dokładnością 😉

 

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

zadanie 7.1: zdjęcie:

IMG20210228182519.thumb.jpg.788a6f8bc45ba06ba8b8d92588390f22.jpg

Pytanie: a czy jest jakiś sposób na wyświetlanie polskich znaków poprawnie?

zadanie 7.2: faktycznie tak mruga, że niezbyt widać napis

zadanie 7.3: gdy odświeżana jest tylko wartość to da się  odczytać nawet bez delay. Ale cały tekst - to już widać tylko początek napisu, dalej zanika. Ciekawy efekt.

zadanie 7.4: Stoper. Kod:

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

void setup() {
  pinMode(przycisk, INPUT_PULLUP);

  lcd.begin(16, 2); //Deklaracja typu
  lcd.clear();
  lcd.setCursor(0, 0); //Ustawienie kursora
  lcd.print("Nacisnij przy-");
  lcd.setCursor(0, 1);
  lcd.print("cisk,aby zaczac");
}

double odczyt;
boolean przyciskStan = HIGH; // czyli nie jest wciśnięty
boolean przyciskPoprzedniStan = HIGH; // czyli poprzednio też nie wciśnięty
unsigned long czasStart = 0;
boolean pomiar = false;

void loop()
{
  przyciskStan = digitalRead(przycisk);
  if (przyciskStan == LOW && przyciskPoprzedniStan == HIGH) { //przycisk wciśnięty i w poprzednim odczycie nie był wciśniety
    if (pomiar == false) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Czas start!");
      czasStart = millis();
      pomiar = true;
    } else {
      //czyli czas leci, czyli stop
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Zmierzony czas");
      lcd.setCursor(0, 1);
      lcd.print(String(((millis() - czasStart) / 1000.0)) + " s");
      pomiar = false;
    }
  }
  przyciskPoprzedniStan = przyciskStan;
  if (pomiar == true) { //czyli jest mierzony
    lcd.setCursor(0, 1);
    lcd.print(String(((millis() - czasStart) / 1000.0)) + " s");
  }
}

Uwaga: albo coś przegapiłem, albo nic o tym jak zmierzyć czas nie było. Dla początkujących przydałoby się dodać wskazówkę, nawet: "wyszukaj w internecie Arduino time", albo "Spójrz do dokumentracji Arduino: https://www.arduino.cc/reference/pl/#time

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

@pawelmb

10 godzin temu, pawelmb napisał:

zadanie 7.4: Stoper. Kod:

Fajnie, że użyłeś dodatkowej zmiennej i zatrzasku, super!

10 godzin temu, pawelmb napisał:

Pytanie: a czy jest jakiś sposób na wyświetlanie polskich znaków poprawnie?

Jest taka możliwość, możesz przedefiniować znaki które Ci się nie podobają albo dodać własne, tu masz coś na ten temat.

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

Witam

Mam mały problem z tym LCD, jest sprawny i działa. 

Mianowicie jest tak, że jak LCD jest podłączony do UNO i właczam  Serial Monitor w celu przesłania danych do komputera to na wyświetlaczu pojawiają się krzaki. Problem krzakow dzieje się o d I kursu Arduino. (Jest to bardzo wybiórcze, raz sie pojawia a raz nie.. jak im sie zachce). Przy przeładowaniu software w UNO też się podobnie dzieje.

Poniżej kod programu, bez żadnych udziwnień. Mierze sobie temperaturę i wilogotność.

#include <LiquidCrystal.h> //ddodanie biblioteki
#include <DHT.h>           //dodanie bibliteki
DHT dht;
#define DHT11_PIN 9

LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Informacja o podlaczeniu wyswietlacza

float wilgotnosc = 0;
float temperatura = 0;
float maxTemp = 0;
float minTemp = 100;
float maxWilg = 0;
float minWilg = 100;

void setup()
{
    Serial.begin(9600);
    dht.setup(DHT11_PIN);
    lcd.begin(16, 2); //Deklaracja typu
    delay(20);

    lcd.setCursor(0, 0); //ustawienie kursora
    lcd.print("Witaj w pomiarze");
    lcd.setCursor(0, 1);
    lcd.print("temp i wilgot");
}

void loop()
{
    delay(100);
    delay(dht.getMinimumSamplingPeriod());
    temperatura = dht.getTemperature();
    wilgotnosc = dht.getHumidity();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Temp.:");
    lcd.setCursor(7, 0);
    lcd.print(temperatura);
    lcd.setCursor(13, 0);
    lcd.print("*C");

    lcd.setCursor(0, 1);
    lcd.print("Wilg.:");
    lcd.setCursor(7, 1);
    lcd.print(wilgotnosc);
    lcd.setCursor(13, 1);
    lcd.print("%RH");

    if ((temperatura > maxTemp) | (wilgotnosc > maxWilg))
    {
        maxTemp = temperatura;
        maxWilg = wilgotnosc;
    }

    if ((temperatura < minTemp) | (wilgotnosc < minWilg))
    {
        minTemp = temperatura;
        minWilg = wilgotnosc;
    }

    Serial.print(maxTemp);
    Serial.print(" *C  ");
    Serial.print(minTemp);
    Serial.print(" *C  ");
    Serial.print(maxWilg);
    Serial.print(" %RH  ");
    Serial.print(minWilg);
    Serial.print(" %RH ");
    Serial.println("  ");
}

Dzisiaj okazało się, że po odłączeniu kabla USB od Andruino ani razu na LCD nie pojawiły sie krzaki, i tak się zastanawiam, czym to może być spowodowane?

Włączanie i wyłączanie zasilania nic - wszystko działa jak należy. Tak samo RESET UNO i jest też w porządku.

LCD podpięty sandardowo, na pinach od 2 do 7. Do tego DHT 11. Na szynie zasilania dołozyłem 2 elektrolity z zestawu i 2 kondensatory perełki 10n.

Dodam jeszcze zdjęcie mojego układu, akurat z krzaczkami, linijka sterowalna WS, LED i przyciski nie podpięte i nie uzyte w programie.

 

Z góry dziękuję z podpowiedzi.

Benij_Tomek

20210305_125259.jpg

Link do komentarza
Share on other sites

@Benji_Tomek takie krzaki mogą być efektem tego, że są jakieś problemy z przewodami - czasami coś przez chwilę nie styka i pojawiają się wtedy takie "krzaki". Może to też być związane z zasilaniem. Jeśli natrafisz na taki problem to najlepiej postaraj się poruszać trochę przewodami i zresetuj Arduino. Jeśli problem ustąpi to znak, że winne były połączenia.

Link do komentarza
Share on other sites

Hej

@Treker dzieki za podpowiedź. Do programowania Arduino używam Arduino IDE lub Visual Studio Code(to narzędzie jest bardziej wygodne), bez znaczenia.

Testy z przed chwili:

1. Uno i wyświetlacz LCD na zasilaniu zwenętrznym bez podłączenia USB do komputera, wszystko śmiga jak złoto. Dosłownie, przed chwilą siadłem do kompa, coś tam porbie z UNO. Podłaczam Uno do komputera, nic się nie dzieje. (Używam VSC) i właczam Serial Monitor, na LCD krzaczki.

 

2. Zmieniniam na środowisko Andruino IDE, odpalam Serial Monitor, i od razu wywalają się krzaki.

 

3. Samo uruchomienie komunikacji komputer - Andruino Uno powoduje wyświtlanie krzaków. Dziwna sprawa.

Myśle, że to nie problem w przewodach, bo nawet ich nie ruszałem a krzaki sie pjawiają.., Hm ciekawy temat.

Link do komentarza
Share on other sites

Cześć, czy jesteście w stanie ocenić po tych zdjęciach czy te luty mają szansę zadziałać? 
Żeby rozpocząć podłączanie układu musiałem najpierw pierwszy raz w życiu posłużyć się lutownicą 😄 

IMG_0304.jpg

IMG_0305.jpg

Link do komentarza
Share on other sites

 

Hejka może ktoś pomoże. Lekcja 7 wyświetlacz. Kompilacja programu przebiegła OK, lecz próba wgrania wygenerowała błąd:

Podczas ładowania szkicu wystąpił błąd
avrdude: ser_open(): can't set com-state for "\\.\COM3"

jestem początkującym i nie wiem co jest nie tak? 
 

Edytowano przez Gieneq
Zachęcam do korzystania z bloku kodu programu
Link do komentarza
Share on other sites

@bartekv253 to nie ma związku z tym programem, coś bloku port którym wgrywasz kod. Spróbuj odpiąć i piąć Arduino i próbować wgrać kod klikając przycisk reset. Do tego oczywiście uruchom ponownie komputer 🙂

Link do komentarza
Share on other sites

Upewnij się że masz wybrany prawidłowy port COM przed wgraniem programu lub czy arduino jest dobrze podpięte do USB. 

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.