14 Mart 2016 Pazartesi

RASPBERRY PI 2 ile 16x2 LCD KULLANIMI ve TÜRKÇE KARAKTER OLUŞTURMA

    Herkese Merhabalar,

     Bu yayınımızda Raspberry Pi 2 ile HD44780 kontrolcüsüne sahip 16x2 karakter LCD' yi sürmeyi öğreneceğiz. Daha sonra da kendi oluşturduğumuz Türkçe karakterleri LCD ekrana print edeceğiz. İlk önce LCD pinlerini görevleriyle birlikte inceleyelim. 16x2 LCD'nin 16 adet pini vardır. Bunlar;
GND [1]: LCD toprak pini,
VCC [2]: LCD'nin +5V beslemesi,
VEE [3]: Kontrast pini; bu pin 10K pot üzerinden toprağa çekilerek kontrast ayarı yapılır.
RS [4]: (Register select) LCD nin şartlanması ve konum belirtme gibi durumlarda lcd ye komut, ekrana yazı yazma durumunda ise karakter yollanır. Eğer LCD ye komut yazacaksak bu pini lojik 0 seviyesine, karakter yazacaksak lojik 1 seviyesine çekmemiz gereklidir.  
R/W [5]: (Read/Write) LCD ye veri yazılacaksa bu pin lojik 0 'a, veri okunacaksa lojik 1'e çekilir. Biz uygulamamızda ekrandan veri okumayıp sadece yazacağımız için bu pini GND ye bağladık.
E [6]: Raspberry pi nin GPIO pinlerine yazdığımız verilerin LCD ye yazılması için bu pine düşen kenarlı bir clock gönderilir. Eğer okuma yapılacaksa bu pine yükselen kenarlı clock gönderilir.
D0-D7 [7-14]: D0 dan D7 ye kadar olan pinler data pinleridir. Bu pinler üzerinden LCD ye veri yazılır/okunur.
A [15]: Bu pin lcd arka aydınlatma ledinin anotudur.
K [16]: Bu pin lcd arka aydınlatma ledinin katodudur.

   HD44780 kontrolcülü karakter LCD, D0-D7 data pinleri üzerinden 8 bit ve 4 bit olarak sürülebilmektedir. Aşağıdaki devre şemasından da görüldüğü gibi  LCD yi 4 bit olarak süreceğiz. Bunun için data binlerinin üst 4 biti (D4-D5-D6-D7) ni Raspberryi Pi nin GPIO pinlerine bağladık. LCD 4 bit sürüldüğünde ilk önce bilginin üst 4 bitleri yazılır ardında da alt 4 bitleri yazılır.



   
       Raspberry Pi ile LCD'nin bağlantısını aşağıdaki GPIO pin konfigürasyonuna  uygun olarak yapabilirsiniz.

     Proje programını Python ile yazacağız. Raspberry Pi'nin GPIO pinlerini kullanabilmemiz için programa GPIO modülü import etmemiz gerekmektedir. Ayrıca programda bazı yerlerde bekleme(gecikme) kullanmamız gerekeceğinden time modülünü de import edeceğiz. 

#import
import RPi.GPIO as GPIO
import time

# GPIO pin numaralarının sabitlere atanması

LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18


# Sabitlerin tanımlanması
LCD_CHR = True
LCD_CMD = False

    Programı, LCD'nin çalışma mantığına uygun olarak belirli görevleri yerine getiren alt fonksiyonlar halinde yazıp daha sonra main fonksiyonu içinde alt fonksiyonları çağıracağız. Bu fonksiyonları tek tek inceleyelim.

LCD'nin E pinine düşen kenarlı clock uygulayan fonksiyon:
def enable_clk():
  GPIO.output(LCD_E, True)
  time.sleep(0.0005)
  GPIO.output(LCD_E, False)
  time.sleep(0.0005)


    LCD'ye veri yazan fonksiyon:
    Bu fonksiyona yazılacak olan veri ve modu parametre olarak gönderilecektir. Verinin modu, yazılacak olan veri komut mu yoksa ekrana bir karakter mi yazdırılmak isteniyor onu belirtecektir. 

def veri_gonder(veri, mode):
  # Verinin önce üst 4 biti, 
  # daha sonrada alt 4 biti gönderilir
  # karakter yazmak için mode true 
  # komut yazmak için ise mode false
  
  ikilik_veri = bin(veri)[2:].zfill(8)
  
  #RS 
  GPIO.output(LCD_RS, mode) 
  
  
  # Üst 4 bit
  GPIO.output(LCD_D4, int(ikilik_veri[3]))
  GPIO.output(LCD_D5, int(ikilik_veri[2]))
  GPIO.output(LCD_D6, int(ikilik_veri[1]))
  GPIO.output(LCD_D7, int(ikilik_veri[0]))
  
 

  # Düşen kenar clock
  enable_clk()

  # Alt dört bit
  GPIO.output(LCD_D4, int(ikilik_veri[7]))
  GPIO.output(LCD_D5, int(ikilik_veri[6]))
  GPIO.output(LCD_D6, int(ikilik_veri[5]))
  GPIO.output(LCD_D7, int(ikilik_veri[4]))

  # Düşen kenar clock
  enable_clk()


    HD44780 konrolcüsünün DDRAM, CGROM ve CGRAM bellekleri vardır. Bu belleklerden kısaca bahsedelim;
DDRAM: DDRAM mesajların ekrana basıldığı anda ki kapladığı bellektir.
16x2 LCD nin DDRAM adresleri şu sıradadır;
   1. satır:  0x80 -0x81 -0x82-0x83.......................-0x8C-0x8D -0x8E-0x8F 
   2. satır:  0xC0-0xC1-0xC2-0xC3......................-0xCC-0xCD-0xCE-0xCF


CGROM: HD44780'in  üreticisi tarafından tanımlanmış özel karakterlerin yer aldığı bellektir. Bu belleğin içerisinde yer alan karakterler değiştirilemez sadece ekrana basılabilir.

CGRAM: Bu bellek kullanıcıya kendi karakterlerini tanımlaması için sunulmuş bellektir. Yani bu belleğin içeriği kullanıcı tarafından değiştirebilir. Biz de Türkçe karakterlerimizi bu bellek içerisinde tanımlayacağız. Yalnız CGRAM de en fazla 8 adet karakter tanımlamamıza izin vermektedir. Aşağıda CGROM ve CGRAM belleklerinin yerleşimi görülmektedir. Bizim Türkçe karakterlerimiz de sıra ile tabloda ki mavi sütuna (0-7 arası) yerleşecektir.



   Şimdi Türkçe karakterlerimizi nasıl oluşturacağımıza bakalım. LCD de 5x8 lik hücreler bulunmaktadır. Her bir 5x8 lik hücre bir karakter için ayrılmıştır. Biz karakterlerimizi  5x7 boyutunda tasarlayacağız. Yani, en alt satırda bir boşluk bırakacağız ki hücreler birleşmesin ve imleç boşluğu kalsın. Yan tarafda 5x8 lik hücre içinde 'ç' karakterimiz tasarlanmıştır. Diğer türkçe karakterlerimizi de bu şekilde tasarlayacağız. Oluşturduğumuz her karakter için pythonda 8 elemanlı bir liste oluşturacağız. Herbir karakter için oluşturduğumuz listenin elemanlarını HD44780 nin CGRAM'ine 64. adresinden itibaren yazacağız. Böylece artık Türkçe karakterlerimizi tanımlamış olacağız ve istediğimiz zaman çağırıp ekrana bastırabiliriz.


LCD de Türkçe karakterleri tanımlayan fonksiyon:
def LCD_turkce_karakter():
  harf_1 = [0, 14, 16, 14, 1, 30, 4, 0]  #Ş - ş 
  harf_2 = [0, 14, 17, 16, 17, 14, 4, 0] #Ç - ç
  harf_3 = [0, 0, 12, 4, 4, 4, 14, 0]  #ı
  harf_4 = [4, 0, 14, 4, 4, 4, 14, 0]    #İ
  harf_5 = [0, 10, 0, 17, 17, 17, 14, 0] #Ü - ü
  harf_6 = [10, 0, 14, 17, 17, 17, 14, 0]#Ö- ö
  harf_7 = [14, 0, 14, 18, 14, 2, 28, 0] #ğ
  harf_8 = [14, 0, 14, 16, 22, 18, 14, 0]#Ğ
  
  veri_gonder(64 , LCD_CMD)
 
  for i in range(8):
    veri_gonder(harf_1[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_2[i] , LCD_CHR)

  for i in range(8):
    veri_gonder(harf_3[i] , LCD_CHR)

  for i in range(8):
    veri_gonder(harf_4[i] , LCD_CHR) 
 
  for i in range(8):
    veri_gonder(harf_5[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_6[i] , LCD_CHR) 

  for i in range(8):
    veri_gonder(harf_7[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_8[i] , LCD_CHR)

LCD'yi şartlayan program:
def lcd_sartla():
  veri_gonder(0x33,LCD_CMD) # init
  veri_gonder(0x32,LCD_CMD) # init
  veri_gonder(0x28,LCD_CMD) # 4 bit, 2 satır, 5x8 dots
  veri_gonder(0x0C,LCD_CMD) # Display açık ,Cursor gizli
  veri_gonder(0x06,LCD_CMD) # Kursor her karakterden sonra sağa kayar
  veri_gonder(0x01,LCD_CMD) # displayi temizle
  time.sleep(0.0005)
  
  LCD_turkce_karakter()

    LCD'ye mesajımızı göndermeden önce mesajın görüntüleneceği konumu belirtmemiz gerekir. Yukarıda  DDRAM adreslerinin 1.  satır için 0x80-0x8F  ve 2. satır için 0xC0-0xCF arasında olduğunu belirtmiştik. Şimdi ona  göre ekranda mesaj görüntüleyeceğimiz konuma gitmemizi sağlayan fonksiyonu yazabiliriz.

LCD'ye satır ve sütun bilgisini gönderen fonksiyon:
def satirXsutun( satir, sutun):
  if satir==1:
    sutun -=1
    veri_gonder(0x80 + sutun , LCD_CMD)
  elif satir==2:
    sutun -=1
    veri_gonder(0xC0 + sutun , LCD_CMD)

  Satır-sütun konumunu belirledikten sonra LCD'ye yazdırmak istediğimiz mesajı gönderen fonksiyonu  yazabiliriz. 

LCD'ye mesaj gönderen fonksiyon:
def lcd_yaz(mesaj):
  for i in range(len( mesaj)):
    if mesaj[i]=='Ş' or mesaj[i]=='ş':
      veri_gonder(0 , LCD_CHR)
      
    elif mesaj[i]=='Ç' or mesaj[i]=='ç':
      veri_gonder(1 , LCD_CHR)

    elif mesaj[i]=='ı': 
      veri_gonder(2 , LCD_CHR)

    elif mesaj[i]=='İ':
      veri_gonder(3 , LCD_CHR)

    elif mesaj[i]=='Ü' or mesaj[i]=='ü':
      veri_gonder(4 , LCD_CHR)
      
    elif mesaj[i]=='Ö' or mesaj[i]=='ö':
      veri_gonder(5 , LCD_CHR)

    elif mesaj[i]=='ğ':
      veri_gonder(6 , LCD_CHR)

    elif mesaj[i]=='Ğ':
      veri_gonder(7 , LCD_CHR)   
 
    else:
      veri_gonder(ord(mesaj[i]) , LCD_CHR)

     LCD'ye yeni bir mesaj yazacağımızda ekranda ki eski mesajları temizlememiz gerekebilir. Şimdi yazacağımız fonksiyon LCD'yi temizler.

LCD'yi temizleyen fonksiyon:
def lcd_temizle():
  veri_gonder(0x01 , LCD_CMD)
  time.sleep(0.0005)

    Programımız da yer alan fonksiyonları tek tek inceledik. Program bir bütün halinde aşağıdaki gibidir.
Programın Bütünü:
#!/usr/bin/python
#-*-coding:utf-8-*-

#import
import RPi.GPIO as GPIO
import time

# GPIO pin numaralarının sabitlere atanması
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18


# Sabitlerin tanımlanması
LCD_CHR = True
LCD_CMD = False

def main():
    
  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BCM)       # BCM sırasına göre GPIO
  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7

  lcd_sartla()

  while True:    
    satirXsutun(1,3)
    lcd_yaz("Eser şentürk")
    time.sleep(1) 
    satirXsutun(2,2)
    lcd_yaz("Raspberry Pi 2")
    time.sleep(3) 
 
    lcd_temizle()
 
    satirXsutun(1,1)
    lcd_yaz("Türkçe Karakter")
    time.sleep(1)
    satirXsutun(2,1)
    lcd_yaz("ı ğ Ğ ü ş İ ö ç") 
    time.sleep(3)
 
    lcd_temizle()


def lcd_sartla():
  veri_gonder(0x33,LCD_CMD) # init
  veri_gonder(0x32,LCD_CMD) # init
  veri_gonder(0x28,LCD_CMD) # 4bit, 2 satır, 5x8 dots
  veri_gonder(0x0C,LCD_CMD) # Display açık, Cursor gizli
  veri_gonder(0x06,LCD_CMD) # Kursor her karakterden sonra sağa kayar
  veri_gonder(0x01,LCD_CMD) # Displayi temizle
  time.sleep(0.0005)
  
  LCD_turkce_karakter()
  

def veri_gonder(veri, mode):
  # Verinin önce üst 4 biti, 
  # daha sonrada alt 4 biti gönderilir
  # karakter yazmak için mode true 
  # komut yazmak için ise mode false
  
  ikilik_veri = bin(veri)[2:].zfill(8)
  
  # RS
  GPIO.output(LCD_RS, mode) 
  
  
  # Üst 4 bit
  GPIO.output(LCD_D4, int(ikilik_veri[3]))
  GPIO.output(LCD_D5, int(ikilik_veri[2]))
  GPIO.output(LCD_D6, int(ikilik_veri[1]))
  GPIO.output(LCD_D7, int(ikilik_veri[0]))
  
 

  # Düşen kenar clock
  enable_clk()
  
  
  # Alt 4 bit
  GPIO.output(LCD_D4, int(ikilik_veri[7]))
  GPIO.output(LCD_D5, int(ikilik_veri[6]))
  GPIO.output(LCD_D6, int(ikilik_veri[5]))
  GPIO.output(LCD_D7, int(ikilik_veri[4]))

  # Düşen kenar clock
  enable_clk()
  
def LCD_turkce_karakter():
  harf_1 = [0, 14, 16, 14, 1, 30, 4, 0]  #Ş - ş 
  harf_2 = [0, 14, 17, 16, 17, 14, 4, 0] #Ç - ç
  harf_3 = [0, 0, 12, 4, 4, 4, 14, 0]  #ı
  harf_4 = [4, 0, 14, 4, 4, 4, 14, 0]    #İ
  harf_5 = [0, 10, 0, 17, 17, 17, 14, 0] #Ü - ü
  harf_6 = [10, 0, 14, 17, 17, 17, 14, 0]#Ö- ö
  harf_7 = [14, 0, 14, 18, 14, 2, 28, 0] #ğ
  harf_8 = [14, 0, 14, 16, 22, 18, 14, 0]#Ğ
  
  veri_gonder(64 , LCD_CMD)
 
  for i in range(8):
    veri_gonder(harf_1[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_2[i] , LCD_CHR)

  for i in range(8):
    veri_gonder(harf_3[i] , LCD_CHR)

  for i in range(8):
    veri_gonder(harf_4[i] , LCD_CHR) 
 
  for i in range(8):
    veri_gonder(harf_5[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_6[i] , LCD_CHR) 

  for i in range(8):
    veri_gonder(harf_7[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_8[i] , LCD_CHR)
 
def enable_clk():
  GPIO.output(LCD_E, True)
  time.sleep(0.0005)
  GPIO.output(LCD_E, False)
  time.sleep(0.0005)
def satirXsutun( satir, sutun):
  if satir==1:
    sutun -=1
    veri_gonder(0x80 + sutun , LCD_CMD)
  elif satir==2:
    sutun -=1
    veri_gonder(0xC0 + sutun , LCD_CMD)
def lcd_temizle():
  veri_gonder(0x01 , LCD_CMD)
  time.sleep(0.0005)
  
def lcd_yaz(mesaj):
  print (mesaj)
  for i in range(len( mesaj)):
    if mesaj[i]=='Ş' or mesaj[i]=='ş':
      veri_gonder(0 , LCD_CHR)
      
    elif mesaj[i]=='Ç' or mesaj[i]=='ç':
      veri_gonder(1 , LCD_CHR)

    elif mesaj[i]=='ı': 
      veri_gonder(2 , LCD_CHR)

    elif mesaj[i]=='İ':
      veri_gonder(3 , LCD_CHR)

    elif mesaj[i]=='Ü' or mesaj[i]=='ü':
      veri_gonder(4 , LCD_CHR)
      
    elif mesaj[i]=='Ö' or mesaj[i]=='ö':
      veri_gonder(5 , LCD_CHR)

    elif mesaj[i]=='ğ':
      veri_gonder(6 , LCD_CHR)

    elif mesaj[i]=='Ğ':
      veri_gonder(7 , LCD_CHR)   
 
    else:
      veri_gonder(ord(mesaj[i]) , LCD_CHR)
      

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    veri_gonder(0x01, LCD_CMD)
    satirXsutun(1,6)
    lcd_yaz("bitti")
    GPIO.cleanup()


    Raspberry Pi terminaline aşağıda ki kodu yazarak python dosyanızı oluşturup ardından içine yukarıda verilen programın bütününü, yapıştırıp kaydedebilirsiniz.
nano TLCD16x2.py

  Dosyanıza istediğiniz ismi verebilirsiniz. Biz örneğimizde TLCD16x2.py ismini verdik. Değişiklikleri kaydettikden sonrada aşağıdaki kodu yazıp programı çalıştırabilirsiniz.
sudo python3 TLCD16x2.py
     
     İlgilenenlere kolay gelsin.
     Başarılar...

1 yorum: