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

Kiblograjek - automatyczny odtwarzacz muzyki

Tailsy 18 Lis 2025 22:10 4581 37

TL;DR

  • Kiblograjek to mały automatyczny odtwarzacz muzyki na PY32F002AF15P6TU, z kartą MicroSD, dwoma przyciskami, diodą stanu i wyjściem audio mini-jack.
  • Odtwarza pliki SBC Stereo 44,1 kHz 10 bit, używa 2 kanałów PWM z DMA i czujnika światła na ADC do automatycznego startu oraz zatrzymania.
  • Karta MicroSD 64 GB mieści ponad 400 godzin muzyki, a konfigurację i stan obsługują pliki config.ini oraz opcjonalny state.bin.
  • Losowanie bez powtórek realizuje permutacja Feistela, więc można skakać po utworach bez zmiany wylosowanej kolejności.
  • Projekt jest tani: PCB kosztuje około 15 zł, a cały odtwarzacz wychodzi 4,43 zł za sztukę, bez głośników USB i karty SD.
Wygenerowane przez model językowy.
📢 Słuchaj (AI):
  • Dwa kompaktowe odtwarzacze audio w obudowach 3D, trzymane na dłoni.

    Cześć,
    pod tą niecodzienną nazwą tematu prezentuję projekt małego, automatycznego odtwarzacza muzyki do umilania posiedzeń na toalecie. Oczywiście to jedno zastosowanie, w innych sytuacjach pewnie też może się przydać ;)
    Głównym założeniem była niewielka złożoność, banalny interfejs, bezobsługowość po wstępnej konfiguracji i pomieszczenie niskim kosztem setek albo tysięcy godzin muzyki.

    Pięć kolorowych odtwarzaczy DIY z przyciskami i portami USB, mini-jack i logo lisa. Mały odtwarzacz audio DIY podłączony do dwóch czarnych głośników z czerwonym detalem

    Cechy:
    - Obsługa kart MicroSD z systemem plików Fat32.
    - Dekodowanie plików SBC Stereo, z pełnym bitpool, 44.1kHz 10bit.
    - Bardzo prosty interfejs w postaci 2 przycisków i diody stanu.
    - Złącza: USB type C (zasilanie). USB A (źródło zasilania głośników), Mini-Jack (dźwięk).
    - Czujnik światła - automatyczne uruchamianie i zatrzymywanie odtwarzania w zależności od jasności.
    - Obsługa katalogów: zapętlanie utworów wewnątrz katalogu albo przeskakiwanie do następnego.
    - Funkcja odtwarzania losowego bez powtórzeń: każdy utwór z katalogu będzie odtwarzany tylko raz, chyba że odtworzą się już wszystkie inne.
    - Przeskakiwanie do następnego/poprzedniego utworu, zachowując wylosowaną kolejność (po cofnięciu się i przeskoczeniu do przodu wrócimy do tego samego utworu).
    - Pełna konfigurowalność za pomocą pliku na karcie SD.
    - Zapisywanie aktualnego stanu na karcie SD na wypadek zaniku zasilania, opcjonalne.
    - Opcjonalny efekt fade in / fade out z regulowaną prędkością.


    Projekt powstał w dużej mierze z ciekawości, ile można wycisnąć z mikrokontrolera za 8 centów.
    Ten użyty tutaj to Pyua PY32F002AF15P6TU. O tych chińskich układach za grosze przeczytamy chociażby tutaj: https://www.elektroda.pl/rtvforum/topic3946116.html albo ostatnio tutaj: https://www.elektroda.pl/rtvforum/topic4144976.html
    Mikrokontroler posiada 32kB pamięci flash i jedynie 4kB pamięci SRAM.
    Dekodowanie MP3 w takich warunkach nie jest możliwe. Mamy tu kilkukrotnie za mało ramu i prawdopodobnie mocy obliczeniowej.
    Z drugiej strony odtwarzanie nieskompresowanych plików wav byłoby marnotractwem przestrzeni i cały projekt nie wniósłby niczego ciekawego. Zewnętrznego dekodera też nie chciałem użyć, bo zwielokrotniłoby to cenę całości i znowu, nie byłoby w tym nic ciekawego.
    Możliwie lekkim, jakościowo wystarczającym i całkiem wydajnym kodekiem okazał się SBC, powszechnie używany w urządzeniach bluetooth jako podstawowy kodek.

    Nośnikiem danych została karta MicroSD. Obecnie za mniej niż 8 złotych można zakupić kartę o pojemności 64GB, która przy kodeku SBC zmieści ponad 400 godzin muzyki.
    Tak wypchana karta w połączeniu z losowym odtwarzaniem naprawdę może dać efekt idealnego "radia" - bez reklam i bez powtórek.

    Firmware jest napisany trochę w C, trochę w C++. Obsługa sprzetu zrealizowana jest na gołych rejestrach (HAL Puya jest bazowany na halu STM32 i paskudny), za wyjątkiem konfiguracji zegarów, której nie chciało mi się pisać od zera.

    Dekoder SBC znalazłem na githubie: http://github.com/google/libsbc/ . Zrobiłem kilka lekkich optymalizacji takich jak zinlinowanie czego się da i wywalenie liczenia sumy kontrolnej.
    Na początku było za wolno, zwłaszcza w stereo, ale na szczęście po tych zmianach dekoder okazał się mieścić "na styk" i ostatecznie więcej pary poszło w system plików i optymalne użycie karty SD.

    Wykorzystana Puya ma tylko 4kB pamięci ram. Musi się tu zmieścić całkiem spory stos dla dekodera SBC, bufory dla lewego i prawego kanału, bufor dla danych i cache sektora karty SD.
    Z powodu tycich buforów nie ma mowy o żadnych opóźnieniach: po rozpoczęciu odtwarzania pliku transmisja z karty musi być możliwie szybka i nieprzerywana.
    Mikrokontroler taktuję z częstotliwością 48MHz z użyciem PLLa, którego teoretycznie nie powinno być :P. Do wytwarzania dźwięku zostały uzyte 2 kanały PWM, spięte z 2 kanałami "gratisowego" DMA.
    Na początku ustawiłem PWM do generowania przebiegu na 176,4kHz, co miało wyciągnąć potencjalny pisk daleko poza zakres słyszenia. Nowa próbka była pobierana co 4 przebiegi, co dawało ostateczną częstotliwość próbkowania 44,1kHz. Niestety taka konfiugracja PWM ograniczała odtwarzanie do 8 bitów - więcej osiągnąć przy taktowaniu 48MHz się po prostu nie dało.

    W ramach eksperymetu zrezygnowałem z pobierania próbki co 4 przebiegi i zwiększyłem zakres do 10 bitów. Pisku na 44,1kHz uszy i tak nie słyszą, ale 10bitów już zdecydowanie tak.
    Na początku planowałem dodać jakiś podstawowy dithering, ale 10bit okazało się brzmieć na tyle lepiej, że na razie zrezygnowałem z tego pomysłu.
    Do próbek wyjściowych stworzyłem 2 bufory cykliczne (dla lewego kanału i prawego) i dekodowanie synchronizuję za pomocą przerwań DMA o połowie transferu i jego końcu.
    DMA "odtwarza" połówkę bufora, gdzie kolejna połówka jest wypełniana przez dekoder. Transfer jest cykliczny, więc po jego wykonaniu od razu startuje kolejny.
    Karta jest obsługiwana za pomocą sprzetowego SPI o najszybszym możliwym taktowaniu. Przeprowadziłem testy na kilkunastu kartach MicroSD i każda współpracuje, o ile jest to MicroSDHC albo MicroSDXC.
    Na szybko dodałem też obsługę starych kart, więc powinno działać praktycznie wszystko. Trzeci kanał DMA jest obecnie nieużywany - rozważam użyć go do przyspieszenia transferów z karty, ale ciężko ogarnąć dwukierunkowe SPI za pomocą jednego transferu.

    Jako czujnik światła wykorzystuję dzielnik napięcia z fotorezystorem spięty z ADC, używając ciekawej funkcjonalności "window watchdoga". ADC działa w tle autonomicznie i pilnuje, czy wartość napięcia mieści się w ustalonym przedziale. Jeżeli nie - generuje przerwanie.
    W przerwaniu zmieniam stan odtwarzania i ustawiam nowy przedział - inny dla światła i mroku. Dzięki czemu podczas normalnego odtwarzania nie marnuję żadnych cykli procesora na pilnowanie ADC.

    Urządzenie zostało zaprojektowane do wspołpracy z tanimi głośniczkami komputerowymi zasilanymi z USB, dlatego posiada wbudowane wyjście zasilania USB, które może się wyłączać razem z odtwarzaniem (drobna oszczędność energii), albo działać cały czas.

    Do obsługi systemu plików wybrałem bibliotekę Petit FAT. Nie był to chyba najtrafniejszy wybór, bo ostatecznie musiałem ją trochę rozbudować.
    Dodałem:
    - Cachowanie zakresów sektorów dla aktualnie otwieranego pliku, co umożliwia streamowanie zawartości pliku bez zerkania co chwilę do FATu. Najoptymistyczniej, bez fragmentacji jedną komendą CMD18 można odczytać cały plik.
    - Liczenie elementów w katalogu
    - Poruszanie się w katalogu do tyłu
    - Stosunkowo szybkie przeskakiwanie do n-tego elementu w katalogu.
    - Zapis i przywrócenie aktualnego wewnętrznego stanu Petit FAT, żeby móc w razie potrzeby zapisywać plik stanu bez zamykania odtwarzanego pliku.

    Początkowo nie wiedziałem jak zabrać się za implementację losowania utworów. Bardzo chciałem uniknąć powtórek utworów podczas odtwarzania, ale naiwne implementacje (np. trzymanie bitmapy rzeczy już odtworzonych) nie mogły dobrze działać przy tak ograniczonej pamięci RAM.
    Ostatecznie, po konsultacji z AI doszedłem do kodu, który można zobaczyć w pliku feistel.cpp. Algorytm robi permutację zbioru możliwych utworów 1...N na zbiór utworów przemieszanych 1...N na podstawie klucza.
    Klucz jest albo stały - dostarczony przez użytkownika w pliku konfiguracyjnym (jako seed), albo generowany na podstawie wartości timera kręcącego się cały czas w tle + crc32. Na losowość wpływają opóźnienia karty i czasy wciśnięć przycisku przez użytkownika.
    Jako że kolejność odtwarzania jest z góry ustalona przez permutację, można swobodnie nawigować po utworach bez powtórzeń. Oczywiście losowanie można wyłączyć i wtedy utwory odtwarzają się w kolejności skopiowania ich do katalogu. Na sortowanie alfabetyczne zabrakłoby ramu.
    W końcowych etapach zabawy dodałem efekt płynnego zgłaśniania i ściszania dźwięku przy zapalaniu i zgaszaniu światła - aby odtwarzanie się muzyki nie było nagłym zaskoczeniem.
    W konfiguracji można ustalić jak szybko muzyka ma się zgłaśniać i ściszać (i czy w ogóle) oraz czy ma to się też dziać przy zmianie trybu za pomocą przycisku.

    Podczas projektu dużo przesiedziałem na jak optymalniejszym wykorzystaniu karty SD. Na początku spodziewałem się, że czytanie pojedynczego sektora za pomocą CMD17 i sprytne "proszenie" karty o kolejny sektor z wyprzedzeniem, będzie porównywalne do stosowania CMD18 (odczyt wielu sektorów).
    W rzeczywistości owszem, na niektórych kartach to działało, ale zaskakująco wiele "złośliwych" kart wykonywało periodycznie jakieś operacje w tle, co ogromnie zwiększało czas oczekiwania na każdy sektor.
    No i miałem efekt w postaci 2 minut bezproblemowego odtwarzania, po których następowało 20 sekund kompletnej "sieczki". Wnioskuję, że karty otrzymują swoją klasę wydajności przy komendzie CMD18 i żadnej innej.
    Jest też możliwe, że tryb SPI nie gwarantuje niczego i po prostu miałem szczęście, że przy CMD18 karty okazały się wystarczająco szybkie.


    Interfejs jest prosty:
    - Lewy przycisk, wciśnięcie: zmiana trybu (Auto - Sensor światła/Włączony/Wyłączony). Przytrzymanie: następny folder.
    Jeżeli sensor światła jest wyłączony to trybu auto nie ma.
    - Prawy przycisk, wciśnięcie: następny utwór. Przytrzymanie: poprzedni utwór.
    - Dioda świeci się kiedy utwór powinien być odtwarzany.

    Konfiguracja jest możliwa przez utworzenie pliku config.ini na karcie pamięci:

    ; LooTunes config file
    
    ; Enable random playback mode. 0: disabled, 1: enabled
    ; This affects playback order in subdirectories. Directory selection order is not randomized.
    random_mode=1
    ; Randomization key (32-bit unsigned integer). Change this value to get a different order.
    ; Set to 0 to generate a random key based on time each time a new directory is being opened.
    seed=0
    
    ; Light intensity auto power on / power off feature
    ; Light feature enabled, 0: disabled, 1: enabled, normal, 2: enabled, reversed
    ; In normal mode, light value higher than on_threshold will turn on the music
    ; and light value lower than off_threshold will turn off the music.
    ; In reversed mode, light value lower than on_threshold will turn on music
    ; and value higher than off_threshold will turn it off.
    ; Light sensor range is from 0 to 4095, where 0 is the darkest value and 4095 is the brightest.
    ; When light feature is disabled, player will only have two modes: forced on and forced off.
    light_mode=1
    on_threshold=2000
    off_threshold=500
    
    ; USB port power. 0: port always powered off; 1: port always powered on; 2: port powered on during playback.
    usb_mode=2
    
    ; Fade in / fade out effect
    ; When turning music on and off, the player can slowly fade in or fade out music in 8 steps.
    ; This value specifies how long (in ms) each step should take. Set to 0 to start/stop instantly.
    fade_in=50
    fade_out=100
    ; If instant_mode_change is set to 1, fade in / fade out will be skipped when changing mode (left button press).
    instant_mode_change=0
    
    ; Current state saving (on SD). Requires state.bin file to be present in the root directory.
    ; Save current directory on directory change. Generate write cycle when changing directory.
    save_directory=1
    ; Save current track. Can wear card a little more. Saving track will enable saving directory as well.
    save_track=1
    ; Save current playback mode (light sensor / forced on / forced off). Generate write cycle when changing mode.
    save_mode=1
    
    ; Jump to next directory after current one is finished
    ; 0: loop current directory, 1: jump to next directory
    jump_next_dir=1


    Aktualny stan zapisuje się w pliku state.bin. Co jest tam zapisywane można ustawić w konfiguracji. Więcej rzeczy bardzej obciąży kartę, ale przy wspołczesnych kartach z wear levelingiem to wciąż powinny być śladowe ilości zapisów.
    Zapis stanu to zawsze nadpisanie jednego sektora na karcie. Brak pliku state.bin powoduje wyłączenie zapisywania stanu.



    Schemat i PCB:
    Schemat ideowy oraz PCB zostały zaprojektowane w KiCAD, a PCB wyprodukowane w taniej płytkarni. PCB jest dwustronne, każdy normalny producent PCB powinien bezproblemowo je wytworzyć w najtańszej opcji.

    Schemat ideowy małego odtwarzacza audio z mikrokontrolerem PY32F002AF15P
    Dwie czerwone płytki PCB z nadrukiem „LooTunes FxDev.pl” i logo liska

    Główny mikrokontroler to Puya PY32F002AF15P6TU, używana jako PY32F030. Wszystkie sztuki jakie sprawdziłem działały, ale producent nie gwarantuje istnienia peryferiów których używam.
    Całość jest zasilana napięciem 3,3V przez dwa stabilizatory typu "662K" - bardzo tanie i powszechne klony XC6206P332MR. Drugi stabilizator jest wykorzystywany zasilania bufora do dźwięku na 74LVC2G14GW.
    Schemat całego wyjścia audio jest niemalże w 100% skopiowany z Raspberry Pi, tylko tam jest używany droższy NC7WZ16, którego tutaj też można bez żadnych przeróbek wstawić. To tylko bufor, więc brzmi tak samo.
    W pierwszej wersji nie było bufora a jedynie filtr dolnoprzepustowy i niestety praca karta pracy pamięci była bardzo wyraźnie słyszalna. Dodanie oddzielnego stabilizatora 3,3v i bufora ZNACZNIE poprawiło jakość dźwięku.
    Na PCB zrobiłem zwory które można zlutować, żeby pominąć drugi stabilizator i bufor - będzie działać, tylko gorzej.
    Jest też zwora umożliwiająca odcięcie masy od mini jacka - chciałem uniknąć pętli masy przy zasilaniu głośników z gniazda USB A urządzenia, ale w praktyce raczej nie słychać róznicy.

    Zdaje sobie sprawę, że zastosowany filtr dolnoprzepustowy absolutnie nie pomoże na nośną PWM: 44100Hz. W załączonych próbkach wyraźnie ją widać, jednak w normalnych warunkach nie jest słyszalna.
    Z tego co mi wiadomo nie da się skonstruować prostego filtru dolnoprzepustowego na 44100Hz, który nie zmasakrowałby wysokich tonów.

    Sterowanie gniazda USB A zrealizowane jest na 2 standardowych mosfetach Si2302 i Si2301. Nie przesadzałbym z obciązeniem tego portu, ale do głośniczków na USB starczy.
    Jest zwora, która pozwala pominąć również tę część układu i nie obsadzać tranzystorów - wtedy port będzie zawsze włączony. Można oczywiście w ogóle nie obsadzać tego portu, jeżeli nie jest potrzebny.
    Zastosowane układy są na tyle tanie, że gniazda mogą okazać się najdroższym elementem całości.

    Programowanie odbywa się przez gniazdo SWD, a do programowania i całego developmentu użyłem chyba najtańszego możliwego programatora: debugprobe opartego na Raspberry Pi Pico. Klona płytki można kupić u Chińczyka już za dolara, a oryginalna też jest bardzo tania.
    Jest szansa, że zadziałają inne programatory jak J-Link albo może nawet ST-Link. Programowałem całość za pomocą PyOCD, wcześniej wspomagając się moim "brudnym" forkiem OpenOCD z dodaną obsługą Puya.
    Myślałem, że możliwe będzie programowanie płytki przez zwykły adapter USB-TTL, ale wyprowadzone na padach RX i TX zostały podłączone do pinów innych, niż używanych przez wbudowany bootloader...
    Jeżeli ktoś porwie się na odtworzenie konstrukcji to chętnie pomogę przy programowaniu.

    Obudowa:

    Cztery części obudowy z druku 3D w różnych kolorach leżą na stole

    Obudowa została zaprojektowana w Blenderze i wykonana w druku 3D. Dzieli się na trzy stosunkowo proste do wydrukowania kawałki, które ciasno szczepiają się za pomocą zatrzasków.
    Na PCB zostawiłem 2 otwory montażowe które w ostatecznie się nie przydały - wszystko siedzi stabilnie bez śrubek.
    Całość jest prosta w druku, wymagane jest tylko działające chłodzenie, aby wykonać kilka łuków. Ponadto adhezja warstw musi być dobra na tyle, żeby haczyki nie połamały się podczas montażu.
    Drukować można zupełnie bez supportów, ustawiając obiekty płasko, aby nic - poza wcięciom na porty - nie wisiało w powietrzu. Dzięki temu, że trzy elementy drukuje się oddzielnie, można uzyskać różnorodne warianty kolorystyczne bez specjalnej drukarki :)
    Całość waży ok. 8,5g i na szybszej drukarce drukuje się w mniej niż 30min.
    Chyba najlepszy efekt daje drukowanie na chropowatej podstawie PEI - nadaje to lekkiej tekstury, która ukrywa niedoskonałości druku.

    Montaż:
    PCB lutowałem samodzielnie, chociaż za pewną opłatą możnaby poprosić producenta PCB o obsadzenie elementów.

    Całość zacząłem od posmarowania wszystkiego topnikiem i pocynowania padów mniejszych elementów.
    Czerwona płytka PCB z białym nadrukiem i nazwą „LooTunes” pośrodku

    Następnie przylutowałem MCU, pozycjonowanie nie było idealne ale stwierdziłem że poprawię je przy kolejnym etapie.
    Umieściłem PCB na małym hotplate i włączyłem grzanie. Cyna roztopiła się i z pewnymi korektami przy pomocy pęsety, elementy osadziły się na swoich miejscach.

    Czerwony obwód drukowany LooTunes z mikrokontrolerem i komponentami SMD.
    Na końcu przylutowałem grotem elementy przewlekane, port USB, przyciski i slot na kartę pamięci.
    Zbliżenie na czerwoną płytkę PCB odtwarzacza LooTunes z gniazdami USB i mini-jack

    Po montażu elementów warto sprawdzić czy jest generowane poprawnie napięcie 3,3V. Jeżeli tak jest, można podłączyć programator/debugger i wgrać oprogramowanie.
    Po włożeniu odpowiednio przygotowanej karty (i włączeniu odpowiedniego trybu) muzyka powinna zacząć grać.

    Montaż obudowy zaczynam od włożenia PCB do środkowego elementu (body). PCB musi satysfakcjonująco wskoczyć w swoją szczelinę, a przyciski zacząć klikać.
    Mały odtwarzacz muzyki w czerwonej obudowie z portami USB, mini-jack i czujnikiem światła

    Następnie wciskam "kapsel" na górze oraz ostrożnie podstawę, co kończy montaż urządzenia.
    Małe urządzenie w czerwono-czarnej obudowie z dwoma przyciskami i złączem USB typu C.

    Koszty:
    Koszty jakie poniosłem były mniejsze, bo kupowałem części w większych ilościach.
    Drobnicy takiej jak rezystory i kondensatory SMD nie rozpisuję - wyszłyby centy, a kupowałem je do wielu róznych projektów.
    Podobnie jest ze zużytym filamentem - filamenty już miałem, a kilogramową szpulę da się kupić nawet za 20zł. Kompletna obudowa waży 8,5g.

    Przeliczając, za 5 sztuk grajków:
    - PCB $4.17 (JLCPCB: $2 PCB, transport i podatki: $2.17) = ~15zł
    - MCU: PY32F002AF15P6TU (LCSC, kupiłem swego czasu 300 sztuk): $0.08 * 5 = $0.40 = ~1.46zł
    - Gniazdo USB A (na aliexpress) $1 za 10 sztuk = $0.50 = 1.82zł
    - Gniazdo USB C (LCSC) $0.06*5 = $0.30 = 1,09zł
    - Gniazdo Mini-jack $0.08*5 = $0.40 = ~1,46zł
    - Bufor 74LVC2G14GW $0.03 * 5 = $0.15 = 0.55zł
    - Przyciski (LCSC) $0.02 szt *2 *5 = $0.20 = 0.73zł
    - Czas (inaczej i tak grałbym w grę) $0 = 0zł

    Suma: 22,11zł za 5szt = 4,43zł za 1szt.

    Oczywiście tanie głośniki do komputera zasilane na USB to dodatkowy koszt: ok. 20zł, a karta SD np. 64GB to 8zł.

    Wszystko co potrzebne do stworzenia i rozbudowy projektu: schemat, projekt w KiCAD, obudowę jak i cały firmware udostępniam na swoim githubie:
    https://github.com/l0ud/LooTunes
    Licencja to MIT.
    Dla osób chcących po prostu odtworzyć projekt zapraszam do katalogu assets, gdzie jest już zbudowany FW oraz Gerbery do produkcji PCB:
    https://github.com/l0ud/LooTunes/tree/master/assets

    W załącznikach udostępniam to samo, pliki najnowsze w momencie pisania wiadomości.
    Dodatkowo dodaje 2 próbki dźwięku: nowy utwór typu "kiełbasa", oraz coś o wiekszej dynamice, gdzie będzie bardziej słychać niedoskonałości dźwięku 10bit.
    Pierwotnie nagrałem je specjalnie bezstratnie z większym próbkowaniem, żeby pokazać "nośną" pwm na ~44100Hz. Na spektrogramie wyraźnie ją widać:
    Spektrogram pliku audio przedstawiający nagromadzenie składowych wysokiej częstotliwości
    Niestety forum nie zmieści takich dużych plików. Więc ostatecznie sample umieszczam w mp3 44100Hz do oceny pasma słyszalnego ;)

    Pliki do SBC można skonwertować za pomocą FFmpeg, komenda to:
    ffmpeg -n -i "plik_wejsciowy.mp3" -ac 2 -c:a sbc -b:a 328k "plik_wyjsciowy.sbc"

    Na repozytorium umieściłem skrypt bash, który konwertuje wszystkie pliki mp3 oraz flac z katalogu "in" do katalogu "out":
    https://github.com/l0ud/LooTunes/blob/master/assets/convert.sh

    W głównym katalogu powinnien się znaleźć plik config.ini oraz state.bin (jeżeli chcemy przechowywać aktualny stan). Pliki .sbc muszą znajdywać się w podkatalogach. Jeżeli nie chcemy dzielić muzyki na foldery, należy i tak utworzyć co najmniej jeden folder i tam umieścić te pliki.

    Krótkie wideo demonstrujące działanie:




    Zapraszam do komentowania ale nie zjedzcie mnie, bo to tutaj moje pierwsze DIY ;)
    Załączniki:
    • sample_kielbasa.mp3 (9.79 MB) Musisz być zalogowany, aby pobrać ten załącznik.
    • sample_marsz.mp3 (7.08 MB) Musisz być zalogowany, aby pobrać ten załącznik.
    • karta_sd.zip (1.42 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • firmware_wsad.zip (73.47 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • gerbery.zip (136.45 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • schemat.pdf (85.98 KB) Musisz być zalogowany, aby pobrać ten załącznik.

    Fajne? Ranking DIY
    O autorze
    Tailsy
    Poziom 15  
    Offline 
    Tailsy napisał 85 postów o ocenie 57, pomógł 14 razy. Jest z nami od 2009 roku.
  • #2 21755670
    gulson
    Administrator Systemowy
    Posty: 29319
    Pomógł: 148
    Ocena: 6018
    Dzięki kiblograjkowi każde posiedzenie będzie wręcz spotkaniem z tym, co najważniejsze.
    Doskonale dobrałeś utwory - już od pierwszych dźwięków czuć, że pozwalają uwolnić wszystko, co w nas siedzi :)

    Jednym słowem: GRATULACJE z powodu całego, kompletnego projektu to z wykorzystaniem PY32.
    Pozwolisz, że przetłumaczę na angielski? Niech cały świat zobaczy, jak można przyjemnie kontemplować podczas posiedzenia.

    Podaj mi Paczkomat na PW, to coś wyślę, może się przyda przy kolejnej realizacji kiblograjka v2! :)
  • #3 21755676
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    Jasne, można tłumaczyć ;) Sam mam w planach opisać to ładnie po angielsku, stąd ten język w filmie i też gdzieniegdzie angielska nazwa (LooTunes).
  • #4 21755689
    Plumpi
    Specjalista - systemy grzewcze
    Posty: 7972
    Pomógł: 859
    Ocena: 2616
    To ja proponuję utworzyć listę przebojów do kilblograjka.
    Oto moja propozycja :)
    https://www.cda.pl/video/10077d4
    a tutaj coś dla rozluźnienia zwieraczy:
    https://www.youtube.com/watch?v=4PtqvJc7PPo
  • #5 21755698
    gulson
    Administrator Systemowy
    Posty: 29319
    Pomógł: 148
    Ocena: 6018
    Wbrew pozorom, muzyka nie musi się od razu z jednym kojarzyć ;)
    Wystarczy, że po prostu bity się powoli wydostają i relaksują.
  • #6 21755710
    auto_joker
    Poziom 12  
    Posty: 54
    Pomógł: 2
    Ocena: 7
    Można by projekt dopracować tak, aby dźwięki się wydobywały z wnętrza muszli klozetowej. Rzecz jasna chodzi o muzykę . . . :-)
  • #7 21755716
    gulson
    Administrator Systemowy
    Posty: 29319
    Pomógł: 148
    Ocena: 6018
    A teraz pomyślałem o wstydliwych dziewczynach, wchodzi sobie do kibelka, odpala ręcznie muzyczkę i zagłusza swoje odgłosy.
    Kiblograjek w każdym domu i publicznej toalecie.
    Klikasz i leci muzyczka aż do zgaszenia światła.
  • #8 21755718
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    auto_joker napisał:
    Można by projekt dopracować tak, aby dźwięki się wydobywały z wnętrza muszli klozetowej. Rzecz jasna chodzi o muzykę . . . :-)

    No niestety, jedną z pierwszych uwag które dostałem było to, że całość powinna wyglądać jak kostka do ubikacji, a nie do zmywarki ;)
  • #9 21755728
    m2606
    Poziom 34  
    Posty: 2718
    Pomógł: 171
    Ocena: 564
    auto_joker napisał:
    Można by projekt dopracować tak, aby dźwięki się wydobywały z wnętrza muszli klozetowej.

    Koncertowej? :-)
    Ja poszedłem w "gotowce",aż mi teraz wstyd...
    Tailsy napisał:
    nie zjedzcie mnie, bo to tutaj moje pierwsze DIY

    Przecież tutaj nie ma się do czego przyczepić :-)
  • #10 21755758
    Damian_Max
    Poziom 21  
    Posty: 395
    Pomógł: 40
    Ocena: 96
    Po tytule i pierwszym zdjęciu, pomyślałem że to podkleja się pod deskę i że muzyka uruchamia się po usiądnięciu xD (ala pozytywka) xD.
    Nie na temat, ale też kiedyś rozwiązywałem taki problem, poszedłem w gotowca za pare dyszek, takie mini radyjko+SD+BT, z ładowalnym akumulatorkiem → ogólnie dawało radę; jedyną wadą to dźwięk startowy.

    Determinacja i zakres modyfikacji zależności robi wrażenie, gratulacje!
    Długo to robiłeś? Dużo iteracji kodowania i testowania potrzebowałeś by osiągnąć ów efekt?
    Pytam bo mnie to ciekawi a pisałeś też, że odkryłeś peryferia z poza dokumentacji jak rozumiem xD.
  • #11 21755768
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    Damian_Max napisał:
    Długo to robiłeś? Dużo iteracji kodowania i testowania potrzebowałeś by osiągnąć ów efekt?

    Szczerze mówiąc startowałem z jakimś doświadczeniem, bo wcześniej zrobiłem 2 inne projekty z puya (i widzę że w historii commitów są ogromne pozostałości po poprzednim projekcie, ups). Ale można przyjąć, że ten grajek powstawał od marca, gdzie podstawowa funkcjalność (gra w stereo widząc światło) została osiągnięta w sierpniu, wtedy też zacząłem na poważniej prowadzić gita.
    Oczywiście całość robiona jako poboczny projekt hobbystyczny wieczorami.

    W software było kilka "kamieni milowych".
    1. System plików startuje, widzę że czyta plik SBC, ale trwa to dużo za długo.
    2. Po dodaniu cache sektora karty: plik czyta się z OK prędkością, brak jeszcze dekodowania.
    3. Dekoder próbuje dekodować plik, ale brakuje pamięci RAM, stos wjeżdża na system plików i go rozwala.
    4. Po wyłączeniu -flto w kompilatorze (zmniejsza zużycie stosu), poprawie linker scriptów, Dekoder czyta plik i produkuje sample, DMA się kręci i zmienia wypełnienie PWM. Całość jest mono, trzeszczy i brzmi strasznie, ledwo idzie zgadnąć co to miał być za utwór.
    5. Poprawienie buga w implementacji bufora cyklicznego: muzyka zaczyna brzmieć OK, ale tylko mono.
    6. Po walkach z DMA który nie chciał triggerować 2 transferów, odkrycie słabo udokumentowanych bitów ACKLVL w SYSCFG->CFGR3. Mamy podwaliny do stereo! Niestety dekoder nie wyrabia się w czasie z 2 kanałami i wszystko trzeszczy.
    7. Zinlinowanie wszystkiego co się prosto da w dekoderze SBC i odkrycie że wywalenie z kompilatora flagi -s (optimize for size) przyspiesza całość: dekoder wyrabia się ze stereo na styk i tylko przy niektórych kartach. Ale juz wiem, że to będzie działać.
    8. Optymalizacja odczytu z karty - używanie komendy czytania wielu sektorów, unikanie czytania FAT podczas odtwarzanie, zaczyna wyrabiać przy każdej karcie SD jaką mam.
    9. Bajery: reakcja na światło, obsługa folderów, fade-in, fade-out, losowanie utworów...

    Jeżeli chodzi o sprzęt to iteracje były 3. Pierwsza była wersja na breadboardzie (w przejściówce którą sobie zrobiłem), z przylutowanym adapterem Sd-MicroSD który służył jako slot na karty. Na tym najpierw udowodniłem że to co chcę, da się zrobić (odtwarzanie stereo bez przycięć na "złotej" karcie).
    Później zaprojektowałem PCB w wersji pierwszej (jest na repo) które niby działało, ale zrobiłem bez wiedzy jakiś pasywny dwustopniowy low-pass filter, który przycinał dużo za nisko. Go dało się pominąć, ale czegokolwiek bym nie zrobił, hałas od karty pamięci grał pierwsze skrzypce. W v2 skopiowałem pomysł z buforem z Raspberry Pi i osiągnąłem już akceptowalną jakość bez pisków karty.

    Damian_Max napisał:
    Pytam bo mnie to ciekawi a pisałeś też, że odkryłeś peryferia z poza dokumentacji jak rozumiem xD.

    Dokumentacja jest, tylko trzeba czytać reference manual do py32f030 zamiast py32f002 ;)

    Z featurów których nie powinno być używam:
    - PLL (do 48MHz)
    - DMA
    - SPI z dzielnikiem 2 (powinno być wolniejsze)
    - dodatkowego 1kB ramu
    - dodatkowych 12kB pamięci flash (no, w rzeczywistości całość zajmuje ok. 28kB)
    - TIM3
    - TIM14
  • #12 21755783
    dorge
    Poziom 11  
    Posty: 10
    Sprzedaj to Japończykom. Oni zagłuszają w publicznych toaletach od dawna odgłosy. Dla nich to jest chleb powszedni.
  • #14 21755972
    Konto nie istnieje
    Poziom 1  
  • #16 21756002
    Konto nie istnieje
    Poziom 1  
  • #17 21756097
    pikarel
    Poziom 39  
    Posty: 4986
    Pomógł: 409
    Ocena: 1827
    Kolejna perełka DiY w pełnym znaczeniu słów ze skrótu, więc napiszę tylko: ogromny plus ode mnie.
    Twój opis zawiera wszystko, co ważne, a resztę dopowiadasz w kolejnych postach.
    Kiedyś pewnie skusiłbym się na wykonanie tego grajka, teraz już tylko pogratuluję projektu i jego ukończenia.
  • #19 21756656
    megao
    Poziom 25  
    Posty: 690
    Pomógł: 66
    Ocena: 91
    Świetnie przemyślany i dopracowany projekt, do tego zoptymalizowany jeśli chodzi o koszta produkcji.
    Może warto pomyśleć o komercjalizacji?
    Chętnie zakupiłbym takie urządzenie, najlepiej w wersji do samodzielnego montażu.
  • #20 21757035
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    Ze sprzedażą jako produkt byłby taki problem, że ten grajek nie obsługuje Spotify ;). W dzisiejszych czasach wiele osób nie będzie wiedziało jak sformatować kartę pamięci na Fat32, jak zdobyć pliki mp3 i jak je skopiować. A tutaj przecież nie ma mp3, tylko dziwne .sbc.
    Jako kit dla początkujących też to średnio widzę, bo tu są elementy SMD 0402 i najlepiej się to lutuje na podgrzewaczu. Mój hotplate kosztował 40zł, ale jednak mało kto go ma.
    Możliwe, że to miałoby sens jako zestaw dla średnio zaawansowanych ze wstępnie zaprogramowanym MCU, elementami SMD i już wydrukowaną obudową, ale każdy bardziej zaawansowany "maker" ma w zanadrzu jakąś drukarkę 3D, a części poza MCU są chyba najbardziej powszechnymi "jelly bean" elementami. Procek natomiast można kupić za grosze na lcsc albo trochę drożej na aliexpress. No i organizacja sprzedaży to jest jednak większe przedsięwzięcie.
  • #21 21757040
    szeryf3
    Poziom 30  
    Posty: 2046
    Pomógł: 12
    Ocena: 672
    Co za czasy kiedy to ,,kiblo grajek" wyeliminował ,, Trybunę Ludu" .
    Co ja powiem starszemu panu, że czas na nowe.

    Fajny DIY.
  • #23 21757136
    m2606
    Poziom 34  
    Posty: 2718
    Pomógł: 171
    Ocena: 564
    Nie jest niezbędny,ale co w tym złego? U mnie np. głośniki są osadzone we wnęce w ścianie dla pogłębienia basu i pogłosu
    Moja żona moczy się w wannie to sobie słucha. Całkiem przyjemnie jest jak coś gra.
  • #24 21757217
    Homo_toxicus
    Poziom 27  
    Posty: 1107
    Pomógł: 76
    Ocena: 374
    klamocik napisał:
    ..... Nie obrażam tematu i umiejętności ale czy potrzebny papier toaletowy z melodyjka???.


    Jestem chyba w podobnym wieku i pierwsza moja myśl to była "przecież to nie jest pierwszy kwietnia". Ale po dłuższym zastanowieniu i wysłuchaniu kilku sampli pomyślałem "W sumie dlaczego by nie?"😂
  • #25 21757252
    jackfinch
    Poziom 19  
    Posty: 348
    Pomógł: 21
    Ocena: 42
    Tailsy napisał:
    Jako kit dla początkujących też to średnio widzę, bo tu są elementy SMD 0402 i najlepiej się to lutuje na podgrzewaczu. Mój hotplate kosztował 40zł, ale jednak mało kto go ma.


    Witam

    Możesz pokazać jak wygląda ten twój podgrzewacz?

    Pozdrawiam
  • #26 21757624
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    jackfinch napisał:
    Tailsy napisał:
    Jako kit dla początkujących też to średnio widzę, bo tu są elementy SMD 0402 i najlepiej się to lutuje na podgrzewaczu. Mój hotplate kosztował 40zł, ale jednak mało kto go ma.


    Witam

    Możesz pokazać jak wygląda ten twój podgrzewacz?

    Pozdrawiam


    Dwa miniaturowe hot-plate'y z wyświetlaczami OLED, jeden zardzewiały, drugi czysty

    Ten po lewej, ale gruntownie wyczyszczony z topnika :P Niestety teraz zdaje się sprzedają tylko takie jak ten po prawej - ma gorszy soft - nie umie zrobić dobrego PID i piszczy. Czy to podróba, czy "upgrade" od producenta cięzko powiedzieć. Oczywiście oba da się używać i działają, po prostu ten po lewej działa lepiej.
  • #27 21758432
    jackfinch
    Poziom 19  
    Posty: 348
    Pomógł: 21
    Ocena: 42
    Witam

    Znalazłem ten podgrzewacz na Ali: G3061 PD65W Mini Hot Plate Digital Soldering Preheating Rework Station, ale nie spodziewałem się ze jest taki mały 6cm x 6cm x 4 cm, na zdjęciu wydaję się większy. Także jego zastosowanie jest tylko do takich małych projektów jak twój.

    Pozdrawiam
  • #28 21758440
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    >>21758432
    Jego rozmiar to tak naprawdę 5,5cm x 5,5cm. Robiłem już większe PCB po kawałku, ale raczej nie nada się do płytek większych niż 10x10cm. Chyba że jako punktowy podgrzewacz. Zdjęcie z lutowania jest pod lupą, to pcb jak i cały projekt jest bardzo mały ;)
  • #29 21758536
    acctr
    Poziom 39  
    Posty: 4553
    Pomógł: 389
    Ocena: 2019
    Parę uwag do programu
    Tailsy napisał:
    Początkowo nie wiedziałem jak zabrać się za implementację losowania utworów. Bardzo chciałem uniknąć powtórek utworów podczas odtwarzania, ale naiwne implementacje (np. trzymanie bitmapy rzeczy już odtworzonych) nie mogły dobrze działać przy tak ograniczonej pamięci RAM.
    Ostatecznie, po konsultacji z AI doszedłem do kodu, który można zobaczyć w pliku feistel.cpp. Algorytm robi permutację zbioru możliwych utworów 1...N na zbiór utworów przemieszanych 1...N na podstawie klucza.

    AI się postarało, ale mogłeś tutaj równie dobrze użyć prostej funkcji bijektywnej z operacją modulo, o wiele prostszej w implementacji i używającej mniej zasobów mcu. To jest dosłownie jedna linijka kodu. Stosowanie tutaj sieci Feistela, używanej w kryptografii, jest zbędną komplikacją.
    Tailsy napisał:
    Na sortowanie alfabetyczne zabrakłoby ramu.

    Nie potrzebujesz tutaj sortowania, wystarczy wyszukiwanie, które wymaga znacznie mniej pamięci - kilkanaście bajtów na zmienne plus implementacja komparatora i pętli.
    Pomogłem? Kup mi kawę.
  • #30 21758548
    Tailsy
    Poziom 15  
    Posty: 85
    Pomógł: 14
    Ocena: 57
    acctr napisał:
    AI się postarało, ale mogłeś tutaj równie dobrze użyć prostej funkcji bijektywnej z operacją modulo, o wiele prostszej w implementacji i używającej mniej zasobów mcu. To jest dosłownie jedna linijka kodu. Stosowanie tutaj sieci Feistela, używanej w kryptografii, jest zbędną komplikacją.

    W sumie... racja. Chociaż raczej będzie to trochę więcej niż jedna linia do wyliczenia właściwych współczynników do tej funkcji w trakcie zmiany folderu.
    Mogę dodać to na listę TODO. Chociaż obecnie główny narzut jest chyba na zajętości flasha. Na czas zmiany utworów to nie ma wpływu, bo to tak czy siak ostatecznie tylko kilka prostych operacji bitowych.

    acctr napisał:
    Nie potrzebujesz tutaj sortowania, wystarczy wyszukiwanie, które wymaga znacznie mniej pamięci - kilkanaście bajtów na zmienne plus implementacja komparatora i pętli.

    Absolutnie się zgadzam, po napisaniu tego tekstu zacząłem mysleć nad odtwarzaniem alfabetycznym i jak najbardziej byłoby możliwe. Jedynie obawiam się, że prędkość tego mogłaby być mocno średnia przy dużych folderach, a z takimi przynajmniej ja używam grajka: >1000 utworów w jednym folderze. Co każdą zmianę utworu musielibyśmy przelecieć przez listę plików dwukrotnie, gdzie za pierwszym razem - przez wszystko, przetwarzając nazwy plików. Obecny kod do wskoczenia do "n-tego" elementu w ogóle nie musi patrzeć na nazwy plików co go przyspiesza. No i szczerze przyznam, że mam trochę "lenia" żeby znowu wgryzać się w PetitFat.

    Dzięki za konstruktywne uwagi.
📢 Słuchaj (AI):

Podsumowanie tematu

✨ Projekt "Kiblograjek" to automatyczny odtwarzacz muzyki zaprojektowany do użytku m.in. w toaletach, charakteryzujący się prostotą obsługi i niskim kosztem. Urządzenie obsługuje karty MicroSD z systemem plików FAT32, dekoduje pliki SBC stereo 44,1 kHz z pełnym bitpoolem, posiada prosty interfejs z dwoma przyciskami i diodą stanu oraz złącza USB typu C (zasilanie), USB A (zasilanie głośników) i mini-jack (wyjście audio). Wbudowany czujnik światła automatycznie uruchamia i zatrzymuje odtwarzanie w zależności od jasności otoczenia. Projekt powstał na bazie mikrokontrolera PY32F030, a jego rozwój trwał od marca do sierpnia, obejmując optymalizację odczytu plików, dekodowanie i zarządzanie pamięcią RAM. Dyskutowano także o implementacji filtru FIR w arytmetyce stałoprzecinkowej dla poprawy jakości dźwięku. Autor podkreślił wyzwania związane z lutowaniem elementów SMD 0402 oraz ograniczenia komercjalizacji ze względu na format plików i stopień zaawansowania użytkowników. Wątek poruszał także kwestie optymalizacji algorytmów sortowania i wyszukiwania plików w dużych katalogach oraz zastosowanie prostszych funkcji bijektywnych zamiast złożonych sieci Feistela. W dyskusji pojawiły się także informacje o używanym podgrzewaczu do lutowania (hotplate) o wymiarach około 5,5 x 5,5 cm, wykorzystywanym do montażu SMD. Projekt spotkał się z pozytywnym odbiorem jako ciekawy i dopracowany DIY, choć niektórzy uczestnicy dyskusji kwestionowali praktyczność urządzenia.
Wygenerowane przez model językowy.
REKLAMA