Cuprins:

Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC: 9 pași
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC: 9 pași

Video: Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC: 9 pași

Video: Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC: 9 pași
Video: Modul Audio MP3 VS1053 2024, Iulie
Anonim
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC
Redarea fișierelor audio audio (Wav) cu un Arduino și un DAC

Redați fișierul WAV de pe cardul SD Audino. Acest instructable vă va arăta cum poate fi redat un fișier wav de pe SdCard printr-un circuit simplu către un difuzor.

Fișierul wav trebuie să fie mono pe 8 biți. Nu am avut probleme la redarea fișierelor de 44 KHz.

Deși nu este fidelitate, calitatea sunetului este foarte satisfăcătoare.

Monitorul serial este utilizat pentru a selecta fișierul. Fișierele trebuie să se afle într-un folder numit adlog.

Acest instructable rezultă dintr-un proiect anterior în care am salvat înregistrări wav pe SdCard:

Circuitul folosește un convertor ieftin digital pe analog pe 8 biți (DAC) și un amplificator audio cu un singur cip.

Secțiunile cheie pentru configurarea întreruperilor au fost preluate din excelentul articol de Amanda Ghassaei:

Pasul 1: Cerințe

Cerințe
Cerințe
Cerințe
Cerințe

Arduino- Eu folosesc Mega, totuși nu există niciun motiv pentru care Uno să nu funcționeze.

Cititor SdCard - programul este configurat pentru: MicroSD Breakout Board Regulated with Logic Conversion V2

Vedeți acest instructable pentru detalii despre configurarea SdCard:

DAC0832 LCN - un excelent convertor digital pe analog pe 8 biți - Câteva kilograme.

LM386 N-1 Op amplificator - ieftin ca jetoane

Soclu cu 20 de căi

Soclu cu 8 căi

Alimentare de 9 volți - o baterie va funcționa.

LM336 2,5 V tensiune de referință

10uF Condensator * 3 (orice tensiune mai mare de 9V)

Rezistor de 10 ohmi

50nF condensator- (Sau undeva aproape-47nF, 56nf, 68nf- va face)

Condensator 220uF

Difuzor de 64 ohm

Potențiometru liniar 10K

Cablu pentru a lega cele 8 linii de date dintre Arduino și circuit-

Pe Uno cele 8 conexiuni sunt în linie, pe Mega sunt în perechi.

Pe Mega am folosit un cablu panglică cu 10 căi, cu un antet IDC cu 10 căi. (2 fire sunt de rezervă)

Conectori de soclu pentru ieșire 0V, 9V și DAC

Placă de cupru, lipit, sârmă, freze etc.

Pasul 2: Specificațiile

Specificațiile
Specificațiile

Serial setat la 115200 baud.

Există suport pentru placa Hobbytronics MicroSD Breakout Board folosind un Mega. Selectarea cipului și alte porturi se vor modifica între Mega și Uno.

Fișierele Wav trebuie să existe într-un director numit adlog- Simțiți-vă liber să-l numiți altceva și să aranjați din nou codarea necesară.

Fișierul WAV trebuie să fie mono pe 8 biți. Am testat până la 44KHz.

Monitorul serial afișează fișierele wav din folderul adlog. Numele fișierelor sunt trimise de pe linia de ieșire a monitorului.

Dimensiunea fișierului este limitată doar de dimensiunea SdCard.

Pasul 3: Introducere

Noțiuni de bază
Noțiuni de bază

Conectați cititorul de card SD. Acestea sunt conexiunile pentru Mega.

0, 5V

CLK la pinul 52

D0 la pinul 50

D1 la pinul 51

CS la pinul 53

(Vedeți site-ul furnizorilor pentru conexiunea la portul Uno)

Veți dori să testați dacă cardul dvs. funcționează în această etapă - utilizați scripturile furnizate de furnizor.

Trebuie să facem un circuit mic

Vom trimite un flux de octeți audio de la Arduino.

Aceste numere sunt cuprinse între 0 și 255. Ele reprezintă tensiunea.

Tăcerea este 127-128.

255 este conul difuzorului într-un singur sens.

0 este conul difuzorului greu invers.

Deci, sunetul este înregistrat ca numere salvate, care creează tensiuni diferite, care creează conuri de difuzor în mișcare.

Putem trimite numerele din 8 linii pe Arduino, simultan, folosind un „port”.

Dacă alimentăm cele 8 linii într-un convertor digital în analog, acesta face ceea ce spune pe tablă și produce o tensiune analogică proporțională cu numărul digital.

Tot ce trebuie să facem atunci este să împachetați tensiunea la un amplificator operațional mic și apoi la un difuzor.

Pasul 4: Circuitul mic

Circuitul mic
Circuitul mic
Circuitul mic
Circuitul mic
Circuitul mic
Circuitul mic
Circuitul mic
Circuitul mic

DAC0832 LCN

Acesta este un convertor excelent, ieftin, digital pe analog pe 8 biți. (DAC)

Poate fi controlat complet cu o serie de linii de păstrare a datelor, eșantion de date.

Sau poate fi configurat pentru a face totul automat în „Flow through operation”.

Pentru a cita manualul:

Pur și simplu legarea la pământ a CS, WR1, WR2 și XFER și legarea ILE high permite ambelor registre interne să urmărească intrările digitale aplicate (flow-through) și să afecteze direct ieșirea analogică DAC.

OK, adică patru conexiuni la setul de cipuri redus și o setare la 9V - ușor.

Nu dorim ca tensiunile negative să iasă, așa că manualul spune că ar trebui să folosim „modul de comutare a tensiunii” și ele furnizează diagrama.

Tot ce trebuie să facem este să înlocuim un amplificator audio mic în loc de cel pe care îl sugerează.

Amplificatorul audio LM386-N

Manualul amplificatorului oferă o diagramă minimă a pieselor - oferind un câștig de 20 (Foarte mult pentru noi - dar are un control al volumului).

Tot ce trebuie să facem este să adăugăm un condensator între DAC și amplificator, astfel încât să amplificăm doar semnalele de curent alternativ.

De asemenea, trebuie să adăugăm câțiva condensatori aproape de pinul de alimentare al fiecăruia dintre cipurile noastre, altfel vom primi zumzet de la sursa noastră de 9V.

Pasul 5: Scoateți fierul de lipit

Scoate fierul de lipit
Scoate fierul de lipit
Scoate fierul de lipit
Scoate fierul de lipit
Scoate fierul de lipit
Scoate fierul de lipit

Deoarece circuitul este simplu, nu intenționez să dau o lovitură de lovitură.

Iată câteva indicații:

  • Pregătiți o bucată de placă de cupru de cel puțin 28 pe 28 de găuri. (Da, știu că chirurgii cerebrali îl pot micșora)
  • Dacă intenționați să îl montați cu șuruburi, permiteți-le la început!
  • Montați așchii pe prize. Introduceți jetoanele numai când totul a fost verificat.
  • Păstrați firele de intrare departe de ieșire.
  • Respectați polaritatea corectă a condensatoarelor.
  • Consultați diagrama pentru vizualizarea de bază a tensiunii de referință LM336. Piciorul de reglare nu este folosit și poate fi tăiat.
  • Rețineți conexiunea directă la pinul 8 al DAC - Este foarte util pentru testare.
  • M-am conectat la Audino cu un cablu ribbon și un conector IDC cu 10 căi.
  • Pe Uno conexiunile sunt în linie dreaptă - este posibil să constatați că aranjarea celor 8 conexiuni de intrare într-o singură linie dreaptă vă permite să vă conectați la Arduino cu un conector cumpărat, gata făcut, cu 8 căi,

Când se termină, verificați lipirea și verificați golurile dintre șinele de cupru.

Mi se pare o lame de fierăstrău junior de 36 tpi foarte utile pentru curățarea resturilor. Îndepărtez știfturile de localizare ale lamei și alunec vârful lamei în șină - Evident, lama nu se află într-un cadru.

Pasul 6: Testarea DAC

Testarea DAC
Testarea DAC

Lăsați conexiunea între circuit și Arduino oprită.

Setați controlul volumului pe circuitul dvs. la jumătatea distanței.

Porniți alimentarea de 9V DC pe noul dvs. circuit.

Verificați dacă circuitul este în regulă - nu pot să-mi asum nicio răspundere pentru circuitul dvs.!

Oprire

Conectați-vă circuitul la Arduino.

Pe Mega folosiți pinii 22-29. (PORTA) Nu confundați cei doi pini de 5V de mai sus!

Pe Uno folosiți pinii 0-7. Acesta este PORTD

Conectați 0V al sursei de alimentare la 0V de pe Arduino.

Porniți.

Deschideți acest program de testare DAC_TEST

Pentru ONU, înlocuiți toate referințele la PORTA la PORTD

Înlocuiți DDRA cu DDRD - această instrucțiune setează toate cele 8 linii pentru a ieși dintr-o dată. Acesta este registrul de direcție a datelor.

Setați monitorul serial la 115200.

Conectați un voltmetru între ieșirea DAC și OV

Programul va seta ieșirea la 255 - toate liniile pornite - tensiunea maximă.

Ieșire 128 - jumătate tensiune maximă.

Ieșire 0- tensiune zero (sau probabil aproape zero).

Apoi, va trece în sens bit: 1, 2, 4, 8, 16, 32, 64, 128

Tensiunea ar trebui să crească constant.

Dacă tensiunea scade în timp ce numărul crește, probabil că aveți două dintre firele de interconectare inversate.

De asemenea, ar trebui să auziți difuzorul făcând clic liniștit pe măsură ce tensiunea se schimbă

Pasul 7: Citirea antetului Wav

Citind antetul Wav
Citind antetul Wav

Fișierele Wav sunt salvate cu o frecvență specificată și dimensiunea datelor.

Aceste informații sunt conținute într-un antet de 44 octeți la începutul unui fișier wav.

Deși unele programe extind antetul (după octetul 35), ceea ce face ca locația dimensiunii datelor să fie mai dificil de localizat.

Pentru a citi antetul creăm un tampon și copiem începutul fișierului.

Frecvența este stocată în 4 octeți, începând cu 24 de octeți în fișier.

// frecvența de citire specificată în antetul fișierului wav

octet headbuf [60]

tempfile.seek (0);

tempfile.read (headbuf, 60);

retval = headbuf [27];

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

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

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

Serial.print (F ("Frecvența fișierului"));

Serial.print (retval);

Cel mai bun mod de a găsi informațiile despre dimensiunea datelor este să căutați cuvântul „date” în antet.

Apoi extrageți cei 4 octeți care îl urmează, care alcătuiesc valoarea lungă

retval lung nesemnat;

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') {

// în sfârșit o avem

mypos = i + 4;

i = 60;

}

}

}

}

}

tempfile.seek (mypos);

retval = headbuf [mypos + 3];

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

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

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

OK, avem lungimea și frecvența datelor!

Datele audio urmează cei 4 octeți care alcătuiesc valoarea lungimii datelor.

Pasul 8: întrerupe, întrerupe …

Întrerupe, întrerupe …
Întrerupe, întrerupe …

Folosim informațiile despre frecvență pentru a crea o întrerupere a software-ului la sau aproape de frecvența necesară.

Întreruperea nu poate fi întotdeauna setată cu precizie, dar este suficientă. Frecvența citită din fișier este transmisă subrutinei setintrupt.

void setintrupt (float freq) {float bitval = 8; // 8 pentru temporizatoarele de 8 biți 0 și 2, 1024 pentru temporizatorul de 1 octet

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

// Valoarea setocroa necesită o scădere de -1. Cu toate acestea, adăugând 0,5 runde la cea mai apropiată 0,5

// Rezoluția temporizatorului este limitată

// Determinat în cele din urmă de magnitudinea bitval

cli (); // dezactivează întreruperile // setează temporizatorul 2 întrerupe

TCCR2A = 0; // setați întregul registru TCCR2A la 0

TCCR2B = 0; // la fel pentru TCCR2B

TCNT2 = 0; // inițializează valoarea contorului la 0

// setează comparați registrul de potrivire pentru incrementele de frecvență (hz)

OCR2A = setocroa; // = (16 * 10 ^ 6) / (frecvență * 8) - 1 (trebuie să fie <256)

// activați modul CTC

TCCR2A | = (1 << WGM21); // Setați bitul CS21 pentru 8 prescaleri

TCCR2B | = (1 << CS21); // activa temporizator compara întrerupere

// TIMSK2 | = (1 << OCIE2A); // funcționează, la fel ca linia următoare

sbi (TIMSK2, OCIE2A); // activați întreruperea pe temporizatorul 2

sei (); // activează întreruperile

Cititorii cu discernământ vor fi observat sbi (TIMSK2, OCIE2A)

Am configurat câteva funcții (achiziționate prin internet) pentru setarea și ștergerea biților de registru:

// Definește pentru ștergerea biților de registru # ifndef cbi

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

#endif

// Definește pentru setarea biților de registru

#ifndef sbi

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

#endif

Aceste funcții oferă un apel ușor pentru a seta sau a șterge întreruperea.

Deci întreruperea se execută, ce o putem face să facă?

Pasul 9: întreruperi și tamponare dublă

Întreruperi și dublă tamponare
Întreruperi și dublă tamponare
Întreruperi și dublă tamponare
Întreruperi și dublă tamponare

La 22 Khz, un octet de date audio este trimis la fiecare 0,045 ms

512 octeți (dimensiunea bufferului) sunt citite în 2,08 ms.

Deci tamponul nu poate fi citit de pe cardul SDCard într-un singur ciclu de scriere.

Cu toate acestea, 512 octeți sunt scrise în port în 23.22ms.

Deci, tot ce trebuie să facem este să configurați un nou fișier citit de fiecare dată când bufferul se golește și avem suficient timp pentru a obține datele înainte de a fi necesar un nou bloc de date … Presupunând că folosim două buffere, golind unul în timp ce umplem altul.

Acesta este un tampon dublu.

Citirea fișierului va fi încetinită de întreruperea repetată, dar se va termina.

Am configurat două tampoane de 512 octeți numite bufa și bufb.

Dacă steagul este adevărat, citim din porta, altfel citim din portb

Când poziția buffer (bufcount) atinge dimensiunea buffer (BUF_SIZE 512), setăm un flag denumit readit la true.

Rutina de buclă nulă caută acest semnal și pornește un bloc citit:

if (readit) {if (! aready) {

// inițiați blocul SDCard citit pe bufa

tempfile.read (bufa, BUF_SIZE);

} altceva {

// inițiați blocul SDCard citit pe bufb

tempfile.read (bufb, BUF_SIZE);

}

readit = fals;

}

Când a terminat semnalizările de rutină readit = false.

În cadrul rutinei de întrerupere trebuie să verificăm dacă bucla de gol a terminat verificând dacă readit == false.

În acest caz, semnalăm că este necesară o altă citire și comutăm semnalizatorul pregătit pentru a comuta bufferele.

Dacă cardul SD încă citeste, trebuie să urmărim înapoi o citire (contor--; bufcount--;) și să ieșim din întrerupere pentru a încerca din nou mai târziu. (Clicurile pe semnalul de ieșire audio implică faptul că acest lucru a avut loc.)

Când toate datele sunt citite, întreruperea este anulată, portul readus la valoarea medie a tensiunii 128 și fișierul audio închis.

Înainte de a rula pentru prima dată scriptul dac2.ino, setați volumul la 50%. Acest lucru va fi prea tare, dar este mai bun decât 100%!

Dacă controlul volumului funcționează invers, schimbați cablurile la capetele opuse ale potențiometrului de 10K.

Spune-mi cum sună.

Recomandat: