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:
- Arduino UNO
- Breadboard
- 74HC595 shift register entegresi
- 8 adet LED
- 8 adet 220 Ω
- İki ucu erkek jumper kablo
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:
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.
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.
a ve b değişkenleri nedir ?
öylesine bir örnek verdi. Sen onlari istedigin gibi degistirebilirsin.
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…
Hocam devredeki ledlerin anot ve katot bacakları ters gibi duruyor yanlış mıyım?
ledin içindeki büyük parça katottur yani gnd. yani dogru baglanmıs.
Düz mantık gitme dostum o eskidendi, bir çok led teknolojisi var.
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..
74HC595 shift registerin 2 tanesini cascade bağlantı için http://www.learningaboutelectronics.com/Articles/Cascade-shift-registers.php
Ledlerin yönleri yanlış ayrıca registerın 7. pini GNDye bağlanacak
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??
Kodu eksik kopyalamış olabilir misiniz?
yok hayır. eminim. defalarca denedim cunki. Robotistandaki ldr li baska bi projedede karsılastım aynı hatayla.
Merhaba. Çok geç cevaplıyorum ama sorun şu. Kodunuz derlenirken, yani Arduino IDE kodunuzu Arduino’nuza yüklemek için işlerken kodu yukarıdan aşağı satır satır okuyor. Bunun sonucunda void loop()’un içeriğini okurken registeraYaz() diye bir fonksiyonun çağrıldığını görüyor. Oysaki bizim registeraYaz fonksiyonu az daha sonra tanımlandığı için henüz daha orayı görmemiş oluyor. Dolayısıyla bu registeraYaz da ne ben böyle bir şey bilmiyorum deyip hata veriyor. Yine en yukarıdan satır satır aşağı indiği için. Sorunu iki yolla çözebiliriz. Birincisi: registeraYaz fonksiyonunu komple void loop()’tan önceki satırlara taşımak. Böylece derleyici (Arduino IDE) void loop() içindeyken de registeraYaz’ın ne olduğunu biliyor. İkinci yol da registeraYaz fonksiyonuna dokunmayıp void loop()’tan önceki satıra şu kodu yerleştirmek:
void registeraYaz();
Bu kod parçasında fonksiyondan sonra küme parantezi açmak yerine sadece noktalı virgül kulandık. Böylece şunu demiş oluyoruz: “Oralarda bir yerde registeraYaz diye bir fonksiyon var. Eğer registeraYaz diye bir şey görürsen bu ne deme. Zaten az sonra ne olduğunu öğreneceksin”.
Saygılarımla.
İyi günler,bağlantı şemasını yenileyebilir misiniz rica etsem kafa karışıklığına yol açıyor
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.
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?
“RegistereYaz” kelimesi içerisinde Türkçe hiçbir karakter bulunmadığı için sorun olmayacaktır 🙂
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.
teşekkürler hocam elinize sağlık.
Harikasınız Kerem hocam elinize emeğinize sağlık çok sağolun
leds değişkenini neden 0 olarak atadık açıklayabilir misiniz?
LED’lerimiz 0 verdiğimizde sönecek, 1 verdiğimizde yanacaktır. Varsayılan durum olarak tüm LED’lerin sönük kalması için başlangıçta 0 değeri atıyoruz.
Merhaba,
74HC595 yerine robotistan.com da hangi ürünü alabilirm? Bu ürün tükenmiş durumda..
dirençler anot uca bağlı olması gerekmiyormu?
Fark etmiyor, LED’in herhangi bir ucuna bağlayabilirsiniz.
Merhaba. Ben aynı bu şekilde uyguladım ancak ne yaptıysam sorunu çözemedim. Problemim şu- ledlerin en baştan 1-2-3-4 numaralı olanları çalışıyor diğerleri çalışmıyor. Anlamadım gitti. Neden kaynaklanabilir? Tüm elektriksel bağlantılara baktım. Malzemelerin sağlamlığını test ettim ama çözemedim sorunu.
bendede aynı problem oldu katotdan gnd ye bir jumper daha bağlaynca çözüldü
3 adet 74HC595 kullandığımda istediğim herhangi bir ledi örneğin 12. ledi yada 22.ledi yakmak için nasıl bir kod kullanmam lazım
Bu örnekteki leds değişkeni 8 adet integer’a sahip bir array’dir. Siz 3 adet entegrenin her birisi için ayrı birer registeraYaz fonksiyonu tanımlamanız ve parça parça 8-bitlik değişkenleri bu fonksiyonlar içerisinde yazdırmanız gerekecektir.
pwm uygulamalı nasıl yaparız acaba ?
Entegrenin OE pinine PWM sinyal uygulamayı deneyebilirsiniz. Fakat bu durumda tüm çıkışlara tek bir pinden PWM uygulamış olacaksınız. Alternatif olarak buradaki gibi bir PWM sürücü kartı kullanabilirsiniz.
mrb. en fazla kaç adet 74HC595 baglanabilir?
Mrb en fazla kaç adet 74HC595 Bağlanabilir 1 adet arduinoya?
74HC595 entegresiyle kullanım için burada bir kütühane bulunuyor.
https://github.com/Simsso/ShiftRegister-PWM-Library
Kütüphane sahibine ait makale de burada
https://timodenk.com/blog/shiftregister-pwm-library
Ben buradaki şemaya göre bağlantıları yaptım. entegreye ardiuno’daki D1,D2 ve D9 pinini bağladım. verilen örnek kodu da kendime uyarladım.
Ama bir türlü istediğim sonuçları alamadım. Sizin makalenizi de inceledim.
Bu 74HC595 ile “pwm çıkışı” elde edilebiliyor mu?
benim yapmak istediğim uno’ya ait pwm çıkışları yetersiz geldiğinden bunları çoğaltmak.
yani entegre den “pwm” çıkışı almam gerekiyor ki “dc motor” sürücü kartında bulunan “enA” pinine bağlayabileyim.
Bu konu da yardımcı olabilirmisiniz?
D2, D3,D4 pinlerine bağladım. tercihli olarak pinleri değiştirmedim.
brada anlatıldığı gibi yaptım.
https://timodenk.com/blog/shiftregister-pwm-library
entegrenin ilk 3 ayağına 1 adet rgb led bağlamıştım.(rgb led 4 ayaklı, 3 ayağını entegreye bağladım.) entegredeki 4 ve 5nci pinleri de birbirinden ayrı 2 dc motorun enA pinleri olarak bağladım.
motorları hareket ettirip, durdurabiliyorum.
rgb led’de ise henüz istediğim rengi yakamadım.
motor ve rgb led için şöyle bir sorun var ki benim entegreye bağlantı yaptığım sırayı takip etmiyorlar.
sanırım bazen de pinlerin yeri değişiyor. ilginç ama led’e renk emri veriyorum bazen 2 motor birden hareket ediyor.
yine bir yerde yanlışlık yapıyorum galiba ama ardiunodan entegreye 2,3,4ncü pinleri bağladım bunlarda sorun yok. sadece nasıl çalışıyor onu anlamaya çalışıyorum.
registeraYaz bir komut mu bunu kabul etmiyor hata veriyor buraya ne yazmalıyım
Bu bağlantıyla istediğimiz led yakıp söndürebilir miyiz yada hepsini aynı anda yakabilir miyiz
Arduino dan bağımsız bir sistem de 5 adet 74hc595 kullanılarak 5 adet 7segment display e değer yazdırılıyor . Sistem kendi içinde 3 adet kablo ile kontrol ediyor bunu bu kablolar clock latch ve data pinine gidiyor. Benim sorum ise biz bu 3 kabloyu arduinoya bağlayarak display de yazan yazıyı nasıl okuruz.