___________________________________________________________________________________________________________________________________________________________________________
___________________________________________________________________________________________________________________________________________________________________________

18 września 2026

Tester rozdzielczości i offsetów wyświetlaczy z rodziny ST77xx

 


 

Wstęp

Kiedy kupujemy wyświetlacz TFT z rodziny ST77xx (ST7789, ST7735, ST7796 itp.) — zwłaszcza na portalach aukcyjnych, bez dokładnej dokumentacji — często nie wiemy, jaką ma prawdziwą rozdzielczość ani jakie są jego offsety (colstart / rowstart). Biblioteki Adafruit domyślnie zakładają konkretne wartości, a gdy się pomylimy, efekt jest natychmiastowy:

  • obraz jest przesunięty, ucięty na krawędzi,

  • widać „duchy" pikseli poza obszarem rysowania,

  • tekst jest lustrzany lub do góry nogami,

  • kolory są odwrócone (negatyw),

  • podświetlenie nie działa.

Zamiast metodą prób i błędów modyfikować docelowy projekt — można użyć dedykowanego testera. Poniżej opisuję program, który napisałem na ESP32 z myślą o szybkiej kalibracji dowolnego panelu z rodziny ST77xx.


Co potrafi tester

Program obsługuje się wyłącznie z Serial Monitora (115200 baud, Newline) — nie trzeba podłączać żadnych przycisków, enkoderów ani potencjometrów. Po wgraniu na ESP32 i podłączeniu wyświetlacza wystarczy otworzyć Serial Monitor i wydawać komendy.

Wzorzec testowy

Na ekranie rysowany jest czytelny wzorzec referencyjny:

  • Biała ramka dokładnie na krawędziach zadeklarowanego obszaru W × H — od razu widać, czy rozdzielczość jest poprawna.

  • Siatka co 20 px (ciemnoszara) — ułatwia ocenę przesunięcia.

  • Dwie przekątne (cyjan) — przecinają się w geometrycznym środku.

  • 4 kolorowe znaczniki w rogach:

    • czerwony — lewy-górny,

    • zielony — prawy-górny,

    • niebieski — lewy-dolny,

    • żółty — prawy-dolny.

    Dzięki nim od razu widać orientację i ewentualne lustro. Czerwony znacznik zawsze musi trafić w lewy-górny róg czytelnego obrazu.

  • Na środku ekranu wyświetlane są: aktualne W × H, colstart/rowstart, rotacja oraz status INV / MX / MY.

Gotowe profile

Program zawiera kilkanaście wpisanych profili najpopularniejszych paneli — m.in.:

ProfilRozdzielczośćUwagi
ST7789 240×2401.3" / 1.54"klasyk prosto z AliExpress
ST7789 240×3202.0" / 2.4"najczęstszy „2.4 cala"
ST7789 135×2401.14"mały IPS
ST7789 170×3201.9"
ST7789 172×3201.47"
ST7789 240×2801.69"
ST7789 240×2961.72"
ST7789P3 76×282pasekaktywny LOW, rotacja 1
ST7735 128×1601.8"
ST7735 128×1280.96" / 1.44"
ST7735 80×1600.96" mini
ST7796 320×4803.5"

Plus osobny profil „MANUAL / nieznany" — do kalibracji od zera.

Sterowanie z Serial Monitora

n / p    - następny / poprzedni gotowy profil
w / W    - width -1 / +1
h / H    - height -1 / +1
x / X    - colstart -1 / +1
y / Y    - rowstart -1 / +1
r        - rotacja 0 -> 1 -> 2 -> 3 -> 0
v        - przełącz negatyw / pozytyw
m        - lustro w poziomie (bit MX w MADCTL)
M        - lustro w pionie   (bit MY w MADCTL)
f        - cykl przez 4 kombinacje MX/MY (naprawa lustrzanego obrazu)
c        - wyczyść CAŁY obszar GRAM (480×480)
B        - przełącz polaryzację podświetlenia (HIGH/LOW)
i        - wymuś ponowną inicjalizację i przerysowanie
s        - zapisz konfigurację do NVS i wypisz gotowy kod
l        - lista wbudowanych profili z numerami
g<nr>    - skocz bezpośrednio do profilu o numerze <nr>, np. "g3"
a        - włącz / wyłącz auto-cykl (zmiana profilu co 8 s)
b        - mignij podświetleniem (test przewodu BL)
?        - pomoc

Po zmianie dowolnego parametru ekran jest natychmiast czyszczony i rysowany od nowa — efekt widoczny od razu, bez restartu ESP32.

Zapis i eksport gotowego kodu

Komenda s zapisuje aktualną konfigurację do NVS (pamięci nieulotnej ESP32) — po restarcie program startuje z tymi samymi ustawieniami. Co ważniejsze, na Serial wypisuje gotowy kod do wklejenia w docelowym projekcie:

cpp
class ST77xxDisplay : public Adafruit_ST7789 {
public:
  ST77xxDisplay(int8_t cs, int8_t dc, int8_t rst) : Adafruit_ST7789(cs, dc, rst) {}
  void setOffsets(int8_t col, int8_t row) { setColRowStart(col, row); }
};
ST77xxDisplay tft(TFT_CS, TFT_DC, TFT_RST);

pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);  // podświetlenie aktywne HIGH
tft.init(240, 320);
tft.setOffsets(0, 0);
tft.setRotation(0);
tft.invertDisplay(false);
{ uint8_t m = 0xC0; tft.sendCommand(0x36, &m, 1); }  // rot=0 MX=0 MY=0

Wklejasz, kompilujesz, działa.


Ostatnia poprawka do starej wersji: pełne czyszczenie GRAM

Problem

Podczas kalibracji zmienia się rozdzielczość, offsety, rotację i inwersję dziesiątki razy. Standardowa funkcja fillScreen() czyści tylko obszar bieżącego W × H — więc jeśli wcześniej testowałeś panel 320×480, a teraz przeskakujesz na 135×240, to poza nowym oknem adresowym zostają śmieci z poprzedniego profilu. Utrudnia to ocenę, czy np. colstart jest już ustawiony dobrze, bo widać „duchy" pikseli w miejscach, których nowy obraz nie zdołał zamalować.

Dodatkowo okazuje się, że Adafruit_ST7789::setAddrWindow() automatycznie dodaje offsety colstart / rowstart do podanych współrzędnych. Więc próba wyczyszczenia ekranu przez setAddrWindow(0, 0, 480, 480) przy profilu z colstart = 80 adresuje w rzeczywistości 80..559 × 80..559 — sterownik zawija licznik GRAM, część ekranu pozostaje nietknięta, a inne piksele są zapisywane wielokrotnie.

Rozwiązanie

W wersji v1.6 funkcja clearScreen() wysyła surowe komendy CASET / RASET / RAMWR bezpośrednio przez sendCommand(), z pełnym zakresem 0..479 i bez offsetów:

cpp
void clearScreen() {
  uint8_t caset[4] = { 0x00, 0x00, (uint8_t)((CLEAR_MAX_W - 1) >> 8), (uint8_t)((CLEAR_MAX_W - 1) & 0xFF) };
  uint8_t raset[4] = { 0x00, 0x00, (uint8_t)((CLEAR_MAX_H - 1) >> 8), (uint8_t)((CLEAR_MAX_H - 1) & 0xFF) };

  tft.sendCommand(ST77XX_CASET, caset, 4);
  tft.sendCommand(ST77XX_RASET, raset, 4);
  tft.sendCommand(ST77XX_RAMWR, (const uint8_t *)NULL, 0);

  tft.startWrite();
  tft.writeColor(ST77XX_BLACK, (uint32_t)CLEAR_MAX_W * CLEAR_MAX_H);
  tft.endWrite();
}

Ta funkcja jest wywoływana automatycznie w applyProfile(), przed narysowaniem wzorca. Efekt: po każdej zmianie profilu / rozdzielczości / offsetów / rotacji / inwersji / lustra ekran jest w 100% czysty — żadnych „duchów" po poprzednich próbach.


Jak używać — krok po kroku

  1. Podłącz wyświetlacz zgodnie z pinami zdefiniowanymi na górze pliku (TFT_CS=15, TFT_DC=2, TFT_RST=4, TFT_MOSI=23, TFT_SCLK=18, TFT_BL=32).

  2. Wgraj program na ESP32 (Arduino IDE, płytka ESP32 Dev Module).

  3. Otwórz Serial Monitor — 115200 baud, Newline.

  4. Wpisz l, żeby zobaczyć listę profili.

  5. Wybierz profil komendą g<nr> — np. g1 dla ST7789 240×320.

  6. Dostrajaj: w/W, h/H, x/X, y/Y — aż biała ramka pokryje się z krawędziami ekranu, a czerwony znacznik będzie w lewym-górnym rogu czytelnego obrazu.

  7. Jeśli obraz jest lustrzany — wciskaj f, aż tekst będzie czytelny.

  8. Jeśli kolory są odwrócone — wciśnij v.

  9. Jeśli podświetlenie nie działa — wciśnij B i/lub b.

  10. Wpisz s — konfiguracja trafia do NVS i na Serial wypisuje się gotowy kod do wklejenia w projekcie docelowym.

Kalibruj w rotacji 0 (pionowej) — dopiero po ustaleniu offsetów i rozdzielczości przechodź na inne rotacje.


Pod maską — ciekawe rozwiązania

  • ST77xxTester jako podklasa Adafruit_ST7789setColRowStart() bywa oznaczone jako protected w niektórych wersjach biblioteki. Utworzenie podklasy z publicznym wrapperem setOffsets(col, row) obchodzi ten problem czysto, bez modyfikowania biblioteki.

  • Ręczne wysyłanie MADCTL po setRotation()init() resetuje rejestr MADCTL, więc ustawienia lustra trzeba nakładać po każdej inicjalizacji. Program robi to w applyMADCTL().

  • Obszar czyszczenia 480×480 — pokrywa wszystkie panele z listy profili (w tym ST7796 320×480). Nadmiarowe adresy po prostu zawijają licznik GRAM, a ponieważ piszemy wszędzie czarny — efekt jest dokładnie taki, jak trzeba.

  • Rzutowanie (const uint8_t *)NULL — bez tego kompilator nie wie, które przeciążenie sendCommand wybrać (z uint8_t* czy const uint8_t*), bo NULL pasuje do obu.


Wnioski

Tester skrócił mi czas kalibracji nowego panelu z nawet godzin (metodą prób i błędów w docelowym projekcie) do kilku minut w dedykowanym narzędziu. Kluczowe okazały się:

  1. Natychmiastowa reakcja na każdą zmianę — czysty ekran i świeżo narysowany wzorzec po każdym naciśnięciu klawisza.

  2. Czytelny wzorzec — kolorowe znaczniki w rogach od razu pokazują orientację i ewentualne lustro.

  3. Eksport gotowego kodu — komenda s eliminuje przepisywanie parametrów do projektu ręcznie.

  4. Pełne czyszczenie GRAM — bez tego połowa czasu kalibracji schodzi na odróżnianie śmieci od rzeczywistych artefaktów nowego ustawienia.

Program jest dostępny na licencji otwartej — wystarczy wkleić do Arduino IDE, wgrać na ESP32 i cieszyć się szybką kalibracją kolejnych egzotycznych paneli z rodziny ST77xx. Miło by było gdybyś pamiętał o jego autorze i włożonej przez niego pracy 😊.


 

Na koniec kilka fotek z kalibrowania:

Źle dobrana rozdzielczość i rotacja.

Źle dobrana rozdzielczość. Rotacja OK.

 

 

 

 

 

 

 

 

Jeszcze zła rozdzielczość i rotacja.


Poprawna rozdzielczość, zła rotacja.

 

 

 

 

 

 

 

Poprawna rozdzielczość i rotacja.

 

 

Po włączeniu negacji widać 

przesunięcie krawędzi.


 

 

 

 

 

 

 

Teraz jest poprawnie. Tak można zapisać -> [s].


 

 

  

 

 

 

 

 

 

 Miłego kalibrowania!



✍️ Autor: Robert HF5WWL
📅 Data projektu: wrzesień 2026 r.
 📍 Lokalizacja: Wołomin, POLSKA
📁 Coś nie jasne? Pytaj poprzez e-mail (hf5wwl@gmail.com) lub w komentarzu 
🛠️ Poziom trudności: Łatwy  (jak się wie co się robi) 
😊

📜 Program jest dostępny za darmo /aktualna wersja/. Wystarczy poprosić via e-mail.

 

. 


Brak komentarzy:

Prześlij komentarz

Zastanów się, czy to co tu napiszesz było by mile widziane na Twojej stornie www lub na Twoim blogu...
Niestosowne komentarze będą cenzurowane.