İçindekiler:

Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma: 9 Adım
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma: 9 Adım

Video: Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma: 9 Adım

Video: Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma: 9 Adım
Video: Arduino Ses Kaydedici ISD1820 ve Pir Sensörü Kullanımı 2024, Aralık
Anonim
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma
Arduino ve DAC ile Ses Ses Dosyalarını (Wav) Çalma

Wav dosyasını Audio'yu Audino SD kartınızdan oynatın. Bu Eğitilebilir Tablo, SdCard'ınızdaki bir wav dosyasının basit bir devre aracılığıyla bir hoparlöre nasıl çalınabileceğini size gösterecektir.

wav dosyası 8 bit mono olmalıdır. 44 KHz dosyalarını oynatmada sorun yaşamadım.

Yüksek sadakat olmasa da, ses kalitesi çok tatmin edicidir.

Seri monitör, dosyayı seçmek için kullanılır. Dosyalar adlog adlı bir klasörde olmalıdır.

Bu talimat, wav kayıtlarını SdCard'a kaydettiğim önceki bir projeden geliyor:

Devre, ucuz bir 8 bit dijital-analog dönüştürücü (DAC) ve tek çipli bir ses yükseltici kullanır.

Kesintileri ayarlamak için önemli bölümler Amanda Ghassaei'nin mükemmel makalesinden alınmıştır:

Adım 1: Gereksinimler

Gereksinimler
Gereksinimler
Gereksinimler
Gereksinimler

Arduino- Mega kullanıyorum, ancak Uno'nun çalışmaması için hiçbir sebep yok.

SdCard okuyucu- program şunlar için yapılandırılmıştır: Logic Conversion V2 ile Düzenlenmiş MicroSD Breakout Board

SdCard kurulum ayrıntıları için bu talimata bakın:

DAC0832 LCN- mükemmel bir 8 bit dijitalden analoga dönüştürücü- Birkaç pound.

LM386 N-1 Op amp- cips kadar ucuz

20 yollu çip soketi

8 yollu çip soketi

9 volt güç kaynağı - bir pil yapacaktır.

LM336 2,5 V voltaj referansı

10uF Kapasitör * 3 (9V'dan fazla herhangi bir voltaj)

10 ohm direnç

50nF kapasitör- (Veya yakın bir yerde-47nF, 56nf, 68nf- yapacak)

220uF Kapasitör

64 ohm hoparlör

10K lineer potansiyometre

Arduino ve devre arasındaki 8 veri hattını bağlamak için kablo-

Uno'da 8 bağlantı aynı hizada, Mega'da ise çiftler halinde.

Mega'da 10 yollu IDC başlıklı 10 yollu şerit kablo kullandım. (2 kablo yedektir)

0V, 9V ve DAC çıkışı için soket konnektörleri

Bakır şerit levha, lehim, tel, kesiciler vb.

2. Adım: Özellikler

Özellikler
Özellikler

Seri, 115200 baud'a ayarlandı.

Mega kullanan Hobbytronics MicroSD Breakout Board desteği mevcuttur. Çip seçimi ve diğer bağlantı noktaları Mega ve Uno arasında değişecektir.

Wav dosyaları adlog adlı bir dizinde bulunmalıdır - Başka bir ad vermekten çekinmeyin ve gerekli kodlamayı yeniden düzenleyin.

wav dosyası 8 bit mono olmalıdır. 44KHz'e kadar test ettim.

Seri monitör, wav dosyalarını adlog klasöründe görüntüler. Dosya adları, monitör çıkış satırından gönderilir.

Dosya boyutu yalnızca SdCard boyutuyla sınırlıdır.

3. Adım: Başlarken

Başlarken
Başlarken

SD kart okuyucuyu bağlayın. Bunlar Mega için bağlantılar.

0, 5V

52 numaralı pime CLK

D0'dan 50'ye pin

D1'den pin 51'e

CS'den pin 53'e

(Uno bağlantı noktası bağlantısı için tedarikçilerin web sitesine bakın)

Bu aşamada kartınızın çalışıp çalışmadığını test etmek isteyeceksiniz - satıcı tarafından sağlanan komut dosyalarını kullanın.

Küçük bir devre yapmamız gerekiyor

Arduino'dan bir ses bayt akışı göndereceğiz.

Bu sayılar 0 ile 255 arasındadır. Gerilimi temsil ederler.

Sessizlik 127-128'dir.

255, tek yönlü hoparlör konisidir.

0, diğer taraftan hoparlör konisidir.

Böylece ses, hareketli hoparlör konileri oluşturan değişen voltajlar oluşturan kayıtlı sayılar olarak kaydedilir.

Arduino üzerindeki 8 satırdan sayıları aynı anda bir "port" kullanarak gönderebiliriz.

8 hattı bir dijital-analog dönüştürücüye beslersek, kalayda ne diyorsa onu yapar ve dijital sayıyla orantılı bir analog voltaj üretir.

O zaman tek yapmamız gereken voltajı küçük bir işlemsel yükselticiye ve ardından bir hoparlöre paketlemek.

Adım 4: Küçük Devre

Küçük Devre
Küçük Devre
Küçük Devre
Küçük Devre
Küçük Devre
Küçük Devre
Küçük Devre
Küçük Devre

DAC0832 LCN

Bu süper, ucuz bir 8 bit Dijitalden analoga dönüştürücüdür. (DAC)

Bir dizi veri tutma, veri örnek satırı ile tamamen kontrol edilebilir.

Veya "Akış işlemi" içinde hepsini otomatik olarak yapacak şekilde ayarlanabilir.

Kılavuzdan alıntı yapmak için:

Basitçe CS, WR1, WR2 ve XFER'i topraklamak ve ILE'yi yüksek bağlamak, her iki dahili kaydın da uygulanan dijital girişleri (akış) izlemesine ve DAC analog çıkışını doğrudan etkilemesine izin verir.

Tamam, yonga setine dört bağlantı düşük ve bir tanesi 9V'a ayarlanmış - kolay.

Herhangi bir negatif voltaj istemiyoruz, bu yüzden kılavuz "voltaj anahtarlama modunu" kullanmamız gerektiğini söylüyor ve diyagramı veriyorlar.

Tek yapmamız gereken, önerdikleri amfi yerine küçük bir Ses amfisi kullanmak.

LM386-N Ses Amplifikatörü

Amp'in kılavuzu, minimum parça şeması sağlar - 20'lik bir kazanç sağlar (Bizim için çok fazla - ancak ses kontrolü vardır).

Tek yapmamız gereken, sadece AC sinyallerini yükseltmek için DAC ile amfi arasına bir kapasitör eklemek.

Ayrıca çiplerimizin her birinin besleme pimine yakın bir çift kapasitör eklemeliyiz, aksi takdirde 9V kaynağımızdan uğultu alacağız.

Adım 5: Havyayı Çıkarın

Havyayı Çıkarın
Havyayı Çıkarın
Havyayı Çıkarın
Havyayı Çıkarın
Havyayı Çıkarın
Havyayı Çıkarın

Devre basit olduğu için darbe hesabı vermek niyetinde değilim.

İşte bazı işaretçiler:

  • En az 28 x 28 delikli bir Bakır şerit levha parçası hazırlayın. (Evet, beyin cerrahlarının küçültebileceğini biliyorum)
  • Vidalarla monte etmeyi düşünüyorsanız, başlangıçta bunlara izin verin!
  • Çipleri soketlere takın. Çipleri yalnızca her şey kontrol edildiğinde yerleştirin.
  • Giriş kablolarını çıkıştan uzak tutun.
  • Kondansatörler için doğru polariteye dikkat edin.
  • LM336 voltaj referansının temel görünümü için şemaya bakın. Ayar ayağı kullanılmaz ve kesilebilir.
  • DAC'nin 8 numaralı pinine doğrudan bağlantıya dikkat edin- Test için çok kullanışlıdır.
  • Audino'ya şerit kablo ve 10 yollu IDC konektörü ile bağlandım.
  • Uno'da bağlantılar düz bir çizgidedir - 8 giriş bağlantısını tek bir düz çizgide düzenlemenin, satın alınmış, hazır bir 8 yollu konektör ile Arduino'ya bağlanmanıza izin verdiğini görebilirsiniz.

Tamamlandığında, lehimlemeyi kontrol edin ve bakır parçalar arasındaki boşlukları kontrol edin.

36 tpi'lık küçük bir demir testere bıçağını enkazları temizlemek için çok faydalı buluyorum. Bıçağın tespit pimlerini çıkarıyorum ve bıçağın ucunu rayın içine kaydırıyorum- Belli ki bıçak bir çerçeve içinde değil.

Adım 6: DAC'yi Test Etme

DAC'yi test etme
DAC'yi test etme

Devre ve Arduino arasındaki Bağlantıyı kapalı bırakın.

Devrenizdeki ses kontrolünü orta noktaya ayarlayın.

Yeni devrenize 9V DC Gücü açın.

Devrenin iyi olduğunu kontrol edin - Devreniz için herhangi bir sorumluluk kabul edemem!

Kapat

Devrenizi Arduino'ya bağlayın.

Mega'da 22-29 pinlerini kullanın. (PORTA) Yukarıdaki iki 5V pini karıştırmayın!

Uno'da 0-7 pinlerini kullanın. Bu PORTD

Güç kaynağınızın 0V'sini Arduino'daki 0V'a bağlayın.

Güç ver.

Bu test programını açın DAC_TEST

UNO için, PORTA'ya yapılan tüm referansları PORTD'ye değiştirin

DDRA'yı DDRD ile değiştirin - bu talimat, 8 satırın tümünü tek seferde çıktı verecek şekilde ayarlar. Bu, veri yönü kaydıdır.

Seri monitörünüzü 115200'e ayarlayın.

DAC çıkışı ile OV arasına bir voltmetre bağlayın

Program çıkışı 255- tüm hatlar açık - maksimum voltaja ayarlayacaktır.

Çıkış 128- maksimum voltajın yarısı.

Çıkış 0- sıfır voltaj (Ya da muhtemelen neredeyse sıfır).

Daha sonra bit düzeyinde adım atacaktır: 1, 2, 4, 8, 16, 32, 64, 128

Voltaj sürekli artmalıdır.

Sayı artarken voltaj düşerse, muhtemelen birbirine bağlanan iki kablonuz ters çevrilir.

Voltaj değiştikçe hoparlörün sessizce tıkladığını da duymalısınız.

Adım 7: Wav Başlığını Okumak

Wav Başlığını Okumak
Wav Başlığını Okumak

Wav dosyaları belirli bir frekans ve veri boyutunda kaydedilir.

Bu bilgi, bir wav dosyasının başlangıcındaki 44 baytlık bir başlıkta bulunur.

Bazı yazılımlar başlığı genişletse de (bayt 35'ten sonra), veri boyutunun konumunun bulunmasını zorlaştırır.

Başlığı okumak için bir arabellek oluşturuyoruz ve dosyanın başlangıcını kopyalıyoruz.

Frekans, dosyaya 24 bayttan başlayarak 4 bayt olarak saklanır.

// wav dosya başlığında belirtilen frekansı oku

bayt başlığı[60]

tempfile.seek(0);

tempfile.read(headbuf, 60);

retval=kafa[27];

retval=(retval<<8) | kafa başlığı[26];

retval=(retval<<8) | kafa tamponu[25];

retval=(retval<<8) | kafa tamponu[24];

Serial.print(F("Dosya Frekansı"));

Serial.print(geri alma);

Veri boyutu bilgisini bulmanın en iyi yolu, başlıkta "veri" kelimesini aramaktır.

Ardından, uzun değeri oluşturan onu takip eden 4 baytı çıkarın.

imzasız uzun retval;

int mypos=40;

for (int i=36; i<60;i++) {

if (headbuf == 'd') {

if(headbuf[i+1]=='a') {

if(headbuf[i+2]=='t') {

if(headbuf[i+3]=='a') {

// sonunda elimizde

mypos=i+4;

ben=60;

}

}

}

}

}

tempfile.seek(mypos);

retval=headbuf[mypos+3];

retval=(retval<<8) | kafa buf[mypos+2];

retval=(retval<<8) | kafa buf[mypos+1];

retval=(retval<<8) | kafa buf[mypos];

Tamam, veri uzunluğuna ve frekansına sahibiz!

Ses verileri, veri uzunluğu değerini oluşturan 4 baytı takip eder.

Adım 8: Kesinti, Kesinti…

Kesinti, Kesinti…
Kesinti, Kesinti…

Frekans bilgilerini, gerekli frekansta veya yakınında bir yazılım kesintisi oluşturmak için kullanırız.

Kesinti her zaman tam olarak ayarlanamayabilir, ancak yeterlidir. Dosyadan okunan frekans, setintrupt alt yordamına iletilir.

void setintrupt(float freq){float bitval=8; // 8 bit zamanlayıcı 0 ve 2 için 8, zamanlayıcı 1 bayt için 1024

setocroa=(16000000/(freq*bitval)) - 0,5;

// Setocroa değeri, -1'in çıkarılmasını gerektirir. Ancak en yakın 0,5'e 0,5 tur ekleyerek

// Zamanlayıcının çözünürlüğü sınırlıdır

// Nihai olarak bitval büyüklüğüne göre belirlenir

kli(); // kesmeleri devre dışı bırak // timer2 kesmesini ayarla

TCCR2A = 0; // tüm TCCR2A kaydını 0'a ayarla

TCCR2B = 0; // TCCR2B için aynı

TCNT2 = 0; // sayaç değerini 0 olarak başlat

// frekans (hz) artışları için karşılaştırma eşleşme kaydını ayarla

OCR2A = setokroa; // = (16*10^6) / (frekans*8) - 1 (<256 olmalıdır)

// CTC modunu aç

TCCR2A |= (1 << WGM21); // 8 ön ölçekleyici için CS21 bitini ayarla

TCCR2B |= (1 << CS21); // zamanlayıcı karşılaştırma kesmesini etkinleştir

// TIMSK2 |= (1 << OCIE2A); // bu, aşağıdaki satırda olduğu gibi çalışır

sbi(TIMSK2, OCIE2A); // zamanlayıcı 2'de kesmeyi etkinleştir

ben(); // kesmeleri etkinleştir

Zeki okuyucular sbi(TIMSK2, OCIE2A) tespit etmiş olacaktır.

Kayıt bitlerini ayarlamak ve temizlemek için birkaç (internetten edinilen) işlev kurdum:

// Kayıt bitlerini temizlemeyi tanımlar#ifndef cbi

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#endif

// Kayıt bitlerini ayarlamayı tanımlar

#ifndef sbi

#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#endif

Bu işlevler, kesmeyi ayarlamak veya temizlemek için kolay bir çağrı sağlar.

Yani kesme çalışıyor, ne yapmasını sağlayabiliriz?

9. Adım: Kesintiler ve Çift Arabelleğe Alma

Kesintiler ve Çift Arabelleğe Alma
Kesintiler ve Çift Arabelleğe Alma
Kesintiler ve Çift Arabelleğe Alma
Kesintiler ve Çift Arabelleğe Alma

22 Khz'de her 0,045 ms'de bir ses verisi bayt çıkışı verilir

512 bayt (arabellek boyutu) 2,08 ms'de okunur.

Böylece arabellek, tek bir yazma döngüsünde SDCard'dan okunamaz.

Ancak porta 23.22ms'de 512 bayt yazılır.

Yani tek yapmamız gereken, arabellek her boşaldığında okunacak yeni bir dosya oluşturmak ve yeni bir veri bloğu gerekmeden önce verileri almak için yeterli zamanımız var… İki arabellek kullandığımızı varsayalım, birini doldururken diğerini boşaltıyoruz.

Bu çift tamponlamadır.

Dosya okuması, tekrarlanan kesinti nedeniyle yavaşlar, ancak yapılır.

Bufa ve bufb adında iki adet 512 baytlık arabellek kurdum.

Bayrak alanı doğruysa, porta'dan okuruz, aksi halde portb'den okuruz

Arabellek konumu (bufcount) arabellek boyutuna (BUF_SIZE 512) ulaştığında readit adlı bir bayrağı true olarak ayarlarız.

Void döngü rutini bu bayrağı arar ve bir blok okuması başlatır:

if(oku){if (! alan){

// bufa'ya okunan SDCard bloğunu başlat

tempfile.read(bufa, BUF_SIZE);

} Başka {

// bufb'ye okunan SDCard bloğunu başlat

tempfile.read(bufb, BUF_SIZE);

}

okuma=yanlış;

}

Rutin bayrakları bittiğinde readit=false.

Kesme rutini içinde readit== false olup olmadığını kontrol ederek void döngüsünün bitip bitmediğini kontrol etmeliyiz.

Bu durumda, başka bir okumanın gerekli olduğunu bildiririz ve arabellekleri değiştirmek için alan bayrağını değiştiririz.

SD kart hala okuyorsa, bir okuma (counter--; bufcount--;) izlemeli ve daha sonra tekrar denemek için kesmeden çıkmalıyız. (Ses çıkış sinyalindeki tıklamalar bunun gerçekleştiğini gösterir.)

Tüm veriler okunduğunda kesinti iptal edilir, port yeniden 128 orta gerilim değerine ayarlanır ve ses dosyası kapanır.

dac2.ino betiğini ilk kez çalıştırmadan önce, ses düzeyinizi %50'ye ayarlayın. Bu çok gürültülü olacak, ancak %100'den daha iyi!

Ses kontrolünüz ters çalışıyorsa, 10K potansiyometrenin zıt uçlarındaki uçları değiştirin.

Kulağa nasıl geldiğini bilmeme izin ver.

Önerilen: