Introduction: Raspberry Pi Wireless Bluetooth Audio FM Radio Transmitter
Use your raspberry pi to wirelessly stream music directly from your phone to your radio! Fantastic to get music to your car stereo.
This instructable draws on information from two other instructables, and fills in the gaps to make them work together. All of the steps to complete your Wireless Bluetooth Audio FM Radio Transmitter will be listed here, but more (specific) information about each piece can be found in these instructables:
- Turn your Raspberry Pi into a Wireless Portable Bluetooth Audio System A2DP
- Raspberry Pi Radio Transmitter
Also many thanks to the Imperial College Robotics Society, for the pifm software.
Step 1: The Prerequisites
The parts (to make it work):
- Raspberry Pi with power supply (any model, but A+ or B+ are recommended)
- At least 2GB micro SD card with Raspian on it
- You'll need to burn the image to the SD card
- For windows, use a handy utility such as Win32DiskImager
- For mac, there's instructions here
- Bluetooth A2DP dongle (something like this)
- Antenna
- Just a length of wire will do (30cm - 75cm), attached to GPIO 4
The extra parts (needed only to complete the installation)
- Ethernet cable (and internet access)
- USB keyboard (or ssh)
- HDMI display and cable (or ssh)
Before you plug the SD card into your pi, plug it into your computer. Open up the drive, and find the config.txt file. Uncomment the following lines. This will allow us to force audio to be played through the HDMI output, rather than the stereo jack, which is necessary for the pi to stream music from bluetooth to the fm transmitter (without which you'd just get a loud, screechy noise on both the audio jack and on your radio).
hdmi_force_hotplug=1 hdmi_drive=2
Step 2: The Software
Plug the SD card (with OS image) into your pi, plug in the USB keyboard, the ethernet cable, connect it to the display, and power it up.
If it asks for login credentials, the default username is pi and the default password is raspberry.
Proceed with downloading the necessary software by executing the following commands:
sudo apt-get upgrade
sudo apt-get install bluez pulseaudio-module-bluetooth python-gobject python-gobject-2 bluez-tools sudo apt-get install sox libsox-fmt-all cd /home/pi; mkdir fm; cd fm wget http://www.icrobotics.co.uk/wiki/images/c/c3/Pifm.tar.gztar -zxvf Pifm.tar.gz
Step 3: The Configuration
Make the following modifications
Add our user pi to the Pulse audio group
sudo usermod –a –G lp pi
Audio configuration settings
sudo nano /etc/bluetooth/audio.conf
Add the following text under
[General]:
Enable=Source,Sink,Media,Socket
Pulse settings
sudo nano /etc/pulse/daemon.conf
Comment this line by adding a semicolon
; speex-float-3
Add these lines
resample-method = trivial
exit-idle-time = -1
Bluetooth configuration
sudo nano /etc/bluetooth/main.conf
Modify these lines to customize your bluetooth device name and class
Name = nameyourbluetoothdevicehere
Class = 0x20041C
Bluetooth configuration of your device
sudo nano /var/lib/bluetooth/<bluetooth mac address>/config
Modify these lines to customize your bluetooth device name and class
(Note, the class may reset on reboot. Don't worry too much about it)
name nameyourbluetoothdevicehere
class 0x20041C
Input rules
sudo nano /etc/udev/rules.d/99-input.rules
Add this line
KERNEL=="input[0-9]*", RUN+="/usr/lib/udev/bluetooth"
Device initialization (auto-login)
sudo nano /etc/inittab
Modify the following line to look like this
(was something like this) 1:2345:respawn:/sbin/getty --noclear 38400 tty1
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1
== OPTIONAL ==
Increase the audio quality of the fm transmitter
sudo nano /home/pi/fm/pifm.c
Find and modify the following lines
QUALITY=15 SQUALITY=20
Then recompile
cd /home/pi/fm; mv pifm pifm_bak;
g++ -O3 -o pifm pifm.c
Step 4: The Scripts
Create the following scripts
sudo nano /usr/lib/udev/bluetooth Type this all into the empty editor, then save Note and adjust the radio frequency and volume to your preference #!/bin/bash AUDIOSINK="alsa_output.platform-bcm2835_AUD0.0.analog-stereo" ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*") echo "Executing bluetooth script...|$ACTION|" >> /var/log/bluetooth_dev if [ "$ACTION" = "add" ] then # Turn off BT discover mode before connecting existing BT device to audio hciconfig hci0 noscan # Turn off BT auto connect if it is still running sudo killall bluetooth-auto # set the audio output to the hdmi amixer cset numid=3 2 # Set volume level to 100 percent amixer set Master 100% # Set sink volume to 125% pacmd set-sink-volume 0 0x12500 for dev in $(find /sys/devices/virtual/input/ -name input*) do if [ -f "$dev/name" ] then mac=$(cat "$dev/name") # Add this mac address to list of trusted addresses TRUST=$(grep "$mac" /usr/lib/udev/bluetooth-trust) if [ -z "$TRUST" ] then echo "Adding $mac to trusted addresses" >> /var/log/bluetooth_dev echo $mac >> /usr/lib/udev/bluetooth-trust fi mac_underscore=$(cat "$dev/name" | sed 's/:/_/g') bluez_dev=bluez_source.$mac_underscore # Set source volume to 125% pacmd set-source-volume $bluez_dev 0x12500 sleep 1 CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev` if [ ! -z "$CONFIRM" ] then echo "Setting bluez_source to: $bluez_dev" >> /var/log/bluetooth_dev echo pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev sudo -u pi pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> /var/log/bluetooth_dev echo "Killing any existing radio connections" >> /var/log/bluetooth_dev sudo killall pifm >> /var/log/bluetooth_dev echo "Connecting bluetooth output to radio input, playing on 87.7" >> /var/log/bluetooth_dev # Using $AUDIOSINK instead of 0 here doesn't seem to work, not sure why echo pacat -r -d 0 --latency-msec=50 | sox -t raw -r 44100 -e signed-integer -b 16 -c 2 - -t wav - gain -l 10 | sudo /home/pi/fm/pifm - 87.9 44100 stereo >> /var/log/bluetooth_dev sudo -u pi pacat -r -d 0 --latency-msec=50 | sudo -u pi sox -t raw -r 44100 -e signed-integer -b 16 -c 2 - -t wav - gain -l 10 | sudo /home/pi/fm/pifm - 87.7 44100 stereo >> /var/log/bluetooth_dev fi fi done fi if [ "$ACTION" = "remove" ] then # Turn on bluetooth discovery if device disconnects sudo hciconfig hci0 piscan # Turn on bluetooth auto discovery sudo /usr/lib/udev/bluetooth-auto & fi Finally, grant appropriate permissions to the script sudo chmod 774 /usr/lib/udev/bluetooth
sudo nano /usr/lib/udev/bluetooth-auto Type this all into the empty editor, then save #!/bin/bash while [ true ] do sleep 1 echo "Scanning for trusted devices" >> /var/log/bluetooth_dev for mac in $(sudo hcitool scan | grep ":" | awk '{print $1}') do trust=$(grep "$mac" /usr/lib/udev/bluetooth-trust) if [ ! -z "$trust" ] then _BT_ADAPTER=`dbus-send --system --print-reply --dest=org.bluez / org.bluez.Manager.DefaultAdapter|awk '/object path/ {print $3}'` BT_ADAPTER=${_BT_ADAPTER//\"/} mac_underscore=$(cat "$mac" | sed 's/:/_/g') echo "Connecting to device at: $mac" >> /var/log/bluetooth_dev sudo dbus-send --print-reply --system --dest=org.bluez $BT_ADAPTER/dev_$mac_underscore org.bluez.AudioSource.Connect >> /var/log/bluetooth_dev exit 0 fi done done Finally, grant appropriate permissions to the script, and create the trust file sudo chmod 774 /usr/lib/udev/bluetooth-auto sudo touch /usr/lib/udev/bluetooth-trust
sudo nano /etc/init.d/bluetooth-agent Type this all into the empty editor, then save #!/bin/sh #/etc/init.d/bluetooth-agent ### BEGIN INIT INFO # Provides: bluetooth-agent # Required-Start: $remote_fs $syslog bluetooth pulseaudio # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Makes Bluetooth discoverable and connectable to 0000 # Description: Start Bluetooth-Agent at boot time. ### END INIT INFO USER=root HOME=/root export USER HOME case "$1" in start) echo "initializing pulseaudio" sudo pactl info echo "setting bluetooth discoverable" sudo hciconfig hci0 piscan start-stop-daemon -S -x /usr/bin/bluetooth-agent -c pi -b -- 0000 echo "bluetooth-agent started pw: 0000" sudo /usr/lib/udev/bluetooth-auto & echo "bluetooth-auto-discovery started" sudo /home/pi/fm/pifm /home/pi/fm/silence 87.7 44100 stereo echo "pifm started at 87.7, playing silence" ;; stop) echo "Stopping bluetooth-agent" start-stop-daemon -K -x /usr/bin/bluetooth-agent ;; *) echo "Usage: /etc/init.d/bluetooth-agent {start|stop}" exit 1 ;; esac exit 0 Finally, create the silence file, grant appropriate permissions to the script, and add it to the list of programs that run on startup sudo touch /home/pi/fm/silence sudo chmod 755 /etc/init.d/bluetooth-agent sudo update-rc.d bluetooth-agent defaults
Step 5: Enjoy
That's it. Restart your pi - either by just disconnecting and reconnecting the power supply, or by running the command:
sudo reboot
Disconnect the keyboard, display, and ethernet cable. You no longer need these.
You should see the pi as a bluetooth device to which you can connect. After connecting the first time, the pi will add your phone to its list of trusted devices. Each time the pi powers up, it will attempt to automatically connect to nearby trusted devices. Likewise, if you move out of bluetooth range, the pi will attempt to reconnect when you're back in range.
Begin playing music, send it to the pi, and tune your radio to your chosen frequency (default 87.7).
35 Comments
8 years ago on Introduction
Update: Turns out pacat adds delay by default. Updated the line in /usr/lib/udev/bluetooth to read as follows:
sudo -u pi pacat -r -d 0 --latency-msec=50 | sudo -u pi sox -t raw -r 44100 -e signed-integer -b 16 -c 2 - -t wav - gain -l 10 | sudo /home/pi/fm/pifm - 87.7 44100 stereo >> /var/log/bluetooth_dev
I've also added 10dB gain to the line, as I found the volume on the radio was too low. The docs say this may produce some clipping/distortion, but I've yet to really notice any.
Question 1 year ago on Step 5
Ive tried again but used a raspberry pi1 this time, it seems to work but all i get is silence. i though it hadnt work to start of with but when i turn the pi off all i get on the radio then is static so im guessing it works to a fashion but no audio is being played. ive tried it with both bluetooth and a .wav file on the pi itself
Question 1 year ago on Introduction
im being awkward as i have a zero on hand but its just a zero. Is this at all possible without bluetooth? can you play music from spotify/youtube music or any other audio input and just have it output over fm? ive looked at other projects and most only enable playing music that is on the pi itself but these are 5-8 year old projects. any help would be very greatful
Answer 1 year ago
The idea here is that the pi is acting simply as a sort of transcoder. Your phone (or other device) would load the music (via spotify/youtube or whatever you want). The phone would connect to the pi via bluetooth, and the pi would take the music data from your phone and output it over FM.
If you want to not use a phone (or other device) and simply connect the pi directly to a music service, then you can probably still make use of pifm, but the connecting to a music service and transcoding between said service and pifm is outside the scope of this instructable.
7 years ago
Sorry it's been a while since you posted, but my phone keeps saying "pairing rejected" after inputting the passcode. Any fix?
Reply 6 years ago
you could use my custom simple-agent, check out my website's post (comments above)
7 years ago
Hello, anyone for update this how to, it doesn't work anymore on Raspbian jessie and Raspberry 2 B+
Reply 6 years ago
Check out my comment above :)
7 years ago
Have anyone tried this radio application working in Raspberry Pi A+?
8 years ago on Introduction
hi, right after i can't seem to get any audio from my device to stream to pifm
this is the output of the log
Setting bluez_source to: bluez_source.EC_88_92_6C_3B_58
pactl load-module module-loopback source=bluez_source.EC_88_92_6C_3B_58 sink=alsa_output.platform-bcm2835_AUD0.0.analog-stereo rate=44100 adjust_time=0
Killing any existing radio connections
Connecting bluetooth output to radio input, playing on 87.7
exiting
Reply 8 years ago on Introduction
Try getting rid of the platform-bcm2835_AUD0. in the script. That worked for me
8 years ago on Step 2
https://github.com/markondej/fm_transmitter
Can you update using the new program for both RPi 1 and 2?
8 years ago on Introduction
Hi Tinclon,
I followed the steps above but i'm unable to get it working correctly. I went through the scripts and found that it's failing in /usr/lib/udev/bluetooth when running the following:
CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev`
Modifying the script to output $bluez_dev I have the following:
/org/bluez/2069/hci0
Attempting to run the pactl line manually, I found that my device isn't listed:
pi@raspberrypi ~ $ sudo -u pi pactl list short | grep /org/bluez/2069/hci0
pi@raspberrypi ~ $
Running 'sudo -u pi pactl list short' I have the following:
0 module-device-restore
1 module-stream-restore
2 module-card-restore
3 module-augment-properties
4 module-alsa-card device_id="0" name="0" card_name="alsa_card.0" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes card_properties="module-udev-detect.discovered=1"
5 module-udev-detect
6 module-bluetooth-discover
7 module-native-protocol-unix
8 module-default-device-restore
9 module-rescue-streams
10 module-always-sink
11 module-intended-roles
12 module-suspend-on-idle
13 module-console-kit
14 module-systemd-login
15 module-position-event-sounds
16 module-role-cork
17 module-filter-heuristics
18 module-filter-apply
19 module-dbus-protocol
20 module-switch-on-port-available
21 module-alsa-sink device_id=0
23 module-cli-protocol-unix
0 alsa_output.0.analog-stereo module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
1 alsa_output.0.analog-stereo.2 module-alsa-sink.c s16le 2ch 44100Hz SUSPENDED
0 alsa_output.0.analog-stereo.monitor module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
1 alsa_output.0.analog-stereo.2.monitor module-alsa-sink.c s16le 2ch 44100Hz SUSPENDED
25 protocol-native.c pactl
0 alsa_card.0 module-alsa-card.c
I backtracked a bit and made sure the device was connected to the PulseAudio server:
udo dbus-send --print-reply --system --dest=org.bluez $BT_ADAPTER/dev_$mac_underscore org.bluez.AudioSource.Connect
I tested by running the following:
sudo dbus-send --print-reply --system --dest=org.bluez /org/bluez/2069/hci0/dev_D4_F4_6F_B1_1F_FF org.bluez.AudioSource.Connect
And i get the following:
Error org.bluez.Error.AlreadyConnected: Already Connected
Also, I think you might have an error in your bluetooth-auto script:
mac_underscore=$(cat "$mac" | sed 's/:/_/g')
I changed this to:
mac_underscore=$(echo "$mac" | sed 's/:/_/g')
Any ideas as to where i can go from here?
8 years ago on Step 4
I looked At the instructable you used to make this and answered my own question. You may need to create the folder /usr/lib/udev to do so, simply type
sudo mkdir /usr/lib/udev
Thats it! good luck!
8 years ago on Step 4
I got to the start of step 4, I copied and pasted the sudo command at the start for the first script, copied the text for it. All was good until I tried to save it. I got the error [Error writing /usr/lib/udev/bluetooth: No such file or directory ]. what do I do? i have no udev file under lib
8 years ago on Introduction
It doesn't work for me :/ Can someone check if the tutorial is up to date ? Because my level for scripting or for the linux environment is not very high :/
8 years ago on Introduction
So I got everything working except streaming audio. I can connect to the pi as a speaker and play music to it but the pi isn't routing the music to 87.7 or HDMI and I followed every step carefully and setup config.txt to output on HDMI only.
8 years ago on Introduction
I followed the instructions carefully for 4 times now. But i cant get it to work, the sound quality is very, very poor. You have to listen very carefully to recognize the song. Has anyone tried this recently? Maybe it's due to an update or something...
8 years ago on Introduction
I made this but it doesn't work to output sound to hdmi from the bluetooth input device. I can connect my iPhone to the Pi fine via bluetooth. I can output sound via pifmplay if I play the sound (MP3) directly from the SD card using the command sudo sh /home/pi/pifmplay/pifmplay "/home/pi/music" 91.3 and it plays over Pin 4 on the GPIO and I can hear it on my radio. But the bluetooth sound does not output over FM. How can I redirect the bluetooth input to the FM output on pin 4 of the GPIO (HDMI)?
8 years ago on Introduction
I am so glad to have found this; I've been wanting to do this with my rpi for a while now. I've set everything up and I can hear the audio on my radio, but it is very slow and delayed. Any ideas on how to go about fixing it? I'm fairly new to all of this..