Rehber 16x2 LCD ile menü yapımı - Arduino

157134

Kilopat
Katılım
22 Şubat 2017
Mesajlar
1.635
Makaleler
3
Çözümler
5
Bugünkü rehberimizde sizlere LCD ekran ile menü yapımı, menüler arasında gezme ve menülere yerleştirdiğimiz değişkenleri kontrol etmeyi göstereceğim.

malzemeler:
  • 16x2 LCD ekran.
  • Karakter LCD I2C/IIC dönüştürücü kartı.
  • 4 adet buton.
  • 5 adet 220/330 ohm direnç.
  • 1 adet kırmızı LED.
  • Jumper kablolar.
İlk olarak bağlantılarımızı yapıyoruz.

LCD_bb.png


İlk kez fritzing kullandım, çizim kötüyse özür dilerim. 😀

önemli not: ı2C dönüştürücüde bulunan sda ve scl pinlerini sırasıyla A4 ve A5 pinlerine bağladığımı görüyoruz. Fakat bu kullandığınız Arduino'ya göre değişen bir şey. Eğer elinizdeki Arduino klon model ise üzerlerinde halihazırda sda ve scl pinlerinin olduğunu göreceksiniz. Bağlantıları A4 ve A5 pinleri yerine sda ve scl yazılı pinlere yapın. Eğer elinizdeki model orijinalse yukarıdaki gibi A4 ve A5 pinine bağlayın. Diğer orijinal Arduino modellerinde sda ve scl pinlerinin nerede olduğunu görmek için aşağıdaki bağlantıyı kullanabilirsiniz.

Aşağıdaki resimlerde de görebileceğiniz gibi klon Arduino'da sda ve scl pinleri varken orijinal Arduino'da bulunmuyor.
Klon Arduino:

Klon.jpg


Orijinal Arduino:

orjinal-arduino-uno-r3-yeni-versiyon-27092-47-B.jpg


Breadbordumuza 4 adet butonu sırasıyla yerleştiriyoruz. Ben butonları soldan sağa sırasıyla aşağı, yukarı, azalt, arttır olarak kullandım. Bağlantıları da buna göre anlatacağım.

IMG_20210121_164124.jpg


Mavi ile yazılmış rakamlar pinleri, kırmızı ile yazılmışlarda +5V'yi belirtiyor. Ayrıca altlarına da ne işe yaradıklarını yazdım. Öncelikle bütün butonların sağ bacağına +5v bağlıyoruz. Sol bacaklarına ise hangi pine atamak istiyorsak onu bağlıyoruz. Resim de zaten gerekli pinler mavi renk ile yazıyor. Son olarak butonun sol bacağının olduğu dikey sıraya butonun bir bacağına yerleştirip diğer bacağını gnd hattına bağlıyoruz. Bu sisteme pull down buton ismi veriliyor. Eğer bilmiyorsanız aşağıdaki yazıyı okuyabilirsiniz.

Son olarak LED bağlantımızı yapıyoruz.

IMG_20210121_170912.jpg


Kırmızı LED'i herhangi bir yere yerleştiriyoruz. LED'in uzun (+) bacağına bir direnç çekiyoruz. Direncin diğer ucuna LED'i yakmak için güç alacağımız sinyal pinini yerleştiriyoruz. Bu pinizimizde 6'ya denk geliyor. Son olarak LED'in kısa (-) bacağını gnd pinine bağlıyoruz.

Bağlantı kısmımız bitti. Şimdi kodlama kısmına geçiyoruz.

Arduino uygulaması üzerinden araçlar>>kütüphaneleri yönet... kısmına geliyoruz. Arama kısmına "liquidcrystal ı2c" yazıp, aşağıdaki fotoğrafta gözüken kütüphanenin son sürümünü indiriyoruz.

I2c.PNG


Artık kod kısmına gelebiliriz.

kod1.PNG


C++:
#include <LiquidCrystal_I2C.h>

Kütüphanemizi tanımlıyoruz.

C++:
LiquidCrystal_I2C lcd(0x27, 16, 2);

Burada LCD ekranımızı tanımlıyoruz. İlk yazdığımız değişken arabirim adresidir. Eğer bilmiyorsanız aşağıdaki adrese gidip nasıl öğrenildiğine bakabilirsiniz.

2. ve 3. değişken de LCD ekranımızın kaç satır ve sütuna sahip olduğunu belirtiyoruz. Benimki 16x2 olduğu için bu şekilde belirttim.

C++:
#define arttir 2.
#define azalt 3.
#define yukari 4.
#define asagi 5.
#define led 6

Butonlara ve LED'e atadığımız pinleri tanımlıyoruz.

C++:
int menu = 0;
int imlec = 0;
int sure = 0;
int cursor = 0;
int blink = 0;
int leddurum = 0;

Buradaki "menu" değişkenini kaçıncı menüde olduğumuzu tutmak için, "imlec" değişkenini imlecimizin kaçıncı satırda olduğunu tutmak için, "sure" değişkenini butonun basılı tutulma süresini ölçmek için (yeri geldiğinde anlatacağım), "cursor", "blink" ve "leddurum" değişkenini açık mı kapalı mı durumunu tutmak için tanımladım.

C++:
byte ok[8] = {
B00000,
B00100,
B00010,
B00001,
B00010,
B00100,
B00000,
B00000.
};

Bu kısımda kullandığım imlecin şeklini yaptım. Mantığı ise şöyle.

black-box.png


Burada yatay olarak dizilmiş 16 adet dikdörtgene dikkat edin. Bunlar bizim yazımı oluşturan hücreler. Dikkat ederseniz 1 dikdörtgende 5 yatay 8 dikey olmaz üzere toplam 40 adet hücre var. Biz bu hücrelerden yakmak istediğimiz hücrelere "1", yakmak istemediğimiz hücerelere "0" vererek istediğimiz şekli yaratacağız. Bunun için ilk olarak değişkenimizi tanımlıyoruz. 8 adet satırımız olduğu byte ok[8] şeklinde değişkeni tanımlıyoruz. B00000, burada dikkat ettiyseniz B'den sonra 5 adet rakam var. Bu her bir satırdaki yatay hücre sayısına denk geliyor. Burada sırasıyla yakmak istediniz hücrelere 1, yakmak istemediklerinize 0 vererek şeklinizi oluşturun. Eğer uğraşmak istemezseniz aşağıdaki siteden otomatik oluşturabilirsiniz.


kod2.PNG


kod3.PNG


kod4.PNG


kod5.PNG


Setup kısmına geçmeden önce tanımladığımız fonksiyonu açıklamak istedim çünkü neredeyse çoğu işlem buradan dönüyor.

C++:
int menuac(int menu, int imlec, int cursor, int blink, int leddurum) {

switch (menu)

Bu kısımda" menuac" isimli bir fonksiyon oluşturup, içine tanımladığımız değişkenleri atıyoruz. Ardından bir Switch kalıbı oluşturarak "menu" değişkenimizin değerine göre istediğimiz menüyü açacağız.

C++:
case 1:

if (cursor == false) {

if (blink == false) {

lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Cursor = Kapali");
lcd.setCursor(1,1);
lcd.print("Blink = Kapali");
}
else {

lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Cursor = Kapali");
lcd.setCursor(1,1);
lcd.print("Blink = Acik");
}
}
else {

if (blink == false) {

lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Cursor = Acik");
lcd.setCursor(1,1);
lcd.print("Blink = Kapali");
}
else {

lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Cursor = Acik");
lcd.setCursor(1,1);
lcd.print("Blink = Acik");
}
break;

İlk durumumuzu tanımlayarak başlıyoruz. Burada "blink" ve "cursor" değişkenlerinin durumuna göre çalışması için bir iç içe if döngüsü hazırladım. Olasılık dersi alanlar bilir. İki farklı değişkenimiz var ve bu değişkenler iki farklı değer alabiliyor. Bunlar;
Blink = false.
Cursor= false.
Blink = false.
Cursor = true.
Blink = true.
Cursor = false.
Blink = true.
Cursor = true olmak üzere 2*2'den toplam 4 farklı durumumuz var. İlk if döngüsünde Cursor'ın doğruluk durumunu kontrol ediyoruz. Ardından bir if döngüsü daha yazıyoruz ve Blink'in doğruluk durumunu kontrol ediyoruz. Başlangıçta kapalı olacağı için ben ilk başta false durumunu kontrol etmek istedim. İki durumu kontrol ettikten sonra gelen ilk süslü parantezde de yapmak istediklerimi yazdım.

C++:
lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Cursor = Kapali");
lcd.setCursor(1,1);
lcd.print("Blink = Kapali");

"lcd.clear()" komutu ile önceden ekranda yazılı olan şeyleri siliyoruz. Aksi taktirde onlar silinmeden yeni yazıları üstüne yazacaktır. "lcd.setCursor" komutu ile imlecimizin yerini ayarlayabiliyoruz. lcd.setCursor(0,imlec); bu komutla yazımıza başlamak istediğimiz hücremizi seçiyoruz ve lcd.write(0); komutu ile hazırladığımız oku yazdırıyoruz (Hazırladığımız karakteri setup kısmında yaratıp rakama atıyoruz. Daha o kısıma gelmediğimiz için burayı anlamayabilirsiniz. Setup kısmını okuduktan sonra gelip tekrardan inceleyip anlamaya çalışın.). İlk hücremize imlecimizi yazdırmıştık. Bu yüzden yazımızı 2. hücreye yazdırmamız gerekiyor. lcd.setCursor(1,0); koduyla 2. hücreye atlıyoruz. lcd.print("Cursor = Kapali"); koduyla Cursor durumunu yazdırıp lcd.setCursor(1,1); koduyla bir alt satıra geçip lcd.print("Blink = Kapali"); ile Blink durumunu yazdırıyoruz.

Sonra else koşuluna geçiyoruz. Bu durumda cursor = false, blink = true durumunda olacaktır. Kod mantığını anlatmıştım. Tamamen aynı mantık.

Ardından ilk if durumumuzun else koşulu geliyor. Artık burada cursor = true olacak ve blink değişkenimizin true ya da false olmasına göre seçili kodlarımız yazacağız.

Son olarak her case durumu bittiğinde sonuna break; koymayı unutmayın. Bu işlemler bittiğinde Switch kalıbını durdurmanızı ve çıkmanızı sağlayacaktır. Aksi taktirde hatalarla karşılaşabilirsiniz.

C++:
case 2:

if (leddurum == false) {

lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Led = Kapali");
}
else {

lcd.clear();
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Led = Acik");
}
break;

Durum 2 yani 2. menü de tek durum olacağı için iç içe if döngüsü yazmamıza gerek yok. Değişkenimizin doğruluk durumuna göre yazılarımı yazdırıp işlemi bitiriyoruz.

C++:
case 3:
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Menu3");
break;

case 4:
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Menu4");
break;

case 5:
lcd.setCursor(0,imlec);
lcd.write(0);
lcd.setCursor(1,0);
lcd.print("Menu5");
break;

default:
lcd.print("Hoşgeldiniz...");
break;
}

}
}

Bu kısımda da diğer menülerimizi ayarlıyoruz. Default kısmı eğer bizim tanımladığımız menüler dışında menü gelirse devreye giriyor. Ben burayı bir kez çalışmak üzere ayarladım ve başlangıçta hoş geldiniz deyip kapanıyor.

setup.PNG


C++:
void setup() {

pinMode(arttir, INPUT);
pinMode(azalt, INPUT);
pinMode(yukari, INPUT);
pinMode(asagi, INPUT);

lcd.init();
lcd.backlight();
lcd.createChar(0, ok);
[ICODE] lcd.clear();[/ICODE]

menuac(5235,imlec,cursor,blink,leddurum);

}

Burada butonlarımızı sinyal almak için kullanacağımız için "ınput" moduna alıyoruz. lcd.init(); komutuyla LCD'yi başlatıp lcd.backlight(); ile arka plan ışığını açıyoruz. Geldik karakterimizi yaratmaya. lcd.createChar(0, ok); kodu ile karakterimizi yaratıyoruz. İlk değişken olarak verdiğimiz 0, LCD'nin özel hafızası. Bu hafıza 0'dan 7'ye kadar gidebiliyor. İkinci değişkenimiz ise yarattığımız karakter. Ardından ekranda önceden bir şey kalmışsa silmek için lcd.clear(); kodunu kullanıyoruz. Ardından menuac(5235,imlec,cursor,blink,leddurum); kodunu vererek ilk menümüzün gelmesini sağlıyoruz. Peki, neden ilk değişken 5235? Hatırlarsanız Switch kalıbını kullanırken default durumunu koymuştuk. Bu durum eğer menülerimizde olmayan bir şey varsa otomatik olarak çalışıyordu. Ben de hoş geldiniz yazısını ilk başta çalıştırmak için salladım açıkçası. İsterseniz 49524 yapın yine de fark etmez.😀

loop1.PNG


loop2.PNG


loop3.PNG


loop4.PNG


C++:
while (digitalRead(arttir) == HIGH) {

delay(100);
sure++;
digitalRead(arttir);
}

Elimde daha fazla buton kalmadığı için arttır butonuna ekstra özellik ekledim. Arttır butonu High koşulunu sağladığı zaman (yani basıldığı zaman) eğer 2 saniyeden fazla basılı tutarsam seçili olduğu değişkenin değerini değiştiriyor. Bunu yapmak için basit bir zamanlayıcı kullanmak istedim ve bunu yazdım. delay(100); burada 0.1 saniye bekliyoruz ve ardından sure++; ile süre değişkenimizi 1 arttırıyoruz. Son olarak arttir butonumuzun durumunu tekrar kontrol ederek döngümüzün sonsuz döngüye girmemesini sağlıyoruz.

C++:
 if ( sure>0 && sure <20) {

lcd.clear();

if (menu < 5) {

menu++;
delay(500);
menuac(menu,imlec,cursor,blink,leddurum);
sure = 0;

}
else{

menu = 1;
menuac(menu,imlec,cursor,blink,leddurum);
delay(200);
sure = 0;

}
}

Burada süre 0'dan büyük 20'den küçükse (20 * 0.1 = 2 saniye) menümüzü arttırmak için kullanıyoruz. 0'dan büyük olma sebebi sonsuz döngüye girmemesi için. 5 tane menümüz olduğu için menü 5'ten küçük koşulunu sağlarsa menüyü bir arttır diyoruz. delay(500); ile 0.5 saniye bekliyoruz çünkü bu işlem çok hızlı gerçekleşiyor ve bekleme koymazsak siz 1 kez basıp çekseniz bile değişkeni 1'den fazla arttırıyor. Ardından menümüzü açıp süreyi 0'a eşitliyoruz. Else durumunda artık menü 5'den küçük değil veya 5'e eşitse tekrar başa dönmesini sağlıyoruz.

C++:
else if (sure != 0 && sure >= 20) {

if (menu == 1 && imlec == 0) {

if (cursor == false) {

cursor = true;
delay(50);
lcd.cursor();
sure = 0;
menuac(menu,imlec,cursor,blink,leddurum);
}
else {

cursor = false;
delay(50);
lcd.noCursor();
sure = 0;
menuac(menu,imlec,cursor,blink,leddurum);

}
}

Burada sure değişkeninin 0'dan farklı olduğunu ve 20'den büyük olduğu sorguluyoruz. Şartlar sağlanıyorsa diğer if döngümüze giriyoruz. Şimdi hatırlarsanız Switch kalıbındaki durumlarda menü 1'de iki farklı değişkenimiz vardı. Biz bunlardan hangisinin imleç tarafından seçildiğini tespit etmeliyiz. Yoksa yanlış değişkenin değerini değiştirebiliriz. Bu durumu da if döngüsüyle tekrar kontrol edeceğiz. Eğer menü 1'e eşitse ve imlec 0'a eşitse koşulumuz sağlanmış olacak. Eğer koşul sağlanırsa menü 1'de ki 1. satırdaki değişkenimizi değiştireceğiz.

1. menünün 1. satırında cursor olduğunu biliyoruz. Bir if döngüsü daha oluşturarak cursor değişkeninin değerini kontrol ediyoruz ve buna göre değerini değiştiriyoruz. lcd.cursor(); Cursor'un açılmasını sağlar. lcd.noCursor(); Cursor'un kapanmasını sağlar. Bunları yaptıktan sonra işlemimiz biteceği için sureyi 0'a eşitleyip menümüzü açıyoruz.
Geriye kalan kısımlarda da mantık aynı sadece değişkenler farklı. Birazcık bakınmayla hemen mantığını çözebilirsiniz.

C++:
else {

sure = 0;
}

}

Son olarak ilk if döngümüzün else koşulunda sureyi 0'a eşitliyoruz.

azalt.PNG


C++:
 if (digitalRead(azalt) == HIGH) {

if (menu > 1) {

menu--;
delay(500);
menuac(menu,imlec,cursor,blink,leddurum);

}
else{

menu = 5;
menuac(menu,imlec,cursor,blink,leddurum);
delay(200);

}

}

Burada da azalt tuşuna basıldığı zaman menü 1'den büyükse 1 azaltıp menüyü açıyoruz. Eğer menü 1'e gelirse else koşulunda 5'e eşitleyip menüyü açıp çıkıyoruz. Gördüğünüz gibi ufak şeyler hariç mantık tamamen aynı.

yukarı.PNG


C++:
 if (digitalRead(yukari) == HIGH) {

if (imlec == 0){

imlec = 1;
delay(500);
lcd.clear();
menuac(menu,imlec,cursor,blink,leddurum);

}
else {

imlec--;
delay(500);
lcd.clear();
menuac(menu,imlec,cursor,blink,leddurum);

}

}

Burada da yukarı tuşuna bastığımız zaman imlec sıfırsa bire, birse sıfıra eşitleyip menüyü tekrardan açıyoruz. Eğer sizin lcd'nizin satır sayısı daha fazlaysa bunu arttir, azalt butonlarının mantığı gibi yapabilirsiniz.

asagi.PNG


C++:
 if (digitalRead(asagi) == HIGH) {

if (imlec == 1){

imlec = 0;
delay(500);
lcd.clear();
menuac(menu,imlec,cursor,blink,leddurum);

}
else {

imlec = 1;
delay(500);
lcd.clear();
menuac(menu,imlec,cursor,blink,leddurum);

}

}

}

Yine dediğim gibi, mantık aynı. Sadece işlev farklı.

Dosyayı indirmek isteyenler için:

Çalışma videosu:

Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
 

Dosya Ekleri

  • IMG_20210121_170912.jpg
    IMG_20210121_170912.jpg
    149,7 KB · Görüntüleme: 180
  • IMG_20210121_170912.jpg
    IMG_20210121_170912.jpg
    152,1 KB · Görüntüleme: 191
Son düzenleyen: Moderatör:
Allah belasını vermesin bu LCD ekranların. Lehimsiz geliyorlar ve yüzeyine bir şeyler sürülmüş olduğu için lehim çok zor yapışıyor.

Yararlı bir rehber olmuş teşekkürler.
 
Allah belasını vermesin bu LCD ekranların. Lehimsiz geliyorlar ve yüzeyine bir şeyler sürülmüş olduğu için lehim çok zor yapışıyor.

Yararlı bir rehber olmuş teşekkürler.
Ben de ilk lehimimi bunun üzerinde denedim, bir de yanında gelen o kötü lehim teliyle hiç yapamadım. Kaldırırken de çıkarmayı beceremedim ama çalıştı. Bende kullanıyorum. 😀
 
Hocam 328P çipli Arduino kartlarında da var. O en soldaki pinlerin altında yazıyor. Şahsen denedim bile. :)
 

Geri
Yukarı