Adafruit GFX, Arduino’daki neredeyse her ekran kütüphanesinin üzerine oturduğu katmandır. Adafruit_SSD1306, Adafruit_ILI9341, Adafruit_ST7735, e-kağıt kütüphaneleri ve onlarca üçüncü parti sürücü hep ondan türer. Aynı drawLine çağrısının hem 128x64 tek renkli OLED’de hem 320x240 renkli TFT’de çalışmasının sebebi budur.

Kafa karıştıran nokta şu: çizim fonksiyonları temel sınıfta durur, renkler ve kurucu ile tampon davranışı ise sürücüden gelir. Bu rehber API’nin tamamını tek yerde topluyor.

Katmanlar Nasıl Diziliyor?

Adafruit GFX katman şeması: eskiz, Adafruit_GFX taban sınıfı, SSD1306 ve ILI9341 gibi sürücü kütüphaneleri ve en altta donanım
Adafruit GFX katmanları, Proje Defteri

Her zaman iki kütüphane kurarsınız: Adafruit GFX Library ve panelinize ait sürücü. Yalnızca sürücüyü kurarsanız Adafruit_GFX.h: No such file or directory hatası alırsınız.

Reklam

Koordinat Sistemi

Başlangıç noktası sol üst köşedir. x sağa, y aşağı doğru artar. Panel dışına taşan çizimler hata vermez, sessizce atılır; kayan animasyonları kolaylaştıran şey budur.

tft.width()      // guncel genislik, dondurmeyle degisir
tft.height()     // guncel yukseklik, dondurmeyle degisir
tft.setRotation(0);  // 0, 1, 2, 3 = 0, 90, 180, 270 derece

setRotation tek adımlarda genişlik ile yüksekliği takas eder. Değerleri sabit yazmak yerine width() ve height() ile okuyun, yoksa döndürülen yerleşim bozulur.

Renk

Paneller arası geçişte en çok yanlış yapılan kısım burası.

Panel tipiRenk argümanıÖrnek
Tek renkli OLED / LCD1 = yak, 0 = söndürSSD1306_WHITE, SSD1306_BLACK
Renkli TFT16 bit RGB565ILI9341_RED, 0xF800

Renkli panelde değeri color565() ile üretirsiniz:

uint16_t turuncu = tft.color565(255, 140, 0);
tft.fillRect(0, 0, 60, 40, turuncu);

// veya hesaplanmis sabiti dogrudan yazin, daha hizli ve daha kucuk
#define TURUNCU 0xFC60
RGB565 değerini hesaplamak
RGB565 Renk Çevirici aracımız bir HEX rengi 0x.... sabitine çevirir, kuantalama sonrası panelin gerçekte basacağı rengi gösterir ve color565() çağrısını hazır verir.

Tam Fonksiyon Referansı

Piksel ve çizgi

FonksiyonNe yapar
drawPixel(x, y, renk)Tek piksel. Sürücünün yazmak zorunda olduğu tek fonksiyon.
drawLine(x0, y0, x1, y1, renk)İki nokta arası çizgi.
drawFastHLine(x, y, w, renk)Yatay çizgi, drawLine‘dan hızlı.
drawFastVLine(x, y, h, renk)Dikey çizgi, drawLine‘dan hızlı.

Dikdörtgen

FonksiyonNe yapar
drawRect(x, y, w, h, renk)Çerçeve.
fillRect(x, y, w, h, renk)Dolu.
drawRoundRect(x, y, w, h, r, renk)Yuvarlak köşeli çerçeve, r köşe yarıçapı.
fillRoundRect(x, y, w, h, r, renk)Yuvarlak köşeli ve dolu.
fillScreen(renk)Tüm paneli doldurur.

Daire ve üçgen

FonksiyonNe yapar
drawCircle(x, y, r, renk)Çerçeve, x ve y merkezdir.
fillCircle(x, y, r, renk)Dolu.
drawTriangle(x0,y0, x1,y1, x2,y2, renk)Çerçeve.
fillTriangle(x0,y0, x1,y1, x2,y2, renk)Dolu.

Yazı

FonksiyonNe yapar
setCursor(x, y)Dahili fontta karakterin sol üstü, özel fontta taban çizgisi.
setTextColor(renk)Saydam yazı, arka plana dokunmaz.
setTextColor(on, arka)Arka planı da çizer, eski değeri temiz siler.
setTextSize(n)Tam sayı piksel ölçekleme, 1-8. Yumuşatma yok.
setTextWrap(bool)Sağ kenarda alt satıra geçme, varsayılan açık.
setFont(&font)Özel GFX fontuna geçer. Argümansız setFont() dahili fonta döner.
print() / println()Standart Print arayüzü, print(23.4) çalışır.
getTextBounds(str, x, y, &x1, &y1, &w, &h)Yazıyı çizmeden önce ölçer.

getTextBounds çoğu kişinin gözden kaçırdığı fonksiyondur. Yazıyı ortalamanın yolu budur:

int16_t x1, y1;
uint16_t w, h;
tft.getTextBounds("23.4 C", 0, 0, &x1, &y1, &w, &h);
tft.setCursor((tft.width() - w) / 2, (tft.height() - h) / 2);
tft.print("23.4 C");

Bitmap

FonksiyonVeriKullanım
drawBitmap(x, y, bmp, w, h, renk)1 bit/pikselTek renkli paneller
drawBitmap(x, y, bmp, w, h, on, arka)1 bit/pikselArka planı da çizer
drawXBitmap(x, y, bmp, w, h, renk)1 bit, XBM sırasıXBM olarak dışa aktarılmış bitmap
drawGrayscaleBitmap(x, y, bmp, w, h)8 bitGri tonlamalı paneller
drawRGBBitmap(x, y, bmp, w, h)16 bit RGB565Renkli TFT
Diziyi üretmek
image2cpp bu biçimlerin hepsinde çıktı verir. drawBitmap için Mono - Yatay, 1 bit/piksel, drawRGBBitmap için Renkli RGB565 modunu seçin.

Tip farkına dikkat: 1 bitlik bitmap const unsigned char[], RGB565 bitmap ise const uint16_t[] olmalıdır. Karıştırırsanız kod derlenir ama ekranda çöp çıkar.

Diziyi mutlaka PROGMEM ile işaretleyin. 320x240 RGB565 bir görüntü 153.600 bayttır ve hiçbir Arduino’nun RAM’ine sığmaz.

Fontlar

Dahili font

Varsayılan font, 6x8 hücre içinde 5x7 karakterdir, düz ASCII’dir ve setTextSize() ile ölçeklenir. Neredeyse hiç yer kaplamaz ama 2 ve üstü boyutta köşeli görünür, çünkü ölçekleme tam pikselleri çoğaltır.

Özel GFX fontları

GFX kütüphanesi Fonts/ klasöründe Free* ailelerini içerir:

#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSansBold12pt7b.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>

tft.setFont(&FreeSans9pt7b);
tft.setCursor(0, 20);          // dikkat: y artik TABAN CIZGISI
tft.print("Duzgun tipografi");

tft.setFont();                 // dahili fonta geri don
Özel fontta setCursor başka bir şey ifade eder
Dahili fontta setCursor(x, y) yazının sol üst köşesini belirler. Özel GFX fontunda ise taban çizgisini, yani kabaca harflerin alt hizasını belirler. Özel fontla y = 0 vermek yazıyı ekranın üstüne atar ve hiçbir şey çizilmemiş gibi görünür. GFX’te en sık yapılan hata budur.

Özel fontlar aynı zamanda orantılıdır, bu yüzden setTextWrap ve getTextBounds daha da önem kazanır. Her font birkaç kilobayt flash tüketir.

Kendi fontunuzu üretmek: fontconvert

GFX deposunda fontconvert klasöründe, bir TTF’yi GFX başlığına çeviren küçük bir C programı bulunur:

cd Adafruit-GFX-Library/fontconvert
make
./fontconvert /yol/FontAdi.ttf 12 > FontAdi12pt7b.h

Sayı punto boyutudur. Üretilen başlığı kodunuzun yanına koyup #include edin. Varsayılan olarak ASCII 32-126 aralığını çevirir; aralığı genişletmek için başlangıç ve bitiş kod noktası verin:

./fontconvert FontAdi.ttf 12 32 255 > FontAdi12pt7b.h

Eklediğiniz her karakter flash tükettiği için 255’e genişletmek fontun boyutunu kabaca iki katına çıkarır.

Titremesiz Çizim: GFXcanvas

Renkli TFT’de çerçeve tamponu yoktur; her çizim çağrısı doğrudan panele yazar. Değişen bir değeri yeniden çizdiğinizde eski yazının silinip yenisinin belirmesini görürsünüz, bu da titreme olarak algılanır.

GFXcanvas1 ve GFXcanvas16, önce içine çizip sonra tek seferde bastığınız bir ekran dışı tampon verir:

GFXcanvas16 canvas(120, 30);       // 120 * 30 * 2 = 7200 bayt RAM

void degeriGuncelle(float deger) {
  canvas.fillScreen(ILI9341_BLACK);
  canvas.setFont(&FreeSansBold12pt7b);
  canvas.setCursor(0, 22);
  canvas.setTextColor(ILI9341_GREEN);
  canvas.print(deger, 1);

  tft.drawRGBBitmap(100, 60, canvas.getBuffer(), 120, 30);
}

Bedeli RAM’dir: GFXcanvas16 genişlik * yükseklik * 2 bayt ister, yani bu bir ESP32 veya RP2040 tekniğidir. GFXcanvas1 yalnızca genişlik / 8 * yükseklik ister ve çok daha geniş bir yelpazede kullanılabilir.

Hiç RAM istemeyen daha ucuz bir alternatif: yazıyı arka plan rengiyle çizip kendi kendini silmesini sağlayın.

tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setCursor(100, 60);
tft.print(deger, 1);
tft.print("   ");     // dolgu, yoksa onceki uzun degerin kuyrugu kalir

Sık Karşılaşılan Sorunlar

Adafruit_GFX.h: No such file or directory

Sürücüyü kurdunuz ama temel kütüphaneyi kurmadınız. Kütüphane Yöneticisi’nden Adafruit GFX Library‘yi de kurun.

Tek renkli OLED’de hiçbir şey görünmüyor

Adafruit_SSD1306 gibi tamponlu sürücüler yalnızca RAM’e yazar. Tamponu panele göndermek için display.display() çağırmanız gerekir. Renkli TFT sürücüleri buna ihtiyaç duymaz; aynı kodun iki panel tipinde farklı davranmasının sebebi budur.

setFont() sonrası yazı görünmüyor

setCursor‘daki y taban çizgisine dönüştü. En az font yüksekliği kadar bir değer verin.

Eski değer yeninin altından görünüyor

Varsayılan yazı saydamdır. Ya alanı önce fillRect ile temizleyin ya da iki argümanlı setTextColor(on, arka) kullanın.

Kısa sayı yazınca eski rakam kalıyor

123.4 üzerine yazılan 23.4 yalnızca beş karakteri kapatır. Metni dolgu ile sabit uzunlukta tutun veya yazmadan önce sabit bir dikdörtgeni temizleyin.

TFT’de renkler ters veya yanlış

Bayt sırası. Bazı sürücüler setSwapBytes() sunar; bazı paneller RGB yerine BGR’dir ve sürücünün kendi ayar bayrağını ister. Kırmızı ile mavinin yer değiştirmesi klasik belirtidir.

Bitmap çapraz kaymış

drawBitmap‘e verdiğiniz genişlik, dizinin üretildiği genişlikle aynı değil. 1 bitlik bitmap’lerde genişliğin ayrıca 8’in katı olması gerekir, aksi halde her satır doldurulur ve görüntü kayar.

Sık Sorulan Sorular

Adafruit GFX ESP32 ile çalışır mı? Evet, karttan bağımsızdır. ESP32’de renkli TFT için birçok kişi belirgin şekilde daha hızlı olduğu için TFT_eSPI tercih eder, ancak onun API’si GFX’inkinden farklıdır.

GFX ne kadar flash tüketir? Temel kütüphane küçüktür, birkaç kilobayt. Asıl flash’ı dolduran özel fontlar ve bitmap’lerdir: tek bir FreeSans12pt7b birkaç kilobayt, tek bir 128x64 bitmap 1024 bayttır.

Aynı kodda hem tek renkli hem renkli panel kullanabilir miyim? Evet. İki sürücüyü de örnekleyip aynı GFX metotlarını her ikisine çağırın. Yalnızca renk sabitlerini karıştırmayın: SSD1306_WHITE 1’dir, ILI9341_WHITE 0xFFFF’tir.

Resmi dokümantasyon nerede? Adafruit hem Doxygen referansı hem de öğrenme sitesinde yazılı bir rehber yayımlıyor. Bu sayfa aynı API’nin yoğunlaştırılmış pratik sürümüdür.

İlgili Araçlar ve Yazılar