Merhaba arkadaşlar. Bugünkü dersimizde sizlerle Arduino ve 74HC595 shift register entegresi kullanarak 8 adet LED’i az sayıda pin harcayarak yakmayı öğreneceğiz.

Gerekli malzemelerimiz:

Hepimizin bildiği üzere Arduino UNO kartımızda 13 adet dijital giriş/çıkış pini bulunmakta. Fakat bu pinlerin hepsini LED sürmek için kullanmak istemeyebiliriz. Yada LED haricinde diğer pinlere sensör, switch, buton v.b. diğer girişler bağlamış olabiliriz. Burada kullanacağımız metot sayesinde Arduino’da sadece 3 adet dijital çıkış pini kullanarak 8 adet LED’i kontrol etmemiz mümkün olacak.

74HC595 Shift Register Entegresi

Shift register devresi, peş peşe bağlanmış flip-flop adındaki hafıza elemanı devrelerinden oluşur. Tiplerine göre paralel girişi seri çıkışa (parallel-in, serial-out, PISO) dönüştüren ya da bizim projemizde kullandığımız 74HC595 gibi seri girişi paralel çıkışa (serial-in, parallel-out, SIPO) dönüştüren işlevde olabilirler.

Kullandığımız entegrede Arduino’ya bağlayacağımız 3 adet bacağa sahiptir: Seri data girişi (DS, pin 14), latch (ST_CP, pin 12) ve clock pini (SH_CP, pin 11). Shift register şu şekilde çalışır: veri girişi yapılmak isteniyorsa latch pini lojik 0 seviyesine çekilir, data girişi yapılır (lojik 1 veya 0) ve saat darbesi (clock pulse) clock pinine uygulanır. Bu şekilde 8 bitlik veri tek bir seri giriş pininden girilir ve işlem sonucunda seri olarak girilen veri paralel çıkışlardan (Q0 – Q7 pinleri) alınmış olur.

Eğer shift register’ın çalışma mantığı size karmaşık geldiyse endişelenmenize gerek yok. Arduino yazılımında bulunan shiftOut fonksiyonu bu işlemlerin hepsini üstlenerek size sadece bağlantıda kullandığınız pinleri tanımlamayı bırakıyor.

Entegremizi LED’lerimize ve Arduino’muza şu şekilde bağlıyoruz:

Devre şeması 17/01/2017 tarihinde güncellenmiştir.

Kodumuz şu şekilde:

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
byte leds = 0;
 
void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}
 
void loop() 
{
  leds = 0;
  registeraYaz();
  delay(500);
  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i);
    registeraYaz();
    delay(500);
  }
  for (int i = 8; i >= 0; i--)
{
    bitClear(leds, i);
    registeraYaz();
    delay(500);
  }
}
void registeraYaz()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

Kodumuzun ilk kısmında her zaman yaptığımız gibi çıkış pinlerimizi tanımladık. leds isimli 8 bitlik bir değişken tanımladık (byte tipindeki değişkenler 8 bit büyüklüğündedir). Bu baytın her bir biti, bizim shift register’ımızın çıkışına bağlı olan LED’leri temsil ediyor. registeraYaz fonksiyonumuz, shift register’ın çalışması için gerekli işlemleri yapıyor. loop fonksiyonumuzda bu fonksiyonu çağırarak leds değişkeninde yaptığımız değişiklikleri LED’lerimize aktarmak için bu fonksiyonu çağırıyoruz. loop fonksiyonumuzda ise iki adet for döngüsü kullandık. İlk for döngüsü, leds değişkenimizdeki 8 bitten her birini sırayla 1 yaparak 00000001, 00000011, 00000111… şeklinde bir desen elde etmemizi sağlayacak. Her bir bit 1 olduktan sonra (11111111), ikinci for döngüsü başlayarak bu sefer bitleri 0’layarak 01111111, 00111111,00011111… desenini oluşturacak.

Sizler for döngüsü kullanmayıp, örneğin leds = B00000001, leds = B00000010, leds = B00000100, şeklinde sıralayarak kara şimşek ışıkları yapmayı deneyebilirsiniz. Her komuttan sonra registeraYaz fonksiyonunu çağırmayı unutmayın.

NOT: Eğer derslerimizi sırayla takip ediyorsanız bu dersimizde yaptığımız devreyi sökmeyin. Bir sonraki dersimizde seri haberleşme kullanarak LED yakmayı öğreneceğiz.

19 Yorumlar

  1. Merhaba , birşey soracaktım, bu yöntemle bu 8 ledi ayrı ayrı nasıl kontrol edebiliriz. Yani mesela bir if komutu koyup 1. ledi kontrol edip, başka bir if koyup 2. ledi kontrol nasıl ederiz? Birinci if sonucunu ikinci if etkilemeyecek , bu yapılabilir mi shift registerda ? Teşekkürler.

    • Biraz geç olacak cevap ama belki başkasının işine yarar.Dediğin işlem şu şekilde yapılabilir

      shiftOut(dataPin, clockPin, LSBFIRST, leds); komutunda leds yerine yakmak istediğin ledin bağlı olduğu çıkışın decimal sayı sistemindeki karşılığını yazarsan olur

      Örnek-1: Q5 çıkışına bağladığın ledi yakmak için Q5 in binary karşılığı 00100000 bunun decimal karşılığı 32 olduğundan shiftOut(dataPin, clockPin, LSBFIRST, 32); yaparsan Q5 yanar

      Örnek-2: Q4,Q5,Q6 yakmak istersen bunların binary karşılığı 01110000 olduğundan decimal sayı sistemindeki karşılığı olan 16+32+64 =112 yazarsan bu çıkışlar aktif olur

      if döngüsünde de şu şekil yapabilirsin;

      if( a >= b)
      {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, LSBFIRST, 112);
      digitalWrite(latchPin, HIGH);
      }

      yanlız bu şekil yaptığında void registeraYaz() fonksiyonunu kullanmayacaksın direk void loop() içine yazacaksın.

  2. Merhaba, çalışmalarınızda kolaylıklar dilerim.

    74HC595 entegrenin toprak ucu 8 numaralı bacak gibi gözüküyor. Şemadaki boardda ise 8 numaradan çıkan siyah kablo +V hattına bağlanmış gibi.

    Teşekkürler…

  3. Merhabalar,
    Hocam peki devreye birbirine seri şekilde 3 veya 4 tane 74hc595 bağlarsak diğer 595 ‘in bacaklarına bağladığımız ledleri nasıl kontrol edebiliriz.
    Cevaplarsanız çok memnun olurum..

  4. Arduino:1.6.11 (Windows Store 1.6.11.0) (Windows 10), Kart:”Arduino/Genuino Uno”

    C:\Users\admın\Documents\Arduino\_74hc595\_74hc595.ino: In function ‘void loop()’:

    _74hc595:16: error: ‘registeraYaz’ was not declared in this scope

    exit status 1
    ‘registeraYaz’ was not declared in this scope

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.
    kodda bi hata olabilirmi??

  5. Oktay, yukarıda tanımladığın leds=0; registeraYaz(); olan yerde registeraYaz başına byte eklersen sorun düzelir yani;
    void loop()
    {
    leds = 0;
    byte registeraYaz();
    delay(500); ……. ..} şekinde yazarsan çalışır.

  6. RegisteraYaz Türkçe bir komut. Arduino programı türkçe desteklemeyenlerde var benim gibi. Onlar ne yazıcak bu komut yerine. Register mi yazıcak yalnızca?

  7. iyi günler kerem bey,bu komutları uyguladım fakat ilk çalıştırdığımda tüm ledler yanıktı hızlı bir şekilde tüm ledler yanıp söndü.Sonra dediğiniz şekilde tek tek yanmaya başladı.Başlangıçta hepsinin sönük olması gerekmiyor muydu?Bir de shiftout un içindeki LSBFIRST ne işe yarıyor?

    • Shift register’a ilk bilgi gönderildiğinde oluşan bir durumdan dolayı tüm LED’ler yanıyor. Bu durumun önüne geçmek için 13 numaralı Output Enable pini kullanılabilir. Bu pin lojik 1 seviyesinde iken tüm çıkışlar 0 olarak kalır. shiftOut fonksiyonundaki LSBFIRST seçeneği, gönderilen verinin en önemsiz biti (least significant bit, LSB) ile başlayacağını belirtiyor. Örneğin 11010010 gönderdiğimizi düşünecek olursak, shift register’a sırasıyla 0, 1, 0, 0, 1, 0, 1, 1 şeklinde gönderilecektir.

CEVAP VER