Pi-FM-RDS to nadajnik radia FM wyposażony w RDS, działający na Raspberry Pi. Program do pobrania z GirHuba odpowiedzialny jest za generację przebiegu zmodulowanego częstotliwościowo (FM) z zakodowanymi danymi RDS (system do przesyłania danych wraz z transmisją audio). Wszystko to działa w czasie rzeczywistym i jest w stanie współpracować z sygnałem audio mono- i stereofonicznym.
Układ oparty jest na nadajniku FM stworzonym przez Olivera Marrosa i Oskara Weigla, do którego później Richard Hirst dodał obsługę DMA, a Christophe Jacquet generator i modulator RDS. Do działania nadajnik wykorzystuje generator sygnału PWM, wbudowany w Raspberry Pi.
Oprogramowanie to jest kompatybilne z Raspberry Pi 1 wersji pierwszej, drugiej jak i trzeciej.
Uwaga!
Oprogramowanie to jest rozwijane i dystrybuowane tylko i wyłącznie w celach szkoleniowych. Układ nie powinien być wykorzystywany jako element mediacenter, nadawanie w zakresie FM może być nielegalne.
Korzystanie
Pi-FM-RDS wykorzystuje bibliotekę sndfile. Aby ją zainstalować na każdej maszynie z systemem z rodziny Debiana (np. Raspbianie) wystarczy w terminalu wpisać:
Program zależny jest także od linuksowych sterowników rpi-mailbox, więc potrzebne jest dosyć świeży jądro Linuxa. Zasadniczo każde po sierpniu 2015 roku powinno mieć ten sterownik w sobie.
Uwaga
Binarki skompilowane na Raspberry Pi 1 nie są kompatybilne z maszynami w wersji 2 i 3. Zawsze rekompiluj źródła po zmianie platformy sprzętowej (polecenie make clean w poniższym opisie).
Instalację rozpoczynamy od sklonowania źródeł z repozytorium i juz możemy kompilować:
A następnie możemy uruchomić nasz nadajnik:
Bez dodatkowych parametrów system rozpocznie transmisję FM przy częstotliwości 107,9 MHz, bez audio z domyślnymi danymi RDS: nazwą stacji (PS), radiotekstem (RT) i kodem PI. Sygnał nadawany jest na pinie GPIO 4, czyli pin 7 na wyprowadzeniu z RPi.
Możemy dodać do transmisji dźwięk. W przypadku monofonicznego pliku sound.wav (dołączony do źródeł do testowania) w terminalu piszemy:
Do przetestowania transmisji stereo służy z kolei plik stereo_44100.wav, także dołączony do programu.
W ogólności składania Pi-FM-RDS wygląda następująco:
gdzie:
-freq to częstotliwość nośnej w MHz domyślnie -freq 107.9.
-audio specyfikuje plik audio, który będzie odtwarzany. Nieistotna jest częstotliwość próbkowania pliku, program i tak go przesampluje. Jeśli plik jest stereo to transmisja także taka będzie. Akceptowalne formaty audio zależne są od biblioteki libsndfile. Są to pliki WAV oraz Ogg/Vorbis. Pliki MP3 nie są wspierane.
-pi to kod PI transmisji RDS. Są to cztery cyfry w kodzie szesnastkowym, na przykład: -pi FFFF.
-ps to nazwa stacji w kodzie RDS, nie dłuższa niż osiem znaków; na przyład: -ps RASP-PI.
-rt to tzw. radiotekst. Jest to wiadomość wysyłana RDSem o długości do 64 znaków. Na przykład: -rt 'Hello, world!'.
-ctl specyfikuje wykorzystany kanał FIFO do kontroli PS oraz RT podczas odtwarzania (patrz niżej).
-ppm specyfikuje błąd oscylatora Raspberry Pi w częściach na milion (patrz niżej).
Wszystkie argumenty są opcjonalne.
Domyślnie PS zmienia się cyklicznie pomiędzy Pi-FmRds a rosnącą liczbą, zaczynając od 00000000. PS zmienia się około raz na sekundę.
Kalibracja zegara
Kalibracji dokonać należy tylko, jeśli mamy problemy z odbiorem i dekodowaniem sygnału RDS. Standard tego systemu mówi, że maksymalny błąd dla podnośnej 57 kHz nie może być większy niż ±6 Hz, czyli musi być poniżej 105 ppm±. Oscylator naszej 'Maliny' może być powyżej tej wartości, wtedy konieczne jest wykorzystanie parametru -ppm w programie po uprzedniej kalibracji.
W praktyce w większości przypadków Pi-FM-RDS działa poprawnie, bez wykorzystywania tego przełącznika. Wszystko wskazuje, że odbiorniki RDS są bardziej tolerancyjne niż wymaga od nich specyfikacja.
Jednym ze sposobów na pomiar błędu częstotliwości jest nadawanie dźwięku z pliku pulses.wav. Są to impulsy nadawane równo przez jedną sekundę, a następnie sekundowy odcinek ciszy. Musimy teraz odebrać transmisję z pomocą odbiornika FM i nagrać ją wykorzystując kartę dźwiękową dobrej jakości. Jeśli teraz otworzymy nagranie w dowolnym programie do obróbki audio możemy wyznaczyć błąd licząc zebrane próbki. Jeśli wiemy, że nagrywaliśmy z częstotliwością próbkowania równą 44,1 kHz, to w okresie jednej sekundy powinniśmy mieć 441000 próbek. Autor podczas kalibracji swojego układu policzył, że w nagraniu było 441132 próbki w czasie jednego okres nadawania. Teraz wyznaczyć możemy błąd:
Wartość ta jest oczywiście prawdziwa przy założeniu,że wejście karty dźwiękowej nie ma żadnego błędu częstotliwości próbkowania.
Kanały komunikacyjne
Jeśli korzystamy z przełącznika -audio - to program odczytuje dźwięk z wejścia standardowego. Pozwala to na przekierowywanie strumieni do Pi-FM-RDS z innych programów. W ten sposób możemy przekierować dźwięk z np. odtwarzacz plików MP3 Sox:
Albo wejście AUX karty dźwiękowej:
Zmiana parametrów PS, RT i TA podczas nadawania
Do kontroli parametrów PS, RT oraz TA w transmisji RDSA wykorzystana jest kolejka FIFO, którą możemy uruchomić przełącznikiem -ctl podczas uruchamiania Pi-FM-RDS.
Przykład:
Komendy jakie możemy wysyłać poprzez kolejkę FIFO do zmiany PS, RT i TA to:
cat >rds_ctl
PS MyText
RT Radiotekst do wysłania
TA ON
PS OtherTxt
TA OFF
...
Każda linia zaczynać się musi od komendy: PS, RT bądź TA, spacji i wartości jaką chcemy nastawić. Każda inna linia zostanie zignotowana.
Testy
Pi-FM-RDS został z powodzeniem przetestowany z szeregiem urządzeń obsługujących transmisję RDS:
* Zegarek Sony ICF-C20RDS z 1995,
* Przenośne radio Sangean PR-D1 z 1998, i ATS-305 z1999,
* Telefon Samsung Galaxy S2 z 2011,
* Wieża Philips MBD7020 z 2012,
* Radio na USB Silicon Labs USBFMRADIO-RD z układem Si4701,
* Chiński klon powyższego pod nazwą“PCear Fm Radio”,
We wszystkich przypadkach odbiór był wysokiej jakości, a RDS nie pokazywał żadnych błędów.
Wykorzystanie procesora
Wykorzystanie procesora przez oprogramowanie na RPi1 wygląda następująco:
* Bez podanego sygnału audio: 9%.
* Z monofonicznym audio: 33%.
* Z stereofonicznym audio: 40%.
Jak łatwo zrozumieć, obciążenie procesora wzrasta po podaniu sygnału audio, gdyż musi on zostać w czasie rzeczywistym upsamplowany do 228 kHz - częstotliwości z jaką pracuje system nadajnika. Jest to zrealizowane m.in. przy pomocy filtra FIR, co jest kosztowne obliczeniowo.
Projekt
Kod odpowiedzialny za generację danych RDS znajduje się w pliku rds.c. Program generuje cyklicznie cztery grupy 0A (do nadawania PS) i jedną 2A (do nadawania RT). Dodatkowo, co minutę, dodaje jedną grupę 4A - CT, czyli zegar. Funkcja get_rds_group generuje jedną grupę i korzysta z CRC do obliczenia sum kontrolnych.
Aby dalej uzyskać próbki sygnału RDS, wywoływana jest funkcja get_rds_samples, która wywołuje funkcję get_rds_group, koduje sygnał różnicowo i generuje próbki, które filtrowane są filtrem RRC, według standardów RDS i kodowane w impulsy z wykorzystaniem enkodowania typu Manchester.
Sygnały potrzebne do działania są wcześniej jednorazowo generowane przez program w Pythonie - generate_waveforms.py - którzy korzysta przy tym z biblioteki Pydemod. W wersji pobranej z repozytorium nie ma potrzeby korzystać z tego skryptu, gdyż generowane przezeń pliki waveforms.c i waveforms.h są już w repo.
Próbki sygnału RDS mają częstotliwość próbkowania równą 228 kHz - cztery raz 57 kHz, czyli podnośną sygnału RDS.
Mupltipleksowaniem sygnału FM zajmuje się fm_mpx.c, który najpierw upsampluje audio do 228 kHz, potem generuje sumę sygnałów z obu kanałów (o pasmie ograniczonym do 15 kHz) plus ewentualny sygnał stereo na 19 kHz, sygnały kodowania stereo modulowane amplituowo na 38 kHz oraz finalnie dodaje próbki sygnału RDS.
Źródło: https://github.com/ChristopheJacquet/PiFmRds
Układ oparty jest na nadajniku FM stworzonym przez Olivera Marrosa i Oskara Weigla, do którego później Richard Hirst dodał obsługę DMA, a Christophe Jacquet generator i modulator RDS. Do działania nadajnik wykorzystuje generator sygnału PWM, wbudowany w Raspberry Pi.
Oprogramowanie to jest kompatybilne z Raspberry Pi 1 wersji pierwszej, drugiej jak i trzeciej.
Uwaga!
Oprogramowanie to jest rozwijane i dystrybuowane tylko i wyłącznie w celach szkoleniowych. Układ nie powinien być wykorzystywany jako element mediacenter, nadawanie w zakresie FM może być nielegalne.
Korzystanie
Pi-FM-RDS wykorzystuje bibliotekę sndfile. Aby ją zainstalować na każdej maszynie z systemem z rodziny Debiana (np. Raspbianie) wystarczy w terminalu wpisać:
Kod: Bash
Program zależny jest także od linuksowych sterowników rpi-mailbox, więc potrzebne jest dosyć świeży jądro Linuxa. Zasadniczo każde po sierpniu 2015 roku powinno mieć ten sterownik w sobie.
Uwaga
Binarki skompilowane na Raspberry Pi 1 nie są kompatybilne z maszynami w wersji 2 i 3. Zawsze rekompiluj źródła po zmianie platformy sprzętowej (polecenie make clean w poniższym opisie).
Instalację rozpoczynamy od sklonowania źródeł z repozytorium i juz możemy kompilować:
Kod: Bash
A następnie możemy uruchomić nasz nadajnik:
Kod: Bash
Bez dodatkowych parametrów system rozpocznie transmisję FM przy częstotliwości 107,9 MHz, bez audio z domyślnymi danymi RDS: nazwą stacji (PS), radiotekstem (RT) i kodem PI. Sygnał nadawany jest na pinie GPIO 4, czyli pin 7 na wyprowadzeniu z RPi.
Możemy dodać do transmisji dźwięk. W przypadku monofonicznego pliku sound.wav (dołączony do źródeł do testowania) w terminalu piszemy:
Kod: Bash
Do przetestowania transmisji stereo służy z kolei plik stereo_44100.wav, także dołączony do programu.
W ogólności składania Pi-FM-RDS wygląda następująco:
Kod: Bash
gdzie:
-freq to częstotliwość nośnej w MHz domyślnie -freq 107.9.
-audio specyfikuje plik audio, który będzie odtwarzany. Nieistotna jest częstotliwość próbkowania pliku, program i tak go przesampluje. Jeśli plik jest stereo to transmisja także taka będzie. Akceptowalne formaty audio zależne są od biblioteki libsndfile. Są to pliki WAV oraz Ogg/Vorbis. Pliki MP3 nie są wspierane.
-pi to kod PI transmisji RDS. Są to cztery cyfry w kodzie szesnastkowym, na przykład: -pi FFFF.
-ps to nazwa stacji w kodzie RDS, nie dłuższa niż osiem znaków; na przyład: -ps RASP-PI.
-rt to tzw. radiotekst. Jest to wiadomość wysyłana RDSem o długości do 64 znaków. Na przykład: -rt 'Hello, world!'.
-ctl specyfikuje wykorzystany kanał FIFO do kontroli PS oraz RT podczas odtwarzania (patrz niżej).
-ppm specyfikuje błąd oscylatora Raspberry Pi w częściach na milion (patrz niżej).
Wszystkie argumenty są opcjonalne.
Domyślnie PS zmienia się cyklicznie pomiędzy Pi-FmRds a rosnącą liczbą, zaczynając od 00000000. PS zmienia się około raz na sekundę.
Kalibracja zegara
Kalibracji dokonać należy tylko, jeśli mamy problemy z odbiorem i dekodowaniem sygnału RDS. Standard tego systemu mówi, że maksymalny błąd dla podnośnej 57 kHz nie może być większy niż ±6 Hz, czyli musi być poniżej 105 ppm±. Oscylator naszej 'Maliny' może być powyżej tej wartości, wtedy konieczne jest wykorzystanie parametru -ppm w programie po uprzedniej kalibracji.
W praktyce w większości przypadków Pi-FM-RDS działa poprawnie, bez wykorzystywania tego przełącznika. Wszystko wskazuje, że odbiorniki RDS są bardziej tolerancyjne niż wymaga od nich specyfikacja.
Jednym ze sposobów na pomiar błędu częstotliwości jest nadawanie dźwięku z pliku pulses.wav. Są to impulsy nadawane równo przez jedną sekundę, a następnie sekundowy odcinek ciszy. Musimy teraz odebrać transmisję z pomocą odbiornika FM i nagrać ją wykorzystując kartę dźwiękową dobrej jakości. Jeśli teraz otworzymy nagranie w dowolnym programie do obróbki audio możemy wyznaczyć błąd licząc zebrane próbki. Jeśli wiemy, że nagrywaliśmy z częstotliwością próbkowania równą 44,1 kHz, to w okresie jednej sekundy powinniśmy mieć 441000 próbek. Autor podczas kalibracji swojego układu policzył, że w nagraniu było 441132 próbki w czasie jednego okres nadawania. Teraz wyznaczyć możemy błąd:
$$\frac {441132 - 44100} {441000} \times 10^6 = 299 ppm$$
Wartość ta jest oczywiście prawdziwa przy założeniu,że wejście karty dźwiękowej nie ma żadnego błędu częstotliwości próbkowania.
Kanały komunikacyjne
Jeśli korzystamy z przełącznika -audio - to program odczytuje dźwięk z wejścia standardowego. Pozwala to na przekierowywanie strumieni do Pi-FM-RDS z innych programów. W ten sposób możemy przekierować dźwięk z np. odtwarzacz plików MP3 Sox:
Kod: Bash
Albo wejście AUX karty dźwiękowej:
Kod: Bash
Zmiana parametrów PS, RT i TA podczas nadawania
Do kontroli parametrów PS, RT oraz TA w transmisji RDSA wykorzystana jest kolejka FIFO, którą możemy uruchomić przełącznikiem -ctl podczas uruchamiania Pi-FM-RDS.
Przykład:
Kod: Bash
Komendy jakie możemy wysyłać poprzez kolejkę FIFO do zmiany PS, RT i TA to:
cat >rds_ctl
PS MyText
RT Radiotekst do wysłania
TA ON
PS OtherTxt
TA OFF
...
Każda linia zaczynać się musi od komendy: PS, RT bądź TA, spacji i wartości jaką chcemy nastawić. Każda inna linia zostanie zignotowana.
Testy
Pi-FM-RDS został z powodzeniem przetestowany z szeregiem urządzeń obsługujących transmisję RDS:
* Zegarek Sony ICF-C20RDS z 1995,
* Przenośne radio Sangean PR-D1 z 1998, i ATS-305 z1999,
* Telefon Samsung Galaxy S2 z 2011,
* Wieża Philips MBD7020 z 2012,
* Radio na USB Silicon Labs USBFMRADIO-RD z układem Si4701,
* Chiński klon powyższego pod nazwą“PCear Fm Radio”,
We wszystkich przypadkach odbiór był wysokiej jakości, a RDS nie pokazywał żadnych błędów.
Wykorzystanie procesora
Wykorzystanie procesora przez oprogramowanie na RPi1 wygląda następująco:
* Bez podanego sygnału audio: 9%.
* Z monofonicznym audio: 33%.
* Z stereofonicznym audio: 40%.
Jak łatwo zrozumieć, obciążenie procesora wzrasta po podaniu sygnału audio, gdyż musi on zostać w czasie rzeczywistym upsamplowany do 228 kHz - częstotliwości z jaką pracuje system nadajnika. Jest to zrealizowane m.in. przy pomocy filtra FIR, co jest kosztowne obliczeniowo.
Projekt
Kod odpowiedzialny za generację danych RDS znajduje się w pliku rds.c. Program generuje cyklicznie cztery grupy 0A (do nadawania PS) i jedną 2A (do nadawania RT). Dodatkowo, co minutę, dodaje jedną grupę 4A - CT, czyli zegar. Funkcja get_rds_group generuje jedną grupę i korzysta z CRC do obliczenia sum kontrolnych.
Aby dalej uzyskać próbki sygnału RDS, wywoływana jest funkcja get_rds_samples, która wywołuje funkcję get_rds_group, koduje sygnał różnicowo i generuje próbki, które filtrowane są filtrem RRC, według standardów RDS i kodowane w impulsy z wykorzystaniem enkodowania typu Manchester.
Sygnały potrzebne do działania są wcześniej jednorazowo generowane przez program w Pythonie - generate_waveforms.py - którzy korzysta przy tym z biblioteki Pydemod. W wersji pobranej z repozytorium nie ma potrzeby korzystać z tego skryptu, gdyż generowane przezeń pliki waveforms.c i waveforms.h są już w repo.
Próbki sygnału RDS mają częstotliwość próbkowania równą 228 kHz - cztery raz 57 kHz, czyli podnośną sygnału RDS.
Mupltipleksowaniem sygnału FM zajmuje się fm_mpx.c, który najpierw upsampluje audio do 228 kHz, potem generuje sumę sygnałów z obu kanałów (o pasmie ograniczonym do 15 kHz) plus ewentualny sygnał stereo na 19 kHz, sygnały kodowania stereo modulowane amplituowo na 38 kHz oraz finalnie dodaje próbki sygnału RDS.
Źródło: https://github.com/ChristopheJacquet/PiFmRds
Fajne? Ranking DIY
