Spisu treści:
- Kieszonkowe dzieci
- Krok 1: Budowa - tablica do krojenia chleba
- Krok 2: Budowa - nagłówki wciskane/lutowanie
- Krok 3: Budowa - okablowanie pinów zasilania
- Krok 4: Budowa - okablowanie I2S
- Krok 5: Instalacja biblioteki BtAudio
- Krok 6: Korzystanie z biblioteki BtAudio
- Krok 7: DSP - filtrowanie
- Krok 8: DSP - kompresja zakresu dynamicznego
- Krok 9: Interfejs Wi-Fi
- Krok 10: Plany na przyszłość
Wideo: Bluetooth Audio i cyfrowe przetwarzanie sygnału: struktura Arduino: 10 kroków
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:28
Streszczenie
Kiedy myślę o Bluetooth, myślę o muzyce, ale niestety większość mikrokontrolerów nie może odtwarzać muzyki przez Bluetooth. Raspberry Pi może, ale to jest komputer. Chcę opracować platformę opartą na Arduino dla mikrokontrolerów do odtwarzania dźwięku przez Bluetooth. Aby w pełni naprężyć mięśnie mojego mikrokontrolera, zamierzam dodać do dźwięku cyfrowe przetwarzanie sygnału (DSP) w czasie rzeczywistym (filtrowanie górnoprzepustowe, filtrowanie dolnoprzepustowe i kompresję zakresu dynamiki). Wisienką na torcie dodam serwer sieciowy, który można wykorzystać do bezprzewodowej konfiguracji DSP. Osadzone wideo pokazuje podstawy dźwięku Bluetooth w akcji. Pokazuje również, jak używam serwera WWW do filtrowania górnoprzepustowego, dolnoprzepustowego i kompresji zakresu dynamicznego. Pierwsze użycie kompresji zakresu dynamiki celowo powoduje zniekształcenia jako przykład złego wyboru parametrów. Drugi przykład eliminuje to zniekształcenie.
W przypadku tego projektu mikrokontrolerem z wyboru jest ESP32. Kosztuje mniej niż 10 funtów i jest wyposażony w przetworniki ADC, DAC, Wi-Fi, Bluetooth Low Energy, Bluetooth Classic i dwurdzeniowy procesor 240 MHz. Wbudowany przetwornik cyfrowo-analogowy może technicznie odtwarzać dźwięk, ale nie będzie brzmiał świetnie. Zamiast tego użyję dekodera stereo Adafruit I2S do wytworzenia sygnału wyjścia liniowego. Ten sygnał można łatwo wysłać do dowolnego systemu HiFi, aby natychmiast dodać bezprzewodowy dźwięk do istniejącego systemu HiFi.
Kieszonkowe dzieci
Miejmy nadzieję, że większość producentów będzie miała płytki stykowe, zworki, kable USB, lutownice zasilające i będzie musiała wydać tylko 15 funtów na ESP32 i dekoder stereo. Jeśli nie, wszystkie wymagane części są wymienione poniżej.
- ESP32 - testowany na ESP32-PICO-KIT i TinyPico - 9,50 £ / 24 £
- Dekoder stereo Adafruit I2S - 5,51 £
- Deska do krojenia chleba - £3-£5 za sztukę
- Przewody połączeniowe - £3
- Słuchawki przewodowe/system Hi-Fi - £££
- Nagłówki wciskane lub lutownica - 2,10 £ / 30 £
- Kabel micro USB - 2,10 £ / 3 £
- Złącze 3,5 mm do RCA / gniazdo 3,5 mm do gniazda (lub cokolwiek, czego potrzebuje twój głośnik) - 2,40 GBP / 1,50 GBP
- Zasilacz USB - £5
Krok 1: Budowa - tablica do krojenia chleba
Jeśli kupiłeś ESP32-PICO-KIT, nie będziesz musiał lutować żadnych pinów, ponieważ jest fabrycznie wlutowany. Po prostu umieść go na płytce stykowej.
Krok 2: Budowa - nagłówki wciskane/lutowanie
Jeśli masz lutownicę, przylutuj piny do dekodera stereo zgodnie z instrukcją na stronie Adafruit. W momencie pisania tego tekstu moja lutownica była w pracy, która była zablokowana. Nie chciałem płacić za tymczasową lutownicę, więc wyciąłem kilka nagłówków pchających z pimoroni. Pociąłem je, żeby pasowały do dekodera stereo. Nie jest to najlepsze rozwiązanie (i nie sposób, w jaki miały być używane nagłówki), ale jest to najtańsza alternatywa dla lutownicy. Wsuń pocięty nagłówek do płytki stykowej. Powinieneś potrzebować tylko 1 linii 6 pinów do dekodera. Możesz dodać kolejne sześć po drugiej stronie, aby uzyskać stabilność, ale nie jest to konieczne w przypadku tego prototypowego systemu. Piny, w które można włożyć nagłówki, to vin, 3vo, gnd, wsel, din i bclk.
Krok 3: Budowa - okablowanie pinów zasilania
Umieść dekoder stereo na złączach wciskanych (piny vin, 3vo, gnd, wsel, din i bclk) i mocno je dociśnij. Ponownie, najlepiej byłoby to zrobić za pomocą lutownicy, ale musiałem improwizować. Zauważysz, że wszystkie przewody w tej instrukcji są niebieskie. To dlatego, że nie miałem żadnych zworek, więc pociąłem 1 długi przewód na mniejsze kawałki. Poza tym jestem daltonistą i nie dbam o kolor drutu. Piny zasilania są przymocowane w następujący sposób:
3v3 (ESP32) -> do vin na dekoderze stereo
gnd (ESP32) -> do gnd na dekoderze stereo
Krok 4: Budowa - okablowanie I2S
Aby przesłać dźwięk Bluetooth z ESP32 do dekodera stereo, użyjemy metody komunikacji cyfrowej zwanej I2S. Dekoder stereo weźmie ten sygnał cyfrowy i zamieni go w sygnał analogowy, który można podłączyć do głośnika lub HiFi. I2S wymaga tylko 3 przewodów i jest dość prosty do zrozumienia. Linia zegara bitowego (bclk) zmienia się na wysoki i niski, aby wskazać, że przesyłany jest nowy bit. Linia wyjścia danych (dout) staje się wysoka lub niska, aby wskazać, czy ten bit ma wartość 0 czy 1, a linia wyboru słowa (wsel) staje się wysoka lub niska, aby wskazać, czy transmitowany jest lewy czy prawy kanał. Nie każdy mikrokontroler obsługuje I2S, ale ESP32 ma 2 linie I2S. To sprawia, że jest to oczywisty wybór dla tego projektu.
Okablowanie wygląda następująco:
27 (ESP32) -> wsel (dekoder stereo)
25 (ESP32) -> din (dekoder stereo)
26 (ESP32) -> bclk (dekoder stereo)
Krok 5: Instalacja biblioteki BtAudio
Jeśli nie masz ich jeszcze zainstalowanych, zainstaluj Arduino IDE i rdzeń Arduino dla ESP32. Po ich zainstalowaniu odwiedź moją stronę Github i pobierz repozytorium. W Arduino IDE w Sketch>>Include Library>> wybierz „Dodaj bibliotekę. ZIP”. Następnie wybierz pobrany plik zip. To powinno dodać moją bibliotekę btAudio do twoich bibliotek Arduino. Aby skorzystać z biblioteki, musisz dołączyć odpowiedni nagłówek w szkicu Arduino. Zobaczysz to w następnym kroku.
Krok 6: Korzystanie z biblioteki BtAudio
Po zainstalowaniu podłącz ESP32 do komputera przez micro USB, a następnie podłącz dekoder stereo do głośnika za pomocą przewodu 3,5 mm. Zanim prześlesz szkic, będziesz musiał zmienić kilka rzeczy w edytorze Arduino. Po wybraniu płyty musisz edytować schemat partycji w menu Narzędzia >> Schemat partycji i wybrać „Brak OTA (duża aplikacja)” lub „Minimal SPIFFS (duże aplikacje z OTA)”. Jest to konieczne, ponieważ ten projekt wykorzystuje zarówno WiFi, jak i Bluetooth, które są bibliotekami bardzo obciążającymi pamięć. Po wykonaniu tej czynności wgraj następujący szkic do ESP32.
#włączać
// Ustawia nazwę urządzenia audio btAudio audio = btAudio("ESP_Speaker"); void setup() { // przesyła strumieniowo dane audio do ESP32 audio.begin(); // wysyła odebrane dane do przetwornika I2S DAC int bck = 26; int ws = 27; dout = 25; audio. I2S(bck, dout, ws); } void loop() { }
Szkic można ogólnie podzielić na 3 kroki:
- Utwórz globalny obiekt btAudio, który ustawia „nazwę Bluetooth” Twojego ESP32
- Skonfiguruj ESP32 do odbierania dźwięku za pomocą metody btAudio::begin
- Ustaw piny I2S metodą btAudio::I2S.
To wszystko po stronie oprogramowania! Teraz wszystko, co musisz zrobić, to zainicjować połączenie Bluetooth z ESP32. Po prostu wyszukaj nowe urządzenia w telefonie/laptopie/odtwarzaczu MP3, a pojawi się „ESP_Speaker”. Gdy będziesz zadowolony, że wszystko działa (muzyka gra) możesz odłączyć ESP32 od komputera. Zasil go zasilaczem USB, a zapamięta ostatni kod, który do niego wgrałeś. W ten sposób możesz na zawsze zostawić swojego ESP32 ukrytego za systemem HiFi.
Krok 7: DSP - filtrowanie
Rozszerzenie odbiornika o cyfrowe przetwarzanie sygnału
Jeśli wykonałeś wszystkie kroki (i niczego nie pominąłem), masz teraz w pełni działający odbiornik Bluetooth do swojego systemu HiFi. Chociaż jest to fajne, tak naprawdę nie zmusza mikrokontrolera do granic możliwości. ESP32 ma dwa rdzenie pracujące z częstotliwością 240 MHz. Oznacza to, że ten projekt to znacznie więcej niż tylko odbiornik. Może być odbiornikiem Bluetooth z cyfrowym procesorem sygnału (DSP). Procesory DSP zasadniczo wykonują operacje matematyczne na sygnale w czasie rzeczywistym. Jedną z użytecznych operacji jest filtrowanie cyfrowe. Ten proces tłumi częstotliwości sygnału poniżej lub powyżej określonej częstotliwości odcięcia, w zależności od tego, czy używasz filtra górnoprzepustowego, czy dolnoprzepustowego.
Filtry górnoprzepustowe
Filtry górnoprzepustowe tłumią częstotliwości poniżej pewnego pasma. Zbudowałem bibliotekę filtrów dla systemów Arduino w oparciu o kod z earlevel.com. Główna różnica polega na tym, że zmieniłem strukturę klas, aby łatwiej było budować filtry wyższego rzędu. Filtry wyższego rzędu skuteczniej tłumią częstotliwości przekraczające granicę, ale wymagają znacznie więcej obliczeń. Jednak przy obecnej implementacji możesz nawet używać filtrów 6. rzędu do dźwięku w czasie rzeczywistym!
Szkic jest taki sam jak ten znaleziony w poprzednim kroku, z tą różnicą, że zmieniliśmy główną pętlę. Do włączenia filtrów używamy metody btAudio::createFilter. Ta metoda akceptuje 3 argumenty. Pierwsza to liczba kaskad filtrów. Liczba kaskad filtrów jest o połowę mniejsza niż liczba filtrów. Dla filtra szóstego rzędu pierwszy argument powinien wynosić 3. Dla filtra ósmego rzędu byłby to 4. Drugi argument to odcięcie filtra. Ustawiłem to na 1000 Hz, aby mieć naprawdę dramatyczny wpływ na dane. Na koniec podajemy typ pliku z trzecim argumentem. Powinno to być górnoprzepustowy dla filtra górnoprzepustowego i dolnoprzepustowy dla filtra dolnoprzepustowego. Poniższy skrypt przełącza odcięcie tej częstotliwości między 1000Hz a 2Hz. Powinieneś usłyszeć dramatyczny wpływ na dane.
#włączać
btAudio audio = btAudio("Głośnik_ESP"); void setup() { audio.początek(); int bck = 26; int ws = 27; dout = 25; audio. I2S(bck, dout, ws); } void loop() { opóźnienie(5000); audio.createFilter(3, 1000, górnoprzepustowy); opóźnienie(5000); audio.createFilter(3, 2, górnoprzepustowy); }
Filtry dolnoprzepustowe
Filtry dolnoprzepustowe działają odwrotnie niż filtry górnoprzepustowe i tłumią częstotliwości powyżej określonej częstotliwości. Mogą być zaimplementowane w taki sam sposób jak filtry górnoprzepustowe, z tym wyjątkiem, że wymagają zmiany trzeciego argumentu na dolnoprzepustowy. W poniższym szkicu zmieniam odcięcie dolnoprzepustowe między 2000Hz a 20000Hz. Mam nadzieję, że usłyszysz różnicę. Powinno to brzmieć dość przytłumione, gdy filtr dolnoprzepustowy ma częstotliwość 2000 Hz.
#włączać
btAudio audio = btAudio("Głośnik_ESP"); void setup() { audio.początek(); int bck = 26; int ws = 27; dout = 25; audio. I2S(bck, dout, ws); } void loop() { opóźnienie(5000); audio.createFilter(3, 2000, dolnoprzepustowy); opóźnienie(5000); audio.createFilter(3, 20000, dolnoprzepustowy); }
Krok 8: DSP - kompresja zakresu dynamicznego
Tło
Kompresja zakresu dynamiki to metoda przetwarzania sygnału, która próbuje wyrównać głośność dźwięku. Kompresuje głośne dźwięki, które wznoszą się powyżej pewnego progu, do poziomu cichych, a następnie opcjonalnie wzmacnia oba. Rezultatem jest znacznie bardziej wyrównane wrażenia słuchowe. Przydało się to, gdy oglądałem program z bardzo głośną muzyką w tle i bardzo cichym wokalem. W tym przypadku samo zwiększenie głośności nie pomogło, ponieważ wzmocniło to tylko muzykę w tle. Dzięki kompresji zakresu dynamiki mogłem zredukować głośną muzykę w tle do poziomu wokali i ponownie wszystko usłyszeć.
Kod
Kompresja zakresu dynamiki to nie tylko obniżanie głośności lub progowanie sygnału. To trochę sprytniejsze. Jeśli zmniejszysz głośność, ciche dźwięki zostaną wyciszone, a także głośne. Jednym ze sposobów obejścia tego jest progowanie sygnału, ale powoduje to poważne zniekształcenia. Kompresja zakresu dynamiki obejmuje kombinację miękkiego progowania i filtrowania w celu zminimalizowania zniekształceń, jakie można uzyskać, gdybyśmy mieli progować/przycinać sygnał. W efekcie otrzymujemy sygnał, w którym głośne dźwięki są „obcinane” bez zniekształceń, a ciche pozostają bez zmian. Poniższy kod przełącza między trzema różnymi poziomami kompresji.
- Kompresja ze zniekształceniami
- Kompresja bez zniekształceń
- Brak kompresji
#włączać
btAudio audio = btAudio("Głośnik_ESP"); void setup() { audio.początek(); int bck = 26; int ws = 27; dout = 25; audio. I2S(bck, dout, ws); } void loop() { opóźnienie(5000); kompresja audio(30, 0,0001, 0,0001, 10, 10, 0); opóźnienie(5000); kompresja audio(30, 0,0001, 0,1, 10, 10, 0); opóźnienie(5000); audio.dekompresja(); }
Kompresja zakresu dynamiki jest skomplikowana, a metody btAudio::compress mają wiele parametrów. Postaram się je wyjaśnić (w kolejności) tutaj:
- Próg - poziom, przy którym dźwięk zostaje zmniejszony (mierzony w decybelach)
- Attack time - Czas potrzebny do rozpoczęcia pracy sprężarki po przekroczeniu progu
- Czas zwolnienia - czas, po którym sprężarka przestaje działać.
- Współczynnik redukcji - współczynnik kompresji dźwięku.
- Knee Width - Szerokość (w decybelach) wokół progu, przy której kompresor działa częściowo (bardziej naturalny dźwięk).
- Wzmocnienie (decybele) dodawane do sygnału po kompresji (zwiększenie/zmniejszenie głośności)
Bardzo słyszalne zniekształcenia przy pierwszym użyciu kompresji wynikają z tego, że próg jest bardzo niski, a zarówno czas ataku, jak i czas zwalniania są bardzo krótkie, co skutkuje twardym zachowaniem progowym. Jest to wyraźnie rozwiązane w drugim przypadku poprzez wydłużenie czasu wydania. To zasadniczo powoduje, że kompresor działa w znacznie płynniejszy sposób. Tutaj pokazałem tylko, jak zmiana 1 parametru może mieć dramatyczny wpływ na dźwięk. Teraz twoja kolej na eksperymentowanie z różnymi parametrami.
Implementacja (magiczna matematyka - opcjonalnie)
Odkryłem, że naiwne zaimplementowanie kompresji zakresu dynamicznego jest wyzwaniem. Algorytm wymaga konwersji 16-bitowej liczby całkowitej na decybele, a następnie przekształcenia jej z powrotem na 16-bitową liczbę całkowitą po przetworzeniu sygnału. Zauważyłem, że jedna linia kodu zajmuje 10 mikrosekund, aby przetworzyć dane stereo. Ponieważ dźwięk stereo próbkowany z częstotliwością 44,1 kHz pozostawia tylko 11,3 mikrosekund dla DSP, jest to niedopuszczalnie powolne… Jednak łącząc małą tablicę przeglądową (400 bajtów) i procedurę interpolacji opartą na podzielonych różnicach Netwona, możemy uzyskać prawie 17 bitową precyzję w 0,2 mikrosekundy. Załączam dokument pdf z całą matematyką dla naprawdę zainteresowanych. To skomplikowane, zostałeś ostrzeżony!
Krok 9: Interfejs Wi-Fi
Teraz masz odbiornik Bluetooth, który może obsługiwać DSP w czasie rzeczywistym. Niestety, jeśli chcesz zmienić którykolwiek z parametrów DSP, będziesz musiał odłączyć się od HiFi, przesłać nowy szkic, a następnie ponownie się połączyć. To jest niezgrabne. Aby to naprawić, opracowałem serwer sieciowy, którego możesz użyć do edycji wszystkich parametrów DSP bez ponownego łączenia się z komputerem. Poniżej znajduje się szkic do korzystania z serwera WWW.
#włączać
#include btAudio audio = btAudio("Głośnik_ESP"); webDSP sieć; void setup() { Serial.begin(115200); audio.początek(); int bck = 26; int ws = 27; dout = 25; audio. I2S(bck, dout, ws); // zastąp swoim identyfikatorem WiFi i hasłem const char* ssid = "SSID"; const char* hasło = "HASŁO"; web.begin(ssid, hasło, &audio); } void loop() { web._server.handleClient(); }
Kod przypisuje adres IP do twojego ESP32, którego możesz użyć, aby uzyskać dostęp do strony internetowej. Przy pierwszym uruchomieniu tego kodu powinien on być podłączony do komputera. W ten sposób możesz zobaczyć adres IP przypisany do Twojego ESP32 na monitorze szeregowym. Jeśli chcesz uzyskać dostęp do tej strony internetowej, po prostu wprowadź ten adres IP w dowolnej przeglądarce internetowej (testowane na chrome).
Do tej pory powinniśmy znać metodę włączania Bluetooth i I2S. Kluczową różnicą jest użycie obiektu webDSP. Ten obiekt pobiera Twój identyfikator SSID Wi-Fi i hasło jako argumenty, a także wskaźnik do obiektu btAudio. W głównej pętli nieustannie otrzymujemy obiekt webDSP, który nasłuchuje danych przychodzących ze strony internetowej, a następnie aktualizuje parametry DSP. Na zakończenie należy zauważyć, że zarówno Bluetooth, jak i Wifi używają tego samego radia na ESP32. Oznacza to, że od momentu wprowadzenia parametrów na stronie internetowej do momentu, gdy informacje faktycznie dotrą do ESP32, konieczne może być odczekanie do 10 sekund.
Krok 10: Plany na przyszłość
Mamy nadzieję, że podobało ci się to, a teraz masz Bluetooth Audio i DSP dodany do twojego HiFi. Myślę jednak, że w tym projekcie jest dużo miejsca na rozwój i chciałem tylko wskazać kilka przyszłych kierunków, które mogę obrać.
- Włącz strumieniowe przesyłanie dźwięku przez Wi-Fi (w celu uzyskania najlepszej jakości dźwięku)
- Użyj mikrofonu I2S, aby włączyć polecenia głosowe
- opracować korektor sterowany przez Wi-Fi
- Zrób to ładnie (płyta do krojenia chleba nie krzyczy o świetnym projekcie produktu)
Kiedy zajmę się wdrażaniem tych pomysłów, zrobię więcej instrukcji. A może ktoś inny zaimplementuje te funkcje. To radość, że wszystko jest open source!
Zalecana:
Bluetooth i IMU z płytką Tactigon - przetwarzanie: 7 kroków
Bluetooth i IMU z płytką Tactigon - przetwarzanie: Ta seria artykułów wyjaśnia, jak używać zintegrowanych czujników i interfejsów komunikacyjnych urządzenia Tactigon do stworzenia prostego kontrolera gestów. Kod źródłowy dostępny tutaj na GitHubW tym artykule dowiemy się, jak to zrobić używać prostego
Cyfrowe zasilanie Bluetooth USB C: 8 kroków (ze zdjęciami)
Zasilacz Bluetooth z cyfrowym złączem USB C: Czy kiedykolwiek chciałeś zasilacza, którego możesz używać w podróży, nawet bez gniazdka ściennego w pobliżu? Czy nie byłoby fajnie, gdyby był również bardzo precyzyjny, cyfrowy i można go było sterować za pomocą komputera i telefonu? W tej instrukcji pokażę, jak dokładnie zbudować
Przetwarzanie wideo przy użyciu VHDL i Zybo: 10 kroków
Przetwarzanie wideo przy użyciu VHDL i Zybo: FPGA są szybsze niż procesory w przetwarzaniu, ponieważ mogą wykonywać wiele obliczeń równolegle Uwaga: Ten projekt jest wciąż w budowie i będzie ulepszany (jak tylko będę miał czas). W międzyczasie podróżuję po świecie
Niestandardowe srebrne kable Audio/cyfrowe/wysoka częstotliwość/GPS: 7 kroków
Niestandardowe srebrne kable Audio/cyfrowy/wysokiej częstotliwości/GPS: Z wieloma nowymi modami audio/wideo i nowymi urządzeniami, zarówno audio dla iPoda, jak i cyfrowym dla wideo, musimy podłączyć nasze systemy do nowych urządzeń z bardziej złożonymi kablami. Niektóre bardzo drogie… To muszą mieć komponenty i amp; materiały do budowy projektu
Mysz 3D AIR - Arduino + przetwarzanie: 5 kroków
Mysz 3D AIR | Arduino + Przetwarzanie: mysz 3D AIR | Arduino + ProcessingJestem studentem wzornictwa przemysłowego, a ostatni rok w ramach kursu „Technologia jako materiał RAW” Zbudowałem ten projekt jako moje ostatnie dzieło. Większość czasu pracuję z SolidWorks, oprogramowaniem CAD dla de