wip/fm_mpx
Christophe Jacquet 2014-04-06 20:04:31 +02:00
rodzic a9a15c9a81
commit e474651aee
2 zmienionych plików z 97 dodań i 4 usunięć

Wyświetl plik

@ -1,4 +1,95 @@
PiFmRds
=======
Pi-FM-RDS: FM-RDS transmitter using the Raspberry Pi's PWM
==========================================================
FM-RDS transmitter using the Raspberry Pi's PWM
This program generates an FM modulation, with RDS (Radio Data System) data generated in real time.
It is based on the FM transmitter created by Oliver Mattos and Oskar Weigl, and later adapted to using DMA by Richard Hirst.
## How to use it?
Run `make` in the `src` directory:
```bash
cd src
make
```
Then you can just run:
```
sudo ./pi_fm_rds
```
This will generate an FM transmission on 107.9 MHz, with default station name (PS), radiotext (RT) and PI-code.
You can add a monophonic sound by referencing a WAV file as follows:
```
sudo ./pi_fm_rds -wav sound.wav
```
*Current limitation: the WAV file must be sampled at 228 kHz. Use for instance the two files provided, `sound.wav` and `pulses.wav`.*
The more general syntax for running Pi-FM-RDS is as follows:
```
pi_fm_rds [-freq freq] [-wav file.wav] [-ppm ppm_error] [-pi pi_code] [-ps ps_text] [-rt rt_text]
```
* `-freq` specifies a frequency (in MHz). Example: `-freq 87.5`.
* `-wav` specifies a WAV file to play. It must be sampled at 228 kHz, but no frequency above 18 kHz must be present. Example: `-wav sound.wav`.
* `-ppm` specifies your Raspberry Pi's oscillator error in parts per million (ppm), see below.
* `-pi` specifies the PI-code of the RDS broadcast. 4 hexadecimal digits. Example: `-pi FFFF`.
* `-ps` specifies the station name (Program Service name, PS) of the RDS broadcast. Limit: 8 characters. Example: `-pi RASP-PI`.
* `-rt` specifies the radiotext (RT) to be transmitted. Limit: 64 characters. Example: `-rt 'Hello, world!'`.
### Calibration
The RDS standards states that the error for the 57 kHz subcarrier must be less than ± 6 Hz, i.e. less than 105 ppm (parts per million). The Raspberry Pi's oscillator error may be above this figure. That is where the `-ppm` parameter comes into play: you specify your Pi's error and Pi-FM-RDS adjusts the clock dividers accordingly.
In practice, I found that Pi-FM-RDS works okay even without using the `-ppm` parameter.
One way to measure the ppm error is to play the `pulses.wav` file: it will play a pulse for precisely 1 second, then play a 1-second silence, and so on. Record the audio output from a radio with a good audio card. Say you sample at 44.1 kHz. Measure 10 intervals. With Audacity for instance, measure determine the number of samples of these 10 intervals: it should be 441,000 samples. With my Pi, I found 441,132 samples. Therefore, my ppm error is (441132-441000)/441000 = 299 ppm, *assuming that my sampling device has no clock error...*
## Diclaimer
Never use this to transmit VHF-FM data through an antenna, as it is
illegal in most countries. This code is for testing purposes only.
Always connect a shielded transmission line from the RaspberryPi directly
to a radio receiver, so as *not* to emit radio waves.
## Tests
Pi-FM-RDS was successfully tested with all my RDS-able devices, namely:
* a Sony ICF-C20RDS alarm clock from 1995,
* a Sangean PR-D1 portable receiver from 1998,
* a Philips MBD7020 hifi system from 2012,
* a Silicon Labs [USBFMRADIO-RD](http://www.silabs.com/products/mcu/Pages/USBFMRadioRD.aspx) USB stick, employing an Si4701 chip, using my [RDS Surveyor](http://rds-surveyor.sourceforge.net/) program,
* a “PCear Fm Radio”, a Chinese clone of the above, still using RDS Surveyor.
Reception works perfectly with all the devices above. RDS Surveyor reports no group errors.
## Design
The RDS data generator lies in the `rds.c` file.
The RDS data generator generates cyclically four 0A groups (for transmitting PS), and one 2A group (for transmitting RT). `get_rds_group` generates one group, and uses `crc` for computing the CRC.
To get samples of RDS data, call `get_rds_samples`. It calls `get_rds_group`, differentially encodes the signal and generates a shaped biphase symbol. Successive biphase symbols overlap: the samples are added so that the result is equivalent to applying the shaping filter (a [root-raised-cosine (RRC) filter ](http://en.wikipedia.org/wiki/Root-raised-cosine_filter) specified in the RDS standard) to a sequence of Manchester-encoded pulses.
The shaped biphase symbol is generated by a Python program called `generate_waveforms.py` that uses [Pydemod](https://github.com/ChristopheJacquet/Pydemod), one of my other software radio projects. This Python program generates an array called `waveform_biphase` that results from the application of the RRC filter to a positive-negative impulse pair.
The samples are played by `pi_fm_rds.c` that is adapted from Richard Hirst's [PiFmDma](https://github.com/richardghirst/PiBits/tree/master/PiFmDma). The program was changed to support a sample rate of precisely 228 kHz, four times the RDS subcarrier's 57 kHz.
--------
© Christophe Jacquet (F8FTK), 2014. Released under the GNU GPL v3.

Wyświetl plik

@ -38,7 +38,9 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
set_rds_params(0x1234, argv[2]);
set_rds_pi(0x1234);
set_rds_ps(argv[2]);
set_rds_rt(argv[2]);
float buffer[LENGTH];