Parçalar · 12 dk okuma

ILI9341 Arduino: TFT Ekran Bağlantısı, Dokunmatik ve SD'den Resim

ILI9341 TFT ekran Arduino'ya nasıl bağlanır? Uno'da 3,3 V seviye dönüştürme, Adafruit GFX, XPT2046 dokunmatik, SD'den BMP, ESP32 TFT_eSPI ve beyaz ekran çözümü.

ILI9341 Arduino bağlantısı, projene 240×320 piksellik, 65 bin renkli bir ekran eklemenin en ucuz ve en yaygın yoludur. Kırmızı devre kartlı 2,4 ve 2,8 inçlik bu TFT modüller SPI ile yalnızca birkaç kabloyla bağlanır; dokunmatikli sürümlerinde bir XPT2046 dokunmatik denetleyici ve bir microSD kart yuvası da bulunur. Böylece tek modülle renkli grafikler, dokunmatik düğmeler ve karttan okunan resimler gösterebilirsin. OLED ya da karakter LCD'nin yetmediği menü, gösterge paneli, oyun ve fotoğraf çerçevesi projeleri için idealdir.

Bu rehberde modülün nasıl çalıştığını, Arduino Uno'nun 5 V çıkışlarını ekranın 3,3 V girişlerine nasıl güvenle bağlayacağını, Adafruit_ILI9341 ve Adafruit GFX kütüphaneleriyle yazı, şekil ve renk çizmeyi, dokunmatik okumayı ve SD karttan BMP resim göstermeyi adım adım öğreneceksin. Ardından ESP32'de TFT_eSPI ile çok daha hızlı çizimi, Raspberry Pi Pico'da MicroPython kullanımını ve neredeyse herkesin bir kez karşılaştığı "beyaz ekran" sorununun bütün sebeplerini ele alacağız.

ILI9341 TFT renkli ekran modülü
ILI9341 TFT renkli ekran modülü: 240×320 piksel, SPI bağlantı ve 65 bin renk. Dokunmatikli sürümlerde kartta XPT2046 yongası ve microSD yuvası da bulunur.

ILI9341 TFT ekran nedir, nasıl çalışır?

ILI9341, ekran camının arkasındaki sürücü yongadır. İçinde 240×320 pikselin tamamını tutan yaklaşık 172 KB'lık bir görüntü belleği (GRAM) vardır. Arduino bu belleğe SPI üzerinden komut ve renk verisi gönderir, yonga da görüntüyü kendi kendine saniyede onlarca kez yeniler. Bu yüzden görüntünün Arduino'nun RAM'inde tutulmasına gerek kalmaz: 2 KB RAM'li Uno bile koca bir renkli ekranı sürebilir. Bir şey çizmek için önce bir pencere (x, y, genişlik, yükseklik) seçilir, sonra o pencerenin pikselleri art arda gönderilir. DC pini, giden baytın komut mu (LOW) yoksa veri mi (HIGH) olduğunu söyler. Renkler genellikle RGB565 biçiminde, yani piksel başına 16 bitle gönderilir: 5 bit kırmızı, 6 bit yeşil, 5 bit mavi. SPI hattının çalışma mantığını SPI nedir yazısında ayrıntılı bulabilirsin.

ÖzellikDeğer
Sürücü yongaILI9341
Çözünürlük240×320 piksel (yatay kullanımda 320×240)
RenkRGB565 ile 65.536 renk (yonga 262 bin rengi destekler)
Ekran boyutları2,2", 2,4", 2,8" ve 3,2" (hepsi 240×320)
Arayüz4 telli SPI: CS, DC, SCK, MOSI (okuma için MISO)
Besleme (VCC)3,3–5 V (kartta 3,3 V regülatörü vardır)
Sinyal seviyesi3,3 V (5 V toleranslı değil)
Güç tüketimiYaklaşık 0,3–0,6 W, büyük kısmı arka ışık
DokunmatikRezistif, XPT2046 denetleyici (dokunmatikli modellerde)
Ek donanımmicroSD kart yuvası (ayrı SPI pinleri)

2.4 inç mi 2.8 inç mi? SPI modül ile Uno shield farkı

Özellik2,4" SPI modül2,8" SPI modül2,4" Uno shield
Çözünürlük240×320240×320240×320
BağlantıSPI, kabloylaSPI, kabloyla8 bit paralel, Uno'nun üstüne takılır
Kullandığı pinEkran için 5, dokunmatik ve SD ile 8–9Ekran için 5, dokunmatik ve SD ile 8–9Neredeyse hepsi (D2–D9, A0–A4, SD için D10–D13)
SürücüILI9341ILI9341ILI9341, ILI9325, ST7789 gibi değişebilir
KütüphaneAdafruit_ILI9341, TFT_eSPIAdafruit_ILI9341, TFT_eSPIMCUFRIEND_kbv
DokunmatikXPT2046 (SPI)XPT2046 (SPI)4 telli analog (TouchScreen kütüphanesi)
ESP32 ve PicoUygunUygunUno ve Mega için tasarlanmıştır

Bu yazı SPI modülünü anlatıyor; çünkü ESP32 ve Pico ile de kullanılabiliyor ve Uno'da pinlerin çoğunu boşta bırakıyor. İki SPI modülün pinleri ve kodları birebir aynıdır; 2,8 inçlik ekranın pikselleri biraz daha büyük olduğu için dokunmatik düğmelere basmak daha kolaydır. Elindeki ekran Uno'nun üstüne doğrudan takılan bir shield ise SPI kütüphaneleri onu çalıştıramaz ve sonuç genellikle beyaz bir ekrandır. Böyle bir shield için MCUFRIEND_kbv kütüphanesini kur, tft.readID() ile sürücü kimliğini öğren (ILI9341 için 0x9341) ve tft.begin(ID) ile başlat. Daha küçük ama daha keskin bir alternatif için ST7789 TFT ekran, bütün seçenekleri karşılaştırmak için Arduino ekran çeşitleri yazısına bakabilirsin.

ILI9341 pinleri ve bağlantı tablosu

Modülün bir kenarında 14 pinlik ana konnektör bulunur: ilk 9 pin ekran, T_ ile başlayan son 5 pin dokunmatik içindir. Karşı kenardaki 4 pin (SD_CS, SD_MOSI, SD_MISO, SD_SCK) kart yuvasına gider. Üç cihaz da aynı SPI hattını (SCK, MOSI, MISO) paylaşabilir; yalnızca her birinin CS pini ayrı olmalıdır. Aşağıdaki tablo bu yazıdaki bütün kodlarla uyumludur; Pico'da dokunmatik, hız farkı yüzünden ayrı bir SPI hattına bağlanmıştır.

Modül piniArduino Uno (seviye dönüştürücüyle)ESP32Raspberry Pi Pico
VCC5V3V33V3(OUT)
GNDGNDGNDGND
CSD10GPIO 15GP17
RESETD8GPIO 4GP21
DCD9GPIO 2GP20
SDI (MOSI)D11GPIO 23GP19
SCKD13GPIO 18GP18
LED3.3V3V33V3(OUT)
SDO (MISO)D12 (doğrudan)GPIO 19GP16
T_CLKD13GPIO 18GP10
T_CSD7GPIO 21GP13
T_DIND11GPIO 23GP11
T_DOD12 (doğrudan)GPIO 19GP12
T_IRQD2 (doğrudan)BoşBoş
SD_CSD4GPIO 5Boş
SD_MOSI / SD_MISO / SD_SCKD11 / D12 / D13GPIO 23 / 19 / 18Boş
ILI9341 modüllerinin VCC pini 5 V kabul eder, ama sinyal pinleri yalnızca 3,3 V içindir. Kartın üzerindeki regülatör sadece beslemeyi düşürür; CS, DC, RESET, SCK ve MOSI hatlarında seviye dönüştürücü yoktur. Uno'nun 5 V çıkışlarını doğrudan bağlamak çoğu zaman beyaz ekrana, bazen de yonganın kalıcı olarak bozulmasına yol açar. Kartın arkasındaki J1 köprüsü regülatörü atlamak içindir: yalnızca VCC'yi 3,3 V ile besliyorsan lehimle kapat. J1 kapalıyken VCC'ye 5 V vermek ekranı yakar.

Arduino Uno'da 3,3 V seviye dönüştürme

ESP32 ve Raspberry Pi Pico zaten 3,3 V ile çalıştığı için ekranı doğrudan bağlayabilirsin. Uno, Nano ve Mega gibi 5 V'luk kartlarda ise Arduino'dan ekrana giden her hat 3,3 V'a düşürülmelidir: CS, DC, RESET, SCK, MOSI ve dokunmatik ile SD kullanacaksan T_CLK, T_DIN, T_CS, SD_CS, SD_MOSI ve SD_SCK. Ekrandan Arduino'ya gelen SDO, T_DO, SD_MISO ve T_IRQ hatlarına dönüştürücü gerekmez; Uno 3 V'un üzerindeki gerilimi HIGH kabul eder ve 3,3 V'luk çıkış bunu karşılar. Pratikte dört yol var:

  • 74HC4050 tampon entegresi (en temiz çözüm): 3,3 V ile beslenir, girişlerine 5 V uygulanabilir ve tek yongada 6 hattı dönüştürür. Hızlıdır, 8 MHz SPI'da sorunsuz çalışır. Eski CD4050 da iş görür ama yavaştır; görüntü bozulursa SPI hızını düşürmen gerekir. Yalnız ekran için 5 hat yeter; dokunmatik ve SD de kullanacaksan T_CS ve SD_CS ile 7 hat olur, yedinci hat için ikinci bir yonga ya da bir gerilim bölücü ekle.
  • Gerilim bölücü dirençler: Her hat için Arduino pini ile ekran pini arasına 1 kΩ, ekran pini ile GND arasına 2 kΩ koy; 5 V × 2 / 3 ≈ 3,3 V elde edersin. Elindeki dirençlere göre hesabı gerilim bölücü hesaplayıcı ile yapabilirsin. Ucuzdur ama 5 hat için 10 direnç breadboard'u kalabalıklaştırır.
  • Hazır seviye dönüştürücü modülü: BSS138 mosfetli 4 ya da 8 kanallı modüller kolay bağlanır, ancak çekme dirençleri yüksek hızlarda sinyal kenarlarını yumuşatır. Görüntü bozulursa tft.begin(4000000) ile SPI'ı 4 MHz'e indir. Yöntemlerin karşılaştırması lojik seviye dönüştürücü yazısında.
  • Kaçınman gereken yöntem: İnternette sık görülen "her hatta seri 10 kΩ direnç" çözümü, fazla gerilimi yonganın iç koruma diyotlarına yükler. Bir süre çalışsa da kararsızdır ve uzun vadede ekrana zarar verebilir.

Adım adım: Adafruit_ILI9341 ile ilk test

  1. Arduino IDE'de Kütüphane Yöneticisi'ni aç, Adafruit ILI9341 ara ve kur. Bağımlılıkları sorduğunda Install all seç; böylece Adafruit GFX ve Adafruit BusIO da kurulur. Kütüphane kurmayı ilk kez yapıyorsan Arduino kütüphane ekleme yazısı yardımcı olur.
  2. Dokunmatik için Paul Stoffregen'in XPT2046_Touchscreen kütüphanesini de kur. SD kütüphanesi Arduino IDE ile birlikte gelir.
  3. Ekranı yukarıdaki tabloya göre, Uno'da seviye dönüştürücü üzerinden bağla. İlk testte dokunmatik ve SD pinlerini boş bırakabilirsin.
  4. Aşağıdaki kodu yükle ve Seri Monitör'ü 9600 baud'da aç. Ekranda yazılar ve şekiller, Seri Monitör'de ise ekranın teşhis kodları görünmelidir.
  5. Hazır örnekleri de dene: Dosya > Örnekler > Adafruit ILI9341 > graphicstest, ekranın her çizim işlemini kaç mikrosaniyede yaptığını ölçer.
C++ (Arduino IDE)
1#include <SPI.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_ILI9341.h>
4
5#define TFT_CS  10   // ekran seçme / chip select
6#define TFT_DC  9    // komut/veri seçimi / command/data select
7#define TFT_RST 8    // donanım reset / hardware reset
8
9Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);   // donanım SPI: D11 MOSI, D13 SCK / hardware SPI
10uint16_t orange;                                  // kendi rengimiz / our own colour
11
12void setup() {
13  Serial.begin(9600);
14  tft.begin();                                    // Uno'da 8 MHz SPI / 8 MHz SPI on Uno
15
16  // Teşhis: çalışan ekranda 0x94 ve 0xC0 beklenir / Diagnostics: a working display reports 0x94 and 0xC0
17  Serial.print(F("Power Mode: 0x"));
18  Serial.println(tft.readcommand8(ILI9341_RDMODE), HEX);
19  Serial.print(F("Self Diagnostic: 0x"));
20  Serial.println(tft.readcommand8(ILI9341_RDSELFDIAG), HEX);
21
22  tft.setRotation(1);                             // yatay, 320x240 / landscape, 320x240
23  tft.fillScreen(ILI9341_BLACK);
24  orange = tft.color565(255, 128, 0);             // RGB'den RGB565'e / RGB to RGB565
25
26  tft.setTextColor(ILI9341_WHITE);
27  tft.setTextSize(3);                             // 18x24 piksel karakter / 18x24 px characters
28  tft.setCursor(10, 10);
29  tft.print(F("BlueGrays"));
30  tft.setTextColor(ILI9341_CYAN);
31  tft.setTextSize(2);
32  tft.setCursor(10, 45);
33  tft.print(F("ILI9341 320x240"));
34
35  tft.fillRect(10, 75, 90, 60, ILI9341_RED);                  // dolu dikdörtgen / filled rectangle
36  tft.drawRect(115, 75, 90, 60, ILI9341_GREEN);               // çerçeve / outline
37  tft.fillCircle(265, 105, 30, ILI9341_BLUE);                 // dolu daire / filled circle
38  tft.fillRoundRect(10, 150, 140, 50, 10, orange);            // yuvarlak köşeli düğme / rounded button
39  tft.drawTriangle(180, 200, 240, 150, 300, 200, ILI9341_YELLOW);
40  tft.drawFastHLine(0, 220, 320, ILI9341_MAGENTA);            // yatay çizgi / horizontal line
41}
42
43void loop() {
44  // Arka plan rengiyle yazınca eski rakam silinir, ekran titremez / writing with a background colour erases the old digits, no flicker
45  tft.setTextColor(ILI9341_WHITE, orange);
46  tft.setTextSize(2);
47  tft.setCursor(22, 167);
48  tft.print(millis() / 1000);
49  tft.print(F(" s"));
50  delay(200);
51}
FonksiyonNe yapar?
tft.begin(frekans)Ekranı başlatır; frekans verilmezse Uno'da 8 MHz, ESP32'de 40 MHz SPI kullanır
tft.setRotation(0–3)Yönü seçer: 0 ve 2 dikey (240×320), 1 ve 3 yatay (320×240)
tft.fillScreen(renk)Bütün ekranı tek renge boyar
tft.setTextColor(yazı, arka plan)Yazı rengini seçer; arka plan rengi verilirse eski yazının üstüne silerek yazar
tft.setTextSize(n)Yazıyı n kat büyütür; 1 kat = 6×8 piksellik karakter
tft.drawRect / fillRect(x, y, genişlik, yükseklik, renk)Dikdörtgen çerçeve ya da dolu dikdörtgen
tft.fillRoundRect(x, y, genişlik, yükseklik, r, renk)Köşeleri yuvarlatılmış dolu dikdörtgen; düğmeler için ideal
tft.drawCircle / fillCircle(x, y, r, renk)Daire ya da dolu daire
tft.color565(r, g, b)0–255 arası RGB değerlerini 16 bitlik renge çevirir
tft.readcommand8(komut)Ekrandan bir kayıt okur (MISO bağlı olmalı); arıza tespiti için

Hazır renk sabitleri (ILI9341_RED, ILI9341_NAVY, ILI9341_ORANGE gibi 19 tane) kütüphaneyle gelir; kendi rengini istiyorsan color565() kullan. Bu fonksiyon kırmızının üst 5 bitini, yeşilin üst 6 bitini ve mavinin üst 5 bitini yan yana dizer: renk = (R >> 3) << 11 | (G >> 2) << 5 | (B >> 3). Örneğin turuncu (255, 165, 0) için 31 << 11 = 0xF800 ile 41 << 5 = 0x0520 birleşir ve sonuç 0xFD20 olur; bu, kütüphanedeki ILI9341_ORANGE değerinin ta kendisidir. İnsan gözü yeşile daha duyarlı olduğu için yeşile bir bit fazla ayrılmıştır.

Değişen sayıları her seferinde fillScreen() ile silip yeniden yazmak ekranın titremesine yol açar; Uno'da bütün ekranı boyamak 8 MHz SPI ile en az 0,15 saniye sürer. Bunun yerine koddaki gibi setTextColor(yazı, arka plan) kullan ya da yalnızca değişen küçük alanı fillRect() ile temizle. Sabit metinleri F("...") içine yazmak da Uno'nun 2 KB'lık RAM'ini korur; bellek sorunlarında Arduino bellek yetersiz yazısına bakabilirsin.

XPT2046 dokunmatik ekranı okumak

Dokunmatikli modüllerde camın üstünde ince, rezistif bir katman vardır. Parmağın ya da kalemin bastırdığı noktada iki iletken katman birbirine değer; XPT2046 yongası bu noktanın X ve Y konumunu 12 bitlik ADC ile 0–4095 arası ham değer olarak ölçer ve bir de basınç değeri (Z) verir. Kütüphane Z değeri 400'ün altındaysa dokunma yok kabul eder. Yonga ekranla aynı SPI hattına bağlanır ama 2 MHz gibi daha düşük bir hızda konuşur; kütüphane her okumada hızı kendisi ayarlar. T_IRQ pini dokunulduğunda LOW olur ve işlemciyi boşuna okuma yapmaktan kurtarır. Aşağıdaki kod ekranı küçük bir çizim tahtasına çevirir: üstteki kutulardan renk seçer, "SIL" düğmesiyle ekranı temizlersin.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_ILI9341.h>
4#include <XPT2046_Touchscreen.h>
5
6#define TFT_CS  10
7#define TFT_DC  9
8#define TFT_RST 8
9#define T_CS    7    // dokunmatik seçme / touch chip select
10#define T_IRQ   2    // dokununca LOW olur / goes LOW on touch
11#define SD_CS   4    // SD kullanılmıyor, HIGH tutulur / SD unused, kept HIGH
12
13// Kalibrasyon: Seri Monitör'deki ham değerlerle değiştir / Calibration: replace with the raw values from Serial Monitor
14#define TS_MINX 300
15#define TS_MAXX 3800
16#define TS_MINY 300
17#define TS_MAXY 3800
18
19Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);
20XPT2046_Touchscreen ts(T_CS, T_IRQ);
21
22uint16_t brush = ILI9341_YELLOW;                  // fırça rengi / brush colour
23
24void drawPalette() {
25  tft.fillRect(0, 0, 40, 40, ILI9341_RED);
26  tft.fillRect(40, 0, 40, 40, ILI9341_GREEN);
27  tft.fillRect(80, 0, 40, 40, ILI9341_BLUE);
28  tft.fillRect(120, 0, 40, 40, ILI9341_YELLOW);
29  tft.drawRect(260, 0, 60, 40, ILI9341_WHITE);    // silme düğmesi / clear button
30  tft.setTextColor(ILI9341_WHITE);
31  tft.setTextSize(2);
32  tft.setCursor(273, 13);
33  tft.print(F("SIL"));
34}
35
36void setup() {
37  Serial.begin(9600);
38  pinMode(SD_CS, OUTPUT);
39  digitalWrite(SD_CS, HIGH);                      // SD kart hattı meşgul etmesin / keep the SD card off the bus
40  tft.begin();
41  tft.setRotation(1);                             // ekran yatay / display landscape
42  ts.begin();
43  ts.setRotation(1);                              // dokunmatik de aynı yönde / touch in the same orientation
44  tft.fillScreen(ILI9341_BLACK);
45  drawPalette();
46}
47
48void loop() {
49  if (!ts.touched()) return;                      // dokunma yok / no touch
50  TS_Point p = ts.getPoint();                     // ham x, y (0-4095) ve basınç z / raw x, y and pressure z
51  Serial.print(p.x); Serial.print(',');
52  Serial.print(p.y); Serial.print(',');
53  Serial.println(p.z);
54
55  int16_t x = constrain(map(p.x, TS_MINX, TS_MAXX, 0, 319), 0, 319);   // ekran koordinatı / screen coordinate
56  int16_t y = constrain(map(p.y, TS_MINY, TS_MAXY, 0, 239), 0, 239);
57
58  if (y < 40) {                                   // üst şerit: palet ve düğme / top strip: palette and button
59    if (x < 40)        brush = ILI9341_RED;
60    else if (x < 80)   brush = ILI9341_GREEN;
61    else if (x < 120)  brush = ILI9341_BLUE;
62    else if (x < 160)  brush = ILI9341_YELLOW;
63    else if (x >= 260) { tft.fillScreen(ILI9341_BLACK); drawPalette(); }
64  } else {
65    tft.fillCircle(x, y, 3, brush);               // parmağın altına nokta / dot under the finger
66  }
67}

Ham değerler ekranın tam köşelerinde 0 ve 4095 olmaz; çoğu modülde kenarlar yaklaşık 200–400 ile 3700–3900 arasında kalır. Kalibrasyon için Seri Monitör'ü aç, sol üst ve sağ alt köşeye kalemle dokun, gördüğün x ve y değerlerini TS_MINX, TS_MAXX, TS_MINY ve TS_MAXY sabitlerine yaz. Nokta parmağının ayna görüntüsünde çıkıyorsa o eksenin map() içindeki min ve max değerlerinin yerini değiştir; X ile Y tamamen yer değiştirmişse ts.setRotation() değerini 0–3 arasında dene. Gerçek bir menü yapmak da aynı mantıktır: ekrana düğmeler çizer, dokunulan noktanın hangi dikdörtgenin içinde kaldığına bakarsın. Rezistif katman parmakla da çalışır, ama küçük düğmeler için kalem uçlu bir cisim daha isabetlidir.

SD karttan BMP resim gösterme

Modülün arkasındaki microSD yuvası; logoları, arka planları ve fotoğrafları kartta tutup ekrana basmanı sağlar. Resmi hazırlamak için bir fotoğrafı 320×240 piksele küçült ve Paint ile 24 bit Bit Eşlem (.bmp) olarak kaydet. Arduino'nun SD kütüphanesi kısa dosya adlarıyla çalıştığı için adı RESIM.BMP gibi en fazla 8 karakter yap ve kartı FAT32 olarak biçimlendir. Kartın kendisiyle ilgili ayrıntılar ve initialization failed hatasının çözümü Arduino SD kart modülü yazısında. Unutma: bu yuva da 3,3 V'luktur, Uno'da SD_CS, SD_MOSI ve SD_SCK hatları da seviye dönüştürücüden geçmelidir.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <SD.h>
3#include <Adafruit_GFX.h>
4#include <Adafruit_ILI9341.h>
5
6#define TFT_CS  10
7#define TFT_DC  9
8#define TFT_RST 8
9#define SD_CS   4
10#define T_CS    7
11#define CHUNK   20   // tek okumada 20 piksel (60 bayt) / 20 pixels (60 bytes) per read
12
13Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);
14
15uint16_t read16(File &f) {                        // BMP sayıları küçük uçlu / BMP numbers are little-endian
16  uint16_t lo = f.read();
17  uint16_t hi = f.read();
18  return lo | (hi << 8);
19}
20
21uint32_t read32(File &f) {
22  uint32_t lo = read16(f);
23  uint32_t hi = read16(f);
24  return lo | (hi << 16);
25}
26
27bool drawBmp(const char *name, int16_t x, int16_t y) {
28  File f = SD.open(name);
29  if (!f) return false;                                   // dosya yok / file not found
30  if (read16(f) != 0x4D42) { f.close(); return false; }  // "BM" imzası / "BM" signature
31  read32(f);                                              // dosya boyutu / file size
32  read32(f);                                              // ayrılmış alan / reserved
33  uint32_t offset = read32(f);                            // piksel verisinin başı / start of pixel data
34  read32(f);                                              // başlık boyutu / header size
35  int32_t w = (int32_t)read32(f);
36  int32_t h = (int32_t)read32(f);
37  read16(f);                                              // düzlem sayısı / colour planes
38  uint16_t depth = read16(f);
39  uint32_t comp = read32(f);
40  if (depth != 24 || comp != 0) { f.close(); return false; }   // yalnız 24 bit, sıkıştırmasız / 24-bit uncompressed only
41
42  bool bottomUp = true;                                   // BMP satırları alttan üste / rows are stored bottom-up
43  if (h < 0) { h = -h; bottomUp = false; }
44  uint32_t rowSize = (w * 3 + 3) & ~3UL;                  // satırlar 4 baytın katı / rows padded to 4 bytes
45  int32_t drawW = w, drawH = h;
46  if (x + drawW > tft.width())  drawW = tft.width() - x;   // ekrana sığmayanı kırp / clip to the screen
47  if (y + drawH > tft.height()) drawH = tft.height() - y;
48
49  uint8_t sdBuf[CHUNK * 3];
50  uint16_t line[CHUNK];
51  for (int32_t row = 0; row < drawH; row++) {
52    uint32_t pos = offset + (bottomUp ? (h - 1 - row) : row) * rowSize;
53    f.seek(pos);                                          // satırın başına git / jump to the start of the row
54    for (int32_t col = 0; col < drawW; col += CHUNK) {
55      int16_t n = drawW - col;
56      if (n > CHUNK) n = CHUNK;
57      f.read(sdBuf, n * 3);
58      for (int16_t i = 0; i < n; i++) {                   // BGR'den RGB565'e / BGR to RGB565
59        line[i] = tft.color565(sdBuf[i * 3 + 2], sdBuf[i * 3 + 1], sdBuf[i * 3]);
60      }
61      tft.drawRGBBitmap(x + col, y + row, line, n, 1);    // parçayı ekrana bas / push the chunk to the screen
62    }
63  }
64  f.close();
65  return true;
66}
67
68void setup() {
69  Serial.begin(9600);
70  pinMode(T_CS, OUTPUT);
71  digitalWrite(T_CS, HIGH);                       // dokunmatik hattı meşgul etmesin / keep touch off the bus
72  tft.begin();
73  tft.setRotation(1);                             // 320x240 yatay / landscape
74  tft.fillScreen(ILI9341_BLACK);
75  tft.setTextSize(2);
76
77  if (!SD.begin(SD_CS)) {                         // kart başlatılamadı / card init failed
78    tft.setTextColor(ILI9341_RED);
79    tft.setCursor(10, 10);
80    tft.print(F("SD kart bulunamadi"));
81    return;
82  }
83  uint32_t t = millis();
84  if (!drawBmp("RESIM.BMP", 0, 0)) {
85    tft.setTextColor(ILI9341_YELLOW);
86    tft.setCursor(10, 10);
87    tft.print(F("RESIM.BMP okunamadi"));
88  }
89  Serial.print(F("Cizim suresi / Draw time (ms): "));
90  Serial.println(millis() - t);
91}
92
93void loop() {
94}

BMP dosyasının ilk 54 baytı başlıktır: "BM" imzası, piksel verisinin nerede başladığı, genişlik, yükseklik ve renk derinliği burada yazar. Pikseller mavi, yeşil, kırmızı (BGR) sırasıyla ve normalde alttan üste saklanır; her satır da 4 baytın katına tamamlanır. Kod bu yüzden her ekran satırı için dosyada doğru konuma atlar, 20 pikseli (60 bayt) birden okur, RGB565'e çevirir ve drawRGBBitmap() ile ekrana basar. Küçük parçalarla çalışmak hem Uno'nun RAM'ine sığmanı hem de SD kart ile ekranın aynı SPI hattını sırayla kullanmasını sağlar. Çizim süresi Seri Monitör'e yazılır; Uno'da tam ekran bir resim satır satır, birkaç saniyede belirir. PNG ya da JPEG göstermek ve çok daha hızlı çizmek istersen ESP32 ile TFT_eSPI ve TJpg_Decoder kütüphanelerine geçebilirsin.

ESP32'de TFT_eSPI ile hızlı çizim

ESP32 geliştirme kartı
ESP32, 3,3 V lojiği sayesinde ILI9341'e doğrudan bağlanır ve SPI'ı 40 MHz'te sürerek Uno'dan kat kat hızlı çizer.

ESP32 hem 3,3 V ile çalışır hem de SPI'ı 40 MHz'e kadar sürebilir; seviye dönüştürücüye gerek kalmaz ve tam ekranı boyamak teorik olarak 31 milisaniyeye kadar iner. Bu hızı gerçekten kullanmak için Bodmer'in TFT_eSPI kütüphanesi tercih edilir. Kütüphane ESP32'nin SPI donanımına doğrudan erişir, kenarları yumuşatılmış yazı tiplerini ve en önemlisi sprite denen ekran dışı tamponları destekler. Sprite'a RAM'de istediğin kadar çizip sonucu tek seferde ekrana gönderirsin; böylece hızlı değişen grafiklerde bile titreme olmaz. TFT_eSPI'nin farkı, pinlerin kodda değil kütüphane klasöründeki User_Setup.h dosyasında ayarlanmasıdır. Dosyayı aç, varsayılan olarak açık gelen ESP8266 (NodeMCU) pin satırlarını yorum satırı yap ve şunları etkinleştir:

C++ (Arduino IDE)
1// TFT_eSPI/User_Setup.h içinde yalnız bu satırlar açık kalsın / keep only these lines active in TFT_eSPI/User_Setup.h
2#define ILI9341_DRIVER
3
4#define TFT_MISO 19
5#define TFT_MOSI 23
6#define TFT_SCLK 18
7#define TFT_CS   15   // ekran seçme / chip select
8#define TFT_DC    2   // komut/veri / data/command
9#define TFT_RST   4   // sıfırlama / reset
10#define TOUCH_CS 21   // dokunmatik seçme (T_CS) / touch chip select (T_CS)
11
12#define LOAD_GLCD     // 1: 8 piksel yazı tipi / 8 px font
13#define LOAD_FONT2    // 2: 16 piksel / 16 px
14#define LOAD_FONT4    // 4: 26 piksel / 26 px
15#define LOAD_FONT7    // 7: 7 segment rakamlar / 7-segment digits
16#define LOAD_GFXFF    // Adafruit FreeFont'lar / Adafruit FreeFonts
17#define SMOOTH_FONT
18
19#define SPI_FREQUENCY       40000000   // kablolar uzunsa 27000000 / 27 MHz with long wires
20#define SPI_READ_FREQUENCY  20000000
21#define SPI_TOUCH_FREQUENCY  2500000
C++ (Arduino IDE)
1#include <SPI.h>
2#include <TFT_eSPI.h>                     // pinler User_Setup.h içinde / pins are set in User_Setup.h
3
4TFT_eSPI tft = TFT_eSPI();
5TFT_eSprite graph = TFT_eSprite(&tft);    // ekran dışı çizim alanı / off-screen canvas
6
7// Touch_calibrate örneğinin verdiği 5 sayıyla değiştir / replace with the 5 numbers from the Touch_calibrate example
8uint16_t calData[5] = {286, 3534, 283, 3600, 6};
9
10const int GW = 300, GH = 100;             // grafik boyutu / graph size
11uint8_t samples[GW];                      // son 300 ölçüm / last 300 readings
12uint32_t frames = 0, fps = 0, lastFps = 0;
13
14void setup() {
15  tft.init();
16  tft.setRotation(1);                     // yatay, 320x240 / landscape, 320x240
17  tft.setTouch(calData);
18  tft.fillScreen(TFT_BLACK);
19  tft.setTextColor(TFT_WHITE, TFT_BLACK);
20  tft.drawString("ESP32 + TFT_eSPI", 10, 8, 4);   // 4 numaralı yazı tipi, 26 px / font 4, 26 px
21  graph.createSprite(GW, GH);             // 300x100x2 bayt = 60 KB RAM / 60 KB of RAM
22}
23
24void loop() {
25  memmove(samples, samples + 1, GW - 1);                          // grafiği sola kaydır / scroll the graph left
26  samples[GW - 1] = map(analogRead(34), 0, 4095, 0, GH - 1);       // GPIO 34'teki potansiyometre / pot on GPIO 34
27
28  graph.fillSprite(TFT_BLACK);
29  for (int y = 0; y < GH; y += 25) graph.drawFastHLine(0, y, GW, TFT_DARKGREY);   // ızgara / grid
30  for (int x = 1; x < GW; x++) {
31    graph.drawLine(x - 1, GH - 1 - samples[x - 1], x, GH - 1 - samples[x], TFT_GREEN);
32  }
33  graph.setTextColor(TFT_YELLOW);
34  graph.drawString(String(fps) + " FPS", 4, 4, 2);
35  graph.pushSprite(10, 50);               // tek seferde ekrana gönder, titreme yok / push in one go, no flicker
36
37  uint16_t tx, ty;
38  if (tft.getTouch(&tx, &ty)) {           // dokunulduysa / if touched
39    tft.fillRect(10, 170, 300, 30, TFT_BLACK);
40    tft.setTextColor(TFT_CYAN, TFT_BLACK);
41    tft.drawString("Dokunma / Touch: " + String(tx) + ", " + String(ty), 10, 175, 2);
42  }
43
44  frames++;
45  if (millis() - lastFps >= 1000) {       // saniyede bir FPS hesapla / compute FPS once per second
46    fps = frames;
47    frames = 0;
48    lastFps = millis();
49  }
50}

Kod GPIO 34'e bağlı bir potansiyometrenin değerini kayan bir grafik olarak çizer ve saniyedeki kare sayısını (FPS) sprite'ın köşesinde gösterir. 300×100 piksellik sprite 16 bit renkte 60 KB RAM kaplar; bu Uno'nun bütün belleğinin yaklaşık 30 katıdır ama ESP32 için sorun değildir. Dokunmatikte T_CLK, T_DIN ve T_DO pinleri ekranın SCK, MOSI ve MISO hatlarına birleşir, yalnızca T_CS (GPIO 21) ayrı kalır. Kendi kalibrasyon değerlerin için TFT_eSPI'nin Generic > Touch_calibrate örneğini bir kez çalıştır, ekranda çıkan köşe oklarına dokun ve Seri Monitör'de yazan 5 sayıyı calData dizisine kopyala. User_Setup_Select.h içindeki hazır Setup42_ILI9341_ESP32.h satırı da aynı ekran pinlerini seçer, ama TOUCH_CS satırını ona kendin eklemelisin. ESP32'ye yeni başlıyorsan önce ESP32 nedir yazısına göz at.

Arduino IDE'den TFT_eSPI'yi güncellediğinde kütüphane klasörü baştan yazılır ve User_Setup.h içindeki ayarların silinir; dün çalışan ekran bugün beyaz kalıyorsa ilk bakacağın yer burasıdır, ayar dosyanın yedeğini al. Kırmızı ile mavi yer değiştirmişse TFT_RGB_ORDER TFT_BGR, renkler negatif görünüyorsa TFT_INVERSION_ON satırını aç; bazı panellerde ILI9341_2_DRIVER daha iyi sonuç verir. TFT_eSPI 2.5.43, esp32 kart paketinin 3.x sürümlerinde bazı kartlarda açılışta çöküp yeniden başlayabilir; böyle bir durumda Kart Yöneticisi'nden esp32 paketinin 2.0.x sürümüne dön.

Raspberry Pi Pico ve MicroPython ile ILI9341

Pico da 3,3 V'luk bir kart olduğu için ekran doğrudan bağlanır. MicroPython'da en çok kullanılan sürücü, rdagger'ın micropython-ili9341 deposundaki ili9341.py ve xpt2046.py dosyalarıdır; ikisini Thonny ile Pico'ya kopyalaman yeterlidir. Aşağıdaki kodda ekran 40 MHz'lik SPI0'a, dokunmatik ise 1 MHz'lik ayrı bir SPI1 hattına bağlıdır; böylece iki yonganın hız farkı sorun olmaz. Kod ekrana yazı ve şekil çizer, sonra dokunduğun yere sarı noktalar koyarak basit bir çizim tahtası oluşturur. Pico'yu ve Thonny'yi ilk kez kullanıyorsan Raspberry Pi Pico nedir yazısından başlayabilirsin.

MicroPython
1from machine import Pin, SPI
2from time import sleep_ms
3from ili9341 import Display, color565      # ili9341.py Pico'da olmalı / must be on the Pico
4from xpt2046 import Touch                  # xpt2046.py Pico'da olmalı / must be on the Pico
5
6# Ekran: SPI0, 40 MHz / Display: SPI0, 40 MHz
7spi_tft = SPI(0, baudrate=40000000, sck=Pin(18), mosi=Pin(19), miso=Pin(16))
8tft = Display(spi_tft, cs=Pin(17), dc=Pin(20), rst=Pin(21), width=240, height=320, rotation=0)
9
10# Dokunmatik: ayrı SPI1, 1 MHz / Touch: separate SPI1, 1 MHz
11spi_touch = SPI(1, baudrate=1000000, sck=Pin(10), mosi=Pin(11), miso=Pin(12))
12touch = Touch(spi_touch, cs=Pin(13), width=240, height=320)
13
14WHITE = color565(255, 255, 255)
15YELLOW = color565(255, 255, 0)
16
17tft.clear(color565(0, 0, 0))                                   # ekranı temizle / clear the screen
18tft.draw_text8x8(10, 10, "BlueGrays + Pico", WHITE)
19tft.fill_rectangle(10, 30, 100, 50, color565(255, 0, 0))       # dolu dikdörtgen / filled rectangle
20tft.draw_rectangle(130, 30, 100, 50, color565(0, 255, 0))      # çerçeve / outline
21tft.fill_circle(60, 130, 30, color565(0, 128, 255))            # dolu daire / filled circle
22tft.draw_line(0, 175, 239, 175, color565(255, 0, 255))         # çizgi / line
23tft.draw_text8x8(10, 185, "Ekrana dokun / Touch me", YELLOW)
24
25while True:
26    raw = touch.raw_touch()                # dokunma yoksa None / None when not touched
27    if raw is not None:
28        x, y = touch.normalize(*raw)       # ham değeri piksele çevir / raw value to pixels
29        y = 319 - y                        # eksen ters ise / if the axis is inverted
30        x = min(max(x, 3), 236)            # ekran dışına taşma / keep inside the screen
31        y = min(max(y, 3), 316)
32        tft.fill_circle(x, y, 3, YELLOW)
33    sleep_ms(20)

Dikey kullanımda (rotation=0) genişlik 240, yükseklik 320'dir; ekranı yatay kullanmak istersen rotation=90 ile birlikte width=320, height=240 ver. Dokunmatiğin varsayılan kalibrasyonu (x_min=100, x_max=1962) her modülde tutmayabilir; nokta kayıyorsa raw_touch() değerlerini yazdırıp Touch() içine kendi x_min, x_max, y_min ve y_max değerlerini gir. Resim göstermek için sürücünün draw_image() fonksiyonu, RGB565'e çevrilmiş .raw dosyaları okur; depodaki utils/img2rgb565.py betiği bu dönüşümü bilgisayarda yapar.

Beyaz ekran sorunu ve çözümü

ILI9341'in en meşhur sorunu, arka ışığın yanması ama ekranın bembeyaz kalmasıdır. Beyaz ekran aslında bir ipucudur: güç ve arka ışık çalışıyor ama sürücü yonga hiç başlatılamamış. Panel komut almadığında pikseller ışığı geçirir ve ekran beyaz görünür. Yani sorun neredeyse her zaman iletişimdedir. Aşağıdaki tabloyu yukarıdan aşağıya kontrol et:

BelirtiOlası sebepÇözüm
Beyaz ekran, Uno'ya doğrudan bağlı5 V sinyal, seviye dönüştürücü yok74HC4050 ya da gerilim bölücü kullan; yonga hasar gördüyse modülü değiştir
Beyaz ekran, kablolar takılıCS ile DC yer değiştirmiş ya da koddaki pin numaraları bağlantıyla aynı değilTFT_CS, TFT_DC ve TFT_RST tanımlarını tabloyla tek tek karşılaştır
Beyaz ekran, RESET boştaRESET pini bağlanmamış ya da yanlış pindeRESET'i koddaki pine ya da 3,3 V'a bağla; boşta bırakma
ESP32'de beyaz ekran (TFT_eSPI)User_Setup.h düzenlenmemiş ya da güncellemede silinmişESP8266 satırlarını kapat, ESP32 pinlerini ve ILI9341_DRIVER'ı yeniden yaz
Ara sıra beyaz ekran, kayan ya da bozuk görüntüUzun jumper kablolar, yüksek SPI hızı, gevşek breadboard temasıKabloları 10–15 cm'nin altında tut; SPI'ı 20–27 MHz'e, Uno'da 4 MHz'e düşür
Dokunmatik ya da SD takılıyken beyaz ekranDiğer cihazın CS pini boşta, hattı meşgul ediyorKullanmadığın her CS pinini kodda OUTPUT yapıp HIGH yaz
Hiçbir kodla çalışmıyorEkran ILI9341 değil (ST7789, ILI9488) ya da paralel bir shieldKartın arkasındaki yazıyı oku; 3,5 inç ve 320×480 ise ILI9488, shield ise MCUFRIEND_kbv kullan
Beyaz ekran, arka ışık titriyorYetersiz beslemeVCC'yi 5 V'tan besle, USB kablosunu ve güç kaynağını değiştir
Arızayı ayırmak için ilk koddaki teşhis satırlarını kullan. Seri Monitör'de Power Mode: 0x94 ve Self Diagnostic: 0xC0 görüyorsan ekran komutları alıyor ve sorun yazılımdadır (yön, renk ya da çizim kodu). Değerler 0x0 ya da 0xFF çıkıyorsa Arduino ekranla konuşamıyor demektir: kabloları, seviye dönüştürücüyü ve CS/DC pinlerini kontrol et. Bu okuma yalnızca SDO (MISO) hattı bağlıyken çalışır.

Sık yapılan diğer hatalar

  • Renkler yanlış: Kırmızı mavi görünüyorsa panel BGR sırasıyla çalışıyordur; TFT_eSPI'de TFT_RGB_ORDER ayarını değiştir. Renkler negatif görünüyorsa tft.invertDisplay(true) dene.
  • Görüntü ters ya da ayna: setRotation() değerini 0–3 arasında değiştir ve dokunmatik eksenlerini de buna göre yeniden ayarla.
  • Ekran çalışıyor, dokunmatik ya da SD okunmuyor: T_CS ve SD_CS'nin koddaki pinlerle aynı olduğuna bak. Bazı modüllerde ekranın SDO çıkışı hattı serbest bırakmaz; bu durumda ekranın SDO pinini sökmeyi dene, yalnızca teşhis okuması çalışmaz.
  • BMP görünmüyor: Kart FAT32 değil, dosya adı 8 karakterden uzun ya da resim 24 bit değil. Paint'te 24 bit seçmeyi unutma; 16 ve 32 bitlik BMP'ler bu kodla çizilmez.
  • Türkçe karakterler çıkmıyor: GFX'in varsayılan yazı tipinde ş, ğ ve ı yoktur. TFT_eSPI'de kendi smooth yazı tipini oluşturabilir ya da Türkçe karakterleri içeren bir GFX yazı tipi kullanabilirsin.
  • Ekran yavaş: Uno'da tam ekran yenileme en az 0,15 saniyedir. Animasyon ve oyunlar için ESP32 ya da Pico'ya geç ve yalnızca değişen bölgeyi yeniden çiz.
  • Modül ısınıyor: J1 köprüsü kapalıyken VCC'ye 5 V verilmiş ya da VCC ile GND ters bağlanmış olabilir; beslemeyi hemen kes.

ILI9341 ile proje fikirleri

  • Dokunmatik akıllı ev paneli: Işıkları ve röleleri ekrandaki büyük düğmelerle kontrol et; fikirler için Arduino akıllı ev projesi yazısına bak.
  • Renkli hava durumu ekranı: ESP32 ile internetten aldığın hava durumunu ikonlar ve büyük rakamlarla göster (ESP32 hava durumu).
  • Sensör gösterge paneli: BME280 ile ölçtüğün sıcaklık, nem ve basıncı ibreli göstergeler ve son 24 saatin grafiğiyle çiz.
  • Retro oyun konsolu: Yılan, Pong ya da Tetris'i renkli oyna; kontrol için joystick modülü ekle, fikirler için Arduino oyun projeleri yazısına göz at.
  • Dijital fotoğraf çerçevesi: SD karttaki BMP resimleri birkaç saniyede bir sırayla değiştir.
  • Mini osiloskop: analogRead değerlerini ESP32'de sprite ile akıcı bir dalga şeklinde çiz.
  • Dokunmatik şifreli kilit: Ekrana sayı tuş takımı çiz, doğru şifrede bir röle ya da servo aç.

ILI9341, projelerine renkli ve dokunmatik bir arayüz kazandırmanın en ekonomik yoludur: Uno ile başlayıp temel çizimleri öğren, hız ve akıcılık gerektiğinde ESP32 ile TFT_eSPI'ye geç. Daha küçük bir ekranla başlamak istersen OLED ekran (SSD1306) yazısı iyi bir başlangıçtır. BlueGrays uygulamasında ESP32 hava durumu ekranı, sıcaklık kaydedici, park sensörü ve ekranlı oyun projelerini adım adım devre şemaları ve kodlarıyla bulabilirsin.

Sıkça sorulan sorular

ILI9341 ekran 5 V ile çalışır mı?

Modülün VCC pini 3,3–5 V kabul eder, çünkü kartta bir 3,3 V regülatörü vardır. Ancak CS, DC, SCK ve MOSI gibi sinyal pinleri yalnızca 3,3 V içindir. Arduino Uno ile kullanırken bu hatlara 74HC4050 ya da gerilim bölücü gibi bir seviye dönüştürücü koymalısın.

ILI9341 ekran neden beyaz kalıyor?

Beyaz ekran, arka ışığın yandığını ama sürücü yonganın başlatılamadığını gösterir. En sık sebepler yanlış CS, DC ya da RESET bağlantısı, Uno'da seviye dönüştürücü kullanılmaması, TFT_eSPI'de User_Setup.h dosyasının düzenlenmemesi ve aslında ILI9341 olmayan bir ekranın kullanılmasıdır.

ILI9341 için hangi kütüphane kullanılır?

Arduino Uno, Nano ve Mega için Adafruit_ILI9341 ile Adafruit GFX en kolay seçenektir. ESP32, ESP8266 ve RP2040 kartlarında çok daha hızlı olan TFT_eSPI tercih edilir. Uno'nun üstüne takılan paralel 2,4 inç shield'lar için ise MCUFRIEND_kbv gerekir.

ILI9341 dokunmatik nasıl kalibre edilir?

XPT2046 dokunmatik denetleyici 0–4095 arası ham değerler verir. Köşelere dokunduğunda Seri Monitör'de gördüğün en küçük ve en büyük değerleri not alıp map() ile ekran koordinatlarına çevirirsin. TFT_eSPI kullanıyorsan Touch_calibrate örneği bu işi kendisi yapar ve hazır bir kalibrasyon dizisi verir.

2.4 inç ile 2.8 inç ILI9341 arasındaki fark nedir?

İkisinin de çözünürlüğü 240×320 pikseldir; pinleri ve kodları aynıdır. 2,8 inçlik ekranın pikselleri biraz daha büyük olduğu için yazıları okumak ve dokunmatik düğmelere basmak daha kolaydır. 2,4 inçlik modül ise daha küçük kutulara sığar.

ILI9341 Arduino Nano ile kullanılır mı?

Evet. Nano'nun SPI pinleri Uno ile aynıdır: D13 SCK, D11 MOSI ve D12 MISO. Nano da 5 V lojikle çalıştığı için seviye dönüştürücü gerekir. 2 KB RAM ekranı sürmeye yeter, ama büyük resimleri belleğe alamaz; resimleri SD karttan parça parça okuman gerekir.

Tüm projeleri gör
ESP32 HTTPClient + Hava Durumu API (SSD1306 OLED Ekranlı)
#134İleri
Premium

ESP32 HTTPClient + Hava Durumu API (SSD1306 OLED Ekranlı)

Bu projede ESP32 ile internet üzerinden hava durumu API'sine (wttr.in) HTTPClient.h kullanarak REST API çağrısı yapıyoruz. Bir önceki I2C LCD versiyonundan farklı olarak burada SSD1306 OLED (128×64) ekran kullanıyoruz — büyük font, vector ikonlar ve tek ekranda zengin görsel sunum mümkün oluyor. Hava durumu için 7 farklı vector ikon (güneşli, parçalı bulutlu, bulutlu, yağmurlu, karlı, fırtınalı, sisli) runtime'da çiziliyor (bitmap dosyası gerektirmez). Sıcaklık 3x büyük fontla ortada, hava dur

4.3(10)
19
ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)
#144İleri
Premium

ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)

ESP32 ile zamanlı sıcaklık ve nem kayıt sistemi kur! Bu projede DHT22 sensörü ile dakikada bir sıcaklık/nem okuyup DS1307 RTC modülünden aldığın gerçek zaman etiketiyle microSD karta CSV formatında kaydediyoruz. OLED ekranda büyük font ile son sıcaklık değeri, nem yüzdesi, timestamp ve toplam kayıt sayısı canlı gösterilir. SD kart üzerindeki /temp_log.csv dosyası Excel/Google Sheets/Python pandas ile açılıp analiz edilebilir — sera monitörü, ev/oda sıcaklık takibi, laboratuvar veri toplama,

4.7(7)
12
ESP32 Renk Mikser Lambası (3 Pot + RGB LED + OLED)
#138İleri
Premium

ESP32 Renk Mikser Lambası (3 Pot + RGB LED + OLED)

ESP32 ile 3 potansiyometre çevirerek istediğin rengi karıştıran akıllı bir renk mikser lambası! Kırmızı, yeşil ve mavi potansiyometreleri çevirdikçe ortak katot RGB LED anlık olarak renk değiştirir. SSD1306 OLED ekranda her renk için 0-255 aralığında değer, görsel dolgu barları ve HEX web renk kodu (#FF8040 gibi) canlı olarak gösterilir. Mini bir profesyonel renk stüdyosu — RGB renk teorisi, ADC analog okuma, PWM ile parlaklık kontrolü ve I2C ekran tasarımını tek projede öğretir. Grafik tasarımc

4.7(6)
10
ESP32 Park Sensörü (HC-SR04 + 5 LED Bar + Buzzer + OLED)
#142İleri
Premium

ESP32 Park Sensörü (HC-SR04 + 5 LED Bar + Buzzer + OLED)

Otomobil park sensörünün ESP32 versiyonu! HC-SR04 ultrasonik sensör ile önündeki nesneye olan mesafeyi ölçüyoruz. Mesafe azaldıkça 5 LED'lik bar dolar (yeşil → sarı → kırmızı) ve buzzer bip aralığı kısalır. Çok yakınlaşınca (10 cm altında) sürekli alarm çalar ve tüm LED'ler yanar. SSD1306 OLED ekranda büyük fontla anlık cm değeri, durum metni (SAKIN / DIKKAT / YAKIN / DUR! / TEHLIKE) ve LED bar simülasyonu gösterilir. Klasik ve öğretici bir proje — HC-SR04 pulseIn, digital multi-output, buzzer P

0.0(0)
14
Raket Topu Oyunu - SSD1306
#86Orta
Premium

Raket Topu Oyunu - SSD1306

Bir top, iki raket ve sen: video oyunlarının en eskilerinden masa tenisini küçük bir OLED ekranda oynarsın. İki butonla sağdaki raketini yukarı aşağı oynatırsın, soldaki raketi ise topu gözüyle izleye

4.5(47)
65
OLED T-Rex Run: Arduino Dinozor Oyunu
#87İleri
Premium

OLED T-Rex Run: Arduino Dinozor Oyunu

İnternet kesilince çıkan dinozor oyunu artık masanda: küçük OLED ekranda dinozor koşar, kaktüsler üstüne gelir ve sen tek butonla zıplarsın. Puanın yandaki 4 haneli ekranda canlı olarak artar, her 100

4.7(33)
53
ESP32 I2C LCD Ekran (16x2)
#119Orta
Premium

ESP32 I2C LCD Ekran (16x2)

Bu projede 16x2 karakter LCD ekranı I2C protokolü üzerinden ESP32'ye bağlayarak metin görüntülüyoruz. I2C sayesinde sadece 2 data pini (SDA ve SCL) ile ekranı kontrol edebiliyoruz; klasik paralel bağlantıdaki 6+ pin israfı ortadan kalkıyor. Kod ilk satıra sabit bir mesaj, ikinci satıra ise her saniye artan bir sayaç yazdırıyor. Ayrıca başlangıçta I2C tarayıcı çalıştırarak ekranın adresini Serial Monitor'a yazdırıyoruz (genelde 0x27 veya 0x3F).

4.9(23)
40
Arduino LCD Koşucu Oyunu
#98Orta
Premium

Arduino LCD Koşucu Oyunu

16x2 karakter LCD ekranda çalışan yandan kaydırmalı sonsuz koşucu oyunu. Kahraman otomatik olarak koşar, oyuncu butona basarak engellerin üzerinden zıplar. Alt ve üst sırada rastgele engeller oluşur. Pasif buzzer ile açılış melodisi, zıplama sesi, 50 puan kutlama sesi ve oyun sonu melodisi çalar. Açılışta "BlueGrays — Arduino Projects" splash ekranı gösterilir. Skor ekranın sağ üst köşesinde anlık olarak güncellenir.

4.6(32)
55