0.96 inçlik mavi OLED ekran, Arduino ile yapılan projelerin klasiği. Ucuz, sadece iki kablo istiyor, arka ışığı olmadığı için siyahı gerçekten siyah gösteriyor. Ama ilk defa bağlayanların yarısı boş bir ekrana bakarak başlıyor.

Bu rehber baştan sona gidiyor: modül seçimi, kablolama, I2C adresini bulma, kütüphane seçimi, yazı ve şekil çizme, bitmap gösterme, animasyon ve en sık karşılaşılan altı sorunun çözümü.

Hangi Modüle Sahipsiniz?

Kutudan çıkan modül aynı görünse de dört farklı ihtimal var ve kodu bu belirliyor.

ÖzellikSeçeneklerNasıl anlarsınız
SürücüSSD1306 veya SH1106SH1106’da genelde 1.3 inç yazar, SSD1306 çoğunlukla 0.96 inçtir
Çözünürlük128x64 veya 128x32128x32 gözle bakıldığında belirgin şekilde ince ve uzundur
ArayüzI2C (4 pin) veya SPI (7 pin)Pin sayısını sayın: 4 pin ise I2C
RenkTek renk mavi, beyaz, sarı-maviSarı-mavi modelde üst 16 piksel satırı fiziksel olarak sarıdır
Sarı-mavi modelde renk yazılımsal değildir
Sarı-mavi ekranlarda üst 16 satır sarı, alt 48 satır mavidir ve bu paneldeki fiziksel bir bölünmedir. Kodla değiştiremezsiniz. Başlık satırını üstteki sarı bölgeye denk getirmek dışında yapabileceğiniz bir şey yok.

Bu rehber I2C bağlantılı 128x64 SSD1306 modülünü esas alıyor, çünkü en yaygını o. SH1106 farkına ayrı bir bölümde değiniyorum.

Reklam

Kablolama

I2C dört kablo ister: VCC, GND ve iki veri hattı (SDA, SCL). Veri hatlarının hangi pine gideceği karta göre değişir.

SSD1306 OLED ekranın Arduino Uno ile I2C bağlantı şeması ve ESP32, ESP8266 kartları için pin eşleşme tablosu
SSD1306 I2C bağlantısı ve pin karşılıkları, Proje Defteri
KartSDASCLVCC
Arduino Uno / NanoA4A55V
Arduino Mega 256020215V
Arduino Leonardo / Micro235V
ESP32 (varsayılan)GPIO21GPIO223.3V
ESP8266 / NodeMCUD2 (GPIO4)D1 (GPIO5)3.3V
Raspberry Pi PicoGP4GP53.3V

Modüllerin çoğunda dahili regülatör ve seviye çevirici bulunur, bu yüzden 5V ile de 3.3V ile de çalışırlar. Yine de kendi kartınızın besleme gerilimini kullanın: ESP32’ye 5V vermeyin.

Pin numaralarını unuttunuz mu?
Kartınızın hangi pininin I2C olduğunu Arduino Pinout ve ESP32 Pinout araçlarından hızlıca bakabilirsiniz.

I2C Adresini Bulun

SSD1306 modülleri iki adresten birini kullanır: 0x3C (çok yaygın) veya 0x3D. Yanlış adres, hiçbir hata vermeden boş bir ekran demektir. Tahmin etmek yerine tarayın:

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("I2C taraniyor...");

  byte bulunan = 0;
  for (byte adres = 1; adres < 127; adres++) {
    Wire.beginTransmission(adres);
    if (Wire.endTransmission() == 0) {
      Serial.print("Cihaz bulundu: 0x");
      if (adres < 16) Serial.print("0");
      Serial.println(adres, HEX);
      bulunan++;
    }
  }
  if (bulunan == 0) Serial.println("Hicbir cihaz yok. Kablolamayi kontrol edin.");
}

void loop() {}

Seri monitörü 9600 baud’a alın. 0x3C görüyorsanız hazırsınız. Hiçbir şey görmüyorsanız sorun yazılımda değil, kabloda.

Kütüphane Seçimi: Adafruit mı U8g2 mi?

İki gerçek seçenek var ve ikisi de iyi. Fark, RAM kullanımıyla kolaylık arasındaki takasta.

Adafruit SSD1306 + GFXU8g2
RAM (128x64, tam tampon)1024 bayt1024 bayt (F modu) veya 128 bayt (1 modu)
Font seçeneğiAz, GFX fontlarıÇok geniş, yüzlerce font
Öğrenme kolaylığıDaha kolay, örnek bolBiraz daha dik
Desteklenen ekranAdafruit ekosistemiNeredeyse her tek renkli panel

Arduino Uno kullanıyorsanız bu satır önemli: Uno’nun toplam 2048 bayt SRAM’i var. 128x64 tam tampon bunun yarısını yer. U8g2’nin sayfa modu (U8G2_..._1_HW_I2C) tamponu 128 bayta düşürür, karşılığında çizimi birkaç kez tekrarlar. RAM sıkıntısı yaşıyorsanız çözüm budur.

Kütüphaneleri Arduino IDE’de Araçlar > Kütüphane Yöneticisi’nden kurun: Adafruit tarafı için Adafruit SSD1306 ve Adafruit GFX Library, diğeri için U8g2.

İlk Kod: Ekranda Yazı

Adafruit kütüphanesiyle çalışan en küçük örnek:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define GENISLIK 128
#define YUKSEKLIK 64
#define OLED_RESET -1        // I2C modüllerde reset pini yok
#define OLED_ADRES 0x3C

Adafruit_SSD1306 display(GENISLIK, YUKSEKLIK, &Wire, OLED_RESET);

void setup() {
  Serial.begin(9600);

  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADRES)) {
    Serial.println("SSD1306 baslatilamadi");
    for (;;);           // burada takilirsa adres veya kablo yanlis
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Merhaba OLED");
  display.setTextSize(2);
  display.setCursor(0, 20);
  display.println("23.4 C");
  display.display();      // bu satir olmadan hicbir sey gorunmez
}

void loop() {}

Dikkat edilecek üç nokta:

  1. display.display() çağırmadan hiçbir şey ekrana gitmez. Tüm çizimler önce RAM’deki tampona yapılır.
  2. setTextSize(1) 6x8 piksellik temel fontu kullanır, yani 128x64’e 21 karakterlik 8 satır sığar. setTextSize(2) her pikseli iki katına çıkarır, yumuşatma yapmaz.
  3. setCursor(x, y) metnin sol üst köşesini verir. Bu, U8g2’den farklıdır; orada y taban çizgisidir.

Şekil Çizme

Adafruit GFX’in çizim fonksiyonları tek renkli ekranda SSD1306_WHITE (yak) ve SSD1306_BLACK (söndür) renklerini alır.

display.clearDisplay();

display.drawPixel(10, 10, SSD1306_WHITE);
display.drawLine(0, 0, 127, 63, SSD1306_WHITE);
display.drawRect(4, 4, 60, 30, SSD1306_WHITE);      // sadece cerceve
display.fillRect(70, 4, 50, 30, SSD1306_WHITE);     // dolu
display.drawRoundRect(4, 40, 60, 20, 5, SSD1306_WHITE);
display.drawCircle(100, 48, 12, SSD1306_WHITE);
display.fillTriangle(0, 63, 20, 40, 40, 63, SSD1306_WHITE);

display.display();

Koordinat sistemi sol üst köşeden başlar: x sağa, y aşağı doğru artar. 128x64 ekranda geçerli aralık x için 0-127, y için 0-63’tür. Dışarı taşan çizimler hata vermez, sessizce kırpılır.

Ekranı döndürmek isterseniz display.setRotation(0..3) kullanın; her adım 90 derecedir ve genişlik ile yükseklik yer değiştirir.

Bitmap ve Logo Gösterme

Kendi görselinizi göstermek için önce onu bir C dizisine çevirmeniz gerekir. Bunu tarayıcıda yapabilirsiniz:

Görselden koda
image2cpp aracımızla herhangi bir resmi 128x64 tek renkli bitmap dizisine çevirebilirsiniz. Çizim modunu Mono - Yatay, 1 bit/piksel, çıktı biçimini Adafruit GFX seçin.

Aldığınız diziyi doğrudan kullanın:

const unsigned char logo [] PROGMEM = {
  // image2cpp ciktisini buraya yapistirin
};

display.clearDisplay();
display.drawBitmap(0, 0, logo, 128, 64, SSD1306_WHITE);
display.display();

PROGMEM anahtar kelimesi diziyi RAM yerine flash’ta tutar. 128x64 bir bitmap 1024 bayttır; Uno’nun 2 KB RAM’inde bunu tampon dışında ikinci kez tutmaya yeriniz yoktur, bu yüzden PROGMEM seçenek değil zorunluluktur.

Animasyon

Animasyon, üç adımlık döngünün hızlı tekrarından ibarettir: temizle, çiz, gönder.

int x = 0;
int yon = 2;

void loop() {
  display.clearDisplay();

  display.fillCircle(x, 32, 8, SSD1306_WHITE);
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);

  display.display();

  x += yon;
  if (x >= 120 || x <= 8) yon = -yon;

  delay(20);
}

Kayan yazı da aynı mantıkla yapılır, sadece x negatife doğru gider:

const char* mesaj = "Kayan yazi ornegi - Proje Defteri";
int kayma = 128;

void loop() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(kayma, 28);
  display.print(mesaj);
  display.display();

  kayma -= 2;
  if (kayma < -((int)strlen(mesaj) * 6)) kayma = 128;
  delay(30);
}
Kare hızı beklediğinizden düşük olacak
I2C hattı varsayılan olarak 100 kHz çalışır. 1024 baytlık tamponun tamamını göndermek bu hızda yaklaşık 10 milisaniye tutar, yani üst sınır saniyede 100 kare civarındadır. Pratikte çizim süresiyle birlikte 30-50 kare bulursunuz. Wire.setClock(400000); satırını display.begin() sonrasına ekleyerek hattı 400 kHz’e çıkarabilirsiniz; çoğu modül bunu sorunsuz kaldırır ve kare hızı belirgin şekilde artar.

Birden fazla kareli gerçek bir animasyon için her kareyi ayrı bir bitmap dizisi olarak saklayıp sırayla çizin. Kare başına 1024 bayt flash tükettiğini unutmayın: Uno’nun 32 KB flash’ında, kodun kalanına da yer bırakmak isterseniz 20 kareden fazlasını zorlarsınız.

U8g2 ile Aynı İşler

Daha fazla font seçeneği veya daha az RAM istiyorsanız U8g2 tarafı şöyle görünür:

#include <U8g2lib.h>
#include <Wire.h>

// F = tam tampon (1024 bayt RAM), hizli
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
  u8g2.begin();
}

void loop() {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x10_tr);
  u8g2.drawStr(0, 10, "Sicaklik");
  u8g2.setFont(u8g2_font_logisoso24_tn);
  u8g2.drawStr(0, 50, "23.4");
  u8g2.sendBuffer();
  delay(1000);
}

RAM darsa _F_ yerine _1_ kullanın ve firstPage() / nextPage() döngüsüne geçin:

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

u8g2.firstPage();
do {
  u8g2.setFont(u8g2_font_6x10_tr);
  u8g2.drawStr(0, 10, "Az RAM modu");
} while (u8g2.nextPage());
Hangi fontu seçeceğinizi bilmiyorsanız
U8g2 Font Listesi aracıyla fontları yüksekliğe göre filtreleyebilir, adının ne anlama geldiğini görebilir ve metninizin 128x64 ekrana kaç satır sığacağını hesaplayabilirsiniz.

U8g2’de drawStr‘nin y değeri taban çizgisidir, üst kenar değil. Adafruit kütüphanesinden geçiyorsanız ilk yazınızın ekranın üstünde kaybolmasının sebebi budur.

SH1106 Farkı

SH1106 sürücüsü, SSD1306 ile neredeyse aynıdır ama dahili RAM’i 132 piksel geniştir. 128 piksellik panel bu alanın ortasına oturur. SSD1306 kodunu SH1106 ekranda çalıştırırsanız görüntü 2 piksel sağa kayar ve sağ kenarda ince bir çöp şerit belirir.

Çözüm sürücüyü doğru seçmek:

// U8g2 tarafinda sadece sinif adi degisir
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

Adafruit tarafında ayrı bir kütüphane gerekir: Adafruit_SH110X.

Sık Karşılaşılan Sorunlar

Ekran tamamen boş

Sırayla kontrol edin: I2C tarayıcı cihazı görüyor mu (görmüyorsa kablo), begin() içindeki adres doğru mu, kodun sonunda display.display() var mı. Üçü de doğruysa modülün beslemesini ölçün.

Ekran açılıyor ama sadece rastgele piksel gösteriyor

Neredeyse her zaman display.begin() başarısız olmuş ama kod devam etmiştir. begin() dönüş değerini yukarıdaki örnekteki gibi kontrol edin.

Görüntü 2 piksel kaymış, sağda çöp var

SH1106 paneline SSD1306 sürücüsüyle yazıyorsunuz. Üstteki bölüme bakın.

Yazı ekranın üstünde kayboluyor

U8g2 kullanıyorsanız drawStr‘nin y değeri taban çizgisidir; font yüksekliğinden küçük bir y verirseniz yazı yukarı taşar. drawStr(0, 10, ...) ile başlayın.

Uno’da program çöküyor veya saçmalıyor

RAM bitmiştir. 128x64 tam tampon 1024 bayt, Uno’nun toplamı 2048 bayt. Uzun String nesneleri, büyük diziler ve Serial.print içindeki metinler kalan yeri hızla tüketir. Sabit metinleri F("...") içine alın ve U8g2’nin sayfa moduna geçmeyi deneyin.

Türkçe karakterler bozuk çıkıyor

Adafruit GFX’in varsayılan fontu ASCII’dir, ş/ğ/ı/ö/ç/ü yoktur. U8g2’de _tf ile biten bir font (u8g2_font_6x13_tf gibi) Latin-1 kapsar. Tam Türkçe desteği için ya özel bir font derlemeniz ya da o karakterleri bitmap olarak çizmeniz gerekir. Pratikte çoğu proje “Sicaklik” yazıp geçer.

Sık Sorulan Sorular

SSD1306 ekranı 3.3V ile çalışır mı? Evet. Modüllerin çoğunda dahili regülatör vardır ve 3.3V ile de 5V ile de çalışırlar. ESP32 ve ESP8266’ya 3.3V verin.

Aynı anda iki OLED bağlayabilir miyim? I2C ile evet, ama ikisinin adresi farklı olmalı. Bazı modüllerde kart arkasında 0x3C ve 0x3D arasında geçiş yapan bir lehim köprüsü bulunur. Köprü yoksa iki ekranı ayrı I2C hatlarına almanız veya bir I2C çoklayıcı (TCA9548A) kullanmanız gerekir.

Kaç kare hızına çıkabilirim? 100 kHz I2C ile teorik üst sınır saniyede 100 kare, pratikte 30-50. Wire hızını 400 kHz’e çıkarınca 100’ün üstünü görebilirsiniz.

OLED ekranda yanma (burn-in) olur mu? Evet. OLED pikselleri kullanıldıkça soluklaşır. Sürekli aynı sabit görüntüyü gösteren bir projede, içeriği ara ara birkaç piksel kaydırmak veya ekranı kullanılmadığında display.clearDisplay() ile söndürmek ömrü uzatır.

Renkli OLED alsam olur mu? Renkli sürüm (SSD1331, SSD1351) vardır ama piksel başına 2 bayt tutar, yani 128x64 için 16 KB tampon gerekir. Bu Uno’ya sığmaz. Renkli iş için ESP32 ve bir TFT panel (ST7735, ILI9341) daha mantıklıdır; renk değerlerini RGB565 Renk Çevirici ile hesaplayabilirsiniz.

İlgili Araçlar ve Yazılar