Merhaba arkadaşlar bu yazımda oldukça zevkli bir proje olan Arduino ile 2×16 karakter LCD kullanarak spektrum analizör yapmayı anlatacağım.
Spektum analizör; Girişinde ki elektriksel sinyallerin belirlenen frekans aralığındaki genlik değişimini gösteren cihazlara denir.
Ancak bizim yapacağımız bu cihaz değil. Analizörün ekranında bu değişimler çeşitli grafikler ile gösterilir. Bizde bu grafiğe benzer bir görüntüyü, Winamp programında çalan şarkının belirli frekanslarda ki genliğini alarak bu genlikleri ekranda göstermek olacaktır. Peki bu frekans genliklerini nasıl alacağız? Cevap: Winamp programına yazılmış bir eklenti ile bu genlikleri seri porttan 19200 band hızında Arduino ile alarak belirli bir çözme işleminden geçireceğiz ve LCD ekranda göstereceğiz.
İlk önce eklentinin nasıl yükleneceğini anlatayım;
Bilgisayarımıza Spectrum Analyzer dosyasını indiriyoruz.
İndirilen Winrar arşivi içindeki dosyaları masaüstüne çıkartalım.
Zip içerisinde “gen_crownsoft_lcd.dll” ve “lcd_analyzer.ini” adlı 2 adet dosya bulunmaktadır.
gen_crownsoft_lcd.dll adlı dosyayı Winamp programını kurulu olduğu yere, yani standart olarak “C:\Program Files (x86)\Winamp\Plugins” adresine gidip oraya kopyalayalım.
lcd_analyzer.ini dosyasını da “C:\” sürücüsü içine kopyalayalım. Bu işlemleri yaparken Winamp kapalı olsun.
Kartımızı bağladıktan sonra lcd_analyzer.ini dosyasında değişiklik yapacağız, konu sonunda anlatacağım.
Eklenti yükleme işimiz bitmiştir şimdi devremizi inceleyelim;
Devremizde sadece 2×16 karakter LCD bulunmaktadır. Potansiyometre LCD kontrast ayarı içindir. LCD bağlama ile ilgili konuyu daha önce anlatmıştım. Bağlantı pinlerini istediğiniz gibi değiştirebilirsiniz. Ben yazılımı bu bağlantı üzerinden anlatacağım.
Yazılıma geçmeden önce Winamp programında ki eklenti bize veriyi nasıl gönderiyor inceleyecek olursak;
Resimde ki RealTerm adlı program ile istediğiniz portta ki veri iletişimini izleyebilir veya komut gönderebilirsiniz. Programı sadece giden verileri göstermek amacıyla kullandım.
Gördüğünüz gibi Winamp programı o anda çalan şarkı ile j00a, j51h, j81c, j70e, i90 , i60 gibi komutlar göndermektedir.
Bu komutlar;
j – sütun – satır – bar şeklinde bir komut formatı belirtmektedir. Bar kısmı yazılımda harfler ile tanımlanmış 5×8 LCD matrisini x ekseninde alttan başlayarak dolduran çizgilerdir.
j00a — 0. sütun 0. satırda en alt x eksenine 1 satır çizgi çizer,
j01b — 0. sütun 1. satırda en alt x eksenine 2 satır çizgi çizer,
i – sütun – satır – karakter şeklinde bir komut formatı belirtmektedir. Bu komut formatı belirtilen sütun satır konumuna göre gönderilen karakteri yazdırır. Winamp bu format ile boşluk karakteri gönderir. Bunun nedeni barlar alt satıra indiği anda, inen bara karşılık gelen üst satırdaki çizgileri silmektir.
k komutu şarkı başladığı ve kapatıldığı anda gönderilir. Bu komut LCD ekranıda ki tüm noktaları temizler.
Biraz karışık gelebilir ancak yazılımda inceliğimiz zaman daha net anlaşılacaktır.
Sıra geldi yazılıma. Yazılımda bu gelen komut formatlarını ayrıştırarak belirtilen satır sütün bilgisine göre gönderilen harf değerinde bar çizdireceğiz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#include <LiquidCrystal.h> LiquidCrystal lcd(2, 1, 5, 4, 3, 2); byte custChars[8][8] = { { B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111 }, { B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111 }, { B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111 }, { B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111 }, { B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111 }, { B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111 }, { B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111 }, { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 } }; byte serial_getch() { while (Serial.available() == 0); return Serial.read(); } void setup() { Serial.begin(19200); lcd.begin(16, 2); lcd.clear(); for (int i = 0; i<8; i++) { lcd.createChar(i, custChars[i]); } } void loop() { byte rxbyte = serial_getch(); if (rxbyte == 'j') { byte r1 = serial_getch(); byte r2 = serial_getch(); lcd.setCursor(r1 - '0', r2 - '0'); lcd.write((uint8_t)(serial_getch() - 97)); } else if (rxbyte == 'i') { byte r1 = serial_getch(); byte r2 = serial_getch(); lcd.setCursor(r1 - '0', r2 - '0'); lcd.write((char)serial_getch()); } else if (rxbyte == 'k') { lcd.clear(); } } |
Kısaca anlatacak olursak;
Önceki yazılarımda özel karakter oluşturmayı anlatmıştım. Her bir bar uzunluğu için çizgi tanımlanmıştır.
1 2 3 4 |
for (int i = 0; i<8; i++) { lcd.createChar(i, custChars[i]); } |
for komutu ile bu tanımlanan bar çizgileri LCD özel karakter hafızasına yüklenmiştir.
1 |
byte rxbyte = serial_getch(); |
Komutu ile seri port okunup gelen veri rxbyte adlı değişkene atanmıştır.
Seri porttan verilen bayt(0 – 255) halinde geldiğin için ilk gelen veri i, j veya k olacaktır. if koşulları ile ilk gelen karaktere bakılmaktadır.
1 2 |
byte r1 = serial_getch(); byte r2 = serial_getch(); |
komutları ile satır ve sütün bilgileri alınarak r1 ve r2 değişkenlerine aktarılmıştır.
1 |
lcd.setCursor(r1 - '0', r2 - '0'); |
Bu komut ile gelen sütun ve satır bilgilerine göre LCD kursorü o konuma alınmaktadır.
1 |
lcd.write((uint8_t)(serial_getch() - 97)); |
Bu komutu biraz detaylandıracak olursak; Winampın gönderdiği komutların son harfi a,b,c,d,e,f,g,h olmaktadır. ‘a’ karakteri ASCII tabloda 10luk tabanda 97 sayısına denk gelmektedir. serial_getch() – 97 formülünde gelen veri 97 sayısından çıkarılır. Yani ‘a’ geldiği anda LCD hafızasındaki 0. karakter çağırılır. ‘b’ geldiğinde 98 – 97 olur ve hafızada ki 1. karakter çağrılır. Böylece gelen veriye göre bar yüksekliği değiştirilir.
Şimdi eklenti için ayar yapmamız gerekiyor.
Konunun üst kısımlarında “C:\” adresine lcd_analyzer.ini adlı bir dosya atmıştık. Bilgisayar Arduinoyu seri port bağlantısı olarak gördüğü için belirli bir port adresi atayacaktır. Bu adresler COM1, COM3, COM10 gibi olabilir. Bu port adresini Aygıt Yöneticisini açarak Bağlantı noktaları (COM ve LPT) kısmından görebiliriz. Orada yazan port adını not edelim.
Bende Arduinonun bağlı olduğu port COM3’dür.
lcd_analyzer.ini dosyasını açalım.
[lcd_analyzer] port=COM8baud_rate=19200
update_interval=5
Dosya içinde üstteki yazılar bulunmaktadır. port=COM8 kısmını Aygıt Yöneticisinden not ettiğimiz port numarasını yazalım. Devremiz bitmiştir.
***Dikkat etmeniz gereken nokta bilgisayar o anlık tek protu kullanıma açtığı için Winamp açıkken Arduino ile seri porttan iletişim kuran tüm programları kapatın. Aksi takdirde Winamp açıldığı anda eklenti “COM port open failed” içerikli bir hata verecektir.
Şimdi Winamp programından bir müzik açalım ve LCDye bakalım.
Bunu direk ses cikisindan alabilir miyiz
Alamayız çünkü bilgisayarda çalan müziğin bant bilgisi seri port üzerinden geliyor. Ses çıkışından almak için ADC modülü ile dönüştürüp sonra bunu fft ile çözümleyip istediğin bantları ayrıştırman gerek ancak bunu arduino gibi düşük hızlı kartların/entegrelerin yapması çok zor. MSGEQ7 adlı entegre direk ses çıkışından gelen sesi 7 kanala ayrıştırıp sana 7 bantı dijital veri olarak gönderiyor. Böyle bir entegre ile direk ses çıkışından spektrum analizör yapabilirsin.
Uzun zamandır aradığım içerikdi sağolun
Yine harika bir konu olmuş
İşinize yaradıysa ne mutlu bana.
fantastic put up, very informative. I wonder why the other experts of this sector do not realize this. You should continue your writing. I am sure, you’ve a huge readers’ base already!
I’ve found quite a lot of useful info on your website this page in particular. Thank you for sharing.