Mündəricat:

Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması: 9 Addım
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması: 9 Addım

Video: Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması: 9 Addım

Video: Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması: 9 Addım
Video: Arduino Dərs 2 . Rəqəmsal və Analog siqnal "Serial","digitalRead","analogRead","analogWrite" əmrləri 2024, Iyul
Anonim
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması
Arduino və DAC ilə Audio Səs Fayllarının (Wav) Çalınması

Audino SD kartınızdan wav faylını səsləndirin. Bu Təlimat, SdCard'ınızdakı bir wav faylının dinamikdən sadə bir dövrə ilə necə çalınacağını sizə göstərəcək.

Wav faylı 8 bit mono olmalıdır. 44 KHz faylları oxudanda heç bir problem yaşamadım.

Yüksək sədaqət olmasa da, səs keyfiyyəti çox qənaətbəxşdir.

Fayl seçmək üçün serial monitor istifadə olunur. Fayllar adlog adlı qovluqda olmalıdır.

Bu təlimat, wav yazılarını SdCard-da saxladığım əvvəlki bir layihədən qaynaqlanır:

Dövrə ucuz 8 bitlik rəqəmsaldan analog çeviriciyə (DAC) və tək çipli səs gücləndiricisindən istifadə edir.

Fasilələrin qurulması üçün əsas bölmələr Amanda Ghassaei-nin əla məqaləsindən götürülmüşdür:

Addım 1: Tələblər

Tələblər
Tələblər
Tələblər
Tələblər

Arduino- Meqadan istifadə edirəm, lakin Unonun işləməməsi üçün heç bir səbəb yoxdur.

SdCard oxucu-proqram aşağıdakılar üçün qurulmuşdur: Logic Conversion V2 ilə tənzimlənən MicroSD Breakout Board

SdCard quraşdırma təfərrüatları üçün bu təlimata baxın:

DAC0832 LCN- analoq çeviriciyə əla 8 bit rəqəmsal- Bir neçə kilo.

LM386 N-1 Op amp- çipslər kimi ucuzdur

20 yollu çip yuvası

8 tərəfli çip yuvası

9 volt enerji təchizatı- bir batareya edəcək.

LM336 2.5 V gərginlikli istinad

10 uF kondansatör * 3 (hər hansı bir gərginlik 9 V -dan çox)

10 ohm müqavimət

50nF kondansatör (və ya 47nF, 56nf, 68nf yaxınlığında bir yerdə edəcək)

220 uF kondansatör

64 ohm dinamik

10K xətti potensiometr

Arduino ilə dövrə arasındakı 8 məlumat xəttini birləşdirən kabel

Uno -da 8 əlaqə xətti, Mega -da cüt -cütdür.

Mega -da 10 tərəfli IDC başlığı olan 10 tərəfli lent kabeli istifadə etdim. (2 tel ehtiyatda)

0V, 9V və DAC çıxışı üçün soket bağlayıcıları

Mis şerit lövhəsi, lehim, tel, kəsicilər və s

Addım 2: Xüsusiyyətlər

Xüsusiyyətlər
Xüsusiyyətlər

Seriya 115200 baud olaraq təyin olunur.

Mega istifadə edərək Hobbytronics MicroSD Breakout Board üçün dəstək mövcuddur. Çip seçimi və digər portlar Mega və Uno arasında dəyişəcək.

Wav faylları adlog adlı bir qovluqda olmalıdır- Başqa bir şey adlandırmaqdan və lazımi kodlamanı yenidən təşkil etməkdən çəkinməyin.

Wav faylı 8 bit mono olmalıdır. 44 KHz -ə qədər test etdim.

Serial monitor, wav fayllarını adlog qovluğunda göstərir. Fayl adları monitorun çıxış xəttindən göndərilir.

Fayl ölçüsü yalnız SdCard ölçüsü ilə məhdudlaşır.

Addım 3: Başlayın

Başlanğıc
Başlanğıc

SD kart oxuyucusunu qoşun. Bunlar Mega üçün əlaqələrdir.

0, 5V

PİN 52 -ə keçin

D0 -dan 50 -ə qədər

D1 -dən 51 -ə qədər

CS -ni 53 -ə bağlayın

(Uno liman bağlantısı üçün təchizatçıların veb saytına baxın)

Kartınızın bu mərhələdə işlədiyini yoxlamaq istəyəcəksiniz- satıcı tərəfindən verilən skriptlərdən istifadə edin.

Kiçik bir dövrə etməliyik

Arduinodan audio bayt axını göndərəcəyik.

Bu ədədlər 0 ilə 255 arasındadır. Gərginliyi təmsil edirlər.

Səssizlik 127-128-dir.

255, bir tərəfli dinamik konusudur.

0, başqa bir şəkildə dinamik konusudur.

Beləliklə, səs, dəyişən gərginlik yaradan və hərəkətli dinamik konusları yaradan, saxlanılan nömrələr kimi qeyd olunur.

Arduino üzərindəki 8 xətdən nömrələri eyni anda bir "liman" istifadə edərək göndərə bilərik.

8 xətti rəqəmsaldan analoqa çeviriciyə versək, qalayda dediklərini edər və rəqəmsal rəqəmlə mütənasib bir analoq gərginlik çıxarar.

Bundan sonra etməli olduğumuz şey, gərginliyi kiçik bir əməliyyat gücləndiricisinə və sonra dinamikə bağlamaqdır.

Addım 4: Kiçik Dövrə

Kiçik Dövrə
Kiçik Dövrə
Kiçik Dövrə
Kiçik Dövrə
Kiçik Dövrə
Kiçik Dövrə
Kiçik Dövrə
Kiçik Dövrə

DAC0832 LCN

Bu əla, ucuz 8 bitlik rəqəmsaldan analoqa çeviricidir. (DAC)

Bir sıra məlumat saxlama, məlumat nümunəsi xətləri ilə tam nəzarət edilə bilər.

Yoxsa "Əməliyyat axını" nda hamısını avtomatik olaraq etmək üçün konfiqurasiya edilə bilər.

Təlimatdan sitat gətirmək üçün:

Sadəcə CS, WR1, WR2 və XFER-in topraklanması və ILE-nin yüksək bağlanması hər iki daxili reyestrə tətbiq olunan rəqəmsal girişləri (axını) izləməyə və DAC analoq çıxışına birbaşa təsir etməyə imkan verir.

Tamam ki, çipə dörd dəstə aşağı və bir dəstə 9V - asandır.

Mənfi gərginliyin olmasını istəmirik, buna görə təlimatda "gərginlik keçid rejimi" istifadə etməyimiz lazım olduğu deyilir və onlar diaqramı təmin edirlər.

Etməyimiz lazım olan şey, təklif etdiklərinin əvəzinə kiçik bir Audio amplifikatörü əvəz etməkdir.

LM386-N Audio Gücləndirici

Amp təlimatı, minimum bir hissə diaqramı təmin edir- 20 qazanc təmin edir (Bizim üçün çox çoxdur, ancaq səs idarəedicisinə malikdir).

Etməli olduğumuz şey, yalnız AC siqnallarını gücləndirmək üçün DAC və amp arasında bir kondansatör əlavə etməkdir.

Çiplərimizin hər birinin təchizat pininə yaxın bir neçə kondansatör əlavə etməliyik, əks halda 9V təchizatımızdan zümzümə alacağıq.

Addım 5: Lehimləmə Dəmirindən çıxın

Lehimləmə Dəmirindən çıxın
Lehimləmə Dəmirindən çıxın
Lehimləmə Dəmirindən çıxın
Lehimləmə Dəmirindən çıxın
Lehimləmə Dəmirindən çıxın
Lehimləmə Dəmirindən çıxın

Dövrə sadə olduğu üçün zərbə hesabına zərbə vermək fikrində deyiləm.

İşdə bəzi göstəricilər:

  • Ən az 28 x 28 dəlik olan bir mis zolaq lövhəsi hazırlayın. (Bəli, bilirəm ki, beyin cərrahları bunu kiçiltə bilər)
  • Vidalarla montaj etmək niyyətindəsinizsə, başlanğıcda icazə verin!
  • Çipləri prizlərə quraşdırın. Çipləri yalnız hər şey yoxlanıldıqdan sonra daxil edin.
  • Giriş tellərini çıxışdan uzaq tutun.
  • Kondansatörler üçün doğru polariteyi müşahidə edin.
  • LM336 gərginlik istinadının əsas görünüşü üçün diaqrama baxın. Ayar ayağı istifadə edilmir və kəsilə bilər.
  • DAC-ın 8-ci pinlə birbaşa əlaqəsinə diqqət yetirin- Test üçün çox faydalıdır.
  • Audino -ya lent kabel və 10 yollu IDC konnektoru ilə qoşuldum.
  • Uno -da əlaqələr düz bir xəttdədir - tapa bilərsiniz ki, 8 giriş bağlantısını bir düz xətdə təşkil etmək, satın alınmış, hazır 8 yollu bir bağlayıcı ilə Arduino ilə əlaqə qurmağa imkan verir.

Tamamlandıqda- lehimləmə və mis izlər arasındakı boşluqları yoxlayın.

Dağıntıları təmizləmək üçün çox faydalı olan 36 tpi kiçik bir testere bıçağı tapıram. Bıçağın yerləşmə sancaqlarını çıxarıram və bıçağın ucunu yola sürüşdürürəm- Bıçaq çərçivədə deyil.

Addım 6: DAC testi

DAC testi
DAC testi

Arduino və Circuit arasındakı əlaqəni kəsin.

Dövrünüzdəki səs tənzimləyicisini yarıya qoyun.

9V DC Gücünü yeni dövrə yandırın.

Dövrənin yaxşı olduğunu yoxlayın- Sizin dövrəniz üçün heç bir məsuliyyət daşımıram!

Söndürmək

Dövrənizi Arduinoya bağlayın.

Mega-da 22-29 pinlərindən istifadə edin. (PORTA) Yuxarıdakı iki 5V pinini səhv salmayın!

Uno-da 0-7 sancaqlar istifadə edin. Bu PORTD

0V enerji təchizatını Arduino üzərindəki 0V -ə qoşun.

Gücləndirin.

Bu test proqramını açın DAC_TEST

UNO üçün PORTA ilə əlaqəli bütün istinadları PORTD ilə əvəz edin

DDRA-nı DDRD ilə əvəz edin- bu təlimat bütün 8 xətləri bir anda çıxarmaq üçün təyin edir. Bu məlumat istiqaməti reyestridir.

Serial monitorunuzu 115200 olaraq təyin edin.

DAC çıxışı ilə OV arasında bir voltmetr bağlayın

Proqram çıxışı 255- bütün xətləri açıq qoyacaq - maksimum gərginlik.

Maksimum gərginliyin 128 yarısı.

Çıxış 0- sıfır gərginlik (və ya ehtimal ki, demək olar ki, sıfır).

Daha sonra addım -addım irəliləyəcək: 1, 2, 4, 8, 16, 32, 64, 128

Gərginlik durmadan artmalıdır.

Sayı artdıqca gərginlik geri düşərsə, ehtimal ki, bir -birinə bağlı olan iki telin tərsinə çevrilmiş olarsınız.

Gərginlik dəyişdikcə dinamikin sakitcə tıkladığını da eşitməlisiniz

Addım 7: Wav Başlığını oxuyun

Wav Başlığını oxuyun
Wav Başlığını oxuyun

Wav faylları müəyyən bir tezlik və məlumat ölçüsü ilə qeyd olunur.

Bu məlumat bir wav faylının başında olan 44 baytlıq başlıqdadır.

Bəzi proqramlar başlığı genişləndirsə də (bayt 35 -dən sonra), məlumat ölçüsünün yerini tapmaq çətinləşir.

Başlığı oxumaq üçün bir tampon yaradırıq və faylın başlanğıcını kopyalayırıq.

Tezlik faylda 24 baytdan başlayaraq 4 baytda saxlanılır.

// wav fayl başlığında göstərilən tezliyi oxuyun

bayt başlıq [60]

tempfile.seek (0);

tempfile.read (headbuf, 60);

retval = baş başı [27];

retval = (retval << 8) | baş örtüyü [26];

retval = (retval << 8) | baş örtüyü [25];

retval = (retval << 8) | baş örtüyü [24];

Serial.print (F ("Fayl Tezliyi"));

Serial. çap (retval);

Məlumat ölçüsü məlumatlarını tapmağın ən yaxşı yolu başlıqdakı "data" sözünü axtarmaqdır.

Sonra uzun dəyəri təşkil edən 4 baytı çıxarın

imzasız uzun retval;

int mypos = 40;

üçün (int i = 36; i <60; i ++) {

əgər (headbuf == 'd') {

əgər (headbuf [i+1] == 'a') {

əgər (headbuf [i+2] == 't') {

əgər (headbuf [i+3] == 'a') {

// nəhayət bizdə var

mypos = i+4;

i = 60;

}

}

}

}

}

tempfile.seek (mypos);

retval = headbuf [mypos+3];

retval = (retval << 8) | baş boşluğu [mypos+2];

retval = (retval << 8) | baş boşluğu [mypos+1];

retval = (retval << 8) | headbuf [mypos];

OK məlumatların uzunluğuna və tezliyinə sahibik!

Səs məlumatları, məlumat uzunluğu dəyərini təşkil edən 4 baytı izləyir.

Addım 8: ara ver, ara ver …

Ara, ara ver …
Ara, ara ver …

Lazım olan tezlikdə və ya yaxınlığında bir proqram kəsilməsi yaratmaq üçün tezlik məlumatlarından istifadə edirik.

Fasilə həmişə dəqiq olaraq təyin edilə bilməz, ancaq kifayətdir. Fayldan oxunan tezlik setintrupt alt proqramına ötürülür.

boşluq setintrupt (float freq) {float bitval = 8; // 8 bitlik taymerlər üçün 0 və 2, timer 1 bayt üçün 1024

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

// Setocroa dəyəri -1 çıxarmağı tələb edir. Ancaq ən yaxın 0,5 -ə 0,5 tur əlavə edin

// Taymerin qətnaməsi məhduddur

// Nəticədə bitvalın böyüklüyü ilə müəyyən edilir

cli (); // fasilələri deaktiv edin // taymer2 kəsilməsini təyin edin

TCCR2A = 0; // bütün TCCR2A reyestrini 0 olaraq təyin edin

TCCR2B = 0; // TCCR2B üçün eyni

TCNT2 = 0; // sayğac dəyərini 0 -a endir

// tezlik (hz) artımları üçün müqayisə matç qeydini təyin edin

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

// CTC rejimini yandırın

TCCR2A | = (1 << WGM21); // 8 prescaler üçün CS21 bitini təyin edin

TCCR2B | = (1 << CS21); // timer müqayisə kəsilməsini aktiv edin

// TIMSK2 | = (1 << OCIE2A); // bu, aşağıdakı sətirdə olduğu kimi işləyir

sbi (TIMSK2, OCIE2A); // timer 2 -də kəsilməni aktiv edin

sei (); // fasilələri aktiv edin

Ağıllı oxuyanlar sbi (TIMSK2, OCIE2A) görəcəklər

Qeyd bitlərini təyin etmək və təmizləmək üçün bir neçə (internetdən əldə edilmiş) funksiyanı qururam:

// Qeyd bitlərinin təmizlənməsini təyin edir#ifndef cbi

#müəyyən cbi (sfr, bit) (_SFR_BYTE (sfr) & = ~ _BV (bit))

#endif

// Qeydiyyat bitlərinin təyin olunmasını təyin edir

#ifndef sbi

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

#endif

Bu funksiyalar fasiləni qurmaq və ya silmək üçün asan bir zəng təmin edir.

Beləliklə, fasilə davam edir, onu nə edə bilərik?

Addım 9: Fasillər və ikiqat tamponlama

Fasilələr və ikiqat tamponlama
Fasilələr və ikiqat tamponlama
Fasilələr və ikiqat tamponlama
Fasilələr və ikiqat tamponlama

22 Khz -də hər 0.045 ms -də bir bayt audio məlumat çıxır

512 bayt (tampon ölçüsü) 2.08 ms -də oxunur.

Beləliklə, tampon SDCard -dan bir yazma dövründə oxuna bilməz.

Bununla birlikdə limana 23.22 ms ərzində 512 bayt yazılır.

Beləliklə, etməli olduğumuz şey, hər dəfə tampon boşaldıqda oxunan yeni bir fayl qurmaqdır və yeni bir məlumat bloku tələb olunmadan əvvəl məlumatları əldə etmək üçün kifayət qədər vaxtımız var … İki tampondan istifadə etdiyimizi fərz etsək, birini doldurarkən birini boşaldarıq.

Bu ikiqat tamponlama.

Oxunan fayl təkrarlanan fasilə ilə yavaşlayacaq, ancaq tamamlanacaq.

Bufa və bufb adlı iki 512 baytlıq tampon qurdum.

Əgər bayraq doğrudursa, portadan oxuyuruq, əks halda portbdan oxuyuruq

Tampon mövqeyi (bufcount) tampon ölçüsünə çatanda (BUF_SIZE 512) readit adlı bir bayrağı doğru olaraq təyin edirik.

Void loop rutini bu bayrağı axtarır və blok oxumağa başlayır:

if (readit) {if (! aready) {

// bufaya oxumaq üçün SDCard blokunu başladın

tempfile.read (bufa, BUF_SIZE);

} başqa {

// bufb -də oxumaq üçün SDCard blokunu işə salın

tempfile.read (bufb, BUF_SIZE);

}

readit = yalan;

}

Rutin bayraqlar bitdikdə readit = false.

Fasilə rejimində, readit == false olub olmadığını yoxlayaraq boşluq döngəsinin bitdiyini yoxlamalıyıq.

Bu vəziyyətdə, başqa bir oxunuşa ehtiyac olduğunu bildiririk və tamponları dəyişdirmək üçün aready bayrağını dəyişirik.

SDcard hələ də oxuyursa, bir oxunuşu geri saymalıyıq (counter--; bufcount--;) və sonra yenidən cəhd etmək üçün fasilədən çıxmalıyıq. (Səs çıxışı siqnalının klikləri bunun baş verdiyini göstərir.)

Bütün məlumatlar oxunduqda kəsmə ləğv edilir, port yenidən orta gərginlik dəyərinə 128 olaraq təyin olunur və audio fayl bağlanır.

Dac2.ino skriptini ilk dəfə işə salmadan əvvəl səs səviyyənizi 50%olaraq təyin edin. Bu çox yüksək olacaq, amma 100%-dən daha yaxşıdır!

Səs nəzarətiniz tərs işləyirsə, 10K potansiyometrin əks tərəflərindəki telləri dəyişdirin.

Necə səsləndiyini mənə bildirin.

Tövsiyə: