PiRadio

IMPORTANT UPDATE APRIL 2015: The BBC has changed the way it streams network radio – see here for details.

I love making internet radios with Raspberry Pis. Here are a few that I’ve built:

Update: this project can also now be found on GitHub: https://github.com/blogmywiki/pi-radio

There are a few Raspberry Pi internet radio projects out there. Here’s one I made pretty much from scratch – I think it’s probably the simplest functional bare-bones internet radio you can make. It starts up when you turn your Pi on and has a single push button for changing the station – no display, no volume control, uses the Pi’s on-board sound jack – in fact nothing fancy at all. The only clever thing about it, is that it remembers which station you were listening to last time it was turned on – though you can make it even simpler and more reliable by removing that bit of the code (see the end of this post).

You will need:

  • A RaspberryPi with a fresh headless install of Raspbian – this means you set it not to boot into a graphical environment when it starts up.
  • A push button.
  • A 10k and a 1k ohm resistor, and some way of wiring them together (such as a breadboard) and some way of connecting 3 wires to pins on the RaspberryPi.
  • Headphones or some powered speakers.
  • Optional: USB wifi dongle to make your radio, er, wireless.

First, log into your Pi at the command line. Ensure it’s connected to the internet and update it by typing
sudo apt-get update

Then install mpd (music player daemon) and mpc (client) by typing the following:
sudo apt-get install mpc mpd

UPDATE – JULY 2017
I’ve discovered that recent versions of Raspbian seem to require a bit of tweaking of MPD to get it to work reliably. I had a lot of problems when building a new radio as it would hang after changing channel a few times. Here’s how to fix this.

First open the mpd config file with nano like this:
sudo nano /etc/mpd.conf

Then edit these lines to remove some # signs (uncomment) and change the mixer_type from hardware to software so it looks like this:

audio_output {
type "alsa"
name "My ALSA Device"
device "hw:0,0" # optional
mixer_type "software" # optional
mixer_device "default" # optional
mixer_control "PCM" # optional
mixer_index "0" # optional
}

Add some internet radio stations by typing this at the command line to add BBC Radio 1:
mpc add http://bbcmedia.ic.llnwd.net/stream/bbcmedia_intl_lc_radio1_p?s=1365376033&e=1365390433&h=a0fef58c2149248d6bff1f7b7b438931

There are more stations BBC listed here: http://thenated0g.wordpress.com/2013/06/06/raspberry-pi-add-bbc1-6-radio-streams-and-mpc-play-command/

I’ve also discovered this article on RaspberryPi radio which has some very useful stuff on finding and updating BBC Radio streaming URLs.

I added BBC radios 1-6, and also added US public radio NWPR and the French station Fip, leaving me with 8 stations in total. Here’s how I added Fip (it’s a super-cool French music station):
mpc add http://audio.scdn.arkena.com/11016/fip-midfi128.mp3
(new Fip URL as of July 2015)

And for NPR try:
mpc add http://69.166.45.47:8000
Do try and add the stations in the order you want them to cycle through – you can re-order them using mpc at the command line, but it’s much easier to get them right first time. (I didn’t).

Test mpc is working by typing
mpc play 1
at the command line, and you should hear Radio 1 (or whichever station you added first) coming out of the Pi’s headphone jack. You can adjust the volume of your sound device by typing
alsamixer
at the command line. You get a graphical mixer in the command line which is pretty intuitive:

You can also adjust volume in mpc by typing:
mpc volume +5
or + or – any number you fancy.

Then type
mpc stop
to make the horrible noise go away.

Make your switch by connecting the button and resistors together, as in the circuit diagram above, based on the lower diagram on this page: http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/buttons_and_switches/

Using a little breadboard, connect one side of your push button to the 3.3v pin on the RaspberryPi. The other side of the switch is connected via a 1K resistor to RaspberryPi GPIO pin 23, and via a 10K resistor to a GND pin on the Pi (I used a different one in the photo to my diagram, but I don’t think it matters). You can find a good diagram of the pins here: http://elinux.org/RPi_Low-level_peripherals

Now in the home directory /home/pi save this file and call it radio.py. It assumes you have 8 stations set up – if you have a different number, change the 8 to the number you have.

#!/usr/bin/env python
# Bare bones simple internet radio
# www.suppertime.co.uk/blogmywiki

import RPi.GPIO as GPIO
import time
import os

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN)

# read station number from text file
f = open('/home/pi/station.txt', 'r')
station = int(f.read())
f.close

os.system("mpc play " + str(station))

#initialise previous input variable to 0
prev_input = 0
while True:
  #take a reading from pin 23
  input = GPIO.input(23)
  #if the last reading was low and this one high, do stuff
  if ((not prev_input) and input):
    # assumes you have 8 radio stations configured
    station += 1
    if station > 8:
       station = 1
    print(str(station))
    os.system("mpc play " + str(station))
    f = open('/home/pi/station.txt', 'w')
    f.write('%d' % station)
    f.close

  #update previous input
  prev_input = input

  #slight pause to debounce
  time.sleep(0.05)

Create a file called station.txt in the same folder containing just the number of the station you want it to play on the first run – eg 4 for Radio 4 (if Radio 4 was the
Using a little breadboard, connect one side of your push button to the 3.3v pin on the RaspberryPi. The other side of the switch is connected via a 1K resistor to RaspberryPi GPIO pin 23, and via a 10K resistor to a GND pin on the Pi (I 4th station you added).

Then test it by typing
sudo python radio.py
at the command line. The radio should play, and when you press the button it should change up through the channels, cycling back to 1 when it passes 8.

Next, to make it run at start up, type
sudo nano /etc/rc.local
and add the following line before the exit command:
(sleep 65; python /home/pi/radio.py)&
The ‘sleep 65′ is needed because my Pi has a USB wifi dongle which takes an eternity (well, a minute) to get on the network. If your Pi is connected to the internet by ethernet, you could probably make the sleep time an awful lot shorter.
Save it by typing ctrl-x. Reboot your Pi, and enjoy!

PiRadio rocking the fridge

You can build on this by adding a USB sound card for better audio quality or by adding a display with buttons like this: http://www.suppertime.co.uk/blogmywiki/2013/12/piradio-with-clock/ and http://www.suppertime.co.uk/blogmywiki/2013/12/fip-radio/. Or, if you enjoy listening to one station as much as I like listening to Fip, you could make it even simpler by removing the button!

Update: you can make a really neat, compact radio using a RaspberryPi and a Displayotron3000: http://www.suppertime.co.uk/blogmywiki/2014/11/dot3k/

If you’re interested in making your own, really rather simple, schedule for your own radio, have a look at this idea I had for using cron to ensure you don’t miss your favourite programmes: http://www.suppertime.co.uk/blogmywiki/2013/12/raspi-radio-schedule/

Here’s a simpler version of the code that doesn’t remember the station you last listened to, and doesn’t require the station.txt file. It plays station number 8 by default (which is fip on my install):

#!/usr/bin/env python
# Bare bones simple internet radio
# www.suppertime.co.uk/blogmywiki

import RPi.GPIO as GPIO
import time
import os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN)

# sets initial station number to channel 8
station = 8

os.system("mpc play " + str(station))

#initialise previous input variable to 0
prev_input = 0

while True:
  #take a reading from pin 23
  input = GPIO.input(23)
  #if the last reading was low and this one high, do stuff
  if ((not prev_input) and input):
    # assumes you have 8 radio stations configured
    station += 1
    if station > 8:
       station = 1
    os.system("mpc play " + str(station))

  #update previous input
  prev_input = input

  #slight pause to debounce
  time.sleep(0.05)

See also notes on adding stations and accounting for summer time here: http://www.suppertime.co.uk/blogmywiki/2014/04/sublime-bst/

And there’s a May 2014 update to the LCD code and a useful list of internet radio stations here.

9 Responses to PiRadio

  1. Ian says:

    Giles, thanks so much for writing this up

  2. Pingback: Quick and dirty Raspberry Pi radio scheduling | Blog My Wiki!

  3. Pingback: Making an internet radio from a Griffin iMic and RaspberryPi | Blog My Wiki!

  4. Pingback: Easy internet radio with a #RaspberryPi | Raspberry PiPod

  5. Pingback: PiRadio เครื่องรับวิทยุอินเทอร์เน็ต มีปุ่มเดียว | Raspberry Pi Thailand

  6. Pingback: Link: PiRadio » TechNotes

  7. Ed says:

    Hi there, Thank you so much for this! I want to make a BBC internet radio for my brother that lives outside of the UK, so this is perfect.

    I am a total noob to pi programming, but I hope you wouldn’t mind answering a very few quick questions:

    Q1. Can I add something like:

    input_r4 = GPIO.input(24)

    ...

    else if (input_r4):

    station = 4
    print(str(station))
    os.system("mpc play " + str(station))
    f = open('/home/pi/station.txt', 'w')
    f.write('%d' % station)
    f.close

    for example, assuming I have Radio 4 as my forth station programmed, and then have a stand alone button connected to GPIO pin 24, so that when that button is pressed radio 4 launches?

    Basically, I want to have four buttons. One for Radio 2, one for Radio 4, one radio 6, one for FIP.

    Q2. If that is the case, can I connect a 10kOhm to the same GND pin or do all buttons need a diff GND pin?

    Q3. Finally, I’m assuming I can run them all off the same+3V3?

    Thank you so much!

    • blogmywiki says:

      Really good questions – and an excellent idea to have separate push buttons for each station. As for the precise wiring and coding, I’d need to have a think but yes it should be do-able!

      • Ed says:

        Thank you for your reply. I’ll have a fiddle with a breadboard and some coding. If you do happen to figure out the coding/ wiring, please do let me know!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>