FM transmitter
The Raspberry Pi can be used as an FM transmitter. This applies to Raspberry Pi Zero (W) and other. The only extra hardware required is a cable to act as an antenna that is connected to GPIO 4. To improve it a shielded cable can be used where the shield is connected to GND. The setup to stream audio is the following: 1. mplayer plays a file or a stream and sends the audio to the loopback device like it was an output 2. arecord reads the audio from the loopback device like it was an input 3. Pi-FM-RDS or fm_transmitter gets the audio piped from arecord and sends it to GPIO 4 for FM audio
Installation
Alternative 1, install Pi-FM-RDS, it supports stereo 44100: https://github.com/ChristopheJacquet/PiFmRds/blob/master/README.md Basically: sudo apt-get install libsndfile1-dev. git clone https://github.com/ChristopheJacquet/PiFmRds.git cd PiFmRds/src make clean make Check that it works: sudo ./pi_fm_rds -audio stereo_44100.wav Alternative 2, Install fm_transmitter, it supports mono 22050: https://github.com/markondej/fm_transmitter/ Basically: sudo apt update sudo apt install make build-essential git clone https://github.com/markondej/fm_transmitter cd fm_transmitter make Check that it works by playing the included WAV file on a frequency: sudo ./fm_transmitter -f 100.6 acoustic_guitar_duet.wav Also install mplayer to play streams: sudo apt install mplayer Add the following to /etc/mplayer/mplayer.conf to reduce mplayer startup time. It tells it to use ALSA and not Pulseaudio, disable LIRC and prefer IPv4 over IPv6: ao=alsa lirc=no prefer-ipv4=yes Load loop devices to get a virtual device to play through: modprobe snd-aloop Or make it load on start by adding the following to /etc/modules: snd-aloop List loop devices, there should be at least two named card 0 after that the module has loaded: aplay -l
Begin transmission
Read audio from the loop device and pipe it to Pi-FM-RDS: arecord -fS16_LE -r 44100 -Dhw:0,1,0 -c 2 - | ./PiFmRds/src/pi_fm_rds -ps DEFAULT -rt Default -freq 100.6 -audio - & Or the same for fm_transmitter: arecord -D hw:0,1,0 -c 1 -d 0 -r 22050 -f S16_LE | ./fm_transmitter -f 100.6 - & -D, --device=NAME, Select PCM by name, replace the first number (0) with the loop device number if needed. -r, --rate=#<Hz> Sampling rate in Hertz. The default rate is 8000 Hertz. If the value specified is less than 300, it is taken as the rate in kilohertz. Valid values are 2000 through 192000 Hertz. -f --format=FORMAT Sample format Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUBFRAME_BE MU_LAW A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE Some of these may not be available on selected hardware The available format shortcuts are: -f cd (16 bit little endian, 44100, stereo) [-f S16_LE -c2 -r44100] -f cdr (16 bit big endian, 44100, stereo) [-f S16_BE -c2 -r44100] -f dat (16 bit little endian, 48000, stereo) [-f S16_LE -c2 -r48000] If no format is given U8 is used. 100.6 is the frequency, adjust it to an empty place on the radio where there is only noise. Play a stream - get one from Internet Radio for instance: mplayer http://<stream-url-here> & The audio can be a bit low by default, adjust loopback device the volume with alsamixer by using the up and down keys: alsamixer
End transmission
For Pi FM RDS: killall mplayer killall arecord killall pi_fm_rds fm_transmitter usually exits gracefully with Ctrl+C when it plays files directly. It is however not the case when it is getting data piped from arecord. Then it does not reset the GPIO pin and weird stuff happens - repeats, silence and so on. To stop the playback when piping do the following to stop mplayer, fm_transmitter and set the GPIO pin to output instead of GPCLK0 and to also set it to level low: killall mplayer killall fm_transmitter killall arecord raspi-gpio set 4 op dl
Distances
15 cm antenna, good 125m, audible but noisy 200m 150 cm antenna, good 200-350m, audible but noisy 400m
This is a personal note. Last updated: 2023-02-12 01:26:02.