Pi-FM-RDS is an FM radio transmitter equipped with RDS, running on Raspberry Pi. The GirHub downloadable program is responsible for generating a frequency modulated (FM) waveform with encoded RDS data (data transmission system with audio transmission). All this works in real time and is able to work with both mono and stereo audio signals.
The circuit is based on an FM transmitter created by Oliver Marros and Oskar Weigl, to which Richard Hirst later added DMA support, and Christophe Jacquet a generator and RDS modulator. The transmitter uses a PWM signal generator built into the Raspberry Pi for operation.
This software is compatible with Raspberry Pi 1 version 1, 2 and 3.
Warning!
This software is developed and distributed for training purposes only. The system should not be used as part of the mediacenter, FM broadcasting may be illegal.
Using
Pi-FM-RDS uses the sndfile library. To install it on every machine with the Debian family system (e.g. Raspbianie) just type in the terminal:
The program also depends on Linux rpi-mailbox drivers, so you need a fairly fresh Linux kernel. Basically everyone after August 2015 should have this driver in them.
attention
Binaries compiled on Raspberry Pi 1 are not compatible with machines in version 2 and 3. Always recompile the sources after changing the hardware platform (command make clean in the description below).
We start the installation by cloning the sources from the repository and we can compile:
And then we can start our transmitter:
Without additional parameters, the system will start FM transmission at 107.9MHz, without audio, with the default RDS data: station name (PS), radio text (RT) and PI code. The signal is sent on pin GPIO 4, i.e. pin 7 on the output from RPi.
We can add sound to the broadcast. For the monophonic sound.wav file (included with the test sources) in the terminal we write:
The stereo_44100.wav file, also included with the program, is used to test the stereo transmission.
In general, the Pi-FM-RDS folding is as follows:
where:
-freq is the carrier frequency in MHz by default -freq 107.9.
-audio specifies the audio file to be played. The sampling frequency of the file is irrelevant, the program will sample it anyway. If the file is stereo, the transmission will also be. Acceptable audio formats depend on libsndfile. These are WAV and Ogg / Vorbis files. MP3 files are not supported.
-pi is the PI code of the RDS broadcast. It is four hexadecimal digits, for example: -p and FFFF.
-ps is the station name in RDS code, up to eight characters long; for example: -ps RASP-PI.
-rt is called radio text. This is an RDS message with a length of up to 64 characters. For example: -rt 'Hello, world!'.
-ctl specifies the FIFO channel used for PS and RT control during playback (see below).
-ppm specifies the Raspberry Pi oscillator error in parts per million (see below).
All arguments are optional.
By default, the PS changes cyclically between Pi-FmRds and an increasing number, starting at 00000000. The PS changes approximately once per second.
Clock calibration
Calibration should be performed only if we have problems with receiving and decoding the RDS signal. The standard of this system says that the maximum error for the 57 kHz subcarrier cannot be greater than +- 6 Hz, i.e. it must be below 105 ppm +-. Our 'Raspberry' oscillator may be above this value, then it is necessary to use the -ppm parameter in the program after previous calibration.
In practice, the Pi-FM-RDS works fine in most cases without using this switch. Everything indicates that RDS receivers are more tolerant than their specifications require.
One way to measure the frequency error is to broadcast a sound from the pulses.wav file. These are pulses given evenly for one second, followed by a second-long silence. We now have to receive the broadcast with the help of the FM receiver and record it using a good quality sound card. If we now open the recording in any audio processing program, we can determine the error by counting the collected samples. If we know that we were recording at a sampling rate of 44.1 kHz, we should have 441,000 samples in one second. During the calibration of his system, the author counted that the recording contained 441,132 samples during one transmission period. Now we can determine the error:
This value is of course true assuming that the sound card input has no sampling rate error.
Communication channels
If we use the -audio switch - the program reads the sound from the standard input. This allows streams to be redirected to Pi-FM-RDS from other programs. In this way, we can redirect the sound from e.g. MP3 Sox player:
Or the AUX input of the sound card:
Change of PS, RT and TA parameters during transmission
The FIFO queue is used to control the PS, RT and TA parameters in the RDSA transmission, which can be started with the -ctl switch when starting Pi-FM-RDS.
Example:
The commands that can be sent via the FIFO queue to change PS, RT and TA are:
cat> rds_ctl
PS MyText
RT Radio text to send
THAT ON
PS OtherTxt
TA OFF
...
Each line must start with the command: PS, RT or TA, space and the value we want to set. Any other line will be ignored.
Tests
Pi-FM-RDS has been successfully tested with a range of devices that support RDS transmission:
* Sony ICF-C20RDS watch from 1995,
* Sangean PR-D1 portable radio from 1998, and ATS-305 from 1999,
* Samsung Galaxy S2 phone from 2011,
* Philips MBD7020 tower from 2012,
* Silicon Labs USBFMRADIO-RD USB radio with Si4701 chip,
* Chinese clone of the above named "PCear Fm Radio",
In all cases, reception was high-quality and the RDS showed no errors.
CPU usage
Software CPU utilization on RPi1 is as follows:
* Without input audio signal: 9%.
* With monaural audio: 33%.
* With stereo audio: 40%.
As it is easy to understand, the load on the processor increases when the audio signal is applied, as it must be upsampled in real time to 228 kHz - the frequency at which the transmitter system works. It is implemented, among others using the FIR filter, which is computationally expensive.
Design
The code responsible for generating RDS data can be found in the rds.c. The program cyclically generates four groups 0A (for transmitting PS) and one 2A (for transmitting RT). Additionally, every minute, it adds one 4A - CT group, i.e. clock. The get_rds_group function generates one group and uses the CRC to calculate the checksums.
To obtain samples of the RDS signal further, the get_rds_samples function is called, which calls the get_rds_group function, differentially encodes the signal and generates samples that are RRC filtered according to RDS standards and encoded into pulses using Manchester encoding.
The signals needed for operation are previously generated once by the Python program - generate_waveforms.py - which uses the Pydemod library. In the version downloaded from the repository, there is no need to use this script, because the waveforms.c and waveforms.h files generated by it are already in the repo.
The RDS samples have a sampling frequency of 228 kHz - four times 57 kHz, the subcarrier of the RDS signal.
FM signal muplexing is handled by fm_mpx.c, which first upsamples the audio to 228 kHz, then generates the sum of the signals from both channels (with a bandwidth limited to 15 kHz) plus a possible stereo signal at 19 kHz, stereo coding signals amplitude modulated to 38 kHz and finally adds RDS signal samples.
Source: https://github.com/ChristopheJacquet/PiFmRds
The circuit is based on an FM transmitter created by Oliver Marros and Oskar Weigl, to which Richard Hirst later added DMA support, and Christophe Jacquet a generator and RDS modulator. The transmitter uses a PWM signal generator built into the Raspberry Pi for operation.
This software is compatible with Raspberry Pi 1 version 1, 2 and 3.
Warning!
This software is developed and distributed for training purposes only. The system should not be used as part of the mediacenter, FM broadcasting may be illegal.
Using
Pi-FM-RDS uses the sndfile library. To install it on every machine with the Debian family system (e.g. Raspbianie) just type in the terminal:
Code: bash
The program also depends on Linux rpi-mailbox drivers, so you need a fairly fresh Linux kernel. Basically everyone after August 2015 should have this driver in them.
attention
Binaries compiled on Raspberry Pi 1 are not compatible with machines in version 2 and 3. Always recompile the sources after changing the hardware platform (command make clean in the description below).
We start the installation by cloning the sources from the repository and we can compile:
Code: bash
And then we can start our transmitter:
Code: bash
Without additional parameters, the system will start FM transmission at 107.9MHz, without audio, with the default RDS data: station name (PS), radio text (RT) and PI code. The signal is sent on pin GPIO 4, i.e. pin 7 on the output from RPi.
We can add sound to the broadcast. For the monophonic sound.wav file (included with the test sources) in the terminal we write:
Code: bash
The stereo_44100.wav file, also included with the program, is used to test the stereo transmission.
In general, the Pi-FM-RDS folding is as follows:
Code: bash
where:
-freq is the carrier frequency in MHz by default -freq 107.9.
-audio specifies the audio file to be played. The sampling frequency of the file is irrelevant, the program will sample it anyway. If the file is stereo, the transmission will also be. Acceptable audio formats depend on libsndfile. These are WAV and Ogg / Vorbis files. MP3 files are not supported.
-pi is the PI code of the RDS broadcast. It is four hexadecimal digits, for example: -p and FFFF.
-ps is the station name in RDS code, up to eight characters long; for example: -ps RASP-PI.
-rt is called radio text. This is an RDS message with a length of up to 64 characters. For example: -rt 'Hello, world!'.
-ctl specifies the FIFO channel used for PS and RT control during playback (see below).
-ppm specifies the Raspberry Pi oscillator error in parts per million (see below).
All arguments are optional.
By default, the PS changes cyclically between Pi-FmRds and an increasing number, starting at 00000000. The PS changes approximately once per second.
Clock calibration
Calibration should be performed only if we have problems with receiving and decoding the RDS signal. The standard of this system says that the maximum error for the 57 kHz subcarrier cannot be greater than +- 6 Hz, i.e. it must be below 105 ppm +-. Our 'Raspberry' oscillator may be above this value, then it is necessary to use the -ppm parameter in the program after previous calibration.
In practice, the Pi-FM-RDS works fine in most cases without using this switch. Everything indicates that RDS receivers are more tolerant than their specifications require.
One way to measure the frequency error is to broadcast a sound from the pulses.wav file. These are pulses given evenly for one second, followed by a second-long silence. We now have to receive the broadcast with the help of the FM receiver and record it using a good quality sound card. If we now open the recording in any audio processing program, we can determine the error by counting the collected samples. If we know that we were recording at a sampling rate of 44.1 kHz, we should have 441,000 samples in one second. During the calibration of his system, the author counted that the recording contained 441,132 samples during one transmission period. Now we can determine the error:
$$\frac {441132 - 44100} {441000} \times 10^6 = 299 ppm$$
This value is of course true assuming that the sound card input has no sampling rate error.
Communication channels
If we use the -audio switch - the program reads the sound from the standard input. This allows streams to be redirected to Pi-FM-RDS from other programs. In this way, we can redirect the sound from e.g. MP3 Sox player:
Code: bash
Or the AUX input of the sound card:
Code: bash
Change of PS, RT and TA parameters during transmission
The FIFO queue is used to control the PS, RT and TA parameters in the RDSA transmission, which can be started with the -ctl switch when starting Pi-FM-RDS.
Example:
Code: bash
The commands that can be sent via the FIFO queue to change PS, RT and TA are:
cat> rds_ctl
PS MyText
RT Radio text to send
THAT ON
PS OtherTxt
TA OFF
...
Each line must start with the command: PS, RT or TA, space and the value we want to set. Any other line will be ignored.
Tests
Pi-FM-RDS has been successfully tested with a range of devices that support RDS transmission:
* Sony ICF-C20RDS watch from 1995,
* Sangean PR-D1 portable radio from 1998, and ATS-305 from 1999,
* Samsung Galaxy S2 phone from 2011,
* Philips MBD7020 tower from 2012,
* Silicon Labs USBFMRADIO-RD USB radio with Si4701 chip,
* Chinese clone of the above named "PCear Fm Radio",
In all cases, reception was high-quality and the RDS showed no errors.
CPU usage
Software CPU utilization on RPi1 is as follows:
* Without input audio signal: 9%.
* With monaural audio: 33%.
* With stereo audio: 40%.
As it is easy to understand, the load on the processor increases when the audio signal is applied, as it must be upsampled in real time to 228 kHz - the frequency at which the transmitter system works. It is implemented, among others using the FIR filter, which is computationally expensive.
Design
The code responsible for generating RDS data can be found in the rds.c. The program cyclically generates four groups 0A (for transmitting PS) and one 2A (for transmitting RT). Additionally, every minute, it adds one 4A - CT group, i.e. clock. The get_rds_group function generates one group and uses the CRC to calculate the checksums.
To obtain samples of the RDS signal further, the get_rds_samples function is called, which calls the get_rds_group function, differentially encodes the signal and generates samples that are RRC filtered according to RDS standards and encoded into pulses using Manchester encoding.
The signals needed for operation are previously generated once by the Python program - generate_waveforms.py - which uses the Pydemod library. In the version downloaded from the repository, there is no need to use this script, because the waveforms.c and waveforms.h files generated by it are already in the repo.
The RDS samples have a sampling frequency of 228 kHz - four times 57 kHz, the subcarrier of the RDS signal.
FM signal muplexing is handled by fm_mpx.c, which first upsamples the audio to 228 kHz, then generates the sum of the signals from both channels (with a bandwidth limited to 15 kHz) plus a possible stereo signal at 19 kHz, stereo coding signals amplitude modulated to 38 kHz and finally adds RDS signal samples.
Source: https://github.com/ChristopheJacquet/PiFmRds
Cool? Ranking DIY