Arduino Basit Frekansmetre yapımı.

Bu yazımda sizlere Arduino kullanarak basit olarak nasıl frekans ölçebileceğinizi anlatacağım. Biraz daha gelişmeye ihtiyacı var. Fakat temel kısmı burası olduktan sonra sizlerin katkı yaparak geliştirebileceğinizi umuyorum.
Burada sadece arduino  komut yada fonksiyonlarını değil, yüksek frekansları da ölçebileceğiniz metotlar üzerinde durulacak.

Frekansmetre sadece frekansı göstermez periyodunu ve pals’in nasıl bir pals olduğunu da bize gösterebilecektir.
Dikkat edeceğimiz nokta Arduino 5V tan büyük sinyal genliğinde problem yaşayabilecektir. Bundan dolayı gerektiğinde sinyalin gerilim seviyesini düşürmeyi de eklemeniz gerekir. Genlik bizim için sorun teşkil etmesin diyorsak 5V luk zener diyot ile fazlalık gerilimleri kırpabiliriz. Kırpma işleminde frekans etkilenmez. 

Frekansmetre 2 şekilde yapılabilir.

1-) Pals’in periyodunu ölçüp f=1T kuralından hesaplama yapabilirsiniz. Burada periyot ölçtüğünüz için dalga şekli hakkında da fikir sahibi olabilirsiniz. ( PULSIN kullanımı)
2-) Belirli bir süre içerisinde gelen palsleri sayabilirsiniz. (Millis Kullanımı)

PIC işlemci kullananlar hazır yapılmış bir örneği bu sayfadan bulabilirler.
Mantık benzerdir. 

1- Pals periyodu ölçerek ( PULSIN )

kare dalga Bu kare dalganın gördüğünüz gibi high ve low kısımları birbirine eşit. Zaman zaman bu kısımlar birbirine eşit olmayabilir. Frekans
(T) periyot değeri kadar gösterilecektir. Arduino hem High seviyesini hem de Low seviyesini ayrı ayrı ölçtüğünden sinyalin nasıl bir sinyal olduğunu da fark edebilirsiniz.
Hatta geliştirip grafik ekranda resmi çizdirebilirsiniz.
Arduino ölçme yaparken dijital bir giriş bekler. bundan dolayı sinüs dalga geldiğinde bunu kare dalgaya çevirmemiz gerekir. Bunu yapabilmek için hızlı çalışan (Schmitt-Trigger) 7414 entegresi ile kare dalgaya çevrilir. Aşağıdaki şekil ideal olandır fakat gerçekte kullanacağınız entegrenin sınırlarına göre High ve Low kısımlarında küçük değişiklikler olabilmektedir.
sinuskareBu şekilde sinüs dalga kare dalgaya çevrilecektir.
Entegrenin Datasheet’ine buradan ulaşabilirsiniz.
Ayrıca entegrenin iç yapısına bakarsanız bir parçasını kullandığınızda çıkış sinyali giriş sinyalinin tersi olduğunu görürsünüz. Bunu entegrenin 2 parçasını kullanarak tersinin, tersi= kendisidir kuralı olarak düzenledim. Düzenlemeye ihtiyaç varmıydı? Normalde tek parçası da iş görür fakat siz sinyalin High seviyesi uzun derken aslında High seviyesi kısa bir sinyalle uğraşıyor olabilirsiniz. Bundan dolayı orijinal sinyali yakalamak için 2 parçasını seri olarak kullandım. 

Videoda DUTYcycle anlatılmaya çalışıldı. Dutycycle nedir. Genelde PWM sistemlerde kullanılan bu terim. Sinyalin periyodunu anlatmak için kullanılır. Bir periyot içerisinde High ve Low kısımlarının birbiriyle farkını gösterir. 1 periyot = %100 olarak ifade edilir. %50 dutycycle denildiğinde High=%50 Low=%50 kısmıdır. Bu frekans ölçümü için idealdir. İsterseniz %10 duty cycle sinyalide kullanabilirsiniz fakat burada Low seviyesi uzun olduğunda arduinonun sayma limiti dışına çıkabileceğinden tam periyodu hesaplamak zor olacaktır. Bundan dolayı mümkün olduğu kadar %50 civarı dutycycle bulunması avantajdır. biz bunu nerede kullandık, Bölücü entegrelerde her bacaktan Frekans/10 sinyali alabilirsiniz fakat ideal olanı %50 %50 olanıdır bundan dolayı şemadaki bağlantı şekli kullanılmıştır.
Aşağıdaki tablodan Bu işlemi daha net görebilirsiniz. 
dutycycle

Devremize gelince, Devre proteus üzerinde çizildi ve UNO ile çalışması sağlanacak şekilde dizayn edildi. NANO ile de çalıştırabilirsiniz.

şemaŞemada göreceğiniz gibi dip switchler mevcut. Bu 4 lü switch sinyallerin arduino tarafına geçişte ayırıcı olarak kullanılmasını sağlıyor. Neden buna ihtiyaç var derseniz Arduinonun ölçebileceği frekansların daha yükseğini ölçebilmesini sağlamak amaçlıdır. Gördüğünüz 4017 entegreler Frekans bölücü olarak çalışır. 1000000 Hz frekansı ölçmek sorun oluyorsa frekansı bölerek 1000000Hz / 10 = 100000Hz olarak ölçeriz ayrıca bu da sorun oluyorsa bunu da 10’a bölerek 100000Hz/10=10000Hz olarak ölçebiliriz. hatta daha da bölebiliriz. 4017 entegreleri ardarda bağlayabiliriz.
4017 entegresi yerine 7490 binary sayıcı entegresini de kullanabiliriz. Ya da 10 lu sayıcı bölücü entegreleri kullanabiliriz. Hatta sadece 10lu olması gerekmez çeşitli frekansları bölen özel bölücüler bulunmaktadır bunları da frekans bölücü olarak kullanabiliriz.
4017 entegre datasheet
7490 entegre datasheet
4521 özel bölücü entegre  datasheet. bu entegre belirlenen değerlerde bölme işlemi yapar.
Bölme tablosu aşağıdaki gibidir.

deviderBu tablodan da göreceğiniz gibi 10, 100 gibi bir standart yok. bu tip frekans bölücüler devrede bulunanlar gibi değil içinden sayarlar ve bağlantılı olan çıkıştan bölünerek bir pals çıkışı verir. Bu değere göre arduino yu ayarlayabilirsiniz. Bu Entegre çalışma voltajına göre  6-35Mhz arası çalışabilmektedir.
4017 entegresi 5Mhz civarına kadar çalışabilmektedir. 7490 entegresi ise 42Mhz frekansına kadar çalışabilmektedir. Bu değer ne kadar büyükse o entegreyi kullanıp frekansı bölmek bizim için daha iyi olacaktır. Çünkü yüksek frekansları ölçebilmek için böldüğümüz entegrenin de o frekansta stabil bir şekilde çalışması gerekir.

Programa bir bakalım bütün bunları nasıl yapıyoruz. PULSIN ayrıntılı bilgi
Burada pulsein komutunu kullanıyoruz. gelen sinyalin High seviyesinin kaç mikrosaniye olduğunu 37. satırda pulsin komutuyla buluyoruz.
Komut kullanımı: Htime=pulseIn(8,HIGH); bu satırda 8 arduino’nun input pimi. sinyali algılar. HIGH ifadesi ise High seviyesinde pals varsa say demektir. burada High seviyesinin kaç mikro saniye olduğunu bulup LOW seviyesine düştüğünde de 33 satırdaki gibi kullanıyoruz.
Bu iki sayıyı topladığımızda ise bize periyotu verir. Periyot ne işimize yarar. Aşağıdaki formül ile frekansı bulabiliriz.
Frekans= 1 / T (periyot zamanı saniye olarak yazılacaktır. )
Videoda LCD nin gösterdiği H ve L sinyal zamanlarını toplayıp bu formülden frekansı bulabilirsiniz.
40. satır ve 43. satırda bir açıklama vardır. Pulsin komutunun bir parametresi (Timeout) vasıtasıyla sinyal gelmediğinde hızlı bir şekilde öğrenmemizi sağlayacaktır.  Şayet bu parametre kullanılmazsa maksimum timeout süresi olacağından bu süreye kadar program beklemek zorunda kalacaktır. Videoda bu parametre kullanılmamıştır. Bu parametreyi kullanırsanız sonuç daima sıfır çıkar. Timeout dediğimiz mantık bu süre içerisinde değişim olmazsa mantığıdır. Mesela büyük frekanslarda timeout aşılmazken küçük frekanslarda timeout süresine denk gelir. bunu ayarlayamazsınız. Ne yapabiliriz? Burada yapabileceğimiz bir sinyal geldiğinde sadece High seviyesini kontrol etmek için timeout kullanan pulsin komutunu hesaplamadan önce ekleriz. ve if komutuyla geldiyse hesapla gelmediyse sinyal yok yaz diyebiliriz.

Program çıktısı:  Proteus compim komponenti ile birlikte  Seri haberleşmeli EASYLCD modülünü kullanan LCD göstergedir. Program da Kütüphane kullanan LCD satırları kapatılmıştır. Silinebilirdi. Fakat aradaki farkı görebilmeniz için kapatıldı. Bu haliyle LCD kütüphanesinin de kullanılmasına gerek yoktu hafızadan tasarruf edildi.
Kütüphaneye gerek bırakmayan örnek komutlar, aşağıdaki anlamları taşıyor.
Serial.print(“LCDDD”);  LCD yi temizle Komutu  (Display Delete – DD)
Serial.print(“LCDWR 1,1-FREKANSMETRE Hz.”);  LCD nin 1. satır birinci sütunundan başla ve yazıyı yaz. Komut: LCDWR 1,1- (WR=WRITE 1. satır , 1. sütun.)

 stringOne=freq;stringtwo=bol;strHtime=Htime;  İNT yada FLOAT gibi ifadeleri kolaylıkla yazmak için STRING şekline dönüştürüldü. 
Serial.print(“LCDWR 2,1-   “+stringOne+” Hz  X”+stringtwo)+”        “; Burada yazdırdık.
Başka şekilde de yazdırabilirdik.
Serial.print(“LCDWR 4,1-   “);Serial.print(Ltime); birinci serial komutuyla LCD komutunu,  ikinci serial komutuyla float sayıyı direkt olarak yazdırdık. Bu şekilde hex sayıları da yazdırabilirsiniz. 

EASYLCD Hakkında daha fazla bilgiye buradan ulaşabilirsiniz.
2-) Pals sayarak Frekans bulma. (MILLIS)Bu şekilde de frekans hesaplayabilirsiniz. Örnek programa bakarsanız sade ve anlaşılır durumdadır. 1. programda bulunan X1,X10,X100 bölümleri programa girilmedi. 1. programdan buraya kopyalayabilirsiniz. Frekansmetrenin basit olarak nasıl yapılabileceğini anladığınıza göre geliştirebilirsiniz.
Yukarıda değindiğimiz bir konu vardı Yüksek frekansları bölerken bölücü entegrenin çalıştığı frekans önemlidir dedik. Aşağıdaki linkte görüleceği üzere bu entegre 16 ya bölen bir entegre ve 5ns hızında çalıştığından yüksek frekans 200Mhz e kadar sinyalleri bölüp çalıştırabilirsiniz. SN54LV161A, SN74LV161A Datasheet
Bu şekilde yüksek frekansları bölerek Arduinoya verirseniz bölme hesabınıza göre X? olacak şekilde kullanıcıya bilgi verebilirsiniz.


Yine LCD de göstermek için EASYLCD Modül kullanıldığı için Kütüphaneye gerek duymayan EASYLCD komutu kullanıldı (serial.print kısmında. )

2 Comments

  1. Merhaba Şafak Bey. Elinize sağlık, güzel bir çalışma olmuş. Birkaç ekleme yapmak istiyorum. 4017 çipi CMOS olup 3-18V arasında besleme gerilimi ile kullanılabilir. 5V ‘ta max. 2-3 MHz civarında saat darbesi uygulanabilir. 15 V’da belirttiğiniz gibi 5 MHz’e ulaşır bu frekans. Bunun yerine HCMOS serisi yani 74HC4017 kullanılacak olursa 5V ‘ta 20 MHz saat darbesi uygulamak mümkündür. Bu çipte sayma çıkışları reset girişi ile kombine olarak kullanılmadığı taktirde her çıkışta fclk/10 yani saat darbesi frekansının 1/10 ‘u belirir. Ancak uygun bağlantılarla 2-10 arası bölmek mümkündür. Binary sayıcılarda bölme oranı 2’nin kuvvetleri şeklindedir. Decade yani onluk sayıcılarda 3,5,6,7,9,10 gibi oranları elde etmek kolaydır. Giriş işareti bölündükçe sayma değeri hassasiyetini yitirir. Yani 10 ‘a bölünmüş bir sinyali 10 Hz. hassasiyet ile sayabilirsiniz. Bölme oranı arttıkça bu hassasiyet azalmaya devam eder. Bu nedenle işareti bölmek için kaskad bağlı bölücüler kullanmak yerine kaskad bağlı yüksek hızlı sayıcılar kullanmak ve bu sayıcıların çıkışını okumak daha iyi bir fikir olabilir. Örneğin 3 adet kaskad bağlı 8 bitlik sayıcı ile 24 bitlik bir değer yani 16-17 MHz civarındaki bir frekansı bölmeden, çok hassas olarak saymak mümkün olacaktır.

    1. kusura bakmayın yorumunuzu geç gördüm. siteden bildirim gelmemişti. 74 serisi olanda haklısınız 7490 kullanılması da bu fikirlerden biriydi. yaklaşık 45 mhz. fakat sayıcı kısmı için düşünüyorum harici 24 bitlik bir sayıcının çıkışını arduino ile okumak için araya paralel seri çevirici entegreler girmesi lazım gibi geldi. port sarfiyatından dolayı. Dediğiniz gibi yüksek hızlarda bölmek yerine birim zamanda gelen palsi saymak kolay olacağından belki ikili çalışma gerekebilir. birincisi bölücü kullanılarak frekans kabaca belli olur ve belli bir yükseklikten sonra sayma işlemine dönerek ki arduinoda 24 bit ( sanırım float 24 bit sayıyordu) sayac koyup saydırılabilir. bu da alternetif olacaktır yapmak isteyenlere. 1ms de bir yada 10ms de bir. bu konuyu da sona eklediğim millis komutunun kullanımında görebilirsiniz sanıyorum.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir