Komponen · 14 mnt baca

Panduan ILI9341 Arduino: Pengkabelan Layar TFT, Layar Sentuh, dan Gambar dari SD

Cara menghubungkan layar TFT ILI9341 ke Arduino: penurunan level ke 3,3 V di Uno, Adafruit GFX, layar sentuh XPT2046, BMP dari SD, TFT_eSPI di ESP32, dan solusi layar putih.

Rangkaian ILI9341 Arduino adalah cara termurah dan paling populer untuk menambahkan layar 240×320 piksel dengan 65 ribu warna ke proyekmu. Modul TFT 2,4 dan 2,8 inci dengan PCB merah ini terhubung lewat SPI hanya dengan beberapa kabel, dan versi sentuhnya juga membawa kontroler sentuh XPT2046 serta slot kartu microSD. Dengan satu modul saja kamu bisa menampilkan grafik berwarna, tombol sentuh, dan gambar yang dibaca dari kartu. Modul ini ideal untuk menu, dasbor, game, dan bingkai foto, ketika OLED atau LCD karakter sudah tidak cukup lagi.

Di panduan ini kamu akan belajar langkah demi langkah cara kerja modul ini, cara aman menghubungkan output 5 V Arduino Uno ke input 3,3 V layar, cara menggambar teks, bentuk, dan warna dengan library Adafruit_ILI9341 dan Adafruit GFX, cara membaca layar sentuh, dan cara menampilkan gambar BMP dari kartu SD. Setelah itu kita bahas menggambar jauh lebih cepat di ESP32 dengan TFT_eSPI, memakai MicroPython di Raspberry Pi Pico, dan semua penyebab masalah “layar putih” yang hampir semua orang alami setidaknya sekali.

Modul layar warna TFT ILI9341
Modul layar warna TFT ILI9341: 240×320 piksel, antarmuka SPI, dan 65 ribu warna. Versi sentuh juga punya chip XPT2046 dan slot microSD di board-nya.

Apa itu layar TFT ILI9341 dan bagaimana cara kerjanya?

ILI9341 adalah chip driver di balik kaca layar. Di dalamnya ada sekitar 172 KB memori tampilan (GRAM) yang menyimpan seluruh 240×320 piksel. Arduino mengirim perintah dan data warna ke memori ini lewat SPI, lalu chip menyegarkan gambar sendiri puluhan kali per detik. Karena itu gambar tidak perlu disimpan di RAM Arduino: bahkan Uno dengan RAM 2 KB bisa mengendalikan layar warna yang besar. Untuk menggambar sesuatu, kamu memilih sebuah jendela (x, y, lebar, tinggi) lebih dulu, lalu mengirim piksel jendela itu satu per satu secara berurutan. Pin DC memberi tahu chip apakah byte yang dikirim adalah perintah (LOW) atau data (HIGH). Warna biasanya dikirim dalam format RGB565, artinya 16 bit per piksel: 5 bit merah, 6 bit hijau, dan 5 bit biru. Cara kerja bus SPI secara detail bisa kamu baca di Apa Itu SPI?.

FiturNilai
Chip driverILI9341
Resolusi240×320 piksel (320×240 dalam mode lanskap)
Warna65.536 warna dengan RGB565 (chip mendukung 262 ribu)
Ukuran layar2,2", 2,4", 2,8", dan 3,2" (semuanya 240×320)
AntarmukaSPI 4 kabel: CS, DC, SCK, MOSI (MISO untuk membaca)
Catu daya (VCC)3,3–5 V (ada regulator 3,3 V di board)
Level logika3,3 V (tidak tahan 5 V)
Konsumsi dayaSekitar 0,3–0,6 W, sebagian besar untuk lampu latar
SentuhResistif, kontroler XPT2046 (di model sentuh)
Hardware tambahanSlot kartu microSD (pin SPI terpisah)

2,4 inci atau 2,8 inci? Modul SPI vs shield Uno

FiturModul SPI 2,4"Modul SPI 2,8"Shield Uno 2,4"
Resolusi240×320240×320240×320
KoneksiSPI, dengan kabel jumperSPI, dengan kabel jumperParalel 8-bit, dipasang di atas Uno
Pin yang dipakai5 untuk layar, 8–9 dengan sentuh dan SD5 untuk layar, 8–9 dengan sentuh dan SDHampir semua (D2–D9, A0–A4, D10–D13 untuk SD)
DriverILI9341ILI9341Bervariasi: ILI9341, ILI9325, ST7789, dan lainnya
LibraryAdafruit_ILI9341, TFT_eSPIAdafruit_ILI9341, TFT_eSPIMCUFRIEND_kbv
SentuhXPT2046 (SPI)XPT2046 (SPI)Analog 4 kabel (library TouchScreen)
ESP32 dan PicoCocokCocokDirancang untuk Uno dan Mega

Artikel ini membahas modul SPI, karena modul ini juga bisa dipakai dengan ESP32 dan Pico dan membiarkan sebagian besar pin Uno tetap bebas. Kedua modul SPI punya pin dan kode yang persis sama; layar 2,8 inci punya piksel sedikit lebih besar, jadi tombol sentuh lebih mudah ditekan. Jika layarmu langsung dipasang di atas Uno sebagai shield, library SPI tidak bisa mengendalikannya, dan hasilnya biasanya layar putih. Untuk shield seperti itu, instal library MCUFRIEND_kbv, baca ID driver dengan tft.readID() (0x9341 untuk ILI9341), lalu jalankan dengan tft.begin(ID). Untuk alternatif yang lebih kecil tapi lebih tajam, lihat layar TFT ST7789, dan untuk membandingkan semua pilihan, baca jenis-jenis layar Arduino.

Pinout ILI9341 dan tabel pengkabelan

Satu sisi modul punya header utama 14 pin: 9 pin pertama untuk layar dan 5 pin terakhir yang diawali T_ untuk sentuh. 4 pin di sisi seberangnya (SD_CS, SD_MOSI, SD_MISO, SD_SCK) menuju slot kartu. Ketiga perangkat bisa berbagi bus SPI yang sama (SCK, MOSI, MISO); hanya pin CS masing-masing yang harus terpisah. Tabel di bawah cocok dengan semua sketch di artikel ini; di Pico, sentuh dihubungkan ke bus SPI terpisah karena perbedaan kecepatan.

Pin modulArduino Uno (lewat level shifter)ESP32Raspberry Pi Pico
VCC5V3V33V3(OUT)
GNDGNDGNDGND
CSD10GPIO 15GP17
RESETD8GPIO 4GP21
DCD9GPIO 2GP20
SDI (MOSI)D11GPIO 23GP19
SCKD13GPIO 18GP18
LED3.3V3V33V3(OUT)
SDO (MISO)D12 (langsung)GPIO 19GP16
T_CLKD13GPIO 18GP10
T_CSD7GPIO 21GP13
T_DIND11GPIO 23GP11
T_DOD12 (langsung)GPIO 19GP12
T_IRQD2 (langsung)Tidak dihubungkanTidak dihubungkan
SD_CSD4GPIO 5Tidak dihubungkan
SD_MOSI / SD_MISO / SD_SCKD11 / D12 / D13GPIO 23 / 19 / 18Tidak dihubungkan
Pin VCC modul ILI9341 menerima 5 V, tetapi pin sinyalnya hanya untuk 3,3 V. Regulator di board hanya menurunkan catu daya; tidak ada penurun level di jalur CS, DC, RESET, SCK, dan MOSI. Menghubungkan output 5 V Uno secara langsung sering berujung pada layar putih dan kadang merusak chip secara permanen. Jumper J1 di bagian belakang berfungsi melewati regulator: solder hingga tertutup hanya jika kamu memberi daya VCC dari 3,3 V. Memberi 5 V ke VCC ketika J1 tertutup akan membakar layar.

Penurunan level ke 3,3 V di Arduino Uno

ESP32 dan Raspberry Pi Pico sudah bekerja di 3,3 V, jadi kamu bisa menghubungkan layar secara langsung. Di board 5 V seperti Uno, Nano, dan Mega, setiap jalur dari Arduino ke layar harus diturunkan ke 3,3 V: CS, DC, RESET, SCK, MOSI, dan jika kamu memakai sentuh dan SD, juga T_CLK, T_DIN, T_CS, SD_CS, SD_MOSI, dan SD_SCK. Jalur SDO, T_DO, SD_MISO, dan T_IRQ yang datang dari layar ke Arduino tidak butuh konverter: Uno membaca tegangan di atas 3 V sebagai HIGH, dan output 3,3 V memenuhi itu. Dalam praktiknya ada empat cara:

  • Chip buffer 74HC4050 (solusi paling rapi): chip ini diberi daya 3,3 V, menerima 5 V di input-nya, dan mengonversi 6 jalur dalam satu chip. Chip ini cepat dan bekerja tanpa masalah pada SPI 8 MHz. CD4050 yang lebih lama juga bisa, tapi lambat; jika gambar rusak, kamu perlu menurunkan kecepatan SPI. Layar saja butuh 5 jalur; dengan sentuh dan SD, kamu menambah T_CS dan SD_CS sehingga menjadi 7 jalur, jadi pakai chip kedua atau pembagi tegangan untuk jalur ketujuh.
  • Pembagi tegangan resistor: untuk setiap jalur, pasang 1 kΩ antara pin Arduino dan pin layar, serta 2 kΩ antara pin layar dan GND; hasilnya 5 V × 2 / 3 ≈ 3,3 V. Pasangan resistor lain bisa kamu hitung dengan kalkulator pembagi tegangan. Cara ini murah, tapi 10 resistor untuk 5 jalur membuat breadboard penuh sesak.
  • Modul level shifter siap pakai: modul 4 atau 8 kanal dengan MOSFET BSS138 mudah dirangkai, tapi resistor pull-up-nya melunakkan tepi sinyal pada kecepatan tinggi. Jika gambar rusak, turunkan SPI ke 4 MHz dengan tft.begin(4000000). Perbandingan metodenya ada di konverter level logika.
  • Metode yang harus dihindari: trik populer “resistor seri 10 kΩ di setiap jalur” membuang kelebihan tegangan ke dioda proteksi internal chip. Mungkin bekerja untuk sementara, tapi tidak andal dan bisa merusak layar dalam jangka panjang.

Langkah demi langkah: tes pertama dengan Adafruit_ILI9341

  1. Buka Library Manager di Arduino IDE, cari Adafruit ILI9341, lalu instal. Ketika ditanya soal dependensi, pilih Install all supaya Adafruit GFX dan Adafruit BusIO ikut terinstal. Jika ini library pertamamu, Cara Instal Library Arduino akan membantu.
  2. Untuk sentuh, instal juga library XPT2046_Touchscreen buatan Paul Stoffregen. Library SD sudah ikut bersama Arduino IDE.
  3. Hubungkan layar sesuai tabel di atas, lewat level shifter di Uno. Untuk tes pertama, pin sentuh dan SD boleh dibiarkan tidak terhubung.
  4. Upload sketch di bawah dan buka Serial Monitor di 9600 baud. Kamu seharusnya melihat teks dan bentuk di layar, serta kode diagnostik layar di Serial Monitor.
  5. Coba juga contoh bawaannya: File > Examples > Adafruit ILI9341 > graphicstest mengukur berapa mikrodetik yang dibutuhkan setiap operasi menggambar.
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}
FungsiKegunaannya
tft.begin(frekuensi)Menjalankan layar; tanpa frekuensi, memakai SPI 8 MHz di Uno dan 40 MHz di ESP32
tft.setRotation(0–3)Memilih orientasi: 0 dan 2 potret (240×320), 1 dan 3 lanskap (320×240)
tft.fillScreen(warna)Mewarnai seluruh layar dengan satu warna
tft.setTextColor(teks, latar)Mengatur warna teks; dengan warna latar, teks lama ditimpa dengan rapi
tft.setTextSize(n)Memperbesar teks n kali; ukuran 1 = karakter 6×8 piksel
tft.drawRect / fillRect(x, y, lebar, tinggi, warna)Garis tepi persegi panjang atau persegi panjang terisi
tft.fillRoundRect(x, y, lebar, tinggi, r, warna)Persegi panjang terisi dengan sudut membulat; ideal untuk tombol
tft.drawCircle / fillCircle(x, y, r, warna)Lingkaran atau lingkaran terisi
tft.color565(r, g, b)Mengubah nilai RGB 0–255 menjadi warna 16-bit
tft.readcommand8(perintah)Membaca register dari layar (MISO harus terhubung); untuk mencari masalah

Konstanta warna siap pakai (19 buah, seperti ILI9341_RED, ILI9341_NAVY, dan ILI9341_ORANGE) sudah ikut bersama library; untuk warnamu sendiri, pakai color565(). Fungsi ini menyusun 5 bit teratas merah, 6 bit teratas hijau, dan 5 bit teratas biru berdampingan: warna = (R >> 3) << 11 | (G >> 2) << 5 | (B >> 3). Untuk oranye (255, 165, 0), misalnya, 31 << 11 = 0xF800 dan 41 << 5 = 0x0520 digabung menjadi 0xFD20, yang persis sama dengan nilai ILI9341_ORANGE di library. Hijau mendapat satu bit tambahan karena mata manusia lebih peka terhadap hijau.

Menghapus angka yang berubah dengan fillScreen() lalu menggambarnya ulang setiap kali membuat layar berkedip; di Uno, mewarnai seluruh layar butuh setidaknya 0,15 detik pada SPI 8 MHz. Sebagai gantinya, pakai setTextColor(teks, latar) seperti di sketch, atau hapus hanya area kecil yang berubah dengan fillRect(). Menulis string tetap di dalam F("...") juga menghemat RAM 2 KB milik Uno; untuk masalah memori, lihat memori Arduino tidak cukup.

Membaca layar sentuh XPT2046

Di modul sentuh ada lapisan resistif tipis di atas kaca. Di titik yang ditekan jarimu atau stylus, dua lapisan konduktif saling bersentuhan; chip XPT2046 mengukur posisi X dan Y titik itu dengan ADC 12-bit sebagai nilai mentah dari 0 sampai 4095, dan juga memberikan nilai tekanan (Z). Library menganggap nilai Z di bawah 400 sebagai tidak ada sentuhan. Chip ini berada di bus SPI yang sama dengan layar, tetapi berkomunikasi dengan kecepatan lebih rendah, sekitar 2 MHz; library mengatur kecepatannya sendiri di setiap pembacaan. Pin T_IRQ menjadi LOW ketika layar disentuh, sehingga prosesor tidak perlu membaca dengan sia-sia. Sketch di bawah mengubah layar menjadi papan gambar kecil: kamu memilih warna dari kotak-kotak di bagian atas dan membersihkan layar dengan tombol “SIL” (bahasa Turki untuk “hapus”).

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}

Nilai mentah tidak tepat 0 dan 4095 di sudut-sudut layar; di kebanyakan modul, tepinya berada kira-kira di antara 200–400 dan 3700–3900. Untuk kalibrasi, buka Serial Monitor, sentuh sudut kiri atas dan kanan bawah dengan stylus, lalu masukkan nilai x dan y yang kamu lihat ke konstanta TS_MINX, TS_MAXX, TS_MINY, dan TS_MAXY. Jika titik muncul tercermin dari posisi jarimu, tukar nilai min dan max sumbu itu di map(); jika X dan Y tertukar sepenuhnya, coba nilai ts.setRotation() dari 0 sampai 3. Menu sungguhan bekerja dengan cara yang sama: kamu menggambar tombol dan memeriksa titik yang disentuh jatuh di persegi panjang mana. Lapisan resistif juga bekerja dengan jari, tapi ujung seperti stylus lebih akurat untuk tombol kecil.

Menampilkan gambar BMP dari kartu SD

Slot microSD di bagian belakang modul memungkinkanmu menyimpan logo, latar, dan foto di kartu lalu menampilkannya di layar. Untuk menyiapkan gambar, ubah ukuran foto menjadi 320×240 piksel dan simpan di Paint sebagai Bitmap 24-bit (.bmp). Karena library SD Arduino bekerja dengan nama file pendek, pakai nama paling banyak 8 karakter seperti RESIM.BMP dan format kartu sebagai FAT32. Detail tentang kartunya sendiri dan solusi error initialization failed ada di modul kartu SD. Ingat, slot ini juga 3,3 V: di Uno, jalur SD_CS, SD_MOSI, dan SD_SCK juga harus melewati level shifter.

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}

54 byte pertama file BMP adalah header: tanda tangan “BM”, posisi awal data piksel, lebar, tinggi, dan kedalaman warna disimpan di sana. Piksel disimpan dalam urutan biru, hijau, merah (BGR) dan biasanya dari bawah ke atas, dan setiap baris diisi hingga kelipatan 4 byte. Karena itu sketch melompat ke posisi yang tepat di file untuk setiap baris layar, membaca 20 piksel (60 byte) sekaligus, mengubahnya ke RGB565, lalu mengirimnya dengan drawRGBBitmap(). Bekerja dalam potongan kecil membuat semuanya muat di RAM Uno dan membuat kartu SD dan layar bisa bergantian memakai bus SPI yang sama. Waktu menggambar dicetak ke Serial Monitor; di Uno, gambar layar penuh muncul baris demi baris selama beberapa detik. Jika kamu ingin menampilkan file PNG atau JPEG dan menggambar jauh lebih cepat, pindahlah ke ESP32 dengan library TFT_eSPI dan TJpg_Decoder.

Menggambar cepat di ESP32 dengan TFT_eSPI

Board pengembangan ESP32
Berkat logika 3,3 V-nya, ESP32 terhubung langsung ke ILI9341 dan menjalankan SPI pada 40 MHz, sehingga menggambar berkali-kali lebih cepat daripada Uno.

ESP32 bekerja di 3,3 V dan bisa menjalankan SPI hingga 40 MHz, jadi kamu tidak butuh level shifter, dan secara teori mengisi seluruh layar hanya butuh sekitar 31 milidetik. Untuk benar-benar memanfaatkan kecepatan itu, library TFT_eSPI buatan Bodmer adalah pilihan yang umum. Library ini mengakses hardware SPI ESP32 secara langsung dan mendukung font anti-aliasing (halus) dan, yang paling penting, buffer di luar layar yang disebut sprite. Kamu bisa menggambar sebanyak apa pun ke sprite di RAM lalu mengirim hasilnya ke layar sekaligus, sehingga grafik yang berubah cepat pun tidak berkedip. Yang membuat TFT_eSPI berbeda: pin tidak diatur di sketch-mu, melainkan di file User_Setup.h di dalam folder library. Buka file itu, jadikan komentar baris pin ESP8266 (NodeMCU) yang aktif secara default, lalu aktifkan baris-baris ini:

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}

Sketch ini menggambar nilai potensiometer di GPIO 34 sebagai grafik bergulir dan menampilkan jumlah frame per detik (FPS) di sudut sprite. Sprite 300×100 piksel dengan warna 16-bit memakai 60 KB RAM; itu sekitar 30 kali seluruh memori Uno, tapi tidak masalah bagi ESP32. Untuk sentuh, pin T_CLK, T_DIN, dan T_DO bergabung dengan jalur SCK, MOSI, dan MISO layar, dan hanya T_CS (GPIO 21) yang tetap terpisah. Untuk mendapatkan nilai kalibrasimu sendiri, jalankan contoh Generic > Touch_calibrate dari TFT_eSPI sekali, sentuh panah di sudut yang muncul, lalu salin 5 angka yang dicetak di Serial Monitor ke array calData. Baris siap pakai Setup42_ILI9341_ESP32.h di User_Setup_Select.h memilih pin layar yang sama, tapi baris TOUCH_CS harus kamu tambahkan sendiri. Jika kamu baru mengenal ESP32, baca dulu Apa Itu ESP32?.

Ketika kamu memperbarui TFT_eSPI dari Arduino IDE, folder library ditulis ulang dan pengaturanmu di User_Setup.h hilang; jika layar yang kemarin berfungsi hari ini tetap putih, di sinilah tempat pertama yang perlu dicek, jadi simpan cadangan file pengaturanmu. Jika merah dan biru tertukar, aktifkan TFT_RGB_ORDER TFT_BGR; jika warnanya tampak seperti negatif foto, aktifkan TFT_INVERSION_ON; beberapa panel bekerja lebih baik dengan ILI9341_2_DRIVER. TFT_eSPI 2.5.43 bisa crash dan reboot ketika startup di beberapa board dengan paket board esp32 versi 3.x; jika itu terjadi, kembali ke paket esp32 versi 2.0.x di Boards Manager.

ILI9341 dengan Raspberry Pi Pico dan MicroPython

Pico juga board 3,3 V, jadi layar terhubung langsung. Driver MicroPython yang paling banyak dipakai adalah pasangan ili9341.py dan xpt2046.py dari repositori micropython-ili9341 milik rdagger; cukup salin kedua file itu ke Pico dengan Thonny. Di kode di bawah, layar berada di SPI0 pada 40 MHz dan kontroler sentuh di bus SPI1 terpisah pada 1 MHz, jadi perbedaan kecepatan antara kedua chip tidak jadi masalah. Kode ini menggambar teks dan bentuk, lalu menaruh titik kuning di mana pun kamu menyentuh, sehingga menjadi papan gambar sederhana. Jika kamu baru pertama kali memakai Pico dan Thonny, mulailah dengan Apa Itu Raspberry Pi Pico?.

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)

Dalam mode potret (rotation=0), lebarnya 240 dan tingginya 320; untuk memakai layar dalam mode lanskap, berikan width=320 dan height=240 bersama rotation=90. Kalibrasi default driver sentuh (x_min=100, x_max=1962) mungkin tidak cocok untuk setiap modul; jika titiknya meleset, cetak nilai raw_touch() dan berikan x_min, x_max, y_min, dan y_max milikmu sendiri ke Touch(). Untuk menampilkan gambar, fungsi draw_image() milik driver membaca file .raw yang sudah dikonversi ke RGB565; skrip utils/img2rgb565.py di repositori melakukan konversi itu di komputermu.

Masalah layar putih dan cara mengatasinya

Masalah ILI9341 yang paling terkenal adalah layar yang tetap putih sepenuhnya padahal lampu latarnya menyala. Layar putih sebenarnya adalah petunjuk: daya dan lampu latar bekerja, tapi chip driver tidak pernah diinisialisasi. Ketika panel tidak menerima perintah apa pun, piksel meloloskan cahaya dan layar tampak putih. Jadi masalahnya hampir selalu di komunikasi. Periksa tabel di bawah dari atas ke bawah:

GejalaKemungkinan penyebabSolusi
Layar putih, dihubungkan langsung ke UnoSinyal 5 V, tanpa level shifterPakai 74HC4050 atau pembagi tegangan; ganti modul jika chip-nya rusak
Layar putih, kabel sudah terhubungCS dan DC tertukar, atau nomor pin di kode tidak cocok dengan pengkabelanBandingkan definisi TFT_CS, TFT_DC, dan TFT_RST dengan tabel satu per satu
Layar putih, RESET mengambangRESET tidak terhubung atau di pin yang salahHubungkan RESET ke pin di kode atau ke 3,3 V; jangan pernah biarkan mengambang
Layar putih di ESP32 (TFT_eSPI)User_Setup.h belum diedit atau terhapus oleh pembaruanNonaktifkan baris ESP8266, lalu tulis ulang pin ESP32 dan ILI9341_DRIVER
Kadang layar putih, gambar bergeser atau kacauKabel jumper panjang, SPI terlalu cepat, kontak breadboard longgarJaga kabel di bawah 10–15 cm; turunkan SPI ke 20–27 MHz, atau 4 MHz di Uno
Layar putih hanya ketika sentuh atau SD terpasangPin CS perangkat lain mengambang dan memblokir busAtur setiap pin CS yang tidak dipakai sebagai OUTPUT dan tulis HIGH di kodemu
Tidak bekerja dengan kode apa punLayarnya bukan ILI9341 (ST7789, ILI9488) atau berupa shield paralelBaca label di bagian belakang; layar 3,5 inci 320×480 adalah ILI9488, shield butuh MCUFRIEND_kbv
Layar putih, lampu latar berkedipDaya tidak cukupBeri daya VCC dari 5 V dan coba kabel USB serta catu daya lain
Untuk mempersempit sumber masalah, pakai baris diagnostik di sketch pertama. Jika Serial Monitor menampilkan Power Mode: 0x94 dan Self Diagnostic: 0xC0, layar menerima perintah dan masalahnya ada di software (rotasi, warna, atau kode menggambar). Jika nilainya 0x0 atau 0xFF, Arduino tidak bisa berkomunikasi dengan layar: periksa kabel, level shifter, dan pin CS/DC. Pembacaan ini hanya bekerja jika jalur SDO (MISO) terhubung.

Kesalahan umum lainnya

  • Warna salah: jika merah tampil sebagai biru, panel memakai urutan BGR; ubah pengaturan TFT_RGB_ORDER di TFT_eSPI. Jika warnanya tampak seperti negatif foto, coba tft.invertDisplay(true).
  • Gambar terbalik atau tercermin: ubah nilai setRotation() antara 0 dan 3, lalu sesuaikan sumbu sentuh agar cocok.
  • Layar bekerja tapi sentuh atau SD tidak: pastikan T_CS dan SD_CS cocok dengan pin di kodemu. Di beberapa modul, output SDO layar tidak melepaskan bus; dalam kasus itu, coba lepaskan pin SDO layar, dan hanya pembacaan diagnostik yang akan berhenti bekerja.
  • BMP tidak tampil: kartunya bukan FAT32, nama file lebih dari 8 karakter, atau gambarnya bukan 24-bit. Jangan lupa memilih 24-bit di Paint; BMP 16-bit dan 32-bit tidak digambar oleh sketch ini.
  • Karakter khusus hilang: font GFX default tidak punya huruf beraksen seperti é atau ñ. Di TFT_eSPI kamu bisa membuat smooth font sendiri, atau memakai font GFX yang memuat karakter yang kamu butuhkan.
  • Layar lambat: penyegaran layar penuh di Uno butuh setidaknya 0,15 detik. Untuk animasi dan game, pindah ke ESP32 atau Pico dan gambar ulang hanya area yang berubah.
  • Modul menjadi panas: mungkin ada 5 V di VCC ketika jumper J1 tertutup, atau VCC dan GND terbalik; segera putuskan dayanya.

Ide proyek ILI9341

  • Panel rumah pintar sentuh: kendalikan lampu dan relay dengan tombol besar di layar; untuk ide, lihat proyek rumah pintar Arduino.
  • Layar cuaca berwarna: tampilkan cuaca yang kamu ambil dari internet dengan ESP32 memakai ikon dan angka besar (stasiun cuaca ESP32).
  • Dasbor sensor: gambar suhu, kelembapan, dan tekanan dari BME280 sebagai jarum pengukur dengan grafik 24 jam terakhir.
  • Konsol game retro: mainkan Snake, Pong, atau Tetris dalam warna; tambahkan modul joystick untuk kendali dan lihat proyek game Arduino untuk ide.
  • Bingkai foto digital: tampilkan gambar BMP di kartu SD bergantian setiap beberapa detik.
  • Osiloskop mini: gambar nilai analogRead sebagai bentuk gelombang yang mulus dengan sprite di ESP32.
  • Kunci keypad sentuh: gambar papan angka di layar dan buka relay atau servo ketika kode yang benar dimasukkan.

ILI9341 adalah cara paling terjangkau untuk memberi proyekmu antarmuka sentuh berwarna: mulailah dengan Uno untuk mempelajari fungsi menggambar dasar, lalu pindah ke ESP32 dengan TFT_eSPI ketika kamu butuh kecepatan dan animasi yang mulus. Jika kamu lebih suka mulai dengan layar yang lebih kecil, layar OLED (SSD1306) adalah titik awal yang bagus. Di aplikasi BlueGrays kamu akan menemukan proyek layar cuaca ESP32, pencatat suhu, sensor parkir, dan game berbasis layar, lengkap dengan skema rangkaian dan kode langkah demi langkah.

Pertanyaan umum

Apakah layar ILI9341 bisa bekerja dengan 5 V?

Pin VCC modul menerima 3,3–5 V karena ada regulator 3,3 V di board. Namun, pin sinyal seperti CS, DC, SCK, dan MOSI hanya untuk 3,3 V. Ketika kamu memakainya dengan Arduino Uno, pasang level shifter seperti 74HC4050 atau pembagi tegangan di jalur-jalur itu.

Kenapa ILI9341-ku hanya menampilkan layar putih?

Layar putih berarti lampu latar menyala tapi chip driver tidak pernah diinisialisasi. Penyebab paling umum adalah pengkabelan CS, DC, atau RESET yang salah, tidak ada level shifter di Uno, User_Setup.h di TFT_eSPI yang belum diedit, dan layar yang sebenarnya bukan ILI9341.

Library mana yang sebaiknya kupakai untuk ILI9341?

Untuk Arduino Uno, Nano, dan Mega, Adafruit_ILI9341 dengan Adafruit GFX adalah pilihan termudah. Di board ESP32, ESP8266, dan RP2040, TFT_eSPI yang jauh lebih cepat lebih disukai. Shield paralel 2,4 inci yang dipasang di atas Uno justru butuh MCUFRIEND_kbv.

Bagaimana cara mengalibrasi layar sentuh ILI9341?

Kontroler sentuh XPT2046 mengembalikan nilai mentah dari 0 sampai 4095. Catat nilai terkecil dan terbesar yang kamu lihat di Serial Monitor ketika menyentuh sudut-sudut layar, lalu ubah menjadi koordinat layar dengan map(). Jika kamu memakai TFT_eSPI, contoh Touch_calibrate melakukannya untukmu dan mencetak array kalibrasi siap pakai.

Apa bedanya ILI9341 2,4 inci dan 2,8 inci?

Keduanya punya resolusi 240×320 piksel serta memakai pin dan kode yang sama. Layar 2,8 inci punya piksel sedikit lebih besar, jadi teks lebih mudah dibaca dan tombol sentuh lebih mudah ditekan. Modul 2,4 inci muat di casing yang lebih kecil.

Bisakah aku memakai ILI9341 dengan Arduino Nano?

Bisa. Pin SPI Nano sama dengan Uno: D13 SCK, D11 MOSI, dan D12 MISO. Nano juga memakai logika 5 V, jadi kamu butuh level shifter. RAM 2 KB-nya cukup untuk mengendalikan layar, tapi tidak untuk menyimpan gambar besar, jadi kamu harus membaca gambar dari kartu SD dalam potongan kecil.

Lihat semua proyek
HTTPClient + API Cuaca ESP32 (dengan Layar OLED SSD1306)
#134Mahir
Premium

HTTPClient + API Cuaca ESP32 (dengan Layar OLED SSD1306)

Di proyek ini, kita memakai ESP32 untuk melakukan panggilan REST API ke API cuaca (wttr.in) lewat internet dengan HTTPClient.h. Berbeda dengan versi LCD I2C sebelumnya, di sini kita memakai layar OLED SSD1306 (128×64), yang memungkinkan font besar, ikon vektor, dan tampilan visual yang kaya di satu layar. Tujuh ikon vektor untuk kondisi cuaca (cerah, berawan sebagian, berawan, hujan, salju, badai, berkabut) digambar ketika program berjalan (tanpa file bitmap).

4.3(10)
19
Pencatat Data Suhu ESP32 (DHT22 + RTC DS1307 + microSD + OLED)
#144Mahir
Premium

Pencatat Data Suhu ESP32 (DHT22 + RTC DS1307 + microSD + OLED)

Buat pencatat suhu bercap waktu dengan ESP32! Baca suhu/kelembapan DHT22 setiap menit, ambil waktu sebenarnya dari RTC DS1307, dan catat ke kartu microSD sebagai CSV. OLED menampilkan suhu langsung (font besar), kelembapan, cap waktu, dan penghitung catatan. File /temp_log.csv bisa dibuka di Excel, Google Sheets, atau Python pandas; cocok untuk rumah kaca, suhu kamar, data laboratorium, penyimpanan makanan, atau sarang lebah.

4.7(7)
12
Lampu Pencampur Warna ESP32 (3 Potensiometer + LED RGB + OLED)
#138Mahir
Premium

Lampu Pencampur Warna ESP32 (3 Potensiometer + LED RGB + OLED)

Lampu pencampur warna pintar: campur warna apa pun dengan memutar tiga potensiometer di ESP32! Ketika potensiometer merah, hijau, dan biru diputar, LED RGB katoda bersama berubah warna secara real-time. OLED SSD1306 menampilkan nilai setiap warna dalam rentang 0–255, bar pengisi, dan kode warna web HEX (seperti #FF8040). Studio warna mini yang mengajarkan teori warna RGB, pembacaan ADC, pengaturan kecerahan dengan PWM, dan desain layar I2C sekaligus.

4.7(6)
10
Sensor Parkir ESP32 (HC-SR04 + Bar 5 LED + Buzzer + OLED)
#142Mahir
Premium

Sensor Parkir ESP32 (HC-SR04 + Bar 5 LED + Buzzer + OLED)

Versi ESP32 dari sensor parkir mobil! Kita memakai sensor ultrasonik HC-SR04 untuk mengukur jarak ke benda di depannya. Semakin dekat jaraknya, bar 5 LED semakin penuh (hijau → kuning → merah) dan jeda bunyi bip buzzer semakin pendek. Ketika benda sudah sangat dekat (di bawah 10 cm), alarm berbunyi terus dan semua LED menyala. Layar OLED SSD1306 menampilkan jarak terkini dalam cm dengan font besar, pesan status (STOP / CAUTION / CLOSE / STOP! / DANGER), dan simulasi bar jarak.

0.0(0)
14
Game Bola Pemukul - SSD1306
#86Menengah
Premium

Game Bola Pemukul - SSD1306

Satu bola, dua pemukul, dan kamu: kamu bermain tenis meja, salah satu video game paling awal, di layar OLED kecil. Dua tombol menggerakkan pemukulmu di kanan ke atas dan ke bawah, sementara komputer m

4.5(47)
65
OLED T-Rex Run: Game Dinosaurus Arduino
#87Mahir
Premium

OLED T-Rex Run: Game Dinosaurus Arduino

Game dinosaurus yang muncul ketika internetmu putus, sekarang ada di mejamu: dinosaurus berlari di layar OLED kecil, kaktus datang menghampiri, dan kamu melompat dengan satu tombol. Skormu naik secara

4.7(33)
53
Layar LCD I2C ESP32 (16x2)
#119Menengah
Premium

Layar LCD I2C ESP32 (16x2)

Di proyek ini, kita menampilkan teks dengan menyambungkan layar LCD karakter 16x2 ke ESP32 lewat protokol I2C. Berkat I2C, kita bisa mengendalikan layar hanya dengan dua pin data (SDA dan SCL), sehingga tidak perlu memboroskan 6+ pin seperti pada sambungan paralel klasik. Kode mencetak pesan tetap di baris pertama dan penghitung yang naik setiap detik di baris kedua. Selain itu, kita menjalankan pemindai I2C di awal untuk mencetak alamat layar ke Serial Monitor (biasanya 0x27).

4.9(23)
40
Game Lari LCD Arduino
#98Menengah
Premium

Game Lari LCD Arduino

Game lari tanpa akhir yang bergulir ke samping di layar LCD karakter 16x2. Sang jagoan berlari otomatis, dan pemain melompati rintangan dengan menekan tombol. Rintangan acak muncul di baris atas dan bawah. Buzzer pasif memainkan melodi pembuka, suara lompat, suara perayaan 50 poin, dan melodi akhir game. Layar pembuka "BlueGrays - Arduino Projects" tampil ketika mulai. Skor langsung diperbarui di pojok kanan atas layar.

4.6(32)
55