Renkli TFT LCD ekranlarda grafik çizmeyi öğrendikten sonra, şimdi işi bir adım öteye taşıyor ve ekranımızın dokunmatik panel (Touch Screen) özelliğini aktif ediyoruz! Bu rehberde, ekranımızın üst kısmında renk kutularından oluşan bir palet oluşturacağız. Parmağımızla veya bir dokunmatik kalemle (stylus) ekrana dokunarak istediğimiz rengi seçecek ve ekranın alt kalan kısmını tıpkı dijital bir resim defteri gibi boyayabileceğiz. Ekranın en altına dokunduğumuzda ise tüm çizimi tek seferde temizleyen akıllı bir algoritma inceleyeceğiz.
Kullandığımız ekran Arduino Uno'nun üzerine doğrudan oturan (Shield) yapıda olduğu için ekstra bir kablolamaya gerek yoktur. Ancak dokunmatik hassasiyetin kararlı çalışması için dokunmatik panel katmanının hangi pinleri paylaştığını bilmek önemlidir:

| Dokunmatik Plaka Pini | Arduino Uno Pini | Özelliği / Notlar |
|---|---|---|
| YP (Y Plus) | A1 Analog Pin | Y ekseni pozitif okuma ucu (Kesinlikle Analog pin olmalıdır) |
| XM (X Minus) | A2 Analog Pin | X ekseni negatif okuma ucu (Kesinlikle Analog pin olmalıdır) |
| YM (Y Minus) | Pin 7 | Y ekseni dijital kontrol ucu |
| XP (X Plus) | Pin 6 | X ekseni dijital kontrol ucu |
Bu uygulamada ekran çizimleri için TFTLCD.h kütüphanesinin yanı sıra dokunmatik yüzeydeki basınç ve koordinatları okuyabilmek için TouchScreen.h kütüphanesini kullanıyoruz. Kodu doğrudan kopyalayıp yükleyebilirsiniz:
#include "TFTLCD.h"
#include "TouchScreen.h"
// Dokunmatik ekran pin tanımlamaları
#define YP A1 // Mutlaka bir analog pin olmalı!
#define XM A2 // Mutlaka bir analog pin olmalı!
#define YM 7 // Dijital pin olabilir
#define XP 6 // Dijital pin olabilir
// Dokunmatik panel kalibrasyon değerleri (Ekrana göre ince ayar gerekebilir)
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
// X plakası arasındaki direnç değeri (Hassas basınç algısı için 300 ohm civarıdır)
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// TFT LCD Kontrol Pinleri
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
// 16-bit Renk Kodları
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
#define BOXSIZE 40 // Üstteki renk kutularının boyutu (piksel genişliği)
#define PENRADIUS 3 // Çizim kaleminin kalınlığı (yarıçapı)
int oldcolor, currentcolor; // Renk geçişlerini kontrol eden değişkenler
void setup(void) {
Serial.begin(9600);
Serial.println("Boyama Programi Baslatildi!");
tft.reset();
// Ekran sürücü entegresini (Chipset) tespit etme
uint16_t identifier = tft.readRegister(0x0);
if (identifier == 0x9325) {
Serial.println("ILI9325 surucusu bulundu.");
} else if (identifier == 0x9328) {
Serial.println("ILI9328 surucusu bulundu.");
} else {
Serial.print("Bilinmeyen ekran surucusu: ");
Serial.println(identifier, HEX);
while (1); // Sürücü bulunamazsa programı burada kilitle
}
tft.initDisplay();
tft.fillScreen(BLACK); // Ekranı siyaha boyayarak temizle
// Üst menüdeki renk kutularını çiz (Palet oluşturma)
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN);
tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN);
tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE);
tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA);
// Başlangıçta Kırmızı rengi seç ve etrafına beyaz çerçeve çiz
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
currentcolor = RED;
pinMode(13, OUTPUT); // İşlem bildirimi için Arduino üzerindeki dahili LED
}
// Dokunmatik basınç sınırları (0 = dokunulmadı demektir)
#define MINPRESSURE 10
#define MAXPRESSURE 1000
void loop() {
// Dokunma verisi alınırken dahili LED'i yakıp söndür
digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);
// ÖNEMLİ KRİTİK ADIM: Dokunmatik ekran ve TFT LCD aynı pinleri paylaştığı için
// getPoint() sonrasında pin modlarını yeniden çıkış (OUTPUT) olarak ayarlamalıyız.
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
// Eğer ekrana geçerli bir basınçla dokunulduysa
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
// EĞER ekranın en altına (kalibrasyon sınırının dışına) dokunulursa ekranı temizle
if (p.y < (TS_MINY - 5)) {
Serial.println("Ekran Temizlendi");
tft.fillRect(0, BOXSIZE, tft.width(), tft.height() - BOXSIZE, BLACK);
}
// Dokunmatik panelden gelen 0-1023 arası analog değerleri, ekranın piksel çözünürlüğüne dönüştür
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
// Eğer dokunulan yer üstteki renk paleti menüsündeyse (Y ekseni BOXSIZE'dan küçükse)
if (p.y < BOXSIZE) {
oldcolor = currentcolor; // Eski rengi kaydet
// Hangi renk kutusuna dokunulduğunu X eksenine göre tespit et ve seçilene beyaz çerçeve ekle
if (p.x < BOXSIZE) {
currentcolor = RED;
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 2) {
currentcolor = YELLOW;
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 3) {
currentcolor = GREEN;
tft.drawRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 4) {
currentcolor = CYAN;
tft.drawRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 5) {
currentcolor = BLUE;
tft.drawRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, WHITE);
} else if (p.x < BOXSIZE * 6) {
currentcolor = MAGENTA;
tft.drawRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, WHITE);
}
// Yeni bir renk seçildiyse, eski seçili rengin beyaz çerçevesini kendi rengiyle boyayarak kaldır
if (oldcolor != currentcolor) {
if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
if (oldcolor == GREEN) tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN);
if (oldcolor == CYAN) tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN);
if (oldcolor == BLUE) tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE);
if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA);
}
}
// Eğer dokunulan yer renk paletinin altındaysa ve ekran sınırları içindeyse küçük daireler çizerek boya
if (((p.y - PENRADIUS) > BOXSIZE) && ((p.y + PENRADIUS) < tft.height())) {
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
}
}
}
ts.getPoint() fonksiyonundan hemen sonra gelen pinMode(XM, OUTPUT); pinMode(YP, OUTPUT); komutlarıdır. Dokunmatik kütüphanesi bu pinleri okuma moduna (INPUT) çeker, hemen ardından ekrana çizim yapabilmek için onları tekrar yazma (OUTPUT) moduna geri almamız gerekir. Bu satırlar olmazsa ekran kilitlenir ve çizim yapmaz.map() fonksiyonları sayesinde bu ham veriyi ekranımızın piksel çözünürlüğü olan genişlik (width) ve yükseklik (height) sınırlarına birebir oranlayarak parmağımızın bastığı tam pikseli buluyoruz.Çözüm: Bu durum dokunmatik panellerde çok sık yaşanır. Kodun en üstünde bulunan Kalibrasyon Değerlerini (TS_MINX, TS_MINY vb.) kendi ekranınıza göre kalibre etmeniz gerekir. Çizim sola çok kayıyorsa MINX değerini biraz artırabilir veya azaltabilirsiniz. Seri porttan gelen p.x ve p.y ham değerlerini izleyerek ekranın köşelerine bastığınızdaki değerleri bu define satırlarına yazıp tam kalibrasyon sağlayabilirsiniz.
Çözüm: Rezistif dokunmatik ekranlar basınçla çalışır. Kalemle ya da tırnağınızla biraz daha belirgin basmanız gerekebilir. Kodun içerisindeki MINPRESSURE 10 değerini 5 veya 2 yaparak ekranın en hafif dokunmaları bile algılamasını sağlayabilirsiniz.
Gerekli dosyalar: TFTLCD.zip
Henüz yorum yapılmamış. İlk yorumu siz yapın!