Taula de continguts:

Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC: 9 passos
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC: 9 passos

Vídeo: Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC: 9 passos

Vídeo: Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC: 9 passos
Vídeo: BTT - Manta E3EZ - CB1 with EMMc install 2024, Desembre
Anonim
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC
Reproducció de fitxers de so d'àudio (WAV) amb un Arduino i un DAC

Reprodueix el fitxer wav de l’àudio de la targeta SD Audino. Aquest instructiu us mostrarà com es pot reproduir un fitxer wav a la vostra SdCard a través d’un circuit senzill cap a un altaveu.

El fitxer wav ha de ser mono de 8 bits. No he tingut cap problema en reproduir fitxers de 44 KHz.

Tot i que no és d'alta fidelitat, la qualitat del so és molt satisfactòria.

El monitor sèrie s’utilitza per seleccionar el fitxer. Els fitxers han d’estar en una carpeta anomenada adlog.

Aquest instructable es desprèn d’un projecte anterior on vaig desar enregistraments wav a la SdCard:

El circuit utilitza un convertidor digital a analògic (DAC) de 8 bits i un amplificador d’àudio d’un sol xip.

Les seccions clau per configurar les interrupcions van ser extretes de l’excel·lent article d’Amanda Ghassaei:

Pas 1: requisits

Requisits
Requisits
Requisits
Requisits

Arduino: faig servir el Mega, però no hi ha cap raó perquè l’Uno no funcioni.

Lector SdCard: el programa està configurat per a: MicroSD Breakout Board Regulated with Logic Conversion V2

Consulteu aquest document per obtenir informació sobre la configuració de SdCard:

DAC0832 LCN: un excel·lent convertidor digital a analògic de 8 bits.

LM386 N-1 Op amplificador: barat com a xips

Presa de xip de 20 vies

Presa de xip de 8 vies

Alimentació de 9 volts: una bateria funcionarà.

LM336 2,5 V tensió de referència

Condensador 10uF * 3 (qualsevol tensió superior a 9V)

Resistència de 10 ohm

Condensador de 50 nF (o en algun lloc proper a 47 nF, 56 nf, 68 nf)

Condensador de 220uF

Altaveu de 64 ohm

Potenciòmetre lineal de 10K

Cable per enllaçar les 8 línies de dades entre l’Arduino i el circuit-

A l’Uno les 8 connexions estan en línia, a la Mega estan en parelles.

Al Mega he utilitzat un cable de cinta de 10 vies amb capçalera IDC de 10 vies. (2 cables són de recanvi)

Connectors de sòcol per a sortida de 0V, 9V i DAC

Tauler de tires de coure, soldadura, filferro, talladores, etc.

Pas 2: les especificacions

Les especificacions
Les especificacions

Sèrie fixada en 115200 baud.

Hi ha suport per a la placa Hobbytronics MicroSD Breakout Board que utilitza un Mega. La selecció de xip i altres ports alteraran entre Mega i Uno.

Els fitxers Wav han d’existir en un directori anomenat adlog. No dubteu a posar-li un altre nom i torneu a organitzar la codificació necessària.

El fitxer wav ha de ser mono de 8 bits. He provat fins a 44 KHz.

El monitor de sèrie mostra els fitxers wav a la carpeta d'adlog. Els noms dels fitxers s’envien des de la línia de sortida del monitor.

La mida del fitxer només està limitada per la mida de SdCard.

Pas 3: Introducció

Començant
Començant

Connecteu el lector de targetes SD. Aquestes són les connexions del Mega.

0, 5V

CLK al pin 52

D0 al pin 50

D1 al pin 51

CS al pin 53

(Consulteu el lloc web dels proveïdors per a la connexió del port Uno)

Voleu provar que la vostra targeta funcioni en aquesta etapa: utilitzeu els scripts subministrats pel proveïdor.

Hem de fer un petit circuit

Enviarem un flux de bytes d’àudio des de l’Arduino.

Aquests números estan entre 0 i 255. Representen la tensió.

El silenci és 127-128.

255 és un con d’altaveu dur d’una manera.

0 és el con de l'altaveu a l'altra banda.

Per tant, l’àudio es grava com a nombres guardats, que creen voltatges diferents, que creen cons de l’altaveu en moviment.

Podem enviar els números de vuit línies a l'Arduino simultàniament mitjançant un "port".

Si alimentem les vuit línies en un convertidor digital a analògic, fa el que diu a la llauna i produeix una tensió analògica que és proporcional al nombre digital.

Tot el que hem de fer llavors és empaquetar el voltatge a un petit amplificador operatiu i després a un altaveu.

Pas 4: el circuit petit

El petit circuit
El petit circuit
El petit circuit
El petit circuit
El petit circuit
El petit circuit
El petit circuit
El petit circuit

El DAC0832 LCN

Es tracta d’un convertidor digital a analògic de 8 bits excel·lent i econòmic. (DAC)

Es pot controlar completament amb una sèrie de línies de mostra de dades de retenció de dades.

O també es pot configurar per fer-ho tot automàticament a "Flow through operation".

Per citar el manual:

Simplement posant a terra CS, WR1, WR2 i XFER i lligar ILE high permet a tots dos registres interns seguir les entrades digitals aplicades (flux) i afectar directament la sortida analògica del DAC.

D'acord, és a dir, quatre connexions al xip es redueixen i una a 9V, fàcil.

No volem que es produeixin tensions negatives, de manera que el manual diu que hauríem d’utilitzar el "mode de commutació de tensió" i que proporcionen el diagrama.

Tot el que hem de fer és substituir un petit amplificador d’àudio en lloc del que suggereixen.

L’ampli d’àudio LM386-N

El manual de l'Amp proporciona un diagrama de peces mínim, que proporciona un guany de 20 (massa per a nosaltres, però té un control de volum).

Tot el que hem de fer és afegir un condensador entre el DAC i l'amplificador perquè només amplifiquem els senyals de corrent altern.

També hem d'afegir un parell de condensadors a prop del pin de subministrament de cadascun dels nostres xips, en cas contrari obtindrem un brunzit del subministrament de 9 V.

Pas 5: treure el soldador

Traieu el soldador
Traieu el soldador
Traieu el soldador
Traieu el soldador
Traieu el soldador
Traieu el soldador

Com que el circuit és senzill, no tinc intenció de donar un cop a cop.

Aquí hi ha alguns consells:

  • Prepareu un tros de tauler de tires de coure com a mínim de 28 per 28 forats. (Sí, sé que els cirurgians cerebrals poden fer-lo més petit)
  • Si teniu intenció de muntar-lo amb cargols, permeteu-los al principi.
  • Munteu les fitxes als endolls. Inseriu les fitxes només quan s'hagi comprovat tot.
  • Mantingueu els cables d’entrada allunyats de la sortida.
  • Observeu la polaritat correcta dels condensadors.
  • Consulteu el diagrama per obtenir la vista base de la referència de tensió LM336. La cama d'ajust no s'utilitza i es pot tallar.
  • Tingueu en compte la connexió directa al pin 8 del DAC: és molt útil per fer proves.
  • Em vaig connectar a l'Audino amb un cable de cinta i un connector IDC de 10 vies.
  • A l’Uno, les connexions estan en línia recta; és possible que organitzant les 8 connexions d’entrada en una sola línia recta us permeti enllaçar a l’Arduino amb un connector de 8 vies comprat i preparat,

Quan estigui acabat, comproveu la soldadura i comproveu els buits entre les vies de coure.

Trobo que una fulla de serra junior de 36 tpi és molt útil per eliminar els residus. Retiro els passadors de localització de la fulla i fa lliscar la punta de la fulla cap a la pista. Evidentment, la fulla no es troba en un marc.

Pas 6: provar el DAC

Prova del DAC
Prova del DAC

Deixeu la connexió entre el circuit i l’Arduino apagada.

Estableix el control de volum del circuit a mig camí.

Enceneu l'alimentació de 9 V CC al vostre nou circuit.

Comproveu que el circuit estigui bé: no puc assumir cap responsabilitat pel vostre circuit.

Apagar

Connecteu el vostre circuit a l'Arduino.

Al Mega utilitzeu els pins 22-29. (PORTA) No us equivoqueu amb els dos pins de 5V anteriors.

A l’Uno utilitzeu els pins 0-7. Això és PORTD

Connecteu el 0V de la font d'alimentació al 0V de l'Arduino.

Enceneu-lo.

Obriu aquest programa de prova DAC_TEST

Per a l'ONU, substituïu totes les referències a PORTA per PORTD

Substitueix DDRA per DDRD: aquesta instrucció estableix les 8 línies perquè es generin d'una sola vegada. Aquest és el registre de direcció de dades.

Configureu el monitor sèrie a 115200.

Connecteu un voltímetre entre la sortida DAC i l'OV

El programa configurarà la sortida a 255 - totes les línies activades - tensió màxima.

Sortida de 128 - mitja tensió màxima.

Sortida 0- tensió zero (o probablement gairebé zero).

Tot seguit, es farà un pas a bit: 1, 2, 4, 8, 16, 32, 64, 128

El voltatge hauria d’augmentar constantment.

Si es redueix la tensió mentre augmenta el nombre, probablement tingueu dos dels cables interconnectats invertits.

També haureu d’escoltar l’altaveu fent clic en veu baixa mentre canvia el voltatge

Pas 7: llegir la capçalera Wav

Llegint la capçalera Wav
Llegint la capçalera Wav

Els fitxers WAV es guarden amb una freqüència i una mida de dades especificades.

Aquesta informació es troba en una capçalera de 44 bytes al començament d’un fitxer wav.

Tot i que alguns programes amplien la capçalera (després del byte 35), el que dificulta la localització de la mida de les dades.

Per llegir la capçalera creem un buffer i copiem l'inici del fitxer.

La freqüència s’emmagatzema en 4 bytes començant 24 bytes al fitxer.

// freqüència de lectura especificada a la capçalera del fitxer wav

byte 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 ("Freqüència de fitxers"));

Serial.print (retval);

La millor manera de trobar la informació sobre la mida de les dades és cercar la paraula "dades" a la capçalera.

A continuació, extreu els 4 bytes següents que formen el valor llarg

retval llarg sense signar;

int mypos = 40;

per a (int i = 36; i <60; i ++) {

if (headbuf == 'd') {

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

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

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

// per fi el tenim

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];

D'acord, tenim la longitud i la freqüència de les dades.

Les dades d'àudio segueixen els 4 bytes que formen el valor de longitud de les dades.

Pas 8: interrompre, interrompre …

Interrompre, interrompre …
Interrompre, interrompre …

Utilitzem la informació de freqüència per crear una interrupció de programari a la freqüència requerida o propera.

La interrupció no sempre es pot establir amb precisió, però és suficient. La freqüència llegida del fitxer es passa a la subrutina setintrupt.

void setintrupt (freq float) {float bitval = 8; // 8 per als temporitzadors de 8 bits 0 i 2, 1024 per al temporitzador d'1 byte

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

// El valor setocroa requereix una resta de -1. No obstant això, afegint 0,5 rondes a 0,5 més properes

// La resolució del temporitzador és limitada

// Finalment determinat per la magnitud del bitval

cli (); // desactiva les interrupcions // estableix la interrupció del temporitzador2

TCCR2A = 0; // estableix el registre complet de TCCR2A a 0

TCCR2B = 0; // el mateix per a TCCR2B

TCNT2 = 0; // inicialitzeu el valor del comptador a 0

// Estableix el registre de coincidències de comparació per a increments de freqüència (hz)

OCR2A = setocroa; // = (16 * 10 ^ 6) / (freqüència * 8) - 1 (ha de ser <256)

// activeu el mode CTC

TCCR2A | = (1 << WGM21); // Estableix el bit CS21 per a 8 prescalers

TCCR2B | = (1 << CS21); // habilitar la interrupció de comparació del temporitzador

// TIMSK2 | = (1 << OCIE2A); // això funciona, igual que la línia següent

sbi (TIMSK2, OCIE2A); // habilitar la interrupció al temporitzador 2

sei (); // habilita les interrupcions

Els lectors més exigents hauran vist sbi (TIMSK2, OCIE2A)

He configurat un parell de funcions (adquirides per Internet) per configurar i esborrar bits de registre:

// Defineix per esborrar els bits de registre # ifndef cbi

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

#endif

// Defineix per configurar els bits de registre

#ifndef sbi

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

#endif

Aquestes funcions proporcionen una trucada fàcil per configurar o esborrar la interrupció.

Per tant, la interrupció s'està executant, què podem fer que faci?

Pas 9: interrupcions i doble memòria intermèdia

Interrupcions i doble memòria intermèdia
Interrupcions i doble memòria intermèdia
Interrupcions i doble memòria intermèdia
Interrupcions i doble memòria intermèdia

A 22 kHz es produeix un byte de dades d'àudio cada 0,045 ms

Es llegeixen 512 bytes (la mida del buffer) en 2,08 ms.

Per tant, la memòria intermèdia no es pot llegir des de la targeta SD en un cicle d’escriptura.

Tot i això, s’escriuen 512 bytes al port en 23,22 ms.

Per tant, tot el que hem de fer és configurar un nou fitxer llegit cada vegada que es buida la memòria intermèdia i tenim prou temps per obtenir les dades abans que es requereixi un nou bloc de dades … Suposant que fem servir dos memòries intermèdies, buidant-ne un mentre n'omplim un altre.

Es tracta de doble memòria intermèdia.

La interrupció repetida frenarà la lectura del fitxer, però ja es farà.

Tinc configurats dos buffers de 512 bytes anomenats bufa i bufb.

Si la bandera ja és certa, llegim de porta, en cas contrari, llegim de portb

Quan la posició de la memòria intermèdia (bufcount) assoleix la mida de la memòria intermèdia (BUF_SIZE 512), establim un indicador anomenat readit a true.

La rutina de bucle buit cerca aquesta marca i inicia un bloc de lectura:

if (readit) {if (! aready) {

// Inicieu la lectura del bloc SDCard a bufa

tempfile.read (bufa, BUF_SIZE);

} més {

// Inicieu la lectura del bloc de targetes SDC a bufb

tempfile.read (bufb, BUF_SIZE);

}

readit = fals;

}

Quan hagi acabat els indicadors de rutina readit = false.

Dins de la rutina d’interrupcions hem de comprovar que el bucle buit ha acabat comprovant si readit == false.

En aquest cas, indiquem que es necessita una altra lectura i commutem el senyalador per canviar de memòria intermèdia.

Si la targeta SD encara està llegint, hem de tornar a fer un seguiment d'una lectura (comptador--; bufcount--;) i sortir de la interrupció per tornar-ho a provar més tard. (Els clics al senyal de sortida d'àudio impliquen que això s'ha produït.)

Quan es llegeixen totes les dades, la interrupció es cancel·la, el port es torna a configurar al valor de voltatge mitjà de 128 i el fitxer d'àudio es tanca.

Abans d'executar l'script dac2.ino per primera vegada, configureu el vostre volum al 50%. Serà massa fort, però és millor que el 100%.

Si el control de volum funciona a la inversa, canvieu els cables en extrems oposats del potenciòmetre de 10K.

Feu-me saber com sona.

Recomanat: