Layar Sentuh TFT 2.4" Arduino dan Tampilkan Teks dan Gambar
TFT 2.4" Arduino (Layar Sentuh, Tampil Teks dan Gambar)
A. Pengenalan dan Konfigurasi Pin
2.4″ TFT LCD Shield Arduino – TFT LCD atau Thin-Film Transistor Liquid Crystal Display adalah layar LCD yang terbuat dari sekumpulan transistor, dimana satu transistor akan mengontrol satu piksel.
Piksel adalah titik terkecil LCD yang mana ia mewakili satu blok warna. Ini adalah modul LCD 2.4″ TFT LCD Shield Arduino dengan format resolusi layar 320*240 piksel.
LCD ini mampu menampilkan tampilan warna RGB. Resolusi 320*240 artinya terdapat 76.800 piksel, yang tersusun secara vertikal 320 piksel dan horizontal 240 piksel. Piksel ini dibentuk oleh piksel kristal cair yang mana akan berubah cahaya ketika diberi tegangan listrik.
LCD ini juga dilengkapi dengan SD Card yang berguna untuk menyimpan atau menampilkan gambar yang ada di SD Card. Dilengkapi dengan fitur layar sentuh, LCD ini semakin cocok untuk digunakan sebagai interface pengganti tombol. Dengan menggunakan Arduino, anda bisa membuat projek yang banyak menggunakan LCD ini.
LCD yang dibahas pada tutorial ini adalah 2.4″ TFT LCD yang memiliki alamat/address dengan ID 0x2035. Dengan 2 IC HC245 sebagai Octal Bus Transceiver, LCD ini mampu melakukan buffer dan mengirimkan data dengan kecepatan tinggi.
Transceiver artinya IC ini mampu melakukan komunikasi dua arah, transmitter (mengirim) dan receiver (menerima). Semakin tinggi kecepatan maka semakin banyak data yang bisa di kirim. LCD TFT ini belum bisa berkomunikasi via SPI, jadi pin SPI yang tersedia hanya untuk SD Card saja. Untuk konfigurasi pin ditunjukkan seperti pada gambar berikut:
B. Cara Menampilkan Teks di TFT
1.Sistem koordinat LCD
2. Install Library
//-------------------// //hamboelektronik.com// //-------------------// #include <Adafruit_GFX.h> // Library yang berisikan fungsi-fungsi LCD dan OLED #include <MCUFRIEND_kbv.h> // Library yang berisikan konfigurasi hardware dari LCD MCUFRIEND_kbv tft; #include <FreeDefaultFonts.h> //Menggunakan Font Standar //definisikan warna #define BLACK 0x0000 #define RED 0xF800 #define GREEN 0x07E0 #define WHITE 0xFFFF #define GREY 0x8410 #define BLUE 0x001F #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 void setup(void) { uint16_t ID = tft.readID(); //membaca ID Hardware if (ID == 0xD3) ID = 0x9481; tft.begin(ID); //set pengaturan sesuai dengan ID yang didapat tft.setRotation(0); //0 untuk potrait dan 1 untuk landscape tft.fillScreen(BLACK); showmsgXY(80, 40, 1, NULL, "Selamat Datang"); //tampilkan pesan "Selamat Datang" showmsgXY(30, 80, 2, NULL, "Hambo Elektronik");//tampilkan pesan "Hambo Elektronik" } void loop(void) { } void showmsgXY(int x, int y, int sz, const GFXfont *f, const char *msg) //fungsi tampilan { tft.setFont(f); // Karena font adalah default, maka di tulis NULL tft.setCursor(x, y); // tetapkan kursor atau koordinat awal tulisan tft.setTextColor(GREEN); //tetapkan tulisan warna hijau tft.setTextSize(sz); //tetapkan ukuran font, disini contohnya adalah 1 dan 2px tft.print(msg); //tampilkan tulisan ke layar LCD }
3. Jenis Font
FreeMono12pt7b.h FreeSansBoldOblique12pt7b.h FreeMono18pt7b.h FreeSansBoldOblique18pt7b.h FreeMono24pt7b.h FreeSansBoldOblique24pt7b.h FreeMono9pt7b.h FreeSansBoldOblique9pt7b.h FreeMonoBold12pt7b.h FreeSansOblique12pt7b.h FreeMonoBold18pt7b.h FreeSansOblique18pt7b.h FreeMonoBold24pt7b.h FreeSansOblique24pt7b.h FreeMonoBold9pt7b.h FreeSansOblique9pt7b.h FreeMonoBoldOblique12pt7b.h FreeSerif12pt7b.h FreeMonoBoldOblique18pt7b.h FreeSerif18pt7b.h FreeMonoBoldOblique24pt7b.h FreeSerif24pt7b.h FreeMonoBoldOblique9pt7b.h FreeSerif9pt7b.h FreeMonoOblique12pt7b.h FreeSerifBold12pt7b.h FreeMonoOblique18pt7b.h FreeSerifBold18pt7b.h FreeMonoOblique24pt7b.h FreeSerifBold24pt7b.h FreeMonoOblique9pt7b.h FreeSerifBold9pt7b.h FreeSans12pt7b.h FreeSerifBoldItalic12pt7b.h FreeSans18pt7b.h FreeSerifBoldItalic18pt7b.h FreeSans24pt7b.h FreeSerifBoldItalic24pt7b.h FreeSans9pt7b.h FreeSerifBoldItalic9pt7b.h FreeSansBold12pt7b.h FreeSerifItalic12pt7b.h FreeSansBold18pt7b.h FreeSerifItalic18pt7b.h FreeSansBold24pt7b.h FreeSerifItalic24pt7b.h FreeSansBold9pt7b.h FreeSerifItalic9pt7b.h
//-------------------// //hamboelektronik.com// //-------------------// #include <Adafruit_GFX.h> // Library yang berisikan fungsi-fungsi LCD dan OLED #include <MCUFRIEND_kbv.h> // Library yang berisikan konfigurasi hardware dari LCD MCUFRIEND_kbv tft; #include <FreeDefaultFonts.h> #include <Fonts/FreeMono12pt7b.h> #include <Fonts/FreeSans12pt7b.h> #include <Fonts/FreeSerif12pt7b.h> //definisikan warna #define BLACK 0x0000 #define RED 0xF800 #define GREEN 0x07E0 #define WHITE 0xFFFF #define GREY 0x8410 #define BLUE 0x001F #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 void setup(void) { uint16_t ID = tft.readID(); //membaca ID Hardware if (ID == 0xD3) ID = 0x9481; tft.begin(ID); //set pengaturan sesuai dengan ID yang didapat tft.setRotation(0); //0 untuk potrait dan 1 untuk landscape tft.fillScreen(BLACK); showmsgXY(10, 10, 2, NULL, "Hambo Elektronik"); showmsgXY(10, 50, 1, &FreeMono12pt7b, "Hambo Elektronik"); showmsgXY(10, 80, 1, &FreeSans12pt7b, "Hambo Elektronik"); showmsgXY(10, 110, 1, &FreeSerif12pt7b, "Hambo Elektronik"); } void loop(void) { } void showmsgXY(int x, int y, int sz, const GFXfont *f, const char *msg) //fungsi tampilan { tft.setFont(f); tft.setCursor(x, y); tft.setTextColor(GREEN); tft.setTextSize(sz); tft.print(msg); }
C. Cara Menampilkan Gambar di TFT
2.4″ TFT LCD Shield Arduino Bitmap – Pada tutorial sebelumnya (menampilkan font) kita telah bisa menggunakan library GFX dari adafruit untuk menampilkan tulisan. Sekarang kita akan menampilkan bitmap atau gambar di LCD. Ada dua metode yang akan kita lakukan yaitu, membaca gambar dari memori arduino dan membaca gambar dari memori SD Card.
1. Tampilkan gambar dari SRAM
//-------------------// //hamboelektronik.com// //-------------------// #include "MCUFRIEND_kbv.h" MCUFRIEND_kbv tft; #define LOWFLASH (defined(__AVR_ATmega328P__) && defined(MCUFRIEND_KBV_H_)) #include "bitmap.h" //masukkan file bitmap.h //definisikan warna dengan kode warna #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define GREY 0x8410 #define ORANGE 0xE880 void setup() { Serial.begin(9600); uint16_t ID = tft.readID(); //akan membaca ID dari tipe LCD tft.begin(ID); int x = 5, y, w = 240, h = 320; //definisikan piksel yang akan digunakan const int SZ = w * h ; uint8_t sram[SZ]; tft.fillScreen(BLACK); y = 0; tft.drawRGBBitmap(x, y, doraemon, 100, 82); //tampilkan gambar di LCD } void loop(void) { }
2. Membaca Gambar Dari Memori Card
//-------------------// //hamboelektronik.com// //-------------------// #include <SPI.h> #include <SD.h> #include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> MCUFRIEND_kbv tft; #if defined(ESP32) #define SD_CS 5 #else #define SD_CS 10 #endif #define NAMEMATCH "doraemon" // doraemon.bmp #define PALETTEDEPTH 0 #define BMPIMAGEOFFSET 54 #define BUFFPIXEL 20 char namaBuffer[32] = "/"; //karakter "/" artinya root, atau halaman awal memori bukan folder //char namaBuffer[32] = "/namaFolder/"; //jika gambar berada didalam folder maka ditulis "/namaFolder/doraemon.bmp int bmpWidth, bmpHeight; // lebar dan tinggi gambar dalam satuan piksel uint8_t bmpDepth; uint32_t bmpImageoffset; // memulai data gambar pada file uint32_t rowSize; uint8_t sdbuffer[3 * BUFFPIXEL]; // piksel didalam buffer (R+G+B per piksel) uint16_t lcdbuffer[(1 << PALETTEDEPTH) + BUFFPIXEL], *palette = NULL; uint8_t bitmask, bitshift; boolean flip = true; // File gambar nanti akan di simpan dari baris bawah ke atas //Jika nilainya adalah "false" maka tampilan akan dimulai dari bawah ke atas gambar //Jika nilainya adalah "true" maka tampilan akan dimulai dari atas ke kebawah int w, h, row, col, lcdbufsiz = (1 << PALETTEDEPTH) + BUFFPIXEL, buffidx; uint32_t pos; boolean is565 = false; uint16_t bmpID; uint16_t n; // blok baca uint8_t ret; int pjgPath; char *nm = namaBuffer + pjgPath; uint32_t start; File root; File f; void setup() { uint16_t ID; ID = tft.readID(); tft.begin(ID); tft.setRotation(1); //Jadikan tampilan landscape, jika "0" maka akan potrait tft.fillScreen(0x001F); //tetapkan warna latar sebelum memuat gambar //cek apakah ada memori card bool ada = SD.begin(SD_CS); if (!ada) { //jika tidak ada Serial.print(F("SD tidak terdeteksi")); //beritahu melalui serial monitor while (1); } root = SD.open(namaBuffer); //root artinya buka pada halaman awal memori atau "/" pjgPath = strlen(namaBuffer); //menghitung panjang dari sebuah string dari namaBuffer } void loop() { f = root.openNextFile(); if (f != NULL) { #ifdef USE_SDFAT f.getName(nm, 32 - pjgPath); #else strcpy(nm, (char *)f.name()); #endif f.close(); strlwr(nm); if (strstr(nm, ".bmp") != NULL && strstr(nm, NAMEMATCH) != NULL) { Serial.print(namaBuffer); Serial.print(F(" - ")); tft.fillScreen(0); start = millis(); ret = showBMP(namaBuffer, 5, 5); delay(10000); } } else root.rewindDirectory(); } uint16_t read16(File& f) { uint16_t result; f.read((uint8_t*)&result, sizeof(result)); return result; } uint32_t read32(File& f) { uint32_t result; f.read((uint8_t*)&result, sizeof(result)); return result; } uint8_t showBMP(char *nm, int x, int y) { File bmpFile; if ((x >= tft.width()) || (y >= tft.height())) return 1; // matikan layar bmpFile = SD.open(nm); // Penguraian file BMP bmpID = read16(bmpFile); // BMP signature (void) read32(bmpFile); // Baca dan abaikan ukuran file (void) read32(bmpFile); // Baca dan abaikan byte pembuat bmpImageoffset = read32(bmpFile); // Mulai dari data gambar (void) read32(bmpFile); // Baca & abaikan ukuran header DIB bmpWidth = read32(bmpFile); bmpHeight = read32(bmpFile); n = read16(bmpFile); // bidang harus 1 bmpDepth = read16(bmpFile); // bit per pixel pos = read32(bmpFile); // format if (bmpID != 0x4D42) ret = 2; // ID yang buruk else if (n != 1) ret = 3; // terlalu banyak bidang else if (pos != 0 && pos != 3) ret = 4; // format: 0 = tidak terkompresi, 3 = 565 else if (bmpDepth < 16 && bmpDepth > PALETTEDEPTH) ret = 5; // palette else { bool first = true; is565 = (pos == 3); // Sudah dalam format 16-bit? // Baris BMP diisi (jika perlu) hingga batas 4-byte rowSize = (bmpWidth * bmpDepth / 8 + 3) & ~3; if (bmpHeight < 0) { // Jika negatif, gambar berada dalam urutan top-down. bmpHeight = -bmpHeight; flip = false; } w = bmpWidth; h = bmpHeight; if ((x + w) >= tft.width()) // Pangkas area yang akan dimuat w = tft.width() - x; if ((y + h) >= tft.height()) h = tft.height() - y; if (bmpDepth <= PALETTEDEPTH) { // Mode ini memiliki palet terpisah bmpFile.seek(BMPIMAGEOFFSET); // palet selalu @ 54 bitmask = 0xFF; if (bmpDepth < 8) bitmask >>= bmpDepth; bitshift = 8 - bmpDepth; n = 1 << bmpDepth; lcdbufsiz -= n; palette = lcdbuffer + lcdbufsiz; for (col = 0; col < n; col++) { pos = read32(bmpFile); // peta palet ke 5-6-5 palette[col] = ((pos & 0x0000F8) >> 3) | ((pos & 0x00FC00) >> 5) | ((pos & 0xF80000) >> 8); } } // Tetapkan jendela alamat TFT untuk memotong batas gambar tft.setAddrWindow(x, y, x + w - 1, y + h - 1); for (row = 0; row < h; row++) { // Untuk setiap garis pemindaian ... uint8_t r, g, b, *sdptr; int lcdidx, lcdleft; if (flip) pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize; else pos = bmpImageoffset + row * rowSize; if (bmpFile.position() != pos) { bmpFile.seek(pos); buffidx = sizeof(sdbuffer); // Paksa muat ulang buffer } for (col = 0; col < w; ) { //piksel dalam baris lcdleft = w - col; if (lcdleft > lcdbufsiz) lcdleft = lcdbufsiz; for (lcdidx = 0; lcdidx < lcdleft; lcdidx++) { // buffer sekaligus uint16_t color; // Waktu untuk membaca lebih banyak data piksel? if (buffidx >= sizeof(sdbuffer)) { // Indeed bmpFile.read(sdbuffer, sizeof(sdbuffer)); buffidx = 0; // Set index untuk pemulaian r = 0; } switch (bmpDepth) { // Konversi pixel dari BMP ke format TFT case 1: case 4: case 8: if (r == 0) b = sdbuffer[buffidx++], r = 8; color = palette[(b >> bitshift) & bitmask]; r -= bmpDepth; b <<= bmpDepth; break; case 24: b = sdbuffer[buffidx++]; g = sdbuffer[buffidx++]; r = sdbuffer[buffidx++]; color = tft.color565(r, g, b); break; case 16: b = sdbuffer[buffidx++]; r = sdbuffer[buffidx++]; if (is565) color = (r << 8) | (b); else color = (r << 9) | ((b & 0xE0) << 1) | (b & 0x1F); break; } lcdbuffer[lcdidx] = color; } tft.pushColors(lcdbuffer, lcdidx, first); first = false; col += lcdidx; } // berakhir kolom } // berakhir baris tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1); //kembalikan layar penuh ret = 0; } bmpFile.close(); return (ret); }
D. Cara Menggunakan Layar Sentuh TFT
#include <Adafruit_GFX.h> #include <MCUFRIEND_kbv.h> MCUFRIEND_kbv tft; #include <TouchScreen.h> #define MINPRESSURE 10 #define MAXPRESSURE 1000 const int XP=7,XM=A1,YP=A2,YM=6; const int TS_LEFT = 130, TS_RT = 910, TS_TOP = 100, TS_BOT = 905; TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); Adafruit_GFX_Button tombolBiruLaut, tombolMerah, tombolHijau, tombolKuning; int piksel_x, piksel_y; bool Touch_getXY(void) { TSPoint p = ts.getPoint(); pinMode(YP, OUTPUT); pinMode(XM, OUTPUT); digitalWrite(YP, HIGH); digitalWrite(XM, HIGH); bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE); if (pressed) { piksel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); piksel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height()); } return pressed; } //definisi warna menggunakan format RGB565 #define BLACK 0x0000 #define BLUE 0x001F #define NAVY_BLUE 0x16DD #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF void setup(void) { Serial.begin(9600); uint16_t ID = tft.readID(); tft.begin(ID); tft.setRotation(0); tft.fillScreen(BLACK); tombolBiruLaut.initButton(&tft, 60, 130, 80, 40, WHITE, NAVY_BLUE, BLACK, "1", 2); tombolMerah.initButton (&tft, 180, 130, 80, 40, WHITE, RED, BLACK, "2", 2); tombolKuning.initButton (&tft, 60, 200, 80, 40, WHITE, YELLOW, BLACK, "3", 2); tombolHijau.initButton (&tft, 180, 200, 80, 40, WHITE, GREEN, BLACK, "4", 2); tombolBiruLaut.drawButton(false); tombolMerah.drawButton(false); tombolKuning.drawButton(false); tombolHijau.drawButton(false); tft.fillRect(00, 0, 240, 80, WHITE); } void loop(void) { bool deteksi = Touch_getXY(); tombolBiruLaut.press(deteksi && tombolBiruLaut.contains(piksel_x, piksel_y)); tombolMerah.press (deteksi && tombolMerah.contains(piksel_x, piksel_y)); tombolKuning.press (deteksi && tombolKuning.contains(piksel_x, piksel_y)); tombolHijau.press (deteksi && tombolHijau.contains(piksel_x, piksel_y)); if (tombolBiruLaut.justReleased()) tombolBiruLaut.drawButton(); if (tombolMerah.justReleased()) tombolMerah.drawButton(); if (tombolKuning.justReleased()) tombolKuning.drawButton(); if (tombolHijau.justReleased()) tombolHijau.drawButton(); if (tombolBiruLaut.justPressed()) { tombolBiruLaut.drawButton(true); tft.fillRect(00, 0, 240, 80, NAVY_BLUE); } if (tombolMerah.justPressed()) { tombolMerah.drawButton(true); tft.fillRect(00, 0, 240, 80, RED); } if (tombolKuning.justPressed()) { tombolKuning.drawButton(true); tft.fillRect(00, 0, 240, 80, YELLOW); } if (tombolHijau.justPressed()) { tombolHijau.drawButton(true); tft.fillRect(00, 0, 240, 80, GREEN); } }
Hasil:
Posting Komentar untuk "Layar Sentuh TFT 2.4" Arduino dan Tampilkan Teks dan Gambar"