2500 TL ÜZERİ MNG-DHL KARGO ÜCRETSİZ
SAAT 15.00'A KADAR VERİLEN SİPARİŞLER AYNI GÜN KARGODA !
2500 TL ÜZERİ MNG-DHL KARGO ÜCRETSİZ
TEKNOLOJİ TUTKUNLARI İÇİN MOTOROBİT : HER ŞEY BURADA !
2500 TL ÜZERİ MNG-DHL KARGO ÜCRETSİZ
SAAT 15.00'A KADAR VERİLEN SİPARİŞLER AYNI GÜN KARGODA !
+30.000 ÜRÜN ÇEŞİDİ GENİŞ ÜRÜN YELPAZESİ
ELEKTRONİK KOMPONENT TEDARİKÇİNİZ
YARATICILIĞINIZI MOTOROBİT İLE SINIRLARIN ÖTESİNE TAŞIYIN

{{ t.products }}

{{ live_data.products.length }}

{{ t.categories }}

{{ live_data.categories.length }}

{{ t.brands }}

{{ live_data.brands.length }}
Menü
Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.
Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.Sitemizde veya piyasada bulamadığınız her türlü elektronik ve otomasyon yedek parça için lütfen bizimle iletişime geçiniz.

XIAO ESP32-C6 ve SPI TFT LCD ile Mini Refleks Oyunu Yapımı

•
Yazar: Senanur Yılmaz
•
Yayın Tarihi: 14.11.2026
•
Okuma Süresi: 12 Dakika
XIAO ESP32-C6 ve SPI TFT LCD ile Mini Refleks Oyunu Yapımı

Bu projede XIAO ESP32-C6 geliştirme kartı, 1.8 inç SPI TFT ekran ve bir buton kullanarak tepki süresini ölçen mini bir refleks oyunu yapacağız. Ekranda yeşil renk ve “BAS!” yazısı göründüğü anda butona basacak, tepki süremizi milisaniye cinsinden öğreneceğiz.

Proje; SPI haberleşmesini, TFT ekran kullanımını, buton okumayı, rastgele süre oluşturmayı ve millis() ile zaman ölçmeyi öğrenmek için eğlenceli bir başlangıç uygulamasıdır.

Refleks Oyunu Nasıl Çalışır?

  1. Ekranda “Başlamak için bas” mesajı görüntülenir.
  2. Oyuncu butona basınca yeni oyun başlar.
  3. Ekranda “Hazır ol...” mesajı görünür.
  4. Sistem rastgele olarak 2–5 saniye bekler.
  5. Ekran yeşile döner ve “BAS!” yazısı görünür.
  6. Oyuncunun butona basması için geçen süre ölçülür.
  7. Beş turun sonunda en iyi ve ortalama süre gösterilir.

Oyuncu yeşil ekran görünmeden butona basarsa ekranda “Çok erken!” uyarısı çıkar. Aynı tur yeniden başlatılır ve bu sonuç skora eklenmez.

TEPKI SUREN

247 ms

COK IYI!

Gerekli Malzemeler

Önemli: Program yüklemek için kullandığınız USB kablosunun veri aktarımını desteklemesi gerekir. Yalnızca şarj özelliği bulunan kablolarla kart bilgisayarda görünmeyebilir.

Kullanacağımız TFT Ekran

Projede kullanılan 1.8 inç TFT ekran 128×160 piksel çözünürlüğe ve ST7735R ekran sürücüsüne sahiptir. Görüntü bilgileri XIAO ESP32-C6 kartından ekrana SPI haberleşmesiyle gönderilir.

Ekran dokunmatik değildir. Bu nedenle oyuncunun tepki vermesi için ayrı bir fiziksel buton kullanacağız.

TFT ekran üzerindeki önemli pinler

  • VCC: Ekranın besleme bağlantısıdır.
  • GND: Devrenin ortak eksi bağlantısıdır.
  • SCK veya CLK: SPI saat sinyalidir.
  • SDA veya MOSI: Görüntü verisinin ekrana gönderildiği pindir.
  • CS: Kullanılacak SPI cihazını seçer.
  • DC veya A0: Komut ve görüntü verisini birbirinden ayırır.
  • RST veya RESET: Ekranı sıfırlar.
  • LED veya BL: Ekran arka aydınlatmasıdır.
TFT modülünde bulunan SDA yazısı kafa karıştırabilir. Bu projede söz konusu pin I2C bağlantısı değildir. Ekranın SPI veri girişi olan MOSI pinidir.

XIAO ESP32-C6 ile TFT Ekran Bağlantısı

Bağlantıları yapmadan önce XIAO ESP32-C6 kartını USB kablosundan ayırın. Tüm kabloları kontrol ettikten sonra karta güç verin.

TFT ekran piniXIAO ESP32-C6 piniGörevi
VCC3V3Ekran beslemesi
GNDGNDOrtak eksi bağlantısı
SCK / CLKD8SPI saat sinyali
SDA / MOSID10XIAO'dan ekrana veri gönderir
CSD3Ekranı seçer
DC / A0D2Komut ve görüntü verisini ayırır
RST / RESETD1Ekranı sıfırlar
LED / BL3V3Arka aydınlatmayı çalıştırır

TFT ekran yalnızca veri aldığı için ekranın MISO bağlantısına ihtiyaç duyulmaz. XIAO ESP32-C6 kartının donanımsal SPI pinleri D8=SCK, D9=MISO ve D10=MOSI şeklindedir.

Buton Bağlantısı

Buton bağlantısıXIAO ESP32-C6 pini
Butonun bir tarafıD0
Butonun karşı tarafıGND

Kod içerisinde D0 pini INPUT_PULLUP olarak kullanılacaktır. Böylece ayrıca bir pull-up direnci bağlamamız gerekmez. Buton serbestken pin HIGH, butona basıldığında ise LOW okunur.

Dört pinli tact buton kullanıyorsanız: Butonun aynı tarafındaki iki bacak zaten birbirine bağlıdır. D0 ve GND kablolarını butonun karşılıklı iki tarafına bağlayın. İki kabloyu aynı taraftaki bacaklara bağlarsanız buton sürekli basılıymış gibi çalışabilir.

Arduino IDE Kurulumu

1. Arduino IDE'yi yükleyin

Arduino IDE'nin güncel kararlı sürümünü bilgisayarınıza indirip kurun. Ardından Arduino IDE'yi açın.

2. ESP32 kart adresini ekleyin

Arduino IDE içinde Dosya > Tercihler bölümünü açın. “Ek Kart Yöneticisi URL'leri” alanına aşağıdaki adresi ekleyin:

https://espressif.github.io/arduino-esp32/package_esp32_index.json

3. ESP32 kart paketini kurun

  1. Araçlar > Kart > Kart Yöneticisi bölümünü açın.
  2. Arama alanına esp32 yazın.
  3. Espressif Systems tarafından hazırlanan ESP32 paketini kurun.
  4. Kart olarak XIAO_ESP32C6 seçeneğini seçin.
  5. XIAO kartının bağlı olduğu doğru seri portu seçin.

4. Ekran kütüphanelerini kurun

Araçlar > Kütüphaneleri Yönet bölümünü açarak aşağıdaki iki kütüphaneyi kurun:

  • Adafruit GFX Library
  • Adafruit ST7735 and ST7789 Library

Arduino IDE ek bağımlılıkların kurulmasını sorarsa Install All seçeneğini kullanabilirsiniz.

Mini Refleks Oyunu Arduino Kodu

Aşağıdaki kodu Arduino IDE'ye yapıştırın. Kart ve port seçimlerini kontrol ettikten sonra Yükle butonuna basın.

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <esp_system.h>
#include <limits.h>

// TFT ekran bağlantıları
#define TFT_CS   D3
#define TFT_DC   D2
#define TFT_RST  D1

// Refleks butonu
#define BUTTON_PIN D0

// Oyun ayarları
const uint8_t TOTAL_ROUNDS = 5;
const unsigned long MIN_WAIT_TIME = 2000;
const unsigned long MAX_WAIT_TIME = 5000;

// TFT ekran nesnesi
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// Oyunun bulunabileceği durumlar
enum GameState {
  START_SCREEN,
  WAITING,
  GO_SIGNAL,
  ROUND_RESULT,
  EARLY_PRESS,
  GAME_FINISHED
};

GameState gameState = START_SCREEN;

unsigned long stateStartedAt = 0;
unsigned long randomWaitTime = 0;
unsigned long goStartedAt = 0;
unsigned long reactionTime = 0;
unsigned long totalReactionTime = 0;
unsigned long bestReactionTime = ULONG_MAX;

uint8_t currentRound = 1;

// Ekranın ortasına yazı yazdırır
void drawCenteredText(
  const String &text,
  int16_t y,
  uint8_t textSize,
  uint16_t color
) {
  int16_t x1;
  int16_t y1;
  uint16_t textWidth;
  uint16_t textHeight;

  tft.setTextSize(textSize);
  tft.setTextColor(color);
  tft.setTextWrap(false);

  tft.getTextBounds(
    text.c_str(),
    0,
    y,
    &x1,
    &y1,
    &textWidth,
    &textHeight
  );

  int16_t x = (tft.width() - textWidth) / 2;
  tft.setCursor(x, y);
  tft.print(text);
}

// Butondaki mekanik titreşimleri filtreler
bool buttonPressed() {
  static int lastReading = HIGH;
  static int stableState = HIGH;
  static unsigned long lastChangeTime = 0;

  int currentReading = digitalRead(BUTTON_PIN);

  if (currentReading != lastReading) {
    lastReading = currentReading;
    lastChangeTime = millis();
  }

  if (
    millis() - lastChangeTime > 25 &&
    currentReading != stableState
  ) {
    stableState = currentReading;

    if (stableState == LOW) {
      return true;
    }
  }

  return false;
}

void showStartScreen() {
  tft.fillScreen(ST77XX_BLUE);

  drawCenteredText("MINI REFLEKS", 22, 2, ST77XX_WHITE);
  drawCenteredText("OYUNU", 45, 2, ST77XX_WHITE);

  drawCenteredText(
    "Baslamak icin",
    81,
    1,
    ST77XX_YELLOW
  );

  drawCenteredText(
    "butona bas",
    96,
    1,
    ST77XX_YELLOW
  );
}

void showWaitingScreen() {
  tft.fillScreen(ST77XX_YELLOW);

  drawCenteredText("HAZIR OL...", 42, 2, ST77XX_BLACK);

  drawCenteredText(
    "Tur " + String(currentRound) + "/" + String(TOTAL_ROUNDS),
    78,
    1,
    ST77XX_BLACK
  );
}

void showGoScreen() {
  tft.fillScreen(ST77XX_GREEN);
  drawCenteredText("BAS!", 38, 4, ST77XX_BLACK);
}

void showEarlyPressScreen() {
  tft.fillScreen(ST77XX_RED);

  drawCenteredText("COK ERKEN!", 32, 2, ST77XX_WHITE);
  drawCenteredText("Yesili bekle", 70, 1, ST77XX_WHITE);
  drawCenteredText("Tur tekrarlanacak", 88, 1, ST77XX_WHITE);
}

void showRoundResult() {
  tft.fillScreen(ST77XX_BLACK);

  drawCenteredText("TEPKI SUREN", 16, 2, ST77XX_CYAN);

  drawCenteredText(
    String(reactionTime) + " ms",
    50,
    3,
    ST77XX_WHITE
  );

  String message;

  if (reactionTime < 200) {
    message = "INANILMAZ!";
  } else if (reactionTime < 300) {
    message = "COK IYI!";
  } else if (reactionTime < 450) {
    message = "IYI!";
  } else {
    message = "DAHA HIZLI!";
  }

  drawCenteredText(message, 91, 1, ST77XX_YELLOW);
}

void showFinalScreen() {
  unsigned long averageTime =
    totalReactionTime / TOTAL_ROUNDS;

  tft.fillScreen(ST77XX_MAGENTA);

  drawCenteredText("OYUN BITTI", 9, 2, ST77XX_WHITE);

  drawCenteredText(
    "En iyi: " + String(bestReactionTime) + " ms",
    45,
    1,
    ST77XX_WHITE
  );

  drawCenteredText(
    "Ortalama: " + String(averageTime) + " ms",
    63,
    1,
    ST77XX_WHITE
  );

  drawCenteredText(
    "Tekrar oynamak icin",
    91,
    1,
    ST77XX_YELLOW
  );

  drawCenteredText(
    "butona bas",
    106,
    1,
    ST77XX_YELLOW
  );
}

// Rastgele bekleme aşamasını başlatır
void beginWaiting() {
  randomWaitTime = random(
    MIN_WAIT_TIME,
    MAX_WAIT_TIME + 1
  );

  showWaitingScreen();

  stateStartedAt = millis();
  gameState = WAITING;
}

// Bütün skorları sıfırlayıp yeni oyun başlatır
void startNewGame() {
  currentRound = 1;
  totalReactionTime = 0;
  bestReactionTime = ULONG_MAX;

  beginWaiting();
}

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  // ESP32'nin rastgele sayı üreticisini kullanır
  randomSeed(esp_random());

  // XIAO ESP32-C6 donanımsal SPI pinleri
  SPI.begin(D8, D9, D10, TFT_CS);

  // ST7735R ekranı başlatır
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(1);

  showStartScreen();
}

void loop() {
  bool pressed = buttonPressed();

  switch (gameState) {

    case START_SCREEN:
      if (pressed) {
        startNewGame();
      }
      break;

    case WAITING:
      // Oyuncu yeşil ekran gelmeden bastı
      if (pressed) {
        showEarlyPressScreen();
        stateStartedAt = millis();
        gameState = EARLY_PRESS;
      }
      // Rastgele bekleme süresi tamamlandı
      else if (millis() - stateStartedAt >= randomWaitTime) {
        showGoScreen();

        // Yeşil ekran gösterildiği anı kaydet
        goStartedAt = millis();
        gameState = GO_SIGNAL;
      }
      break;

    case GO_SIGNAL:
      if (pressed) {
        reactionTime = millis() - goStartedAt;
        totalReactionTime += reactionTime;

        if (reactionTime < bestReactionTime) {
          bestReactionTime = reactionTime;
        }

        showRoundResult();
        stateStartedAt = millis();
        gameState = ROUND_RESULT;
      }
      break;

    case ROUND_RESULT:
      // Sonucu 2,5 saniye ekranda tut
      if (millis() - stateStartedAt >= 2500) {

        if (currentRound >= TOTAL_ROUNDS) {
          showFinalScreen();
          gameState = GAME_FINISHED;
        } else {
          currentRound++;
          beginWaiting();
        }
      }
      break;

    case EARLY_PRESS:
      // Erken basma ekranından sonra aynı turu tekrarla
      if (millis() - stateStartedAt >= 2000) {
        beginWaiting();
      }
      break;

    case GAME_FINISHED:
      if (pressed) {
        startNewGame();
      }
      break;
  }
}

Kod Nasıl Çalışıyor?

SPI ekran bağlantılarının tanımlanması

#define TFT_CS   D3
#define TFT_DC   D2
#define TFT_RST  D1

Bu satırlar TFT ekranın CS, DC ve RESET bağlantılarının hangi XIAO pinlerine bağlı olduğunu programa bildirir.

Butonun dahili pull-up direnciyle kullanılması

pinMode(BUTTON_PIN, INPUT_PULLUP);

XIAO'nun dahili pull-up direnci etkinleştirilir. Bu nedenle butona basıldığında D0 pini LOW olarak okunur.

Rastgele bekleme süresi

randomWaitTime = random(2000, 5001);

Her turda 2000–5000 milisaniye arasında farklı bir bekleme süresi oluşturulur. Böylece oyuncu yeşil ekranın ne zaman çıkacağını önceden tahmin edemez.

Tepki süresinin ölçülmesi

goStartedAt = millis();
reactionTime = millis() - goStartedAt;

Yeşil ekran gösterildiği anda başlangıç zamanı kaydedilir. Oyuncu butona bastığında güncel zamandan başlangıç zamanı çıkarılarak tepki süresi hesaplanır.

Neden delay() kullanılmadı?

Oyun sırasında uzun süreli delay() kullanılsaydı XIAO beklerken butonu kontrol edemezdi. Kodda millis() kullanıldığı için bekleme sırasında yapılan erken basışlar da algılanabilir.

Oyunu Çalıştırma

  1. Devre bağlantılarını yeniden kontrol edin.
  2. XIAO ESP32-C6 kartını veri aktarabilen USB kablosuyla bilgisayara bağlayın.
  3. Arduino IDE'de XIAO ESP32-C6 kartını ve doğru portu seçin.
  4. Kodu karta yükleyin.
  5. Ekranda başlangıç mesajı göründüğünde butona basın.
  6. “Hazır ol...” ekranındayken bekleyin.
  7. Yeşil ekran ve “BAS!” yazısı çıkar çıkmaz butona basın.

Karşılaşılabilecek Sorunlar

Ekran tamamen beyaz kalıyor

  • CS, DC ve RESET kablolarını kontrol edin.
  • SCK pininin D8'e bağlı olduğundan emin olun.
  • SDA/MOSI pininin D10'a bağlı olduğundan emin olun.
  • GND bağlantısının ortak olduğunu kontrol edin.

Ekranın arka ışığı yanmıyor

TFT modülündeki LED veya BL pinini kontrol edin. Bu pin boş bırakılmışsa ekran görüntü üretiyor olsa bile arka ışık yanmayabilir.

Görüntü renkleri yanlış

Bazı ST7735 ekran sürümlerinde başlangıç ayarı farklı olabilir. Aşağıdaki satırı:

tft.initR(INITR_BLACKTAB);

sırasıyla şu seçeneklerden biriyle deneyebilirsiniz:

tft.initR(INITR_GREENTAB);
// veya
tft.initR(INITR_REDTAB);

Görüntü ters veya yan duruyor

Aşağıdaki değeri 0, 1, 2 veya 3 yaparak ekran yönünü değiştirebilirsiniz:

tft.setRotation(1);

Buton sürekli basılı görünüyor

Dört bacaklı tact butonda kabloları aynı taraftaki iki bacağa bağlamış olabilirsiniz. D0 ve GND bağlantılarını butonun karşılıklı taraflarına bağlayın.

Projeyi Nasıl Geliştirebiliriz?

  • Yeşil ekran gösterildiğinde ses çıkaran bir buzzer eklenebilir.
  • Kolay, normal ve zor olmak üzere farklı oyun modları hazırlanabilir.
  • En iyi skor kalıcı olarak ESP32 hafızasına kaydedilebilir.
  • İkinci bir buton eklenerek iki oyunculu yarış yapılabilir.
  • Her turda ekranda farklı şekiller veya renkler gösterilebilir.
  • XIAO ESP32-C6'nın kablosuz özelliği kullanılarak skorlar web sayfasında gösterilebilir.
  • LiPo pil ve açma-kapama anahtarı eklenerek taşınabilir oyun cihazı yapılabilir.

Sonuç

Bu projede XIAO ESP32-C6 ile ST7735R tabanlı SPI TFT ekranı kontrol ettik, fiziksel bir butondan giriş aldık ve oyuncunun tepki süresini milisaniye cinsinden ölçtük. Aynı zamanda rastgele sayı oluşturma, buton titreşimini filtreleme ve millis() ile gecikmesiz zamanlama gibi birçok önemli programlama konusunu uygulamalı olarak öğrenmiş olduk.

Devreyi ilk kez kurarken projeyi USB üzerinden çalıştırmanız önerilir. Ekran ve oyun düzgün çalıştıktan sonra projeye pil, switch, buzzer ve özel bir kutu ekleyerek taşınabilir hale getirebilirsiniz.
Paylaş
T-Soft | Premium