Innehållsförteckning:

Bluetooth Audio & Digital Signal Processing: an Arduino Framework: 10 Steg
Bluetooth Audio & Digital Signal Processing: an Arduino Framework: 10 Steg

Video: Bluetooth Audio & Digital Signal Processing: an Arduino Framework: 10 Steg

Video: Bluetooth Audio & Digital Signal Processing: an Arduino Framework: 10 Steg
Video: Building a Digital Music Player with I2S?! What is I2S! EB#45 2024, November
Anonim
Image
Image
Bluetooth -ljud och digital signalbehandling: ett Arduino -ramverk
Bluetooth -ljud och digital signalbehandling: ett Arduino -ramverk

Sammanfattning

När jag tänker på Bluetooth tänker jag på musik men tyvärr kan de flesta mikrokontroller inte spela musik via Bluetooth. Raspberry Pi kan men det är en dator. Jag vill utveckla ett Arduino -baserat ramverk för mikrokontroller för att spela upp ljud via Bluetooth. För att helt böja mina mikrokontrollers muskler kommer jag att lägga till realtid Digital Signal Processing (DSP) till ljudet (högpassfiltrering, lågpassfiltrering och dynamisk omfångskomprimering). För körsbäret på toppen lägger jag till en webbserver som kan användas för att konfigurera DSP trådlöst. Den inbäddade videon visar grunderna för Bluetooth -ljud i funktion. Det visar också att jag använder webbservern för att utföra lite högpassfiltrering, lågpassfiltrering och komprimering av dynamiskt område. Den första användningen av Dynamic range -komprimering orsakar målmedvetet distorsion som ett exempel på dåliga parameterval. Det andra exemplet eliminerar denna snedvridning.

För detta projekt är ESP32 den valda mikrokontrollern. Den kostar mindre än £ 10 och är fullpackad med ADC, DAC, Wifi, Bluetooth Low Energy, Bluetooth Classic och en 240 MHz dual-core processor. Den inbyggda DAC kan tekniskt spela upp ljud men det låter inte bra. Istället använder jag Adafruit I2S stereodekoder för att producera en line-out-signal. Denna signal kan enkelt skickas till alla HiFi -system för att direkt lägga till trådlöst ljud till ditt befintliga HiFi -system.

Tillbehör

Förhoppningsvis kommer de flesta tillverkare att ha brödbrädor, byglar, USB -kablar, lödkolvar för strömförsörjning och behöver bara spendera £ 15 på ESP32 och stereodekoder. Om inte, listas alla delar som krävs nedan.

  • En ESP32 - testad på ESP32 -PICO -KIT och TinyPico - £ 9,50/ £ 24
  • Adafruit I2S Stereo Decoder - £ 5.51
  • Brödbräda - £ 3- £ 5 styck
  • Tröjor - £ 3
  • Trådlösa hörlurar/Hi -Fi -system - £ $$$
  • Skjuthuvuden eller lödkolv - £ 2,10 / £ 30
  • Micro USB -kabel - £ 2,10/ £ 3
  • 3,5 mm till RCA -kontakt/ 3,5 mm jack till jack (eller vad din högtalare behöver) - 2,40 £/ 1,50 £
  • USB -strömförsörjning - £ 5

Steg 1: Konstruktion - brödbrädan

Konstruktion - brödbrädan
Konstruktion - brödbrädan

Om du köpte ESP32-PICO-KIT behöver du inte lödda några stift eftersom det kommer förlödt. Lägg den helt enkelt på brödbrädan.

Steg 2: Konstruktion - Push Headers/lödning

Konstruktion - Push Headers/lödning
Konstruktion - Push Headers/lödning
Konstruktion - Push Headers/lödning
Konstruktion - Push Headers/lödning

Om du har ett lödkolv, löd stiften till stereodekoder enligt instruktionerna på Adafruit -webbplatsen. I skrivande stund var mitt lödkolv på jobbet som var låst. Jag ville inte betala för ett tillfälligt lödkolv så jag skar upp några tryckhuvuden från pimoroni. Jag klippte upp dem så att de skulle passa till stereodekoder. Detta är inte den bästa lösningen (och inte hur rubrikerna var avsedda att användas) men det är det billigaste alternativet till ett lödkolv. Fäst den kapade rubriken på brödbrädan. Du behöver bara 1 rad med 6 stift för avkodaren. Du kan lägga till ytterligare sex till den andra sidan för stabilitet men detta är inte nödvändigt för detta prototypsystem. Stiften att placera rubrikerna i är vin, 3vo, gnd, wsel, din och bclk.

Steg 3: Konstruktion - Koppla ihop Power Pins

Konstruktion - Anslut Power Pins
Konstruktion - Anslut Power Pins

Placera Stereo -avkodaren på tryckhuvudena (vin, 3vo, gnd, wsel, din och bclk -stift) och tryck ihop dem ordentligt. Återigen bör detta helst göras med ett lödkolv men jag var tvungen att improvisera. Du kommer att märka att alla trådar i denna instruerbara är blå. Det beror på att jag inte hade några bygelkablar så jag skar 1 lång tråd i mindre bitar. Jag är också färgblind och bryr mig inte riktigt om trådfärgen. Strömnålarna fästs enligt följande:

3v3 (ESP32) -> till vin på stereodekoder

gnd (ESP32) -> till gnd på stereodekoder

Steg 4: Konstruktion - I2S -ledningar

Konstruktion - I2S ledningar
Konstruktion - I2S ledningar

För att skicka Bluetooth -ljud från ESP32 till stereodekoder kommer vi att använda en metod för digital kommunikation som kallas I2S. Stereodekoder tar denna digitala signal och gör den till en analog signal som kan anslutas till en högtalare eller HiFi. I2S kräver bara 3 trådar och är rimligt enkelt att förstå. Bitklockans (bclk) linje blir hög och låg för att indikera att en ny bit överförs. Data-out-raden (dout) blir hög eller låg för att indikera om den biten har ett värde på 0 eller 1 och ordet för val av linje (wsel) blir högt eller lågt för att indikera om vänster eller höger kanal sänds. Inte alla mikrokontroller stöder I2S men ESP32 har 2 I2S -linjer. Detta gör det till ett självklart val för detta projekt.

Ledningarna är följande:

27 (ESP32) -> wsel (stereodekoder)

25 (ESP32) -> din (stereodekoder)

26 (ESP32) -> bclk (stereodekoder)

Steg 5: Installera BtAudio -biblioteket

Installera BtAudio -biblioteket
Installera BtAudio -biblioteket
Installera BtAudio -biblioteket
Installera BtAudio -biblioteket

Om du inte redan har dem installerade installerar du Arduino IDE och Arduino -kärnan för ESP32. När du har installerat dem besöker du min Github -sida och laddar ner förvaret. I Arduino IDE under Skiss >> Inkludera bibliotek >> välj "Lägg till. ZIP -bibliotek". Välj sedan den nedladdade zip -filen. Detta bör lägga till mitt btAudio -bibliotek till dina Arduino -bibliotek. För att använda biblioteket måste du inkludera relevant rubrik i Arduino -skissen. Du ser detta i nästa steg.

Steg 6: Använda BtAudio -biblioteket

Använda BtAudio -biblioteket
Använda BtAudio -biblioteket
Använda BtAudio -biblioteket
Använda BtAudio -biblioteket

När den är installerad ansluter du din ESP32 till din dator via mikro -USB och ansluter sedan din stereodekoder till din högtalare med din 3,5 mm kabel. Innan du laddar upp skissen måste du ändra några saker i Arduino -redigeraren. När du har valt din tavla måste du redigera partitionsschemat under Verktyg >> Partitionsschema och välja antingen "No OTA (Large APP)" eller "Minimal SPIFFS (Large APPS with OTA)". Detta är nödvändigt eftersom det här projektet använder både WiFi och Bluetooth som båda är mycket minnetunga bibliotek. När du har gjort detta ladda upp följande skiss till ESP32.

#omfatta

// Ställer in namnet på ljudenheten btAudio audio = btAudio ("ESP_Speaker"); void setup () {// strömmar ljuddata till ESP32 audio.begin (); // matar ut den mottagna data till en I2S DAC int bck = 26; int ws = 27; int dout = 25; audio. I2S (bck, dout, ws); } void loop () {}

Skissen kan i stort delas in i 3 steg:

  1. Skapa ett globalt btAudio -objekt som anger "Bluetooth -namn" för din ESP32
  2. Konfigurera ESP32 för att ta emot ljud med btAudio:: start -metoden
  3. Ställ in I2S -stiften med btAudio:: I2S -metoden.

Det är det på mjukvarusidan! Allt du behöver göra är att starta Bluetooth -anslutningen till din ESP32. Sök bara efter nya enheter på din telefon/laptop/MP3 -spelare så visas "ESP_Speaker". När du är glad att allt fungerar (musik spelas) kan du koppla bort ESP32 från din dator. Driv den med USB -strömförsörjningen så kommer den ihåg den senaste koden som du laddade upp till den. På så sätt kan du lämna din ESP32 gömd bakom ditt HiFi -system för alltid.

Steg 7: DSP - filtrering

Utöka mottagaren med digital signalbehandling

Om du följde alla steg (och jag inte lämnade något utanför) har du nu en fullt fungerande Bluetooth -mottagare för ditt HiFi -system. Även om det här är coolt, pressar det inte riktigt mikrokontrollern till sina gränser. ESP32 har två kärnor som arbetar vid 240MHz. Det betyder att detta projekt är mycket mer än bara en mottagare. Den har kapacitet att vara en Bluetooth -mottagare med en digital signalprocessor (DSP). DSP: er utför i huvudsak matematiska operationer på signalen i realtid. En användbar operation kallas Digital filtrering. Denna process dämpar frekvenser i en signal under eller över en viss gränsfrekvens, beroende på om du använder ett högpass- eller lågpassfilter.

Högpassfilter

Högpassfilter dämpar frekvenser under ett visst band. Jag har byggt ett filterbibliotek för Arduino -system baserat på kod från earlevel.com. Den största skillnaden är att jag har ändrat klassstrukturen för att lättare kunna bygga filter av högre ordning. Filter av högre ordning undertrycker frekvenser utanför din avstängning mer effektivt men de kräver mycket mer beräkning. Men med den nuvarande implementeringen kan du till och med använda sjätte ordningsfilter för ljud i realtid!

Skissen är densamma som den som hittades i föregående steg förutom att vi har ändrat huvudslingan. För att aktivera filtren använder vi btAudio:: createFilter -metoden. Denna metod accepterar 3 argument. Den första är antalet filterkaskader. Antalet filterkaskader är hälften av filtret. För ett sjätte ordningsfilter bör det första argumentet vara 3. För ett åttonde ordningsfilter skulle det vara 4. Det andra argumentet är filteravstängning. Jag har ställt in detta på 1000Hz för att få en riktigt dramatisk effekt på data. Slutligen anger vi typen av filer med det tredje argumentet. Detta bör vara högpass för ett högpassfilter och lågpass för ett lågpassfilter. Skriptet nedan växlar avstängningen av denna frekvens mellan 1000Hz och 2Hz. Du bör höra en dramatisk effekt på data.

#omfatta

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 () {delay (5000); audio.createFilter (3, 1000, högpass); fördröjning (5000); audio.createFilter (3, 2, högpass); }

Lågpassfilter

Lågpassfilter gör motsatsen till högpassfilter och undertrycker frekvenser över en viss frekvens. De kan implementeras på samma sätt som högpassfilter förutom att de kräver att det tredje argumentet ändras till lågpass. För skissen nedan alternerar jag lågpassavstängningen mellan 2000Hz och 20000Hz. Förhoppningsvis hör du skillnaden. Det ska låta ganska dämpat när lågpassfiltret är vid 2000Hz.

#omfatta

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 () {delay (5000); audio.createFilter (3, 2000, lågpass); fördröjning (5000); audio.createFilter (3, 20000, lågpass); }

Steg 8: DSP - Dynamic Range Compression

Bakgrund

Dynamisk omfångskomprimering är en signalbehandlingsmetod som försöker jämna ut ljudet. Det komprimerar höga ljud, som stiger över en viss tröskel, till nivån av tysta och förstärker sedan valfritt båda. Resultatet är en mycket jämnare lyssningsupplevelse. Detta kom verkligen till nytta medan jag tittade på en show med mycket hög bakgrundsmusik och väldigt tyst sång. I det här fallet hjälpte bara att öka volymen eftersom det bara förstärkte bakgrundsmusiken. Med komprimering av dynamiskt omfång kunde jag reducera den höga bakgrundsmusiken till sångnivån och höra allt ordentligt igen.

Koden

Komprimering av dynamiskt omfång innebär inte bara att volymen sänks eller tröskelvärdet för signalen. Det är lite smartare än så. Om du sänker volymen kommer tysta ljud att minska såväl som de höga. En väg runt detta är att tröskelvärde signalen men detta resulterar i allvarlig förvrängning. Dynamisk omfångskomprimering innebär en kombination av mjuk tröskel och filtrering för att minimera den förvrängning man skulle få om man skulle tröskla/klippa signalen. Resultatet är en signal där de höga ljuden "klipps" utan förvrängning och de tysta lämnas som de är. Koden nedan växlar mellan tre olika komprimeringsnivåer.

  1. Komprimering med distorsion
  2. Komprimering utan förvrängning
  3. Ingen komprimering

#omfatta

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 () {delay (5000); audio.compress (30, 0,0001, 0,0001, 10, 10, 0); fördröjning (5000); audio.compress (30, 0,0001, 0,1, 10, 10, 0); fördröjning (5000); audio.decompress (); }

Dynamisk omfångskomprimering är komplicerad och btAudio:: komprimeringsmetoderna har många parametrar. Jag ska försöka förklara dem (i ordning) här:

  1. Tröskel - Nivån vid vilken ljudet reduceras (mätt i decibel)
  2. Attacktid - Den tid det tar för kompressorn att börja arbeta när tröskeln har överskridits
  3. Släpptid - Den tid det tar för kompressorn att sluta fungera.
  4. Reduktionsförhållande - den faktor med vilken ljudet komprimeras.
  5. Knebredd - Bredden (i decibel) runt tröskeln vid vilken kompressorn delvis arbetar (mer naturligt ljud).
  6. Förstärkningen (decibel) som läggs till signalen efter komprimering (öka/minska volymen)

Den mycket hörbara förvrängningen vid den första användningen av kompression beror på att tröskeln är mycket låg och både attacktiden och släpptiden är mycket korta effektivt vilket resulterar i ett hårt tröskelbeteende. Detta löses tydligt i det andra fallet genom att öka släpptiden. Detta gör att kompressorn fungerar på ett mycket smidigare sätt. Här har jag bara visat hur ändring av en parameter kan ha en dramatisk effekt på ljudet. Nu är det din tur att experimentera med olika parametrar.

Implementeringen (den magiska matematiken - valfritt)

Jag tyckte att naivt implementering av dynamisk omfångskomprimering var utmanande. Algoritmen kräver att ett 16-bitars heltal omvandlas till decibel och sedan omvandlas till ett 16-bitars heltal när du har bearbetat signalen. Jag märkte att en rad kod tog 10 mikrosekunder för att bearbeta stereodata. Eftersom stereoljud samplat vid 44,1 KHz lämnar endast 11,3 mikrosekunder för DSP är detta oacceptabelt långsamt … Men genom att kombinera en liten uppslagstabell (400 byte) och en interpoleringsprocedur baserad på Netwons delade skillnader kan vi få nästan 17 bitars precision på 0,2 mikrosekunder. Jag har bifogat ett pdf -dokument med all matematik för de riktigt intresserade. Det är komplicerat, du har blivit varnad!

Steg 9: Wifi -gränssnittet

Wifi -gränssnittet
Wifi -gränssnittet
Wifi -gränssnittet
Wifi -gränssnittet

Nu har du en Bluetooth-mottagare som kan köra DSP i realtid. Tyvärr, om du vill ändra någon av DSP -parametrarna måste du koppla från din HiFi, ladda upp en ny skiss och anslut sedan igen. Det här är klumpigt. För att åtgärda detta utvecklade jag en webbserver som du kan använda för att redigera alla DSP -parametrar utan att återansluta till din dator. Skissen för att använda webbservern är nedan.

#omfatta

#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); // ersätt med ditt WiFi -ID och lösenord const char* ssid = "SSID"; const char* password = "LÖSENORD"; web.begin (ssid, lösenord och ljud); } void loop () {web._server.handleClient (); }

Koden tilldelar din IP -adress en IP -adress som du kan använda för att komma åt webbsidan. Första gången du kör den här koden bör du ha den ansluten till din dator. På så sätt kan du se IP -adressen som tilldelats din ESP32 på din seriella bildskärm. Om du vill komma åt den här webbsidan anger du bara denna IP -adress i valfri webbläsare (testad på krom).

Nu borde vi vara bekanta med metoden för att aktivera Bluetooth och I2S. Den viktigaste skillnaden är användningen av ett webDSP -objekt. Detta objekt tar ditt Wifi SSID och lösenord som argument samt en pekare till btAudio -objektet. I huvudslingan får vi kontinuerligt webDSP -objektet att lyssna efter inkommande data från webbsidan och sedan uppdatera DSP -parametrarna. Som en avslutning bör det noteras att både Bluetooth och Wifi använder samma radio på ESP32. Det betyder att du kan behöva vänta i upp till 10 sekunder från det att du anger parametrar på webbsidan till när informationen faktiskt når ESP32.

Steg 10: Framtidsplaner

Förhoppningsvis har du njutit av detta instruerbara och nu har Bluetooth Audio och DSP lagts till i ditt HiFi. Jag tror dock att det finns mycket utrymme för tillväxt i detta projekt och jag ville bara peka på några framtida riktningar jag kan ta.

  • Aktivera Wifi -streaming av ljud (för bästa ljudkvalitet)
  • Använd en I2S -mikrofon för att aktivera röstkommandon
  • utveckla en WiFi -styrd equalizer
  • Gör det vackert (brödbräda skriker inte bra produktdesign)

När jag kommer att implementera dessa idéer kommer jag att göra fler instruktioner. Eller kanske någon annan får dessa funktioner implementerade. Det är glädjen att göra allt öppen källkod!

Rekommenderad: