Turinys:

Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC: 9 žingsniai
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC: 9 žingsniai

Video: Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC: 9 žingsniai

Video: Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC: 9 žingsniai
Video: Slaptas skaitmeninis diktofonas - automatinis garso įrašymas nuo triukšmo - Sekimoiranga.lt 2024, Lapkritis
Anonim
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC
Garso garso failų (Wav) leidimas naudojant „Arduino“ir DAC

Leiskite „wav“garso įrašą iš savo „Audino“SD kortelės. Ši instrukcija parodys, kaip „SdCard“wav failą galima paleisti per paprastą grandinę garsiakalbiui.

„Wav“failas turi būti 8 bitų monofoninis. Aš neturėjau problemų atkurdamas 44 KHz failus.

Nors garso kokybė nėra aukšto lygio, ji yra labai patenkinama.

Failui pasirinkti naudojamas serijinis monitorius. Failai turi būti aplanke, pavadintame „adlog“.

Ši pamoka yra iš ankstesnio projekto, kuriame išsaugojau „Wav“įrašus „SdCard“:

Grandinėje naudojamas pigus 8 bitų skaitmeninis -analoginis keitiklis (DAC) ir vieno lusto garso stiprintuvas.

Pagrindinės pertraukų nustatymo dalys buvo paimtos iš puikaus Amanda Ghassaei straipsnio:

1 žingsnis: Reikalavimai

Reikalavimai
Reikalavimai
Reikalavimai
Reikalavimai

„Arduino“- naudoju „Mega“, tačiau nėra jokios priežasties, kodėl „Uno“neturėtų veikti.

„SdCard“skaitytuvas-programa sukonfigūruota: „MicroSD Breakout Board“, reguliuojama naudojant loginę konversiją V2

Išsamią „SdCard“sąrankos informaciją rasite šioje instrukcijoje:

DAC0832 LCN- puikus 8 bitų skaitmeninis-analoginis keitiklis- keli svarai.

LM386 N-1 Op stiprintuvas- pigus kaip lustai

20 krypčių lizdas

8 krypčių lustas

9 voltų maitinimo šaltinis- tinka baterija.

LM336 2,5 V įtampos etalonas

10uF kondensatorius * 3 (bet kokia įtampa didesnė nei 9V)

10 omų rezistorius

50 nF kondensatorius

220uF kondensatorius

64 omų garsiakalbis

10K linijinis potenciometras

Kabelis, jungiantis 8 duomenų linijas tarp „Arduino“ir grandinės.

„Uno“8 jungtys yra vienoje linijoje, „Mega“- poromis.

„Mega“naudojau 10 krypčių juostinį kabelį su 10 krypčių IDC antrašte. (2 laidai yra atsarginiai)

Lizdų jungtys 0V, 9V ir DAC išėjimui

Vario juostelių lenta, lydmetalis, viela, pjaustytuvai ir kt

2 žingsnis: specifikacijos

Specifikacijos
Specifikacijos

Serijos nustatymas 115200 baudų.

Palaikoma „Hobbytronics MicroSD Breakout Board“, naudojant „Mega“. Lusto pasirinkimas ir kiti prievadai pasikeis tarp „Mega“ir „Uno“.

„Wav“failai turi egzistuoti kataloge, pavadintame „adlog“- nedvejodami pavadinkite jį kažkuo kitu ir iš naujo sutvarkykite reikiamą kodavimą.

„Wav“failas turi būti 8 bitų monofoninis. Aš išbandžiau iki 44KHz.

Serijinis monitorius rodo „wav“failus aplanke „adlog“. Failų pavadinimai siunčiami iš monitoriaus išvesties eilutės.

Failo dydį riboja tik „SdCard“dydis.

3 žingsnis: Darbo pradžia

Darbo pradžia
Darbo pradžia

Prijunkite SD kortelių skaitytuvą. Tai yra „Mega“jungtys.

0, 5V

CLK iki 52 kaiščio

D0 iki 50 kaiščio

D1 - 51 kaištis

CS iki 53 kaiščio

(Žr. Tiekėjų svetainę, kaip prijungti „Uno“prievadą)

Šiame etape norėsite patikrinti, ar jūsų kortelė veikia- naudokite pardavėjo pateiktus scenarijus.

Turime sukurti nedidelę grandinę

Mes siunčiame garso baitų srautą iš „Arduino“.

Šie skaičiai yra nuo 0 iki 255. Jie reiškia įtampą.

Tyla yra 127-128.

255 yra kietas garsiakalbio kūgis vienaip.

0 yra garsiakalbio kūgis sunkiai į kitą pusę.

Taigi garsas įrašomas kaip išsaugoti skaičiai, kurie sukuria skirtingą įtampą ir sukuria judančius garsiakalbių kūgius.

Mes galime išsiųsti skaičius iš 8 „Arduino“eilučių vienu metu, naudodami „prievadą“.

Jei 8 linijas įvedame į skaitmeninį -analoginį keitiklį, jis daro tai, ką sako ant skardos, ir sukuria analoginę įtampą, proporcingą skaitmeniniam skaičiui.

Viskas, ką mums reikia padaryti, tai supakuoti įtampą į mažą operacinį stiprintuvą ir tada į garsiakalbį.

4 žingsnis: maža grandinė

Mažoji trasa
Mažoji trasa
Mažoji trasa
Mažoji trasa
Mažoji trasa
Mažoji trasa
Mažoji trasa
Mažoji trasa

DAC0832 LCN

Tai puikus, pigus 8 bitų skaitmeninis -analoginis keitiklis. (DAC)

Jis gali būti visiškai valdomas naudojant duomenų laikymo masyvą, duomenų pavyzdžių linijas.

Arba galima nustatyti, kad visa tai būtų padaryta automatiškai skiltyje „Srautas per operaciją“.

Cituojant vadovą:

Tiesiog įžeminant CS, WR1, WR2 ir XFER ir susiejant aukštą ILE, abu vidiniai registrai gali sekti pritaikytas skaitmenines įvestis (srautas) ir tiesiogiai paveikti DAC analoginę išvestį.

Gerai, kad keturios jungtys prie lusto yra žemos, o viena - 9 V - paprasta.

Mes nenorime neigiamos įtampos, todėl vadove sakoma, kad turėtume naudoti „įtampos perjungimo režimą“ir jie pateikia diagramą.

Viskas, ką mums reikia padaryti, tai pakeisti nedidelį garso stiprintuvą, o ne tą, kurį jie siūlo.

LM386-N garso stiprintuvas

Stiprintuvo vadove pateikiama minimali dalių schema, suteikianti 20 padidėjimą (mums per daug, bet jame yra garsumo valdymas).

Viskas, ką mums reikia padaryti, tai pridėti kondensatorių tarp DAC ir stiprintuvo, kad tik sustiprintume kintamosios srovės signalus.

Mes taip pat turime pridėti porą kondensatorių prie kiekvieno mūsų lusto maitinimo kaiščio, kitaip gausime dūzgimą iš 9 V maitinimo šaltinio.

5 žingsnis: Išimkite lituoklį

Išimkite lituoklį
Išimkite lituoklį
Išimkite lituoklį
Išimkite lituoklį
Išimkite lituoklį
Išimkite lituoklį

Kadangi grandinė yra paprasta, aš neketinu duoti smūgio smūgiu.

Štai keletas nuorodų:

  • Paruoškite ne mažiau kaip 28 x 28 skylių vario juostos plokštės gabalėlį. (Taip, aš žinau, kad smegenų chirurgai gali jį sumažinti)
  • Jei ketinate jį pritvirtinti varžtais, leiskite juos pradžioje!
  • Sumontuokite drožles ant lizdų. Įdėkite lustai tik tada, kai viskas buvo patikrinta.
  • Įvesties laidus laikykite toliau nuo išvesties.
  • Stebėkite tinkamą kondensatorių poliškumą.
  • LM336 įtampos atskaitos pagrindo vaizdą rasite diagramoje. Reguliuojama kojelė nenaudojama ir gali būti nupjauta.
  • Atkreipkite dėmesį į tiesioginį ryšį su DAC 8 kaiščiu- tai labai naudinga bandymams.
  • Prisijungiau prie „Audino“juostiniu kabeliu ir 10 krypčių IDC jungtimi.
  • „Uno“jungtys yra tiesios linijos - galite pastebėti, kad 8 įvesties jungčių sujungimas į vieną tiesią liniją leidžia susieti su „Arduino“naudojant įsigytą paruoštą 8 krypčių jungtį,

Kai tai bus padaryta- patikrinkite litavimą ir patikrinkite tarpus tarp varinių takelių.

Manau, kad 36 tpi jaunesnio pjūklo pjūklo diskas yra labai naudingas šalinant šiukšles. Nuimu ašmenų fiksavimo kaiščius ir įstumiu ašmenų galą į takelį- Akivaizdu, kad ašmenys nėra rėme.

6 veiksmas: išbandykite DAC

DAC testavimas
DAC testavimas

Palikite ryšį tarp grandinės ir „Arduino“išjungtą.

Nustatykite grandinės garsumo valdiklį į vidurį.

Įjunkite 9 V nuolatinės srovės maitinimą į naują grandinę.

Patikrinkite, ar grandinė yra gerai- aš negaliu prisiimti jokios atsakomybės už jūsų grandinę!

Išjungti

Prijunkite grandinę prie „Arduino“.

„Mega“naudokite 22-29 kaiščius. (PORTA) Nesuklyskite su dviem aukščiau esančiais 5V kaiščiais!

„Uno“naudokite kaiščius 0-7. Tai yra PORTD

Prijunkite 0 V maitinimo šaltinį prie 0 V „Arduino“.

Įjungti.

Atidarykite šią testavimo programą DAC_TEST

UNO pakeiskite visas nuorodas į PORTA į PORTD

Pakeiskite DDRA į DDRD- ši instrukcija nustato visas 8 eilutes vienu išėjimu. Tai duomenų krypčių registras.

Nustatykite nuoseklųjį monitorių 115200.

Prijunkite voltmetrą tarp DAC išvesties ir OV

Programa nustatys išvestį į 255 - visos linijos įjungtos - maksimali įtampa.

Išėjimas 128- pusė maksimalios įtampos.

Išėjimas 0- nulinė įtampa (arba tikriausiai beveik nulis).

Tada žingsnis po žingsnio: 1, 2, 4, 8, 16, 32, 64, 128

Įtampa turėtų nuolat didėti.

Jei įtampa sumažėja, o skaičius didėja, greičiausiai du sujungiami laidai yra atvirkščiai.

Taip pat turėtumėte išgirsti garsiakalbio tylų spragtelėjimą, kai kinta įtampa

7 žingsnis: skaitykite „Wav“antraštę

„Wav“antraštės skaitymas
„Wav“antraštės skaitymas

„Wav“failai išsaugomi nurodytu dažniu ir duomenų dydžiu.

Ši informacija yra 44 baitų antraštėje „wav“failo pradžioje.

Nors kai kuri programinė įranga praplečia antraštę (po 35 baito), todėl sunkiau rasti duomenų dydžio vietą.

Norėdami perskaityti antraštę, sukuriame buferį ir nukopijuojame failo pradžią.

Dažnis saugomas 4 baitais, pradedant 24 baitais į failą.

// skaitymo dažnis, nurodytas wav failo antraštėje

baitas 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 („Failo dažnis“));

Serial.print (pakartotinis);

Geriausias būdas rasti duomenų dydžio informaciją yra ieškoti žodžio „duomenys“antraštėje.

Tada išskleiskite po jo esančius 4 baitus, kurie sudaro ilgą vertę

nepasirašytas ilgas pakartojimas;

int mypos = 40;

už (int i = 36; i <60; i ++) {

jei (headbuf == 'd') {

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

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

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

// pagaliau mes turime

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

Gerai, mes turime duomenų ilgį ir dažnumą!

Garso duomenys seka 4 baitus, sudarančius duomenų ilgio vertę.

8 žingsnis: pertraukimas, pertraukimas…

Nutraukti, nutraukti…
Nutraukti, nutraukti…

Mes naudojame dažnio informaciją, kad sukurtume programinės įrangos pertrauką reikiamu dažniu arba netoli jo.

Ne visada galima tiksliai nustatyti pertrauką, tačiau to pakanka. Dažnis, nuskaitytas iš failo, perduodamas nustatytos trukmės paprogramei.

void setintrupt (float freq) {float bitval = 8; // 8 8 bitų laikmačiams 0 ir 2, 1024 1 baitui

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

// Setokroa reikšmei reikia atimti -1. Tačiau pridedant 0,5 raundo iki artimiausio 0,5

// Laikmačio skiriamoji geba yra ribota

// Galiausiai lemia bitvalo dydis

cli (); // išjungti pertraukas // nustatyti timer2 interrupt

TCCR2A = 0; // nustatyti visą TCCR2A registrą į 0

TCCR2B = 0; // tas pats TCCR2B

TCNT2 = 0; // inicijuoti skaitiklio reikšmę į 0

// nustatyti palyginimo rungtynių registrą dažnio (hz) prieaugiams

OCR2A = setokroa; // = (16*10^6) / (dažnis*8) - 1 (turi būti <256)

// įjungti CTC režimą

TCCR2A | = (1 << WGM21); // Nustatykite CS21 bitą 8 prescaler

TCCR2B | = (1 << CS21); // įjungti laikmačio palyginimo pertraukimą

// TIMSK2 | = (1 << OCIE2A); // tai veikia, kaip ir kita eilutė

sbi (TIMSK2, OCIE2A); // įjungti pertraukimą 2 laikmačiu

sei (); // įjungti pertraukas

Įžvalgūs skaitytojai pastebės sbi (TIMSK2, OCIE2A)

Aš sukonfigūravau keletą (internetu įsigytų) funkcijų, skirtų registro bitams nustatyti ir išvalyti:

// Apibrėžia registro bitų išvalymą#ifndef cbi

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

#endif

// Nustato registro bitų nustatymą

#ifndef sbi

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

#endif

Šios funkcijos leidžia lengvai skambinti, norint nustatyti arba panaikinti pertrauką.

Taigi pertrauka veikia, ką galime padaryti?

9 veiksmas: pertraukimai ir dvigubas buferis

Pertraukos ir dvigubas buferis
Pertraukos ir dvigubas buferis
Pertraukos ir dvigubas buferis
Pertraukos ir dvigubas buferis

22 kHz dažniu garso duomenų baitas išvedamas kas 0,045 ms

512 baitų (buferio dydis) nuskaitomas per 2,08 ms.

Taigi buferio negalima nuskaityti iš SDCard vieno rašymo ciklo metu.

Tačiau 512 baitų į uostą įrašoma per 23,22 ms.

Taigi, viskas, ką turime padaryti, yra nustatyti naują failą, nuskaitytą kiekvieną kartą, kai buferis ištuštinamas, ir mes turime pakankamai laiko gauti duomenis, kol reikalingas naujas duomenų blokas … Darant prielaidą, kad naudojame du buferius, vieną ištuštiname, kai užpildome kitą.

Tai dvigubas buferis.

Failo skaitymą sulėtins pakartotinis pertraukimas, tačiau jis bus atliktas.

Turiu nustatęs du 512 baitų buferius, vadinamus bufa ir bufb.

Jei vėliava yra tiesa, mes skaitome iš portos, kitaip mes skaitome iš portb

Kai buferio padėtis (bufcount) pasiekia buferio dydį (BUF_SIZE 512), mes nustatome vėliavą, vadinamą readit, į true.

Tuštumos ciklo rutina ieško šios vėliavos ir pradeda bloką skaityti:

if (readit) {if (! aready) {

// inicijuoti SDCard bloko skaitymą bufa

tempfile.read (bufa, BUF_SIZE);

} Kitas {

// inicijuoti SDCard bloką, perskaitytą į bufb

tempfile.read (bufb, BUF_SIZE);

}

skaityti = klaidinga;

}

Baigęs įprastas vėliavas readit = false.

Per pertraukos procedūrą turime patikrinti, ar tuštumos ciklas baigtas, patikrindami, ar readit == false.

Tokiu atveju mes signalizuojame, kad reikia dar kartą nuskaityti, ir perjungiame „aready“vėliavą, kad būtų pakeisti buferiai.

Jei SD kortelė vis dar skaito, turime grįžti prie vieno skaitymo (skaitiklis--; bufcount--;) ir išeiti iš pertraukos, kad vėliau bandytume dar kartą. (Paspaudimai garso išvesties signale reiškia, kad tai įvyko.)

Kai visi duomenys perskaitomi, nutraukimas nutraukiamas, prievadas vėl nustatomas į vidutinės įtampos vertę 128 ir garso failas uždaromas.

Prieš paleisdami dac2.ino scenarijų pirmą kartą, nustatykite 50%garsumą. Tai bus per garsiai, bet geriau nei 100%!

Jei garsumo valdymas veikia atvirkščiai, pakeiskite laidus priešinguose 10K potenciometro galuose.

Leiskite man žinoti, kaip tai skamba.

Rekomenduojamas: