logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Odtwarzacz MP3 PWM RP2040 Raspberry Pi Pico

bulek01 01 Lut 2025 11:16 1614 3

TL;DR

  • Powstał odtwarzacz MP3 na Raspberry Pi Pico z RP2040, który czyta pliki z karty SD i odtwarza je przez PWM.
  • Sygnał audio wzmacnia inwerter z filtrem LC na tranzystorach AO3400 i AO3407, co odciąża GPIO i daje większą głośność.
  • PWM pracuje z częstotliwością 160 kHz, a karta SD działa z zegarem 12 MHz.
  • Dodano wyświetlacz OLED SS1306, enkoder do regulacji głośności i zmiany utworu oraz obsługę długich nazw plików przez SdFat.
  • Projekt działa stabilnie po około miesiącu prac i według autora potrafi przesterować głośnik 0.5W, choć wyższe PWM zmniejsza rozdzielczość bitową.
Wygenerowane przez model językowy.
REKLAMA
📢 Słuchaj (AI):
  • Samodzielnie zbudowany odtwarzacz MP3 z RaspBerry Pi Pico
    Przedstawiam prostą konstrukcję, która sprawiła mi sporo frajdy. Jest to odtwarzacz plików MP3 z użyciem RaspBerry Pi Pico na mikrokontrolerze RP2040.
    Pliki wczytywane są z karty SD i odtwarzane z wykorzystaniem PWM.


    Raspberry Pi Pico z podłączonym głośnikiem

    Testy zacząłem od wykorzystania gotowych projektów. Zacząłem od przykładu z CircuitPythonem(https://learn.adafruit.com/mp3-playback-rp2040/pico-mp3), gdzie znalazłem prosty przykład odtwarzający,
    mp3 z wewnętrznej pamięci za pomocą PWM. Głośnik podłączyłem bezpośrednio do pinu mikrokontrolera. I ku mojemu zdziwieniu okazało się,
    że to bardzo ładnie gra, ale bardzo cicho. Potestowałem kilka godzin i nawet PIN się nie uszkodził od przepięć powstających w wyniku podłączenia cewki(głośnika).
    Przebieg na GPIO wyglądał tak:

    Pomiar przebiegu sygnału oscyloskopem cyfrowym.

    W kolejnym etapie dodałem kartę SD podłączoną po SPI, oraz dorobiłem płytkę z inwerterem i filtrem, aby nie przeciążać pinu GPIO i uzyskać większą głośność. Powstało coś w stylu końcówki mocy wzmacniacza klasy D. Jako bazę konstrukcji wykorzystałem starą płytę, która była podstawą wyświetlacza do drukarki 3D.

    Prototyp odtwarzacza MP3 z RaspBerry Pi Pico na czerwonej płytce drukowanej, z podłączonym głośnikiem i kartą SD.

    Płytkę z inwerterem najpierw zaprojektowałem na kartce papieru. Kropkami zaznaczone są miejsca lutowania nóżek tranzystorów. Następnie wyciąłem przerwy nożem do tapet. Wlutowałem dwa tranzystory NMOS i PMOS, a na wyjściu filtr LC. W ten sposób zbudowany inwerter steruje głośnikiem, a częstotliwość PWMu jest znacząco tłumiona filtrem. W ostatecznej wersji kondensator odsprzęgający DC jest nieobecny. Składowa stała jest mała, inwerter jest zasilany z 3.3V. Ja różnicy w dźwięku nie słyszę niezależnie czy kondensator jest obecny czy nie. Teraz mocy mam na tyle, że bez problemu przesterowuję, głośnik 0.5W, muszę redukować głośność.
    Schemat inwertera na kartce papieru obok prototypu z Raspberry Pi Pico.

    Tranzystory jakich użyłem są w obudowie Sot-23. Modele to AO3400, AO3407, zakupione na aliexpress, jako kiedyś przyda się(i się przydały).
    Pakiety tranzystorów AO3400 i AO3407 w opakowaniach z etykietami.

    Inwerter wraz z filtrem przesymulowałem w LTSpice, aby sprawdzić jak to się zachowuje. W symulacji widoczny jest jeż modulator PWM na wzmacniaczu operacyjnym, aby zasymulować pin GPIO. Gdzie sygnałem modulujący czyli udawane audio jest sinusoida 1kHz. Na zrzucie ekranu widać przebieg odfiltrowanego sygnału wyjściowego.


    Symulacja wzmacniacza PWM z wykresem i schematem obwodu w LTSpice.

    Przetestowałem, też wersję gdy za pomocą RP2040 generuję PWmem sygnał 1kHz.

    Ekran oscyloskopu przedstawiający sinusoidalny sygnał elektryczny.

    Przedstawiam, też przebieg na wyjściu inwertera zbudowanego na Mosach. Nie jest idealnie, ale wystarczająco dobrze, aby działało. Widać nawet na takim słabym
    powiększeniu moment gdzie oba tranzystory przewodzą, no ale trudno. Nie jest to nawet po środku zbocza, no ale mają różne napięcia załączenia.
    Nie udało mi się znaleźć symetrycznej pary NMOS PMOS aby miały takie same napięcia progowe.

    Oscyloskop pokazujący przebieg sygnału PWM o częstotliwości 159 kHz.

    W projekcie zmieniłem głośnik na trochę lepszy z obudową(na pierwszych zdjęciach był mniejszy). O mocy 0.5W. Ostatnio miałem go wyrzucić, ale jednak znalazłem dla niego zastosowanie.
    Dodałem wyświetlacz sterowany na I2C SS1306, aby wyświetlał nazwę obecnie odtwarzanego pliku, obecny poziom głośności. Dodałem obsługę enkodera,
    którego obrót zmienia głośność, a przyciśnięcie zmienia piosenkę na następną. Wyświetlacz też wyświetla numer obecnie odtwarzanego utworu, aby można było się łatwiej odnaleźć.Wszystkie elementy zostały razem połączone za pomocą taśmy dwustronnej.
    Odtwarzacz MP3 zbudowany z Raspberry Pi Pico z wyświetlaczem i kartą SD

    Oprogramowanie kompilowane jest w środowisku arduino. Projekt dostępny jest pod linkiem https://github.com/mztulip/rp2040_pwm_mp3_player

    Jako początki uruchamiania projektu dekodera MP3 z kartą sd wykorzystałem przykład z biblioteki BackgorundAudio. https://github.com/earlephilhower/BackgroundA...tSoSimpleMP3Shuffle/NotSoSimpleMP3Shuffle.ino

    Musiałem go przerobić, aby w ogóle zadziałało, bo przykład używał DAca na I2S. Ale poszło szybko z bibliotekami arduino wystarczyło podmienić obiekt I2S na PWMAudio.
    Ogólnie na tym etapie byłem w szoku, że jakość audio jest lepsza niż w moim laptopie Dell XPS.

    Kolejnym etapem było dodanie wyświetlacza, co sprawiło sporo problemów nie chciało to działać. Były problemy z obsługa długich nazw plików na systemie Fat32.
    były wycieki pamięci bufory się rozwalały, z audio leciały trzaski i procek się zawieszał. Choć na początku myślałem,że się nie wyrabiają dwie transmisje DMA jedna do audio a druga do wyświetlacza. Stworzyłem uproszczoną wersję biblioteki Wire, która nie używała DMA, aby I2C działał w pollingu. Co miało ułatwić analizę i weryfikację moich przypuszczeń, gdzie są problemy. Ostatecznie znalazłem miejsce, gdzie używałem obiektu, który był na stosie i już nie istniał, potem bufor audio go używał, a ja po nim pisałem używając wyświetlacza. Więc problemem nie było DMA, ale uproszczone wire już zostało.
    Przerobiłem, też projekt na bezpośrednie użycie biblioteki Sdfat(https://github.com/greiman/SdFat), aby działały długie nazwy plików. Co ciekawe arduino core też używa tej biblioteki po spodem, ale z długimi nazwami kod przez chwile potrafił działać, czyli jakieś bufory się przepełniają. Ostatecznie po mojej modyfikacji z ominięciem biblioteki arduino działa bez problemu. Karta SD śmiga z zegarem 12MHz, który widać na screenie z oscyloskopu.
    Widok przebiegu sygnału oscyloskopu pokazujący falę kwadratową o częstotliwości 11,76 MHz.

    Dodanie enkodera poszło bezproblemowo, użyłem biblioteki https://github.com/gbr1/rp2040-encoder-library, która realizuje obsługę enkodera, wykorzystując maszynkę w PIO.
    Jest tam licznik aktualnej pozycji enkodera i procesor odczytuje wartość.

    Podsumowując działanie ostatecznego kodu to jest ono następujące.
    Procesor pracuje z częstotliwością 133MHz. Choć czy jest to jego rzeczywista prędkość musiałbym zweryfikować, ale nie mam nawet pomysłu jak. Bo kod wykonywany jest z zewnętrznego flasha, który jest dużo wolniejszy. Procesor ma cache wykonywanego kodu, więc jest jakaś szansa, że moja aplikacja mieści się w tym cachu, który o ile pamiętam ma 16kB. Dodatkowym spowalniaczem może być to że domyślnie, kod wykonywany jest w trybie najwolniejszego odczytu po zwykłym SPI zamiast QuadSPI. Ale narazie prędkość mnie nie limitowała więc nic nie zmieniałem.
    Rdzeń 1 zajmuje się czytaniem karty SD, przekazywaniem bloku 512 bajtów do dekodera MP3(którym jest biblioteka libmad https://github.com/sezero/libmad).
    Tak zdekodowane audio jest kopiowane do bufora na który następnie nanoszona jest korekta regulacji głośności poprzez podzielenie próbek. Tak przygotowany bufor jest przekazywany do modułu PWMAudio z arduino. Moduł ten używa bloku PWM w mikrokontrolerze i dane z bufora o audio czyli wartościach PWMa wysyłane są przez DMA.
    Jak odczyt pliku z karty SD zakończy się to otwierany jest kolejny.

    Rdzeń 2
    Zajmuje się odczytywaniem danych z enkodera, wysyłaniem danych, pisaniem po wyświetlaczu OLED oraz miganiem Ledem.

    Cała aplikacja działa bez problemu na jednym rdzeniu, ale chciałem pobawić się drugim.

    Tu jeszcze chciałbym wspomnieć, że PWM pracuje na 160kHz, domyślnie arduino uruchamia go na 49kHz. W przypadku większej częstotliwości uzyskuje się mniejszą rozdzielczość bitową. Co w efekcie powoduje że zmiany o małej amplitudzie nie są odtwarzane, ale jak na razie nie słyszę różnicy, ani dyskomfortu z tym związanego. Nawet odniosłem wrażenie, że na 160kHz gra lepiej, ale tego nie jestem pewien testowałem na jednym utworze w stylu techno.

    Podsumowując
    Powstały projekt/zabawka, testowałem już całymi dniami i gra dobrze. Plan jest użyć tego jako zamiennik elektroniki w zabawce, którą niedawno opisywałem, ale myślę czy nie połączyć tego jeszcze z bluetoothem, choć tu idea mi się jeszcze buduje.
    Prace nad tym projektem trwały około miesiąca.

    Fajne? Ranking DIY
    O autorze
    bulek01
    Poziom 17  
    Offline 
    bulek01 napisał 338 postów o ocenie 295, pomógł 12 razy. Jest z nami od 2006 roku.
  • REKLAMA
  • #2 21433043
    Bucefal76
    Poziom 17  
    Posty: 422
    Pomógł: 2
    Ocena: 450
    bulek01 napisał:
    gdzie używałem obiektu, który był na stosie i już nie istniał

    Och pięknie. Można długo czegoś takiego szukać :)
  • REKLAMA
  • #3 21442107
    lechoo
    Poziom 39  
    Posty: 5161
    Pomógł: 377
    Ocena: 546
    Skąd pomysł na używanie PWM skoro np. MAX98357A (gotowy moduł) kosztuje około 1 dolara?
  • #4 21445217
    bulek01
    Poziom 17  
    Posty: 338
    Pomógł: 12
    Ocena: 295
    Nie miałem wtedy modułu na MAX98357A(już na niego czekałem), więc jedyne co byłem w stanie zrobić to PWM. Drugim argumentem może być to, że lubię rozwiązania proste z jak najmniejszą ilością scalaków, na które trzeba czekać aż przyjdą. Bardzo byłem też ciekaw jak to będzie działać z wykorzystaniem PWM, gdzie zawsze słyszałem, że jakość jest tragiczna. Więc chciałem to zweryfikować i okazało się że jest dość dobrze.
📢 Słuchaj (AI):
REKLAMA