Sadece veri göstermek yetmez; bazen kullanıcıya ayar yaptırmak, mod değiştirmek veya bir işlemi başlatmak istersiniz. İşte burada devreye "Menü Algoritmaları" girer. Bu projede 3 butonla kontrol edilen profesyonel bir arayüz yapacağız.
1. Gerekli Malzemeler ve Bağlantı
LCD ekranı I2C ile (A4, A5), butonları ise dijital pinlere bağlayacağız. Breadboard karmaşasını önlemek için butonlarda harici direnç kullanmayacağız (Dahili PULLUP kullanacağız).
🔌 Pin Bağlantıları
- LCD I2C: SDA->A4, SCL->A5
- Yukarı Butonu: Pin 2 -> GND
- Aşağı Butonu: Pin 3 -> GND
- Seç (Enter) Butonu: Pin 4 -> GND
Navigasyon Sistemi
2. Menü Nasıl Çalışır? (İmleç Mantığı)
Menü sistemi aslında bir "Sayaç"tır. Aşağı bastıkça sayacı artırırız, yukarı bastıkça azaltırız. Sayacın değerine göre ekrana farklı yazılar yazarız.
3. Yazılım (State Machine)
Bu kodda 3 sayfalık bir menü oluşturacağız. Butonlara basıldığında sadece sayfa değişkenini değiştirip, menuGuncelle() fonksiyonunu çağıracağız.
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // Buton Pinleri const int btnYukari = 2; const int btnAsagi = 3; const int btnSec = 4; // Menü Değişkenleri int sayfa = 1; // Hangi menüdeyiz? int toplamSayfa = 3; void setup() { // Butonları INPUT_PULLUP yapıyoruz (Direnç gerekmez) // DİKKAT: Basınca LOW (0), bırakınca HIGH (1) okunur. pinMode(btnYukari, INPUT_PULLUP); pinMode(btnAsagi, INPUT_PULLUP); pinMode(btnSec, INPUT_PULLUP); lcd.init(); lcd.backlight(); menuGuncelle(); // İlk açılışta menüyü çiz } void loop() { // --- AŞAĞI BUTONU --- if (digitalRead(btnAsagi) == LOW) { if (sayfa < toplamSayfa) { sayfa++; } else { sayfa = 1; // Başa dön } menuGuncelle(); delay(200); // Buton arkı (Debounce) için bekleme } // --- YUKARI BUTONU --- if (digitalRead(btnYukari) == LOW) { if (sayfa > 1) { sayfa--; } else { sayfa = toplamSayfa; // Sona git } menuGuncelle(); delay(200); } // --- SEÇ BUTONU --- if (digitalRead(btnSec) == LOW) { aksiyonYap(); delay(200); } } // Ekranı sadece sayfa değişince temizleyip yazar void menuGuncelle() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("MENU SECIMI:"); lcd.setCursor(0, 1); if (sayfa == 1) { lcd.print("> 1. LED Yak"); } else if (sayfa == 2) { lcd.print("> 2. LED Sondur"); } else if (sayfa == 3) { lcd.print("> 3. Bilgi"); } } // Seç tuşuna basılınca ne olacak? void aksiyonYap() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("ISLEM YAPILIYOR"); lcd.setCursor(0, 1); if (sayfa == 1) { lcd.print("LED Yandi!"); // digitalWrite(13, HIGH); kodu buraya } else if (sayfa == 2) { lcd.print("LED Sondu!"); } else if (sayfa == 3) { lcd.print("Ver: v1.0"); } delay(1500); // Mesajı göster ve bekle menuGuncelle(); // Menüye geri dön }
4. Ekran Neden Titriyor? (Flickering)
Sorun: Birçok kişi menuGuncelle() fonksiyonunu doğrudan loop() içine yazar. Bu durumda Arduino saniyede binlerce kez ekranı silip (lcd.clear) tekrar yazar. Bu da ekranın titremesine ve silik görünmesine yol açar.
Çözüm: Kodda dikkat ettiyseniz menuGuncelle() sadece butonlara basıldığında çağırılıyor. Butona basılmadığı sürece ekran yenilenmez ve sabit kalır.
💡 Geliştirme Önerisi
> (Büyüktür) işaretini imleç olarak kullandık. Menüyü daha profesyonel yapmak için 2 satırı aynı anda gösterip, imleci yukarı aşağı kaydırabilirsiniz.