
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 statusINV / MX / MY.
Gotowe profile
Program zawiera kilkanaście wpisanych profili najpopularniejszych paneli — m.in.:
| Profil | Rozdzielczość | Uwagi |
|---|---|---|
| ST7789 240×240 | 1.3" / 1.54" | klasyk prosto z AliExpress |
| ST7789 240×320 | 2.0" / 2.4" | najczęstszy „2.4 cala" |
| ST7789 135×240 | 1.14" | mały IPS |
| ST7789 170×320 | 1.9" | |
| ST7789 172×320 | 1.47" | |
| ST7789 240×280 | 1.69" | |
| ST7789 240×296 | 1.72" | |
| ST7789P3 76×282 | pasek | aktywny LOW, rotacja 1 |
| ST7735 128×160 | 1.8" | |
| ST7735 128×128 | 0.96" / 1.44" | |
| ST7735 80×160 | 0.96" mini | |
| ST7796 320×480 | 3.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)
? - pomocPo 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:
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=0Wklejasz, 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:
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
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).Wgraj program na ESP32 (Arduino IDE, płytka ESP32 Dev Module).
Otwórz Serial Monitor — 115200 baud, Newline.
Wpisz
l, żeby zobaczyć listę profili.Wybierz profil komendą
g<nr>— np.g1dla ST7789 240×320.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.Jeśli obraz jest lustrzany — wciskaj
f, aż tekst będzie czytelny.Jeśli kolory są odwrócone — wciśnij
v.Jeśli podświetlenie nie działa — wciśnij
Bi/lubb.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
ST77xxTesterjako podklasaAdafruit_ST7789—setColRowStart()bywa oznaczone jakoprotectedw niektórych wersjach biblioteki. Utworzenie podklasy z publicznym wrapperemsetOffsets(col, row)obchodzi ten problem czysto, bez modyfikowania biblioteki.Ręczne wysyłanie
MADCTLposetRotation()—init()resetuje rejestr MADCTL, więc ustawienia lustra trzeba nakładać po każdej inicjalizacji. Program robi to wapplyMADCTL().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ążeniesendCommandwybrać (zuint8_t*czyconst uint8_t*), boNULLpasuje 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ę:
Natychmiastowa reakcja na każdą zmianę — czysty ekran i świeżo narysowany wzorzec po każdym naciśnięciu klawisza.
Czytelny wzorzec — kolorowe znaczniki w rogach od razu pokazują orientację i ewentualne lustro.
Eksport gotowego kodu — komenda
seliminuje przepisywanie parametrów do projektu ręcznie.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) 😊







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.