Inhoudsopgave:

Bluetooth-audio en digitale signaalverwerking: een Arduino-framework: 10 stappen
Bluetooth-audio en digitale signaalverwerking: een Arduino-framework: 10 stappen

Video: Bluetooth-audio en digitale signaalverwerking: een Arduino-framework: 10 stappen

Video: Bluetooth-audio en digitale signaalverwerking: een Arduino-framework: 10 stappen
Video: JENSEN® Marine | MS30BT Bluetooth® Pairing Instructions 2024, November
Anonim
Image
Image
Bluetooth-audio en digitale signaalverwerking: een Arduino-framework
Bluetooth-audio en digitale signaalverwerking: een Arduino-framework

Samenvatting

Als ik aan Bluetooth denk, denk ik aan muziek, maar helaas kunnen de meeste microcontrollers geen muziek afspelen via Bluetooth. De Raspberry Pi kan dat maar dat is een computer. Ik wil een op Arduino gebaseerd framework ontwikkelen voor microcontrollers om audio via Bluetooth af te spelen. Om de spieren van mijn microcontroller volledig te buigen, ga ik real-time Digital Signal Processing (DSP) toevoegen aan de audio (high-pass filtering, low-pass filtering en dynamisch bereik compressie). Als kers op de taart zal ik een webserver toevoegen waarmee de DSP draadloos kan worden geconfigureerd. De ingesloten video toont de basisprincipes van Bluetooth-audio in actie. Het laat me ook zien dat ik de webserver gebruik om hoogdoorlaatfiltering, laagdoorlaatfiltering en compressie van dynamisch bereik uit te voeren. Het eerste gebruik van Dynamic Range-compressie veroorzaakt met opzet vervorming als voorbeeld van slechte parameterkeuzes. Het tweede voorbeeld elimineert deze vervorming.

Voor dit project is de ESP32 de microcontroller bij uitstek. Het kost minder dan £ 10 en zit boordevol functies met ADC's, DAC's, Wifi, Bluetooth Low Energy, Bluetooth Classic en een 240 MHz dual-coreprocessor. De ingebouwde DAC kan technisch audio afspelen, maar het zal niet geweldig klinken. In plaats daarvan gebruik ik de Adafruit I2S stereo decoder om een line-out signaal te produceren. Dit signaal kan eenvoudig naar elk HiFi-systeem worden gestuurd om direct draadloze audio toe te voegen aan uw bestaande HiFi-systeem.

Benodigdheden

Hopelijk hebben de meeste makers breadboards, jumpers, USB-kabels, soldeerbouten voor de voeding en hoeven ze slechts £ 15 uit te geven aan de ESP32 en de stereodecoder. Zo niet, dan vindt u hieronder een lijst met alle benodigde onderdelen.

  • Een ESP32 - getest op ESP32-PICO-KIT en TinyPico - £ 9,50 / £ 24
  • Adafruit I2S-stereodecoder - £ 5,51
  • Broodplank - £3-£5 per stuk
  • Doorverbindingsdraden - £ 3
  • Bedrade hoofdtelefoon/hifisysteem - £££
  • Push-headers of soldeerbout - £ 2,10 / £ 30
  • Micro-USB-kabel - £ 2,10 / £ 3
  • 3,5 mm naar RCA-connector / 3,5 mm jack naar jack (of wat uw luidspreker ook nodig heeft) - £ 2,40 / £ 1,50
  • USB-voeding - £ 5

Stap 1: Constructie - de Breadboard

Constructie - de Breadboard
Constructie - de Breadboard

Als je de ESP32-PICO-KIT hebt gekocht, hoef je geen pinnen te solderen omdat deze voorgesoldeerd zijn. Plaats hem eenvoudig op het breadboard.

Stap 2: Constructie - Push Headers/solderen

Constructie - Push Headers/solderen
Constructie - Push Headers/solderen
Constructie - Push Headers/solderen
Constructie - Push Headers/solderen

Als je een soldeerbout hebt, soldeer dan de pinnen aan de stereodecoder volgens de instructies op de Adafruit-website. Op het moment van schrijven was mijn soldeerbout aan het werk die op slot zat. Ik wilde niet betalen voor een tijdelijke soldeerbout, dus knipte ik wat push-headers van pimoroni. Ik heb ze in stukken gesneden zodat ze in de stereodecoder zouden passen. Dit is niet de beste oplossing (en niet hoe de headers bedoeld waren om te gebruiken) maar het is het goedkoopste alternatief voor een soldeerbout. Steek de opgeknipte kop op het breadboard. Voor de decoder heb je maar 1 lijn van 6 pinnen nodig. Je kunt er nog zes aan de andere kant toevoegen voor stabiliteit, maar dit is niet nodig voor dit prototypesysteem. De pinnen om de headers in te steken zijn vin, 3vo, gnd, wsel, din en bclk.

Stap 3: Constructie - Bedrading van de stroompinnen

Constructie - Bedrading van de stroompinnen
Constructie - Bedrading van de stroompinnen

Plaats de stereodecoder op de push-headers (vin, 3vo, gnd, wsel, din en bclk-pinnen) en druk ze stevig tegen elkaar. Nogmaals, dit zou idealiter met een soldeerbout moeten gebeuren, maar ik moest improviseren. U zult merken dat alle draden in deze instructable blauw zijn. Dat komt omdat ik geen jumperdraden had, dus ik knipte 1 lange draad in kleinere stukjes. Ik ben ook kleurenblind en geef niet echt om de draadkleur. De stroompinnen zijn als volgt bevestigd:

3v3 (ESP32) -> naar vin op stereodecoder

gnd (ESP32) -> naar gnd op stereodecoder

Stap 4: Constructie - I2S-bedrading

Constructie - I2S-bedrading
Constructie - I2S-bedrading

Om de Bluetooth-audio van de ESP32 naar de stereodecoder te sturen, gaan we een methode van digitale communicatie gebruiken, I2S genaamd. De stereodecoder neemt dit digitale signaal en zet het om in een analoog signaal dat kan worden aangesloten op een luidspreker of HiFi. I2S vereist slechts 3 draden en is redelijk eenvoudig te begrijpen. De bitkloklijn (bclk) wordt hoog en laag om aan te geven dat er een nieuwe bit is verzonden. De data-uitlijn (dout) wordt hoog of laag om aan te geven of dat bit een waarde van 0 of 1 heeft en de woordselectielijn (wsel) wordt hoog of laag om aan te geven of het linker- of rechterkanaal wordt uitgezonden. Niet elke microcontroller ondersteunt I2S, maar de ESP32 heeft 2 I2S-lijnen. Dit maakt het een voor de hand liggende keuze voor dit project.

De bedrading is als volgt:

27 (ESP32) -> wsel (stereodecoder)

25 (ESP32) -> din (stereodecoder)

26 (ESP32) -> bclk (stereodecoder)

Stap 5: De BtAudio-bibliotheek installeren

De BtAudio-bibliotheek installeren
De BtAudio-bibliotheek installeren
De BtAudio-bibliotheek installeren
De BtAudio-bibliotheek installeren

Als je ze nog niet hebt geïnstalleerd, installeer dan de Arduino IDE en de Arduino-kern voor ESP32. Zodra je ze hebt geïnstalleerd, bezoek je mijn Github-pagina en download je de repository. Binnen de Arduino IDE onder Sketch>>Include Library>> selecteer "Add. ZIP library". Selecteer vervolgens het gedownloade zipbestand. Dit zou mijn btAudio-bibliotheek aan uw Arduino-bibliotheken moeten toevoegen. Om de bibliotheek te gebruiken, moet je de relevante header in de Arduino-schets opnemen. Dit zie je in de volgende stap.

Stap 6: De BtAudio-bibliotheek gebruiken

De BtAudio-bibliotheek gebruiken
De BtAudio-bibliotheek gebruiken
De BtAudio-bibliotheek gebruiken
De BtAudio-bibliotheek gebruiken

Eenmaal geïnstalleerd, sluit u uw ESP32 aan op uw computer via micro-USB en sluit u vervolgens uw stereodecoder aan op uw luidspreker met uw 3,5 mm-draad. Voordat je de schets uploadt, moet je een aantal dingen wijzigen in de Arduino-editor. Nadat je je bord hebt geselecteerd, moet je het partitieschema bewerken onder Extra >> Partitieschema en ofwel "Geen OTA (grote APP)" of "Minimale SPIFFS (grote APPS met OTA)" selecteren. Dit is nodig omdat dit project zowel WiFi als Bluetooth gebruikt, beide zeer geheugenrijke bibliotheken. Zodra je dit hebt gedaan, upload je de volgende schets naar de ESP32.

#erbij betrekken

// Stelt de naam van het audioapparaat in btAudio audio = btAudio ("ESP_Speaker"); void setup() {// streamt audiogegevens naar de ESP32 audio.begin(); // voert de ontvangen gegevens uit naar een I2S DAC int bck = 26; int ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } lege lus() { }

De schets is grofweg in te delen in 3 stappen:

  1. Maak een globaal btAudio-object dat de "Bluetooth-naam" van uw ESP32 instelt
  2. Configureer de ESP32 om audio te ontvangen met de btAudio::begin methode
  3. Stel de I2S-pinnen in met de btAudio::I2S-methode.

Dat is het aan de softwarekant! Nu hoeft u alleen nog maar de Bluetooth-verbinding met uw ESP32 tot stand te brengen. Scan gewoon naar nieuwe apparaten op uw telefoon/laptop/MP3-speler en "ESP_Speaker" zal verschijnen. Als je eenmaal tevreden bent dat alles werkt (muziek speelt) kun je de ESP32 loskoppelen van je computer. Voed hem met de USB-voeding en hij onthoudt de laatste code die je erop hebt geüpload. Zo kun je je ESP32 voor altijd verborgen achter je HiFi-systeem laten.

Stap 7: DSP - Filteren

De ontvanger uitbreiden met digitale signaalverwerking

Als je alle stappen hebt gevolgd (en ik heb niets weggelaten) heb je nu een volledig werkende Bluetooth-ontvanger voor je HiFi-systeem. Hoewel dit cool is, drijft het de microcontroller niet echt tot het uiterste. De ESP32 heeft twee kernen die werken op 240 MHz. Dat betekent dat dit project veel meer is dan alleen een ontvanger. Het heeft de capaciteit om een Bluetooth-ontvanger te zijn met een Digital Signal Processor (DSP). DSP's voeren in wezen in realtime wiskundige bewerkingen op het signaal uit. Een handige bewerking is Digital Filtering. Dit proces dempt frequenties in een signaal onder of boven een bepaalde afsnijfrequentie, afhankelijk van of u een hoogdoorlaat- of laagdoorlaatfilter gebruikt.

Hoogdoorlaatfilters

Hoogdoorlaatfilters dempen frequenties onder een bepaalde band. Ik heb een filterbibliotheek voor Arduino-systemen gebouwd op basis van code van earlevel.com. Het belangrijkste verschil is dat ik de klassenstructuur heb gewijzigd om de constructie van filters van hogere orde gemakkelijker te maken. Hogere-ordefilters onderdrukken frequenties buiten uw grens effectiever, maar ze vereisen veel meer berekening. Met de huidige implementatie kunt u echter zelfs 6e-ordefilters gebruiken voor realtime audio!

De schets is dezelfde als die in de vorige stap, behalve dat we de hoofdlus hebben gewijzigd. Om de filters in te schakelen gebruiken we de btAudio::createFilter methode. Deze methode accepteert 3 argumenten. De eerste is het aantal filtercascades. Het aantal filtercascades is de helft van de grootte van het filter. Voor een filter van de 6e orde zou het eerste argument 3 moeten zijn. Voor een filter van de 8e orde zou dit 4 zijn. Het tweede argument is de filterafsnijding. Ik heb dit ingesteld op 1000 Hz om een echt dramatisch effect op de gegevens te hebben. Ten slotte specificeren we het type filer met het derde argument. Dit moet hoogdoorlaat zijn voor een hoogdoorlaatfilter en laagdoorlaat voor een laagdoorlaatfilter. Het onderstaande script schakelt de cutoff van deze frequentie tussen 1000Hz en 2Hz. U zou een dramatisch effect op de gegevens moeten horen.

#erbij betrekken

btAudio audio = btAudio("ESP_Speaker"); void setup() { audio.begin(); int bck = 26; int ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } void loop() { vertraging (5000); audio.createFilter (3, 1000, highpass); vertraging (5000); audio.createFilter (3, 2, highpass); }

Laagdoorlaatfilters

Laagdoorlaatfilters doen het tegenovergestelde van hoogdoorlaatfilters en onderdrukken frequenties boven een bepaalde frequentie. Ze kunnen op dezelfde manier worden geïmplementeerd als hoogdoorlaatfilters, behalve dat ze het derde argument in laagdoorlaat moeten veranderen. Voor de onderstaande schets wissel ik de low-pass cutoff af tussen 2000Hz en 20000Hz. Hopelijk hoor je het verschil. Het zou behoorlijk gedempt moeten klinken als het laagdoorlaatfilter op 2000Hz staat.

#erbij betrekken

btAudio audio = btAudio("ESP_Speaker"); void setup() { audio.begin(); int bck = 26; int ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } void loop() { vertraging (5000); audio.createFilter (3, 2000, laagdoorlaat); vertraging (5000); audio.createFilter (3, 20000, laagdoorlaat); }

Stap 8: DSP - compressie van dynamisch bereik

Achtergrond

Dynamisch bereikcompressie is een signaalverwerkingsmethode die probeert de luidheid van de audio te egaliseren. Het comprimeert harde geluiden, die boven een bepaalde drempel uitkomen, tot het niveau van stille en versterkt vervolgens optioneel beide. Het resultaat is een veel gelijkmatigere luisterervaring. Dit kwam erg goed van pas tijdens het kijken naar een show met zeer luide achtergrondmuziek en zeer rustige zang. In dit geval hielp alleen het volume verhogen niet, omdat dit alleen de achtergrondmuziek versterkte. Met compressie van het dynamisch bereik kon ik de luide achtergrondmuziek terugbrengen tot het niveau van de zang en alles weer goed horen.

De code

Compressie van dynamisch bereik houdt niet alleen in dat het volume wordt verlaagd of het signaal wordt gedrempeld. Het is iets slimmer dan dat. Als u het volume verlaagt, worden zachte geluiden evenals de luide gedempt. Een manier om dit te omzeilen is om het signaal te drempelen, maar dit resulteert in ernstige vervorming. Compressie van dynamisch bereik omvat een combinatie van zachte drempelwaarde en filtering om de vervorming te minimaliseren die u zou krijgen als u het signaal zou drempelen/knippen. Het resultaat is een signaal waarbij de harde geluiden zonder vervorming worden "geknipt" en de stille geluiden worden gelaten zoals ze zijn. De onderstaande code schakelt tussen drie verschillende compressieniveaus.

  1. Compressie met vervorming
  2. Compressie zonder vervorming
  3. Geen compressie

#erbij betrekken

btAudio audio = btAudio("ESP_Speaker"); void setup() { audio.begin(); int bck = 26; int ws = 27; int dout = 25; audio. I2S(bck, dout, ws); } void loop() { vertraging (5000); audio.compress (30, 0,0001, 0,0001, 10, 10, 0); vertraging (5000); audio.compress (30, 0,0001, 0,1, 10, 10, 0); vertraging (5000); audio.decomprimeren(); }

Dynamisch bereik compressie is ingewikkeld en de btAudio::compress methode heeft veel parameters. Ik zal ze hier (in volgorde) proberen uit te leggen:

  1. Threshold - Het niveau waarop de audio wordt verminderd (gemeten in decibel)
  2. Attack time - De tijd die het duurt voordat de compressor begint te werken zodra de drempel is overschreden
  3. Vrijgavetijd - De tijd die het duurt voordat de compressor stopt met werken.
  4. Reductieverhouding - de factor waarmee de audio wordt gecomprimeerd.
  5. Kniebreedte - De breedte (in decibel) rond de drempel waarbij de compressor gedeeltelijk werkt (natuurlijker geluid).
  6. De versterking (decibel) die na compressie aan het signaal wordt toegevoegd (volume verhogen/verlagen)

De zeer hoorbare vervorming bij het eerste gebruik van compressie is omdat de drempel erg laag is en zowel de aanvalstijd als de releasetijd erg kort zijn, wat resulteert in een hard drempelgedrag. Dit wordt in het tweede geval duidelijk opgelost door de releasetijd te verhogen. Dit zorgt er in wezen voor dat de compressor veel soepeler werkt. Hier heb ik alleen laten zien hoe het veranderen van 1 parameter een dramatisch effect kan hebben op de audio. Nu is het jouw beurt om te experimenteren met verschillende parameters.

De implementatie (de magische wiskunde - optioneel)

Ik vond dat het naïef implementeren van de Dynamic Range-compressie een uitdaging was. Het algoritme vereist het converteren van een 16-bits geheel getal naar decibel en het vervolgens terug transformeren naar een 16-bits geheel getal nadat u het signaal hebt verwerkt. Ik merkte dat één regel code 10 microseconden nodig had om stereogegevens te verwerken. Aangezien stereo audio gesampled op 44,1 KHz slechts 11,3 microseconden overlaat voor de DSP, is dit onaanvaardbaar traag… Door een kleine opzoektabel (400 bytes) en een interpolatieprocedure te combineren op basis van de verdeelde verschillen van Netwon, kunnen we echter bijna 17 bits precisie verkrijgen in 0,2 microseconden. Ik heb een pdf-document bijgevoegd met alle wiskunde voor de echt geïnteresseerden. Het is ingewikkeld, je bent gewaarschuwd!

Stap 9: De wifi-interface

De wifi-interface
De wifi-interface
De wifi-interface
De wifi-interface

Nu hebt u een Bluetooth-ontvanger die realtime DSP kan uitvoeren. Helaas, als je een van de DSP-parameters wilt wijzigen, moet je de verbinding met je HiFi verbreken, een nieuwe schets uploaden en vervolgens opnieuw verbinden. Dit is onhandig. Om dit op te lossen heb ik een webserver ontwikkeld die je kunt gebruiken om alle DSP-parameters te bewerken zonder opnieuw verbinding te maken met je computer. De schets om de webserver te gebruiken staat hieronder.

#erbij betrekken

#include btAudio audio = btAudio("ESP_Speaker"); webDSP-web; void setup() { Serial.begin(115200); audio.begin(); int bck = 26; int ws = 27; int dout = 25; audio. I2S(bck, dout, ws); // vervang door uw WiFi-ID en wachtwoord const char* ssid = "SSID"; const char* wachtwoord = "WACHTWOORD"; web.begin(ssid, wachtwoord, &audio); } void loop() { web._server.handleClient(); }

De code wijst een IP-adres toe aan uw ESP32 dat u kunt gebruiken om toegang te krijgen tot de webpagina. De eerste keer dat u deze code uitvoert, moet deze op uw computer zijn aangesloten. Zo zie je op je seriële monitor het IP-adres dat aan je ESP32 is toegewezen. Als u toegang wilt tot deze webpagina, voert u eenvoudig dit IP-adres in een webbrowser in (getest op Chrome).

Inmiddels zouden we bekend moeten zijn met de methode om Bluetooth en I2S in te schakelen. Het belangrijkste verschil is het gebruik van een webDSP-object. Dit object neemt uw Wifi SSID en wachtwoord als argumenten en als een verwijzing naar het btAudio-object. In de hoofdlus krijgen we voortdurend het webDSP-object om te luisteren naar binnenkomende gegevens van de webpagina en vervolgens de DSP-parameters bij te werken. Als afsluiting moet worden opgemerkt dat zowel Bluetooth als Wifi dezelfde radio gebruiken op de ESP32. Dit betekent dat u mogelijk tot 10 seconden moet wachten vanaf het moment dat u de parameters op de webpagina invoert tot het moment waarop de informatie de ESP32 bereikt.

Stap 10: Toekomstplannen

Hopelijk heb je genoten van deze instructable en heb je nu Bluetooth Audio en DSP toegevoegd aan je HiFi. Ik denk echter dat er veel ruimte is voor groei in dit project en ik wilde alleen wijzen op enkele toekomstige richtingen die ik zou kunnen nemen.

  • Schakel wifi-streaming van audio in (voor de beste audiokwaliteit)
  • Gebruik een I2S-microfoon om spraakopdrachten in te schakelen
  • ontwikkel een wifi-gestuurde equalizer
  • Maak het mooi (breadboard schreeuwt niet om geweldig productontwerp)

Als ik er aan toe kom om deze ideeën te implementeren, zal ik meer instructables maken. Of misschien laat iemand anders deze functies implementeren. Dat is het leuke van alles open source maken!

Aanbevolen: