Elektroda.pl
Elektroda.pl
X
Szkolenia elektronika Udemy
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Programowy projekt radioodbiornika internetowego na STM32F407VGT6

Tytus Kosiarski 23 Wrz 2015 21:44 6243 6
  • Programowy projekt radioodbiornika internetowego na STM32F407VGT6


    Witam wszystkich

    Tym razem chciałbym zaprezentować jeszcze programowy projekt radioodbiornika internetowego. Prezentowany projekt jest rozszerzeniem przedstawionego wcześniej projektu odtwarzacza i dyktafonu na STM32F407VG. Połączenie z Internetem zapewnia moduł WiFi WF121-A (internal antenna) produkcji Bluegiga (teraz Silicon Labs). Radioodbiornik umożliwia odsłuch wybranej radiostacji internetowej, która nadaje audycje w postaci strumienia MP3. Obecnie do wyboru jest 14 radiostacji, jednakże nic nie stoi na przeszkodzie, by zwiększyć liczbę radiostacji.
    Definicje radiostacji pamiętane są w pliku stations.c w postaci tablic znakowych stationxx[], gdzie xx to kolejny numer tablicy station. Każda taka tablica zbudowana jest następująco:
    pierwszy wiersz to ciąg znaków tworzących początek żądania HTTP dla serwera radiowego nadającego audycję wybranej radiostacji,
    dwa kolejne wiersze są komentarzami informującymi, jakie tablice będą później dołączane, aby poskładać kompletne żądanie HTTP: tablica przekazująca nazwę serwera radiowego lub jego adres IPv4 wraz z numerem portu oraz tablica zawierająca niezmienną część żądania HTTP,
    ostatni wiersz tej tablicy nie jest wykorzystywany do żądania HTTP, potrzebny jest natomiast do wyświetlenia nazwy stacji radiowej na przewijalnej liście radiostacji.
    Dopisując według powyższego sposobu, czy usuwając tablice z definicjami stacji radiowych, należy odpowiednio zmodyfikować wartość zmiennej max_stations oraz instrukcję switch (*item_nbr) w funkcji store_stations_in_SPI_RAM w tym samym pliku stations.c.
    Kompletowanie żądania HTTP na podstawie danych zapisanych w pamięci SPI RAM odbywa się w funkcji list_and_scroll_vertical w pliku main.c i dotyczy tylko wybranej podświetleniem stacji radiowej z wyświetlonej listy nazw stacji radiowych.
    Mając już skompletowane żądanie HTTP dla wybranej stacji radiowej, można nawiązać połączenie z jej serwerem. Zajmuje się tym funkcja connect_selected_station w pliku radio_functions.c. W przypadku udanego połączenia z serwerem funkcja ta uaktualnia numer otwartego endpointa, przez który dane odbierane z serwera będą przekazywane do mikrokontrolera.
    Odbiorem danych, ich obróbką w celu wyszukania i wyodrębnienia informacji tekstowych i metadanych oraz wyodrębnienia danych audio (jest to strumień MP3) do ich dekodowania, zajmuje się funkcja play_radio w pliku radio_functions.c. Funkcja ta do swojego działania wykorzystuje dwa bufory: pierwszy, utworzony z górnej połowy BackupSRAM i dodatkowo podzielony na dwa 1kB obszary, odbiera porcje danych z modułu WiFi (jeden obszar zbiera dane, drugi obszar zawiera gotową porcję danych do wykorzystania, po czym następuje zamiana) oraz drugi, utworzony z pamięci TCM Data RAM, pracujący jako bufor kołowy, do którego przepisywane są porcje danych zbierane w pierwszym buforze i z którego pobierane są dane dla dekodera MP3. Przy okazji zbierane są metadane, które są później wykorzystywane do wyświetlenia informacji o tytule i wykonawcy granego utworu. Cały ten proces wykonuje się tak długo, aż serwer nie zerwie nawiązanego połączenia lub nie wystąpi timeout oczekiwania na transmisję danych z serwera lub użytkownik nie naciśnie przycisku Return. Wtedy program znów powraca do wyświetlania listy radiostacji.





    Teraz trochę o samym module WiFi WF121. Na stronie producenta, po uprzednim zarejestrowaniu się, jest dostępna dokumentacja PDF oraz oprogramowanie Bluegiga WF121 GUI w postaci pliku bluegiga_wifi-1.2.2-63.zip, które jest niezbędne do przygotowania zakupionego modułu do pracy w tym układzie (o czym dalej) oraz do tego, by wiedzieć, pisząc swój program, jakie instrukcje i w jakiej kolejności trzeba wysyłać do modułu, oraz odpowiedzi modułu (są prezentowane w oknie terminala w tym oprogramowaniu). Następnie moduł trzeba połączyć z portem COM komputera poprzez układ dopasowujący poziomy (np. MAX3232). Można też wykorzystać konwerter USB->RS232 - ja używam do tego przerobionej przejściówki ZL4USB firmy Kamami. Przerobionej, bo dorobiłem tam sygnały RTS i CTS, których oryginalnie tam nie ma. Przeróbka jest widoczna na jednym ze zdjęć. Dołączenie przejściówki, czy konwertera poziomów należy wykonać do złącza oznaczonego "Kamami ZL4USB" na schemacie ideowym. Moduł do komunikacji z oprogramowaniem wykorzystuje oprócz RxD i TxD handshaking RTS, CTS, stąd konieczna była ta przeróbka przejściówki. Po podłączeniu i zasileniu modułu napięciem 3.3V (ważne: nie mniej, u mnie były problemy z włączeniem radia WiFi w module przy niższym napięciu), spróbować połączyć się z modułem, wybierając w zakładce "Device" Baud rate = 115200 i przycisk "Attach". Sprawdzić poprawność komunikacji modułu z komputerem, naciskając przycisk "Reset" lub "Retrieve info", śledząc rozkazy wysyłane do modułu i jego odpowiedzi w oknie terminala. Brak odpowiedzi, tylko rozkazy, to brak poprawnej komunikacji z modułem. Gdy komunikacja jest OK, to wybrać zakładkę "Network" i zapamiętać (ważne, o czym dalej) adres MAC przydzielony przez producenta. Następnie można wypróbować i sprawdzić działanie modułu w tym programie, obserwując przy okazji okno terminala.
    Fabrycznie moduł jest skonfigurowany do komunikacji poprzez UART1 115200 8N1 i ma wgrany firmware wifi.juo (normal symmertic link według PDF-a WF121 Configuration Guide, rozdział WiFi software profiles). Te nastawy są niewystarczające dla radia internetowego. Trzeba w tym oprogramowaniu wgrać do modułu odpowiedni firmware.
    Należy najpierw w zakładce "Firmware update" otworzyć do edycji plik /Bluegiga/wf121-1.2.2-63/example/wf121/project.xml, wyedytować go, jak poniżej:

    <?xml version="1.0" encoding="UTF-8" ?>
    <project>
    <hardware>
    <uart channel="0" baud="500000" api="false" />
    <uart channel="1" baud="500000" api="true" handshake="True" />
    </hardware>
    <software>
    <binary in="c:/bluegiga/wf121-1.2.2-63/fw/wifi_high_symmetric.juo" />
    </software>
    </project>

    następnie zapisać zmiany i następnie nacisnąć przycisk "Build". Kompilacja musi zakończyć się sukcesem. Następnie przycisk "Boot into DFU mode" (opcja "Erase PS keys after update" odznaczona), by przygotować moduł WiFi do zmiany firmware. Oczywiście moduł musi odpowiedzieć potwierdzeniem widocznym w oknie terminala. Następnie nacisnąć przycisk "Upload" - rozpoczyna się wgrywanie firmware'u do modułu. Po zakończeniu wgrywania połączyć się na nowo z modułem przy użyciu nowej nastawy baud rate i sprawdzić poprawność komunikacji - powinna być OK.
    Pytanie - co zrobić, gdy po powyższym wgrywaniu firmware'u nie uda się już połączyć z modułem? Taka sytuacja może również nastąpić, gdy eksperymentuje się w powyższym pliku XML, a w szczególności wpisanie baud rate innego niż udostępnionego do wyboru w oprogramowaniu Bluegiga WF121 GUI lub wybranie dla "uart channel = 1" api = false. Pozostaje wtedy, poza zakupem nowego modułu, użycie PICKit 2 lub AVT5279 (i zastosowanie się do wskazówek na stronie http://jared.geek.nz/2013/jan/adding-extra-chips-to-the-pickit-2 ) lub PICKit3 wraz z odpowiednim PICKit Programmer. Najpierw przygotować sobie fabryczny firmware. W tym celu znów uruchomić Bluegiga WF121 GUI, tam w zakładce "Device" wybrać cokolwiek i nacisnąć "Attach". Uaktywni się zakładka "Firmware update", wyedytować tam plik /Bluegiga/wf121-1.2.2-63/example/wf121/project.xml, jak poniżej (fabryczne nastawy):

    <?xml version="1.0" encoding="UTF-8" ?>
    <project>
    <hardware>
    <uart channel="0" baud="115200" api="false" />
    <uart channel="1" baud="115200" api="true" handshake="True" />
    </hardware>
    <software>
    <binary in="c:/bluegiga/wf121-1.2.2-63/fw/wifi.juo" />
    </software>
    </project>

    Nacisnąć "Build", kompilacja powinna zakończyć się sukcesem. Wtedy tworzy się plik HEX, który można wgrać programatorem. Dołączyć PICKit-a do złącza oznaczonego "Programmer PICKit2 or PICKit3" na schemacie ideowym, podłączyć go do komputera przez USB i uruchomić na nim odpowiedni program PICKit Programmer. Gdy połączenie OK, to w tym programie wybrać rodzinę PIC32 i następnie mikrokontroler PIC32MX695F512H. Następnie otworzyć wspomniany HEX (/Bluegiga/wf121-1.2.2-63/example/wf121/wifi.hex, zwrócić uwagę na datę i godzinę utworzenia, czy to jest ten plik), wybrać "Erase", potem "Write" i poczekać na wgranie i weryfikację programowania. Podczas takiego programowania modułu traci się fabryczny adres MAC (wpisywany jest wtedy domyślny 00 07 80 FF FF FF). Ponownie uruchomić Bluegiga WF121 GUI, połaczyć się z modułem i w zakładce "Network" przywrócić poprzednio zapamiętany, fabryczny adres MAC. Dokładniej powyższa procedura jest również opisana w PDF-ie WF121 Configuration Guide w rozdziale "Installing the firmware".

    Kilka słów wrażeń z użytkowania. Radio gra dobrze, kiedy w sposób ciągły dostarczany jest strumień danych przez moduł WiFi. Pojemność bufora kołowego wystarcza na niwelowanie 2-3 sekundowych przerw w transmisji danych. Dłuższe przerwy powodują przerwanie grania i oczekiwanie na dostarczenie danych przez moduł. Program radia wydaje się stabilnie chodzić, najdłuższy czas grania radia, jaki uzyskałem, od włączenia do konieczności wyłączenia, to ponad 20h. Zdjęcie elektroniki zrobiłem, gdy radio grało już ponad 11,5h.
    Program radia pisałem w Rowley Crossworks 2.0.11. Zużycie pamięci Flash 518kB, RAM 127,5kB + 4kB BackupRAM + 64kB TCM Data RAM.
    Schemat ideowy narysowany jest w Protelu 99SE. Sam moduł WiFi można kupić w TME.

    Do zrobienia:
    dorobienie odtwarzania strumienia AAC nadawanego przez część radiostacji,
    dorobienie nagrywania audycji radiowych na kartę SD (obecnie przycisk Start record jest nieaktywny),
    zaprojektowanie zasilania (również zarządzanie w sposób energooszczędny zasilaniem),
    zaprojektowanie i wykonanie gotowej elektroniki docelowego urządzenia.

    Pozdrawiam, KT

    Programowy projekt radioodbiornika internetowego na STM32F407VGT6



    Fajne!
  • Szkolenia elektronika Udemy
  • #2 24 Wrz 2015 21:51
    _Arecki_
    Poziom 15  

    Bardzo ciekawa konstrukcja.

    Rozumiem, że dźwięk odtwarzasz wbudowanym na płytce przetwornikiem audio (na zdjęciu nie jest podłączone nic do wyjścia).

    Opis dość obszerny, ale dodawanie stacji dość zagmatwane.
    Dlaczego nie stworzysz dynamicznej tablicy dwuwymiarowej? Ewentualnie tablicy struktur?
    Zadeklarowane masz na stałe stacje, później dodajesz jeszcze jakieś dodatkowe info. Całość skomplikowana a modyfikowanie listy stacji bardzo karkołomne.
    Za pół roku nie będziesz pamiętał co jeszcze trzeba zmienić dodając stację :)

    Oczywiście najlepiej byłoby modyfikować stacje z poziomu wyświetlacza, albo edytując plik na karcie SD (to łatwiejsze do wykonania).
    Wtedy nie trzeba kompilować kodu i wgrywać go za każdym razem gdy chcesz dodać stację.

    Ale sam projekt bardzo mi się podoba.

  • Szkolenia elektronika Udemy
  • #3 25 Wrz 2015 19:00
    Tytus Kosiarski
    Poziom 14  

    Witam
    Dziękuję za słowa uznania :)

    Za przetwornik DAC robi TLV320AIC23 (po lewej stronie na zdjęciu całości). Tamże jest gniazdo słuchawkowe, w którym jest wtyczka przewodu do wzmacniacza (już niewidoczna na zdjęciu).
    Taki sposób definiowania stacji radiowych wydawał mi się najprostszy w realizacji. Ale istotnie każdorazowo wymaga to kompilowania i programowania mikrokontrolera.
    Twój pomysł z edytowaniem wpisów stacji radiowych z poziomu aplikacji jest bardzo dobry i warty wzięcia pod uwagę :) Dzięki :) Lecz nie na karcie SD, bo tej może nie być podczas grania radia. Jedynie tu widzę w tej roli jakąś pamięć nieulotną współpracującą z mikrokontrolerem i chyba przewidzę miejsce na PCB na takową.

    Pozdrawiam, KT

  • #4 02 Paź 2015 13:42
    Marico
    Poziom 19  

    Czemu nie zdecydowałeś się na sprzętowy dokofer typu VS*? Miałbyś z głowy kilka kodeków a nie tylko mp3.
    Drugie pytanie, raczej zdziwnienie, że nie odstraszyło Cię sposób "obsługi" modułów BlueGiga.. przecież to jakieś nieporozumienie.

  • #5 02 Paź 2015 20:14
    Tytus Kosiarski
    Poziom 14  

    Marico, jak napisałem w poście otwierającym ten wątek, radio jest rozszerzeniem wcześniejszego programowego projektu, toteż mam już zaimplementowane dekodery, nie tylko MP3, ale również AAC, WMA i FLAC. Poza tym, jak już pracuję z ARM-em, to powinienem zapomnieć już o sprzętowych dekoderach strumieni audio, jak ktoś kiedyś powiedział mi na Elektrodzie :)
    Aby odpowiedzieć na drugie Twoje pytanie, muszę cofnąć się do historii zakupu. Otóż ok. rok temu, jak szukałem jakichś modułów WiFi w TME, to zwracałem uwagę tylko na jak najmniejsze wymiary zewnętrzne, łatwość polutowania i obecność wbudowanej anteny. A jak już kupiłem ten moduł, to dopiero później okazało się, co to za "stwór"... Chciał, nie chciał, trza było już nim się zająć.

    Pozdrawiam, KT

  • #6 23 Sty 2016 20:36
    Tytus Kosiarski
    Poziom 14  

    Witam

    Dodałem trzy usprawnienia do programu radioodbiornika internetowego. Pierwszym usprawnieniem jest już możliwość odtwarzania strumienia AAC-LC nadawanego przez część radiostacji internetowych.
    Drugim usprawnieniem jest możliwość samoczynnego wznowienia odtwarzania wybranej radiostacji przez program radioodbiornika w przypadku, gdy serwer radiowy zbyt długo nie dostarcza danych lub zerwie połączenie. Wtedy program wysyła polecenie zamknięcia aktywnego endpointa do modułu WiFi - jest to równoznaczne z zakończeniem połączenia z serwerem. Następnie znów łaczy się z tym serwerem i wznawia proces dekodowania strumienia przesyłanego przez serwer. Dopiero zanik sieci WiFi lub naciśnięcie przycisku Return w menu radioodbiornika przez użytkownika kończy ten proces. W pierwszym przypadku wyświetlany jest komunikat ostrzegawczy, w drugim zaś program powraca do wyświetlania listy stacji radiowych.
    Trzecim, chyba najważniejszym usprawnieniem, jest już możliwość dodawania i usuwania definicji stacji radiowych bez potrzeby kompilacji i ponownego programowania mikrokontrolera, jak było to w poprzedniej wersji programu radia. Skorzystałem tu z podpowiedzi kolegi _Arecki_. Obecnie lista radiostacji jest przechowywana w pamięci Flash SPI AT45DB161D. Po połączeniu radia z komputerem poprzez USB pamięć ta jest widziana przez komputer jako 2MB dysk, na którym w głównym katalogu jest zapisany plik stations.txt (jest w paczce zip). Plik ten przechowuje listę stacji radiowych w podobnej postaci do tablic C. Program radioodbiornika pobiera dane z tego pliku i wykorzystuje je do wyświetlenia listy stacji radiowych oraz do sformowania żądania HTTP wybranej stacji radiowej. Edytować ten plik należy w Notatniku lub innym edytorem nie wstawiającym jakichś swoich znaków sterujących. Każdy wiersz wpisu znajdujący się między nawiasami {} jest poprzedzony tabulacją i zakończony naciśnięciem klawisza Enter - przejściem do nowego wiersza (znaki 0x0D 0x0A).

    KT

  • #7 25 Sty 2016 23:06
    _Arecki_
    Poziom 15  

    Dobra robota.
    Oczywiście z plikiem stacji można się jeszcze pobawić, by części stałe, np. zapytanie do hosta, parsować z adresu w kodzie, a nie tworzyć gotowca w pliku, ale to drobiazgi.

    Domyślam się, że listy stacji nie sortujesz w żaden sposób, dzięki czemu pojawia się ona w tej samej kolejności jak jest w pliku. To umożliwia ułożenie listy według własnych upodobań i umieszczenie najczęściej słuchanych stacji na początku, aby nie bawić się w przewijanie kilkudziesięciu stacji w poszukiwaniu ulubionej :)

    Rozwiązanie z "wbudowanym pendrivem" bardzo fajne. Nie ma wymogu obecności karty SD, a przy tym edycja pliku bardzo wygodna.