Skocz do zawartości

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


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ą 😉

 

  • 2 tygodnie później...

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

@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

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

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

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.

  • 1 miesiąc później...

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

Zadziałały, dzięki. Chciałem wykluczyć ewentualność złego przylutowania przewodów gdyby coś nie wyszło, natomiast wszystko działa jak należy.

  • 1 miesiąc później...
(edytowany)

 

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

@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 🙂

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

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