• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Początki z wyświetlaczem TFT
#1
Dzień dobry bardzo wszystkim.

Od kilku dni próbuję zrozumieć jak rozmawiać z wyświetlaczem TFT. 
Egzemplarz jaki posiadam to GMT020-02 VER 1.1 2.0" podłączony pod Arduino Duo.
Jako, że nie lubię pisać bezsensownego kodu założyłem sobie za projekt stworzyć stoper.

Kod jaki napisałem prezentuje się następująco:
Kod:
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>

#define TFT_CS   10
#define TFT_RST  9
#define TFT_DC   8

byte stan = 0;

byte minuty  = 30;
byte sekundy = 00;

unsigned long czasSekundy = 0;

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

void setup(void) {
  pinMode(7 ,INPUT_PULLUP);
  pinMode(4 ,INPUT_PULLUP);
  pinMode(2 ,INPUT_PULLUP);
 
  tft.init(240, 320);
  tft.setRotation(1);
  tft.fillScreen(ST77XX_INVOFF);
}

void loop() {
  ekranPoczatkowy();
  menuPoczatkowe();
  przyciskCentralny();
  odliczanie();
}

void ekranPoczatkowy() {
  if(stan == 0){
    tft.setTextSize(5);
    tft.setTextColor(ST77XX_RED);
    tft.setCursor(45, 30);
    tft.println("Ruszamy?");
  }
}

void menuPoczatkowe() {
  if(stan == 0){
    tft.setTextSize(2);
    tft.setCursor(5, 218);
    tft.setTextColor(ST77XX_WHITE);
    tft.println("<STAT");
    tft.setTextSize(5);
    tft.setCursor(130, 200);
    tft.setTextColor(ST77XX_RED);
    tft.println("GO!");
    tft.setTextSize(2);
    tft.setCursor(265, 218);
    tft.setTextColor(ST77XX_WHITE);
    tft.println("SET>");
  }
}

void przyciskCentralny() {
  if(digitalRead(4) == LOW) {
    if(stan == 2) {
      stan = 0;
    }

    if(stan == 1) {
      tft.fillScreen(ST77XX_INVOFF);
      tft.setTextSize(5);
      tft.setTextColor(ST77XX_RED);
      tft.setCursor(60, 30);
      tft.println("Przerwa");
      tft.setTextSize(5);
      tft.setCursor(90, 200);
      tft.setTextColor(ST77XX_RED);
      tft.println("Wznow");
      tft.setTextSize(2);
      tft.setCursor(265, 218);
      tft.setTextColor(ST77XX_WHITE);
      tft.println("END>");
      stan = 2;
    }

    if(stan == 0) {
      tft.fillScreen(ST77XX_INVOFF);
      tft.fillRoundRect(5, 5, 310, 90, 0, ST77XX_BLACK);
      tft.fillRoundRect(10, 10, 120, 80, 4, ST77XX_INVOFF);
      tft.fillRoundRect(190, 10, 120, 80, 4, ST77XX_INVOFF);
      tft.setTextSize(5);
      tft.setCursor(102, 200);
      tft.setTextColor(ST77XX_RED);
      tft.println("STOP");
      stan = 1;
    }
  }
}

void odliczanie() {
  if(stan == 1) {
    tft.setTextSize(10);
   
    tft.setTextColor(ST77XX_WHITE);
    tft.setCursor(15, 15);
    if(minuty < 10) { tft.print(F("0")); }
    tft.print(minuty);

    tft.setCursor(135, 15);
    tft.setTextColor(ST77XX_WHITE);
    tft.println(":");

    tft.setTextColor(ST77XX_WHITE);
    tft.setCursor(195, 15);
    if(sekundy < 10) { tft.print(F("0")); }
    tft.println(sekundy);
   
    if(minuty > 0) {
      if(sekundy <= 0) {
        sekundy = 59;
        minuty--;
        tft.fillRoundRect(10, 10, 120, 80, 4, ST77XX_INVOFF);
        tft.fillRoundRect(190, 10, 120, 80, 4, ST77XX_INVOFF);
      } else {
        if(czasSekundy == 0){
          czasSekundy = millis();
        } else {
          if(millis() >= (czasSekundy + 1000)){
            czasSekundy = 0;
            sekundy--;
            tft.fillRoundRect(190, 10, 120, 80, 4, ST77XX_INVOFF);       
          }
        }
      } 
    } else {
      if(sekundy > 0) {
        sekundy--;
        tft.fillRoundRect(190, 10, 120, 80, 4, ST77XX_INVOFF);
      } else {   
        tft.fillRoundRect(5, 5, 310, 90, 0, ST77XX_BLACK);
        stan = 0;
      }
    }
  }
}

Po wgraniu niby wszystko działa, niby stoper odmierza czas, ale co pewną randomową chwilę zaczyna rysować niewłaściwie. Na pewnym etapie chciałem dodać miganie dwukropkiem za pomocą funkcji millis() jednak wtedy pojawił się problem rysowania liczb niewłaściwym i nigdzie nie zdefiniowanym kolorem. Długo z tym walczyłem i finalnie się poddałem przez co powyższy kod pozbawiony jest tej funkcji. Jednak nachodzenie na siebie znaków to już za duża abstrakcja. Podsyłam wideo pokazujące problem (problem od 1:13):


Czy są jakieś funkcje dla wyświetlaczy, których nie użyłem i stąd problem?
Ponadto czy są jakieś funkcje dzięki którym mogę wyłączyć wyświetlacz lub samo podświetlenie, tak aby później bez problemu móc go wybudzić? Albo jakaś funkcja czyszcząca ekran zamiast zamalowywania go? Definiowanie ciągle rysowania kwadratów w tle jest w mojej ocenie słabe bo dużo pamięci na to idzie - może powinienem wykonywać to czymś innym?
 
Odpowiedź
#2
Ustal jak często musisz odświeżać ekran i rób to tak często. W każdym loop to na pewno nie ma żadnego sensu.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
(30-01-2023, 01:18)kaczakat napisał(a): Ustal jak często musisz odświeżać ekran i rób to tak często. W każdym loop to na pewno nie ma żadnego sensu.

Nie za bardzo rozumiem. Przecież odświeżanie mam zrobione tylko przed wykonaniem jakiejś zmiany na ekranie. Jeśli zmieni się sekunda to odświeżam tylko kafelek pod nią, jeśli godzina to pod godziną, jeśli cały ekran to maluje na jeden kolor. Nie za bardzo widzę by odświeżanie u mnie było częściej niż potrzebne. Zresztą jakbym miał co chwila odświeżanie to na wideo jak widać mignięcie sekund to takie mignięcie by było po całości, a nie tylko w tym miejscu. Mogę w teorii napisać funkcję która będzie weryfikować kiedy co się zmieni i wtedy podejdzie do odświeżania, jednak wydaje mi się, że zwiększę tym sposobem ilość zmiennych i samego kodu.
 
Odpowiedź
#4
Nic innego mi nie przychodzi do głowy niestety, ja mam osobną funkcję w loop, która tylko zlicza czas i dzieli sekundę na odcinki co np. 10ms, czynności w loop mogę porozdzielać tak by się wykonywały w 100 różnych chwilach. Przy okazji nie muszę wywoływać millis w każdej funkcji korzystającej z czasu, korzystam z małych flag i zmiennych typu bajt by to ogarnąć, jest OK jak nie potrzeba czasów innych niż wielokrotność 10ms. W duo nie powinno mieć to faktycznie takiego znaczenia, ale jak nie masz innego pomysłu to możesz tak zrobić.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#5
Miałeś kiedyś do czynienia z biblioteką Adafruit_ST7789? Może jest coś lepszego do obsługi TFT, a ja walczę z rozwiązaniem słabym samym w sobie?
 
Odpowiedź
#6
Jeżeli faktycznie masz Arduino Due, a nie Duo jak napisałeś to jesteś przynajmniej w niewielkiej części uratowany.
Arduino Due ma DMA i to jest temat do poszukania informacji.

W jednym ze swoich projektów użyłem ekranu TFT z ILI9341 na pokładzie. Miał być z dotykiem, ale chipa brakowało, więc tylko wyświetlał. Przesiadka z MEGI na Due dała ogromną różnicę w szybkości działania ekranu. Możesz na ten temat znaleźć na YT filmy z porównaniem prędkości działania.

Inna sprawa to zmiany w programie - czyszczenie ekranu jest w wielu przypadkach niepotrzebne. Można ekran podzielić na kwadraty i zmieniać tylko kolory kilku z nich.

Nie wiem, czy na swój ekran znajdziesz bibliotekę z DMA, ale od tego zacznij. Być może chochliki płodzi biblioteka.
 
Odpowiedź
#7
Używałem MCUFRIEND_kbv , ale dlatego że to była pierwsza znaleziona, nie wiem czy jest lepsza. Na pewno warto spróbować kilka różnych.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#8
(30-01-2023, 19:00)MadMrQ napisał(a): Jeżeli faktycznie masz Arduino Due, a nie Duo jak napisałeś to jesteś przynajmniej w niewielkiej części uratowany.
W takim razie już po mnie. Faktycznie napisałem błędnie, że mam Duo, a w rzeczywistości mam Uno ;/
 
Odpowiedź
#9
Też się dałem nabrać, wziąłem to za literówkę. W UNO może być po prostu za mało pamięci i dane do wyświetlenia mogą się nadpisywać z innymi. Choć taki prosty program powinien działać, spróbuj jednak ograniczyć wywoływanie tych funkcji, odpalałem demówki z UNO i TFT 240x320, z interfejsem SPI i równoległym, poza wolnym działaniem jakoś to działało.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#10
Nie ogarnie na uno bo to wymaga już dużej wiedzy i oszczędnośći ram.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości