Innholdsfortegnelse:

Spille lydfiler (Wav) med en Arduino og en DAC: 9 trinn
Spille lydfiler (Wav) med en Arduino og en DAC: 9 trinn

Video: Spille lydfiler (Wav) med en Arduino og en DAC: 9 trinn

Video: Spille lydfiler (Wav) med en Arduino og en DAC: 9 trinn
Video: Audacity - kombinere lydfiler 2024, Juli
Anonim
Spille av lydfiler (Wav) med en Arduino og en DAC
Spille av lydfiler (Wav) med en Arduino og en DAC
Spille av lyd lydfiler (Wav) med en Arduino og en DAC
Spille av lyd lydfiler (Wav) med en Arduino og en DAC
Spille av lyd lydfiler (Wav) med en Arduino og en DAC
Spille av lyd lydfiler (Wav) med en Arduino og en DAC

Spill av wav -fillyd fra Audino SD -kortet. Denne instruksen viser deg hvordan en wav -fil på SdCard kan spilles gjennom en enkel krets til en høyttaler.

WAV -filen må være 8 -bits mono. Jeg har ikke hatt noe problem med å spille 44 KHz -filer.

Selv om det ikke er hi-fidelity, er lydkvaliteten veldig tilfredsstillende.

Den serielle skjermen brukes til å velge filen. Filene må være i en mappe som heter adlog.

Dette instruerbare følger av et tidligere prosjekt der jeg lagret wav-opptak til SdCard:

Kretsen bruker en billig 8 -bits digital til analog omformer (DAC) og en enkeltbrikke lydforsterker.

Viktige avsnitt for å sette opp avbrudd ble hentet fra den utmerkede artikkelen av Amanda Ghassaei:

Trinn 1: Krav

Krav
Krav
Krav
Krav

Arduino- Jeg bruker Mega, men det er ingen grunn til at Uno ikke skal fungere.

SdCard-leser-programmet er konfigurert for: MicroSD Breakout Board Regulated with Logic Conversion V2

Se denne instruksjonen for detaljer om SdCard-oppsett:

DAC0832 LCN- en utmerket 8-bits digital til analog omformer- Noen kilo.

LM386 N-1 Op amp- billig som chips

20 -veis brikkekontakt

8 -veis brikkekontakt

9 volt strøm- et batteri vil gjøre.

LM336 2,5 V spenningsreferanse

10uF kondensator * 3 (spenning over 9V)

10 ohm motstand

50nF kondensator- (Eller et sted i nærheten av -47nF, 56nf, 68nf- vil gjøre)

220uF kondensator

64 ohm høyttaler

10K lineært potensiometer

Kabel for å koble de 8 datalinjene mellom Arduino og krets-

På Uno er de 8 tilkoblingene i kø, på Mega er de i par.

På Mega brukte jeg 10 -veis båndkabel med en 10 -veis IDC -topptekst. (2 ledninger er ledige)

Stikkontakter for 0V, 9V og DAC ut

Kobberlist, loddetinn, wire, kuttere osv

Trinn 2: Spesifikasjonene

Spesifikasjonene
Spesifikasjonene

Serielt sett på 115200 baud.

Støtte er på plass for Hobbytronics MicroSD Breakout Board med en Mega. Chip select og andre porter vil skifte mellom Mega og Uno.

Wav-filene må finnes i en katalog som heter adlog- Gi den gjerne noe annet og ordne den nødvendige kodingen på nytt.

WAV -filen må være 8 -bits mono. Jeg har testet opptil 44KHz.

Seriell skjerm viser wav -filene i adlog -mappen. Filnavn sendes fra monitorens utgangslinje.

Filstørrelse er bare begrenset av SdCard -størrelse.

Trinn 3: Komme i gang

Starter
Starter

Koble til SD -kortleseren. Dette er forbindelsene til Mega.

0, 5V

CLK til pin 52

D0 til pinne 50

D1 til pinne 51

CS til pin 53

(Se leverandørens nettsted for Uno -porttilkobling)

Du vil teste at kortet ditt fungerer på dette stadiet- bruk skriptene som leveres av leverandøren.

Vi må lage en liten krets

Vi kommer til å sende en strøm av lydbyte fra Arduino.

Disse tallene er mellom 0 og 255. De representerer spenningen.

Stillhet er 127-128.

255 er en høyttalerkegle.

0 er høyttalerkegle den andre veien.

Så lyd blir spilt inn som lagrede tall, som skaper varierende spenninger, som skaper bevegelige høyttalerkegler.

Vi kan sende tallene ut av 8 linjer på Arduino, samtidig, ved å bruke en "port".

Hvis vi mater de 8 linjene til en digital til analog omformer, gjør den det den sier på tinnet og produserer en analog spenning som er proporsjonal med det digitale tallet.

Alt vi trenger å gjøre er å pakke spenningen til en liten operasjonsforsterker og deretter til en høyttaler.

Trinn 4: Den lille kretsen

Den lille kretsen
Den lille kretsen
Den lille kretsen
Den lille kretsen
Den lille kretsen
Den lille kretsen
Den lille kretsen
Den lille kretsen

DAC0832 LCN

Dette er en suveren, billig 8 -biters digital til analog omformer. (DAC)

Den kan kontrolleres fullt ut med en rekke dataoppbevaringslinjer.

Eller det kan konfigureres for å gjøre alt automatisk i "Gjennomstrømning".

For å sitere manualen:

Bare å jorde CS, WR1, WR2 og XFER og knytte ILE høyt gjør at begge interne registre kan følge de påførte digitale inngangene (gjennomstrømning) og direkte påvirke den analoge DAC-utgangen.

OK, det vil si fire tilkoblinger til brikken satt lavt og ett sett til 9V - enkelt.

Vi vil ikke ha ut noen negative spenninger, så i manualen står det at vi skal bruke "spenningsbrytermodus", og de leverer diagrammet.

Alt vi trenger å gjøre er å bytte ut en liten lydforsterker i stedet for den de foreslår.

LM386-N lydforsterker

Amp-håndboken gir et minimumsdiagram- en gevinst på 20 (altfor mye for oss- men den har volumkontroll).

Alt vi trenger å gjøre er å legge til en kondensator mellom DAC og forsterkeren, slik at vi bare forsterker vekselstrømssignaler.

Vi må også legge til et par kondensatorer i nærheten av forsyningspinnen til hver av brikkene våre, ellers får vi nynne fra 9V -forsyningen.

Trinn 5: Få ut loddejernet

Kom deg ut av loddejernet
Kom deg ut av loddejernet
Kom deg ut av loddejernet
Kom deg ut av loddejernet
Kom deg ut av loddejernet
Kom deg ut av loddejernet

Siden kretsen er enkel, har jeg ikke tenkt å gi et slag for slag -konto.

Her er noen tips:

  • Forbered et stykke kobberstripebrett minst 28 x 28 hull. (Ja jeg vet at hjernekirurger kan gjøre det mindre)
  • Hvis du har tenkt å montere den med skruer, må du tillate dem i starten!
  • Monter chipsene på stikkontakter. Sett inn sjetongene først når alt er sjekket.
  • Hold inngangskablene borte fra utgangen.
  • Vær oppmerksom på riktig polaritet for kondensatorene.
  • Se diagrammet for grunnvisning av LM336 -spenningsreferansen. Justeringsbenet brukes ikke og kan klippes.
  • Legg merke til den direkte tilkoblingen til pin 8 på DAC- Den er veldig nyttig for testing.
  • Jeg koblet til Audino med båndkabel og en 10 -veis IDC -kontakt.
  • På Uno er tilkoblingene i en rett linje - du kan finne ut at å ordne de 8 inngangstilkoblingene i en enkelt rett linje lar deg koble til Arduino med en kjøpt, ferdig 8 -veis kobling,

Når den er ferdig- sjekk lodding og kontroller hullene mellom kobbersporene.

Jeg finner et 36 tpi junior hack sagblad veldig nyttig for å rydde rusk. Jeg fjerner bladets lokaliseringspinner og skyver bladets spiss inn i sporet- Tydeligvis er bladet ikke i en ramme.

Trinn 6: Testing av DAC

Tester DAC
Tester DAC

La forbindelsen mellom kretsen og Arduino være av.

Sett volumkontrollen på kretsen til midtveis.

Slå på 9V DC -strømmen til den nye kretsen.

Sjekk at kretsen er ok- jeg kan ikke påta meg noe ansvar for kretsen din!

Slå av

Koble kretsen til Arduino.

På Mega bruk pins 22-29. (PORTA) Ikke feil de to 5V -pinnene ovenfor!

På Uno bruk pins 0-7. Dette er PORTD

Koble 0V på strømforsyningen til 0V på Arduino.

Start opp.

Åpne dette testprogrammet DAC_TEST

For UNO, erstatt alle referanser til PORTA til PORTD

Erstatt DDRA med DDRD- denne instruksjonen setter alle 8 linjene til utskrift på en gang. Dette er dataretningsregisteret.

Sett den serielle skjermen til 115200.

Koble et voltmeter mellom DAC ut og OV

Programmet vil sette utgangen til 255 - alle linjer på - maksimal spenning.

Utgang 128- halv maksimal spenning.

Utgang 0- null spenning (Eller sannsynligvis nesten null).

Den vil deretter gå bitvis: 1, 2, 4, 8, 16, 32, 64, 128

Spenningen skal øke jevnt og trutt.

Hvis spenningen faller tilbake mens tallet øker, har du sannsynligvis to av de sammenkoblede ledningene omvendt.

Du bør også høre høyttaleren stille klikke når spenningen endres

Trinn 7: Lese Wav -overskriften

Lese Wav -overskriften
Lese Wav -overskriften

WAV -filer lagres med en spesifisert frekvens og datastørrelse.

Denne informasjonen finnes i en 44 byte -overskrift i starten av en wav -fil.

Selv om noe programvare utvider overskriften (etter byte 35), blir det vanskeligere å finne plasseringen av datastørrelsen.

For å lese overskriften lager vi en buffer og kopierer starten av filen.

Frekvensen lagres i 4 byte og starter 24 byte inn i filen.

// lesefrekvens spesifisert i wav -filhodet

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 ("Filfrekvens"));

Serial.print (retval);

Den beste måten å finne datastørrelsesinformasjonen på er å søke etter ordet "data" i overskriften.

Trekk deretter ut de 4 byte som følger den, som utgjør den lange verdien

usignert lang retval;

int mypos = 40;

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

hvis (headbuf == 'd') {

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

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

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

// endelig har vi det

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, vi har datalengde og frekvens!

Lyddataene følger de 4 byte som utgjør datalengdeverdien.

Trinn 8: Avbryt, avbryt…

Avbryt, avbryt…
Avbryt, avbryt…

Vi bruker frekvensinformasjonen til å lage et programavbrudd ved eller i nærheten av den nødvendige frekvensen.

Avbruddet kan ikke alltid settes presist, men det er tilstrekkelig. Frekvensen som leses fra filen overføres til den setintrupt subrutinen.

void setintrupt (float freq) {float bitval = 8; // 8 for 8 bit timere 0 og 2, 1024 for timer 1 byte

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

// Setocroa -verdien krever en subtraksjon på -1. Legger imidlertid 0,5 runder til nærmeste 0,5

// Oppløsningen til timeren er begrenset

// Endelig bestemt av størrelsen på bitval

cli (); // deaktiver avbrudd // sett timer2 avbrudd

TCCR2A = 0; // sett hele TCCR2A -registeret til 0

TCCR2B = 0; // samme for TCCR2B

TCNT2 = 0; // initialiser telleverdi til 0

// sett sammenligne matchregister for frekvens (hz) trinn

OCR2A = setocroa; // = (16*10^6) / (frekvens*8) - 1 (må være <256)

// slå på CTC -modus

TCCR2A | = (1 << WGM21); // Still inn CS21 -bit for 8 forhåndsskaler

TCCR2B | = (1 << CS21); // aktiver tidsur sammenligne avbrudd

// TIMSK2 | = (1 << OCIE2A); // dette fungerer, det samme gjør følgende linje

sbi (TIMSK2, OCIE2A); // aktiver avbrudd på timer 2

sei (); // aktiver avbrudd

Kresne lesere vil ha oppdaget sbi (TIMSK2, OCIE2A)

Jeg konfigurerer et par (Internett -anskaffede) funksjoner for å sette og slette registerbiter:

// Definerer for sletting av registerbiter#ifndef cbi

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

#slutt om

// Definerer for innstilling av registerbiter

#ifndef sbi

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

#slutt om

Disse funksjonene gir en enkel samtale for å angi eller fjerne avbruddet.

Så avbruddet kjører, hva kan vi få det til å gjøre?

Trinn 9: Avbrudd og dobbel buffering

Avbrudd og dobbel buffering
Avbrudd og dobbel buffering
Avbrudd og dobbel buffering
Avbrudd og dobbel buffering

Ved 22 kHz sendes en byte lyddata ut hver 0,045 ms

512 byte (bufferstørrelsen) leses på 2,08 ms.

Så bufferen kan ikke leses fra SDCard i en skrivesyklus.

Imidlertid skrives 512 byte til porten på 23,22 ms.

Så alt vi trenger å gjøre er å sette opp en ny fil som blir lest hver gang bufferen tømmes, og vi har nok tid til å hente dataene før en ny datablokk er nødvendig … Forutsatt at vi bruker to buffere, tømmer en mens vi fyller en annen.

Dette er dobbel buffering.

Fillesningen vil bli bremset av det gjentatte avbruddet, men det vil bli gjort.

Jeg har satt opp to 512 byte buffere kalt bufa og bufb.

Hvis flagget allerede er sant, leser vi fra porta, ellers leser vi fra portb

Når bufferposisjonen (bufcount) når bufferstørrelsen (BUF_SIZE 512) setter vi et flagg kalt readit til true.

Tomrute -rutinen ser etter dette flagget og starter en blokk som leser:

if (readit) {if (! aready) {

// start SDCard -blokk lest for bufa

tempfile.read (bufa, BUF_SIZE);

} annet {

// start SDCard -blokk lest til bufb

tempfile.read (bufb, BUF_SIZE);

}

readit = false;

}

Når den er ferdig, blir rutineflaggene readit = false.

Innenfor avbruddsrutinen må vi kontrollere at tomridsløyfen er ferdig med å sjekke om readit == false.

I dette tilfellet signaliserer vi at det er nødvendig med en annen lesning, og bytter det allerede flagget for å bytte buffer.

Hvis SD-kortet fortsatt leser, må vi spore én lesning (teller--; bufcount--;) og avslutte avbruddet for å prøve igjen senere. (Klikk på lydutgangssignalet antyder at dette har skjedd.)

Når alle dataene er lest avbrytes avbruddet, porten settes på nytt til midtspenningsverdien 128 og lydfilen lukkes.

Før du kjører dac2.ino -skriptet for første gang, må du sette volumet til 50%. Dette blir for høyt, men det er bedre enn 100%!

Hvis volumkontrollen din fungerer omvendt, bytt ledninger i motsatte ender av 10K potensiometeret.

Gi meg beskjed om hvordan det høres ut.

Anbefalt: