Inhoudsopgave:
- Stap 1: Vereisten
- Stap 2: De specificaties:
- Stap 3: Aan de slag
- Stap 4: Het kleine circuit
- Stap 5: Haal de soldeerbout eruit
- Stap 6: De DAC testen
- Stap 7: De Wav-header lezen
- Stap 8: Onderbreken, Onderbreken…
- Stap 9: Onderbrekingen en dubbele buffering
Video: Audio geluidsbestanden (Wav) afspelen met een Arduino en een DAC: 9 stappen
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:18
Speel wav-bestand Audio van uw Audino SD-kaart. Deze Instructable laat je zien hoe een wav-bestand op je SD-kaart kan worden afgespeeld via een eenvoudig circuit naar een luidspreker.
Het wav-bestand moet 8 bit mono zijn. Ik heb geen probleem gehad met het afspelen van 44 KHz-bestanden.
Hoewel niet hi-fidelity, is de geluidskwaliteit zeer bevredigend.
De seriële monitor wordt gebruikt om het bestand te selecteren. De bestanden moeten zich in een map met de naam adlog bevinden.
Deze instructable volgt uit een eerder project waar ik wav-opnames op de SdCard heb opgeslagen:
De schakeling maakt gebruik van een goedkope 8 bit digitaal naar analoog converter (DAC) en een enkele chip audioversterker.
De belangrijkste secties voor het instellen van interrupts zijn overgenomen uit het uitstekende artikel van Amanda Ghassaei:
Stap 1: Vereisten
Arduino- Ik gebruik de Mega, maar er is geen reden waarom de Uno niet zou werken.
SdCard-lezer - het programma is geconfigureerd voor: MicroSD Breakout Board Regulated with Logic Conversion V2
Zie dit instructable voor SdCard setup details:
DAC0832 LCN- een uitstekende 8 bit digitaal naar analoog converter- Een paar pond.
LM386 N-1 Opamp - goedkoop als chips
20-weg chip socket
8-weg chip socket
9 volt voeding - een batterij is voldoende.
LM336 2,5 V spanningsreferentie
10uF Condensator * 3 (elke spanning meer dan 9V)
10 ohm weerstand
50nF condensator- (of ergens in de buurt van-47nF, 56nf, 68nf- zal doen)
220uF condensator
64 ohm luidspreker
10K lineaire potentiometer
Kabel om de 8 datalijnen tussen de Arduino en het circuit te verbinden-
Bij de Uno staan de 8 aansluitingen in lijn, bij de Mega staan ze paarsgewijs.
Op de Mega gebruikte ik een 10-wegs lintkabel met een 10-weg IDC-header. (2 draden zijn reserve)
Socket connectoren voor 0V, 9V en DAC out
Koper strip board, soldeer, draad, scharen etc
Stap 2: De specificaties:
Serieel ingesteld op 115200 baud.
Er is ondersteuning voor het Hobbytronics MicroSD Breakout Board met behulp van een Mega. De chip select en andere poorten zullen veranderen tussen Mega en Uno.
De Wav-bestanden moeten bestaan in een map met de naam adlog. Voel je vrij om het een andere naam te geven en de benodigde codering opnieuw te ordenen.
Het wav-bestand moet 8 bit mono zijn. Ik heb tot 44KHz getest.
De seriële monitor toont de wav-bestanden in de adlog-map. Bestandsnamen worden verzonden vanaf de monitoruitgangslijn.
De bestandsgrootte wordt alleen beperkt door de grootte van de SD-kaart.
Stap 3: Aan de slag
Sluit de SD-kaartlezer aan. Dit zijn de aansluitingen voor de Mega.
0, 5V
CLK naar pin 52
D0 naar pin 50
D1 naar pin 51
CS naar pin 53
(Zie leverancierswebsite voor Uno-poortverbinding)
U zult in dit stadium willen testen of uw kaart werkt - gebruik de scripts die door de leverancier zijn geleverd.
We moeten een klein circuit maken
We gaan een stroom audiobytes sturen vanaf de Arduino.
Deze getallen liggen tussen 0 en 255. Ze vertegenwoordigen de spanning.
Stilte is 127-128.
255 is een luidsprekerconus die in één richting hard is.
0 is de luidsprekerconus hard andersom.
Dus audio wordt opgenomen als opgeslagen nummers, die verschillende spanningen creëren, die bewegende luidsprekerconussen creëren.
We kunnen de nummers van 8 regels tegelijkertijd naar de Arduino sturen door een "poort" te gebruiken.
Als we de 8 lijnen in een digitaal naar analoog converter voeren, doet hij wat het zegt op het blikje en levert hij een analoge spanning op die evenredig is met het digitale getal.
Het enige wat we dan hoeven te doen, is de spanning naar een kleine operationele versterker en vervolgens naar een luidspreker brengen.
Stap 4: Het kleine circuit
De DAC0832 LCN
Dit is een uitstekende, goedkope 8 bit digitaal naar analoog converter. (DAC)
Het kan volledig worden bestuurd met een reeks data hold, data sample-lijnen.
Of het kan worden ingesteld om het allemaal automatisch te doen in "Doorstroombediening".
Om de handleiding te citeren:
Door eenvoudig CS, WR1, WR2 en XFER te aarden en ILE hoog te koppelen, kunnen beide interne registers de toegepaste digitale ingangen volgen (doorstroom) en direct de analoge DAC-uitgang beïnvloeden.
OK, dat zijn vier aansluitingen op de chipset laag en één op 9V - makkelijk.
We willen geen negatieve spanningen, dus de handleiding zegt dat we "spanningsschakelmodus" moeten gebruiken en zij leveren het diagram.
Het enige dat we hoeven te doen, is een kleine audioversterker vervangen in plaats van degene die ze voorstellen.
De LM386-N audioversterker
De handleiding van de versterker geeft een diagram van de minimale onderdelen - wat een versterking van 20 oplevert (veel te veel voor ons - maar het heeft een volumeregeling).
Het enige dat we hoeven te doen, is een condensator tussen de DAC en de versterker toevoegen, zodat we alleen AC-signalen versterken.
We moeten ook een paar condensatoren toevoegen in de buurt van de voedingspin van elk van onze chips, anders krijgen we brom van onze 9V-voeding.
Stap 5: Haal de soldeerbout eruit
Omdat het circuit eenvoudig is, ben ik niet van plan om een klapper te geven.
Hier zijn enkele aanwijzingen:
- Bereid een stuk koperstripplaat voor met minimaal 28 bij 28 gaten. (Ja, ik weet dat hersenchirurgen het kleiner kunnen maken)
- Als u van plan bent om het met schroeven te monteren, houd hier dan in het begin rekening mee!
- Monteer de chips op sockets. Plaats de chips pas als alles is gecontroleerd.
- Houd de ingangsdraden uit de buurt van de uitgang.
- Let op de juiste polariteit van de condensatoren.
- Raadpleeg het diagram voor het basisaanzicht van de LM336-spanningsreferentie. De stelpoot wordt niet gebruikt en kan worden ingekort.
- Let op de directe verbinding met pin 8 van de DAC- Het is erg handig om te testen.
- Ik heb verbinding gemaakt met de Audino met een lintkabel en een 10-weg IDC-connector.
- Op de Uno zijn de aansluitingen in een rechte lijn - het kan zijn dat u door de 8 ingangsaansluitingen in een enkele rechte lijn te rangschikken, u naar de Arduino kunt linken met een gekochte, kant-en-klare 8-weg connector,
Als het klaar is, controleer dan het solderen en controleer de openingen tussen de koperen sporen.
Ik vind een junior zaagblad van 36 tpi erg handig voor het opruimen van puin. Ik verwijder de paspennen van het mes en schuif de punt van het mes in de baan. Het is duidelijk dat het mes niet in een frame zit.
Stap 6: De DAC testen
Laat de verbinding tussen het circuit en de Arduino uitgeschakeld.
Zet de volumeregeling op uw circuit op halverwege.
Schakel de 9V DC-voeding in op uw nieuwe circuit.
Controleer of het circuit in orde is - ik kan geen enkele aansprakelijkheid aanvaarden voor uw circuit!
Uitschakelen
Verbind je circuit met de Arduino.
Gebruik op de Mega pinnen 22-29. (PORTA) Vergis je niet in de twee 5V-pinnen hierboven!
Gebruik op de Uno pinnen 0-7. Dit is PORTD
Sluit de 0V van je voeding aan op de 0V op de Arduino.
Opstarten.
Open dit testprogramma DAC_TEST
Vervang voor de UNO alle verwijzingen naar PORTA naar PORTD
Vervang DDRA door DDRD - met deze instructie worden alle 8 regels in één keer uitgevoerd. Dit is het gegevensrichtingregister.
Stel uw seriële monitor in op 115200.
Sluit een voltmeter aan tussen de DAC out en OV
Het programma stelt de uitgang in op 255 - alle lijnen aan - maximale spanning.
Uitgang 128 - halve maximale spanning.
Uitgang 0- nul spanning (of waarschijnlijk bijna nul).
Het zal dan bitsgewijs stappen: 1, 2, 4, 8, 16, 32, 64, 128
De spanning moet gestaag toenemen.
Als de spanning terugvalt terwijl het aantal toeneemt, hebt u waarschijnlijk twee van de verbindingsdraden verwisseld.
Je zou de luidspreker ook zachtjes moeten horen klikken als de spanning verandert
Stap 7: De Wav-header lezen
Wav-bestanden worden opgeslagen met een opgegeven frequentie en gegevensgrootte.
Deze informatie staat in een header van 44 bytes aan het begin van een wav-bestand.
Hoewel sommige software de header uitbreidt (na byte 35), waardoor de locatie van de gegevensgrootte moeilijker te vinden is.
Om de header te lezen, maken we een buffer en kopiëren we het begin van het bestand.
De frequentie wordt opgeslagen in 4 bytes vanaf 24 bytes in het bestand.
// leesfrequentie gespecificeerd in wav-bestandsheader
byte-headbuf[60]
tempbestand.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("Bestandsfrequentie"));
Seriële.afdruk (opnieuw);
De beste manier om informatie over de gegevensgrootte te vinden, is door te zoeken naar het woord 'gegevens' in de koptekst.
Extraheer vervolgens de 4 bytes die erop volgen, die de lange waarde vormen
niet-ondertekende lange reval;
int mijnpos=40;
voor (int i=36; i<60;i++) {
if (headbuf == 'd') {
if(headbuf[i+1]=='a') {
if(headbuf[i+2]=='t') {
if(headbuf[i+3]=='a') {
// Eindelijk hebben we het
mijnpos=i+4;
ik=60;
}
}
}
}
}
tempfile.seek(mijnpos);
retval=headbuf[mijnpos+3];
retval=(retval<<8) | headbuf[mypos+2];
retval=(retval<<8) | headbuf[mijnpos+1];
retval=(retval<<8) | headbuf[mypos];
OK, we hebben de gegevenslengte en -frequentie!
De audiogegevens volgen de 4 bytes die de gegevenslengte vormen.
Stap 8: Onderbreken, Onderbreken…
We gebruiken de frequentie-informatie om een software-interrupt te creëren op of in de buurt van de vereiste frequentie.
De interrupt kan niet altijd precies worden ingesteld, maar is voldoende. De frequentie die uit het bestand wordt gelezen, wordt doorgegeven aan de subroutine setintrupt.
void setintrupt(float freq){float bitval=8; // 8 voor 8 bit timers 0 en 2, 1024 voor timer 1 byte
setocroa=(16000000/(freq*bitval)) - 0,5;
// De setocroa-waarde vereist een aftrekking van -1. Maar 0,5 rondes toevoegen aan de dichtstbijzijnde 0,5
// De resolutie van de timer is beperkt
// Uiteindelijk bepaald door de grootte van bitval
cli(); // interrupts uitschakelen// timer2 interrupt instellen
TCCR2A = 0; // zet het hele TCCR2A-register op 0
TCCR2B = 0; // hetzelfde voor TCCR2B
TCNT2 = 0; // initialiseer de tellerwaarde op 0
// stel vergelijk match register in voor frequentie (hz) stappen
OCR2A = setocroa; // = (16*10^6) / (frequentie*8) - 1 (moet <256) zijn
// zet CTC-modus aan
TCCR2A |= (1 << WGM21); // Stel CS21 bit in voor 8 prescaler
TCCR2B |= (1 << CS21); // schakel timer vergelijk interrupt in
// TIMSK2 |= (1 << OCIE2A); // dit werkt, net als de volgende regel
sbi(TIMSK2, OCIE2A); // schakel interrupt in op timer 2
zie(); // schakel onderbrekingen in
Veeleisende lezers zullen sbi (TIMSK2, OCIE2A) hebben gezien
Ik heb een aantal (internet verworven) functies ingesteld voor het instellen en wissen van registerbits:
// Definieert voor het wissen van registerbits #ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#stop als
// Definieert voor het instellen van registerbits
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#stop als
Deze functies bieden een eenvoudige oproep om de onderbreking in te stellen of te wissen.
Dus de interrupt is actief, wat kunnen we ervoor zorgen?
Stap 9: Onderbrekingen en dubbele buffering
Bij 22 Khz wordt elke 0,045 ms een byte aan audiogegevens uitgevoerd
512 bytes (de buffergrootte) wordt gelezen in 2,08 ms.
De buffer kan dus niet in één schrijfcyclus van de SDCard worden gelezen.
Er worden echter 512 bytes in 23,22 ms naar de poort geschreven.
Dus alles wat we hoeven te doen is een nieuw bestand in te stellen dat elke keer wordt gelezen als de buffer leeg raakt en we hebben genoeg tijd om de gegevens op te halen voordat een nieuw gegevensblok nodig is… Ervan uitgaande dat we twee buffers gebruiken, waarbij we de ene leegmaken terwijl we de andere vullen.
Dit is dubbel bufferen.
Het lezen van het bestand wordt vertraagd door de herhaalde onderbreking, maar het wordt gedaan.
Ik heb twee buffers van 512 bytes ingesteld, bufa en bufb genaamd.
Als de vlag aready waar is, lezen we uit porta, anders lezen we uit portb
Wanneer de bufferpositie (bufcount) de buffergrootte (BUF_SIZE 512) bereikt, stellen we een vlag met de naam readit in op true.
De void loop-routine zoekt naar deze vlag en begint een blok te lezen:
if(readit){if (! aready){
// initieer SDCard-blok lezen naar bufa
tempfile.read(bufa, BUF_SIZE);
} anders {
// initieer SDCard-blok lezen naar bufb
tempfile.read(bufb, BUF_SIZE);
}
readit=false;
}
Als het klaar is, markeert de routine readit=false.
Binnen de interruptroutine moeten we controleren of de void-lus is voltooid door te controleren of readit== false.
Als dit het geval is, geven we aan dat nog een leesbewerking nodig is en schakelen we de aready-vlag in om van buffer te wisselen.
Als de SD-kaart nog steeds aan het lezen is, moeten we één meting terugdraaien (teller--; bufcount--;) en de onderbreking afsluiten om het later opnieuw te proberen. (Klikken in het audio-uitgangssignaal geven aan dat dit is gebeurd.)
Wanneer alle gegevens zijn gelezen, wordt de interrupt geannuleerd, wordt de poort opnieuw ingesteld op de middenspanningswaarde van 128 en wordt het audiobestand gesloten.
Stel uw volume in op 50% voordat u het dac2.ino-script voor de eerste keer uitvoert. Dit zal te luid zijn, maar het is beter dan 100%!
Als uw volumeregeling omgekeerd werkt, verwissel dan de draden aan de tegenovergestelde uiteinden van de 10K-potentiometer.
Laat me weten hoe het klinkt.
Aanbevolen:
Video afspelen met ESP32: 10 stappen (met afbeeldingen)
Video afspelen met ESP32: deze Instructables laten iets zien over het afspelen van video en audio met ESP32
Pratende Arduino - Een MP3 afspelen met Arduino zonder enige module - Mp3-bestand afspelen vanaf Arduino met PCM: 6 stappen
Pratende Arduino | Een MP3 afspelen met Arduino zonder enige module | Mp3-bestand van Arduino afspelen met PCM: in deze instructie leren we hoe we een mp3-bestand met arduino kunnen spelen zonder een audiomodule te gebruiken, hier gaan we de PCM-bibliotheek voor Arduino gebruiken die 16 bit PCM van 8 kHz-frequentie speelt, dus laten we dit doen
Muziek afspelen met Arduino!: 5 stappen (met afbeeldingen)
Muziek afspelen met Arduino!: In deze instructable laat ik je zien hoe ik muziek speel met een Arduino UNO en een SD-kaartmodule. We zullen de SPI-communicatie gebruiken. Laten we beginnen
Nummers afspelen met stappenmotor !! 11 stappen (met afbeeldingen) Antwoorden op al uw "Hoe?"
Speel nummers af met behulp van stappenmotor!!: Dit project gaat over het ontwerpen van een eenvoudige dynamische interface, die het mogelijk maakt om op twee verschillende manieren met een stappenmotor te communiceren. De eerste interface regelt de richting en snelheid van de stappenmotor door het gebruik van een eenvoudige GUI, die h
5.1 Dolby Digital Audio afspelen in QuickTime Mac OS X: 6 stappen
5.1 Dolby Digital Audio afspelen in QuickTime Mac OS X: In deze Instructable laat ik je zien hoe je meerkanaals Dolby Digital (AC-3) audio afspeelt in QuickTime 7 of QuickTime X, en bitstream via een glasvezel Toslink (S/PDIF) kabel, naar je versterker. Instructievideo: http://www.youtube.com/watc