# RDS, how does it work? We fall to the lowest level of the OSI model

• Tutorial
With the RDS (Radio Data System) system, at least once everyone who saw in the car radio a station name like "Road Radio" came across. In addition to the name, additional data can be displayed - the name of the song being played, temperature, broadcast frequency, etc.

But how does it work? Because my hobby is radio and digital signal processing, it was interesting to figure it out. As it turned out, there is practically no complete information about RDS in Runet (and it is also sparse in English), I hope this publication will fill this gap.

Continuation under the cut (carefully a lot of pictures).

#### Introduction

FM radio stations exist and have been popular for quite some time. But over time, it became clear that in addition to sound, there is not enough textual information - the name of the station, track, artist of the song. There was only one way to add such an opportunity - in addition to sound, transmit an additional digital channel. Moreover, to transmit so that, on the one hand, the data was easy to decode (the computational capabilities of the microcircuit in the radio are quite limited), on the other hand, so as not to compromise compatibility with existing receivers. The problem was solved, so the RDS standard adopted in the 1990s appeared.

The spectrum of a modern FM station looks like this:

In the picture you can see (from left to right) 4 main components.
- Sound in mono format (L + R). It was probably left for compatibility with old receivers (it is interesting to observe how in such standards different technologies “overlap” each other to ensure backward compatibility).
- Pilot tone 19KHz. It is used to decode a stereo signal, for which the pilot-tone frequency is multiplied by 2, and stereo channels are separated relative to the received frequency of 38KHz.
- Stereo sound, the second channel (LR) located in the picture symmetrically with respect to 38KHz.
- The RDS channel, which is transmitted at the 3rd harmonic of the pilot tone, its frequency is 19 * 3 = 57KHz, respectively. We will be engaged in it.

#### RDS Modulation

In order to decode a signal, you first need to understand how it is formed, and there are quite a few "pitfalls" here. The main document describing the RDS is the EUROPEAN STANDARD EN 50067, which we will study.

The RDS encoder, according to the standard, looks like this:

As you can see, the signal in the encoder goes through 5 stages:

1) The original bitstream. To receive it, the RDS messages are first encoded in 16-bit packets, then a 10-bit block is added to them checksum with error correction, the result is 26-bit blocks, which are sent to the encoder. It would seem, take and send? It's more complicated.

2) The bitstream is converted using differential encoding according to the following table:

The unit is encoded to change the bit; the absence of the change is encoded to zero. This is for a simple purpose - the resulting code is independent of inversion. We may not know what to count as “0”, and what to count as “1”; this encoding eliminates this gap.

Consider a simple example, let the transmitted message be 0010100. We encode it according to this table, we get 0011000.
For decoding, another table is used:

Using it, we get the original message 010100. The meaning of the action is that if the original message is inverted (ie 1100111) , then decoding it, we still get the same result.

Now take the signal and send? Not yet, everything is more complicated.

3) At the previous step, we received a bit signal, but the problem is that this signal may very well look like 011000000000011. An electromagnetic wave of such a “shape” will be poorly transmitted and decoded. It is necessary to obtain a signal as close as possible to the "classical" sinusoid of the desired frequency. For this, the so-called "biphasic coding" is used (in Russian-language literature the name "Manchester coding" is often found).
Algorithmically, it is written quite simply:
0 -> 01
1 -> 10
With its help, the signal 011000000000011 given above will be presented as 011010010101010101010101010101010, as you can see, we got rid of long identical sequences.

The signal shown at number “5” on the encoder circuitry is actually our bits after Manchester coding, only the encoder in the standard was considered hardware. It works as follows:
- The bitstream is converted into a sequence of short pulses (number “3” in the picture)
- Manchester coding is performed by delaying the signal by half a period and adding it with the opposite sign (number “4”).
- The received signal in the form of "bursts" of positive and negative pulses is fed to the low-pass filter (low-pass filter), which selects the envelope shown under the number "5".

Now is it possible to transmit a signal? Yes you can. But not at once. The original frequency of the digital RDS signal is 1187.5Hz, which is too small. The received signal is multiplied by another signal with a frequency of 57KHz, which transfers it to a given frequency, we recall the school formula for multiplying cosines:

The received signal has the frequency we need just 57KHz, it is summed with the "main" (sound) signal, which is broadcast. As you can see from the top picture, the addition of a frequency of 57KHz does not affect the sound channels; accordingly, it does not add any distortion even to non-supporting RDS receivers.

#### Demodulation

Now, having understood how the signal is obtained, we can begin to demodulate the signal from a real FM station. To do this, you need an SDR receiver, I used HackRF, but a much cheaper RTL-SDR is also suitable , which you can buy for \$ 10 with free shipping on eBay.

##### Step 1. WFM decoder

Because the original signal is frequency-modulated, first we need to get it in a demodulated form. In order not to write an FM decoder, we will use the GNU Radio package. Run the GNU Radio Companion and assemble the circuit as shown.

We are going to receive an FM station at a frequency of 100.4 MHz, for this we tune the receiver to a frequency of 99 MHz, and programmatically “shift” the signal upwards in frequency by 1.4 MHz, multiplying it by a signal with such a frequency. This is because the SDR receiver has a peak at zero frequency relative to the center, and we cannot tune in to the station right away.

We launch the “scheme”, and see the picture as in the textbook at the beginning of the article.

The 19KHz pilot tone, the 38KHz stereo signal and 2 peaks of the RDS signal around 57KHz are clearly visible.

##### Step 2. Highlight pilot tone and RDS signal.

The next step is to extract the pilot tone and RDS signal. To do this, use a band-pass filter at the appropriate frequencies.

We run the resulting scheme, and see the result, as in any "textbook" according to the description of RDS.

The pilot tone with a frequency of 19KHz and the 57KHz signal modulating a lower-frequency signal with a frequency of 1187.5Hz are clearly visible.

##### Step 3. Highlight a low-frequency signal.

To get the LF signal, 2 steps are required:
3.1) Receiving a 57KHz signal (3rd harmonic of the pilot tone).
We have a 19KHz signal allocated by the filter, but how to get 57KHz from it? To do this, recall school mathematics, the formula of the sine cube:

As you can see, the sine cube contains 2 components: sin (a) and sin (3 * a). Because we work with "analog" blocks, take 2 blocks in GNU Radio - a multiplier, and a high-pass filter. By removing sin (a) with a 38KHz filter, we get the desired 57KHz.
The finished result can be seen on the oscillogram:

3.2) Inverse frequency transfer
When encoding, the signal was transferred from a frequency of 1187.5Hz up, multiplied by 57KHz. Now we perform the reverse operation, transfer the signal "down". To do this, we multiply it again by the 57KHz signal. According to the formula for the product of sines (the school curriculum is a useful thing) we get 2 components - the sum and difference of the frequency. We need the difference, we discard the amount using a low-pass filter.
All this is done by adding blocks to GNU Radio, the finished result is shown in the picture:

Green shows the “model” signal with a frequency of 1187.5Hz to see that the conversion is performed correctly.

##### Step 4. Demodulation of the low-frequency signal

The principle of this part is easiest to illustrate with a picture from the standard (block "biphase symbol decoder").

Demodulation of a biphasic signal consists of 2 parts.
- “Invert” of the signal by the inverter. This is necessary to return from biphasic coding, which was discussed above, to the original signal. In fact, you need to “flip” every second bit, so the process is synchronized with the clock signal.
- Summation of signals for the period. A positive amount corresponds to bit “1”, a negative “0”.
By the way, the 1187.5Hz period was also not chosen by chance - this is the 19KHz pilot tone frequency divided by 16. Everything was done so that the hardware implementation of the decoder in the receiver was as simple and cheap as possible.

After demodulation, the signal is fed to a differential decoder, which was discussed above. Then the signal goes to the error correction module, but as they say, another story, corresponding to the second level of the OSI model.

If you are interested, the theoretical part can be continued, and consider the formation of packages. If anyone wants to experiment on their own, one of the options for a working decoder for RTL-SDR can be found on github . If you want to use a hardware tuner in your projects, you can buy a Si4703 FM RDS Tuner board on eBay, its price is about \$ 6.