Project tutorial

Arduino / Raspberry Pi Internet Radio © CC BY-NC-SA

Make an Internet Radio with the mdp music player.

  • 8,103 views
  • 0 comments
  • 24 respects

Components and supplies

About this project


http://www.youtube.com/embed/_GM5F6AAZ_o

This is a project for Arduino and Raspberry Pi to make an Internet Radio, aimed at intermediate skill level. Some familiarity with Linux usage will be beneficial (or access to someone who can help out if required).

Raspberry Pi runs mpd music player daemon to receive and decode the internet radio stream.
ALSA running on the Raspberry Pi provides the sound through either the Jack Socket or the HDMI output.

Arduino runs a nanpy interface code to interface with Python, providing Text output of the Radio Station playing and Button inputs to control Playback.

Objectives:

  • Learn how to use the mpd/mpc on the Raspberry Pi
  • Learn how to use the nanpy library for Python to interface the Pi to the Arduino
  • Make a Cool Internet Radio 

Step 1: You Will Need

Warning: embedding parts within the project story has been deprecated. To edit, remove or add more parts, go to the "Hardware" tab. To remove this list from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Hardware" tab).
A000066 iso both
Arduino UNO & Genuino UNO
LCD / Keyboard Shield
12994 02
Raspberry Pi 1 Model B+
USB cable
Ethernet cable

Step 2: Install the Required Packages for mpd/mpc

The first thing we have to do is update Raspbian and install the required packages. Make sure you're logged in (obviously), and you have an Internet connection.

1. Update Raspbian to the latest packages
$ sudo apt-get update

2. Install the mpd / mpc packages
$ sudo apt-get install mpc mpd

This installs the Music Player Daemon (mpd) and it's client mpc.
You use the mpc client to configure mpd to add radio streams to the playlist, start and stop the player etc.

Step 3: Install the Required Packages for Python-nanpy

We want to be able to talk to Arduino from Python running on the Pi.
To do that, we need to install the nanpy library for Python and the nanpy firmware for Arduino.

1. Install Arduino packages to build the nanpy firmware for Arduino
$ apt-get install arduino

2. Get the nanpy library for Python and extract
from /home/pi
$ wget http://pypi.python.org/packages/source/n/nanpy/nanpy-v0.7.tar.gz$ tar xvf nanpy-v0.7.tar.gz

3. Get setuptools for Python (a dependancy for nanpy) and extract
$ wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f613b509fb44feefe74e$ tar xvf setuptools-0.6c11.tar.gz

4. Get pyserial for Python (a dependancy for nanpy) and extract
$ wget http://pypi.python.org/packages/source/p/pyserial/pyserial-2.6.tar.gz$ tar xvf pyserial-2.6.tar.gz

5. Go to the setuptools directory and install Python setuptools
$ cd setuptools-0.6c11$ sudo python setup.py install

6. Go to the nanpy directory and install the Python nanpy library
$ cd ../nanpy$ sudo python setup.py install

7. Go to the serial directory and install the Python serial library
$ cd ../pyserial-2.6 $ sudo python setup.py install

Now we've got the files we need let's put the nanpy firmware on the Arduino.

Step 4: Put the nanpy Firmware on the Arduino

nanpy allows a Python program runing on the raspberry Pi to operate the Arduino using conventional Arduino-Sketch syntax e.g. the Python program to read an analogue input from Arduino might read:
int val = Arduino.analogRead(14)

nanpy has two components:
i) a library for Python that allows Arduino commands to be written in a familiar syntax and communicate with Arduino;
ii) firmware that runs on Arduino, communicating with Python on the Pi

We installed the Python part of nanpy, and downloaded the Arduino part of nanpy on the Pi in the last step.

Now we need to upload the nanpy firmware to Arduino.

Plug Arduino into the USB of the Raspberry Pi.

1. Go to the nanpy firmware directory and upload to Arduino
$ cd ../nanpy/firmware$ export BOARD=uno$ make$ make upload

If you get a report that the device is not found on /dev/ttyACM0 , plug the Arduino into the other USB port.

Step 5: Add Radio Streams to mpd

Now that we've done all the preliminary installation and setup, it's time to get on to some fun stuff.

Let's start by getting some music playing.

We need to add some radio stations to be played by mpd.

The mpd music player daemon is controlled and configerd by its client, mpc.

Let's add our first Radio Stream and get some music playing.

"Radio Paradise" is the first station we'll add to get us off to a funky-retro start. To do that we use mpc add as follows:
$ cd $ mpc add http://stream-sd.radioparadise.com:8056

and to play it:
$ mpc play 1

You should now hear Radio Paradise from the Pi and see on the Terminal Window that the station is playing. If you don't hear anything try plugging a speaker or headphones into the Jack Socket.

Congratulations!!

Type mpc help to see other options available to you with mpc.

Other suggested radio streams are:
RTE radio 1: $ mpc add http://icecast2.rte.ie/ieradio1 Monkey Radio: $ mpc add http://76.73.3.245:6969 The Smooth Lounge: $ mpc add http://listen.radionomy.com/the-smooth-lounge Radio Nova: $ mpc add http://radionova128.media.vistatec.ie:80 Newstalk: $ mpc add http://newstalk.fmstreams.com:8080

Step 6: Python Program

Now we have a perfectly good Linux controllable Internet Radio.

But we don't want to stop there. We want to control the Radio from the Buttons on the Arduino and we want to see which Radio Station we're listening to on the LCD display.

To do that we need to write a Python Program running on the Pi that controls the Arduino.

Using nano or your favourite editor enter the following Python code.

Once entered and saved as radio.py , type
$ python radio. py &

You should now be able to control playback and station selection from the buttons on the Pi and see the selected station on the LCD.

Enjoy!!

Untitled file

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

import os
from nanpy import Arduino, Lcd

Arduino.pinMode(14, input)

lcd = Lcd([8,9,4,5,6,7],[16,2])            # Setup the LCD pins for the Sainsmart Shield

max_trax = 6                                    # It would be much better to determine this value from an mpc command

def getKey():                                    # Function to Translate the analogRead values from the Keys to a Command
   val = Arduino.analogRead(14)
   if val == 1023:
      return "NONE"
   elif val < 100:
      return "RIGHT"
   elif val < 150:
      return "UP"
   elif val < 330:
      return "DOWN"
   elif val < 510:
      return "LEFT"
   elif val < 750:
      return "SEL"
   else:
      return "KBD_FAULT"


def getTrack():
   L= [S.strip('\n') for S in os.popen('mpc').readlines()]    # Get the Track info from the stdout of the mpc command
   station = L[0][0:15]                                                         # Pick out the Station and Track info
   track = L[0][-16:-1]
   lcd.printString(16*" ", 0, 0)                                            # Send it out to the LCD Display
   lcd.printString(station, 0, 0)
   lcd.printString(16*" ", 0, 1)
   lcd.printString(track, 0, 1)
   print L
   print station
   print track

track_num = 1                                                     # Start off on Track number 1
os.system("mpc play "+str(track_num))            # Tell the OS to Play it
getTrack()                                                            # Send the Track info to the LCD

while True:
   key = getKey()                                                    # Do something if a key was pressed
   if key == "RIGHT":
      track_num += 1
      if track_num > max_trax:
         track_num = max_trax
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "LEFT":
      track_num -= 1
      if track_num < 1:
         track_num = 1
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "SEL":
      os.system("mpc toggle")
      getTrack() 

Jazzi_p merged this radio project with usualpanic.com web radio. The menu is added to display ip addess, set the audio port to hdmi/analog or auto. Also added the shutdown option. The volume keys are changed to left and right buttons and also it display's the volume status on the LCD, to change the stations we use up and bottom key. The Select key is used to activate the sub menu.

Untitled file

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

from datetime              import datetime 
from subprocess            import * 
from time                  import sleep, strftime 
from Queue                 import Queue 
from threading             import Thread
import os
from nanpy import Arduino, Lcd

Arduino.pinMode(14, input)

lcd = Lcd([8,9,4,5,6,7],[16,2])            # Setup the LCD pins for the Sainsmart Shield
lcd.printString("Jess's Web Radio",0,0)
lcd.printString("Loading" + "."*3,0,1)
sleep(5)
max_trax = 74
x = 1
loop_menu = 1
loop_radio = 1

def display_ipaddr(): 
   show_wlan0 = "ip addr show wlan0 | cut -d/ -f1 | awk '/inet/ {printf \"w%15.15s\", $2}'" 
   show_eth0  = "ip addr show eth0  | cut -d/ -f1 | awk '/inet/ {printf \"e%15.15s\", $2}'" 
   ipaddr = run_cmd(show_eth0) 
   if ipaddr == "": 
      ipaddr = run_cmd(show_wlan0) 
   lcd.printString('IP Address:',0,0)
   lcd.printString(ipaddr,0,1)
   sleep(2)

def displaymenu():    
    if x==1:
        lcd.printString("1. Display      ",0,0)
        lcd.printString("   IP Address   ",0,1)
    elif x==2:
        lcd.printString("2. Audio Output ",0,0)
        lcd.printString("   to hdmi Port ",0,1)
    elif x==3:
        lcd.printString("3. Audio Output ",0,0)
        lcd.printString("  to Analog port",0,1)
    elif x==4:
        lcd.printString("4. Audio Output ",0,0)
        lcd.printString("  Auto Sel. Port",0,1)
    elif x==5:
        lcd.printString("5. Reload the   ",0,0)
        lcd.printString("   Playlist     ",0,1)
    elif x==6:
        lcd.printString("6. ShutDown     ",0,0)
        lcd.printString("   the System   ",0,1)
    else:
        lcd.printString("7. Exit to      ",0,0)
        lcd.printString("   Main Menu    ",0,1)

def load_playlist(): 
   output = run_cmd("mpc clear") 
   output = run_cmd("/home/pi/radio_playlist.sh") 
                             
def run_cmd(cmd): 
   p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) 
   output = p.communicate()[0] 
   return output

def getKey():                             
   val = Arduino.analogRead(14)
   if val == 1023:
      return "NONE"
   elif val < 100:
      return "RIGHT"
   elif val < 150:
      return "UP"
   elif val < 330:
      return "DOWN"
   elif val < 510:
      return "LEFT"
   elif val < 750:
      return "SEL"
   else:
      return "KBD_FAULT"

load_playlist()
def getTrack():
   #L= [S.strip('\n') for S in os.popen('mpc').readlines()]        # Get the Track info from the stdout of the mpc command
   output = run_cmd("mpc current")
   station = output [0:16]                                           # Pick out the Station and Track info
   track =  output [-17:-1]
   lcd.printString(station + " "*(16 - len(station)), 0, 0)
   lcd.printString(track + " "*(16 - len(track)), 0, 1)

track_num = 1                                                     # Start off on Track number 1
os.system("mpc play "+str(track_num))                             # Tell the OS to Play it

while loop_radio == 1:
   getTrack()
   loop_menu = 1
   x = 1
   key = getKey()
   if key == "UP":
      track_num += 1
      if track_num > max_trax:
         track_num = max_trax
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "DOWN":
      track_num -= 1
      if track_num < 1:
         track_num = 1
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "SEL":
      while loop_menu == 1:
           displaymenu()
           key = getKey()
           if key == "RIGHT":
                  os.system("mpc volume +2")
                  lcd.printString(16*" ", 0, 0)
                  lcd.printString(16*" ", 0, 1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME UP:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)
           elif key == "LEFT":
                  os.system("mpc volume -2")
                  lcd.printString(16*" ",0,0)
                  lcd.printString(16*" ", 0,1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME DOWN:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)
           elif key == "UP":
                 if x <= 1:
                     x = 7
                 else:
                    x = x - 1
           elif key == "DOWN":
                 if x >= 7:
                      x = 1
                 else:
                     x = x + 1       
           elif key == "SEL":
                 if x == 1:
                    display_ipaddr()
                    sleep(1)
               elif x == 2:
                     output = run_cmd("amixer -q cset numid=3 2")
                     lcd.printString("Audio OUT-->HDMI", 0, 0)
                     lcd.printString("output ", 0, 1)
                                sleep(.5)
                 elif x == 3:
                     output = run_cmd("amixer -q cset numid=3 1")
                     lcd.printString("Audio OUT->Analog", 0, 0)
                    lcd.printString("output ", 0, 1)
                                sleep(.5)
                 elif x == 4:
                     output = run_cmd("amixer -q cset numid=3 0")
                     lcd.printString("Audio OUT->  Auto", 0, 0)
                     lcd.printString("output ", 0, 1)
                                sleep(.5)
                 elif x == 5:
                     load_playlist()       
                        os.system('mpc play 1')
                 elif x == 6:
                     lcd.printString("Good Bye         ", 0, 0)
                     lcd.printString("Have a Nice Day  ", 0, 1)
                                output = run_cmd("mpc clear")
                                output = run_cmd("sudo shutdown now")
                elif x == 7:
                     loop_menu = 0
                                getTrack()
                                break
   elif key == "RIGHT":
                  os.system("mpc volume +2")
                  lcd.printString(16*" ",0,0)
                  lcd.printString(16*" ", 0,1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME UP:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)
   elif key == "LEFT":
                 os.system("mpc volume -2")
                  lcd.printString(16*" ", 0, 0)
                  lcd.printString(16*" ", 0, 1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME DOWN:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)


Code

file_6775.pythonPython
import os
from nanpy import Arduino, Lcd

Arduino.pinMode(14, input)

lcd = Lcd([8,9,4,5,6,7],[16,2])            # Setup the LCD pins for the Sainsmart Shield

max_trax = 6                                    # It would be much better to determine this value from an mpc command

def getKey():                                    # Function to Translate the analogRead values from the Keys to a Command
   val = Arduino.analogRead(14)
   if val == 1023:
      return "NONE"
   elif val < 100:
      return "RIGHT"
   elif val < 150:
      return "UP"
   elif val < 330:
      return "DOWN"
   elif val < 510:
      return "LEFT"
   elif val < 750:
      return "SEL"
   else:
      return "KBD_FAULT"


def getTrack():
   L= [S.strip('\n') for S in os.popen('mpc').readlines()]    # Get the Track info from the stdout of the mpc command
   station = L[0][0:15]                                                         # Pick out the Station and Track info
   track = L[0][-16:-1]
   lcd.printString(16*" ", 0, 0)                                            # Send it out to the LCD Display
   lcd.printString(station, 0, 0)
   lcd.printString(16*" ", 0, 1)
   lcd.printString(track, 0, 1)
   print L
   print station
   print track

track_num = 1                                                     # Start off on Track number 1
os.system("mpc play "+str(track_num))            # Tell the OS to Play it
getTrack()                                                            # Send the Track info to the LCD

while True:
   key = getKey()                                                    # Do something if a key was pressed
   if key == "RIGHT":
      track_num += 1
      if track_num > max_trax:
         track_num = max_trax
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "LEFT":
      track_num -= 1
      if track_num < 1:
         track_num = 1
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "SEL":
      os.system("mpc toggle")
      getTrack() 
file_6776.pythonPython
from datetime              import datetime 
from subprocess            import * 
from time                  import sleep, strftime 
from Queue                 import Queue 
from threading             import Thread
import os
from nanpy import Arduino, Lcd

Arduino.pinMode(14, input)

lcd = Lcd([8,9,4,5,6,7],[16,2])            # Setup the LCD pins for the Sainsmart Shield
lcd.printString("Jess's Web Radio",0,0)
lcd.printString("Loading" + "."*3,0,1)
sleep(5)
max_trax = 74
x = 1
loop_menu = 1
loop_radio = 1

def display_ipaddr(): 
   show_wlan0 = "ip addr show wlan0 | cut -d/ -f1 | awk '/inet/ {printf \"w%15.15s\", $2}'" 
   show_eth0  = "ip addr show eth0  | cut -d/ -f1 | awk '/inet/ {printf \"e%15.15s\", $2}'" 
   ipaddr = run_cmd(show_eth0) 
   if ipaddr == "": 
      ipaddr = run_cmd(show_wlan0) 
   lcd.printString('IP Address:',0,0)
   lcd.printString(ipaddr,0,1)
   sleep(2)

def displaymenu():    
    if x==1:
        lcd.printString("1. Display      ",0,0)
        lcd.printString("   IP Address   ",0,1)
    elif x==2:
        lcd.printString("2. Audio Output ",0,0)
        lcd.printString("   to hdmi Port ",0,1)
    elif x==3:
        lcd.printString("3. Audio Output ",0,0)
        lcd.printString("  to Analog port",0,1)
    elif x==4:
        lcd.printString("4. Audio Output ",0,0)
        lcd.printString("  Auto Sel. Port",0,1)
    elif x==5:
        lcd.printString("5. Reload the   ",0,0)
        lcd.printString("   Playlist     ",0,1)
    elif x==6:
        lcd.printString("6. ShutDown     ",0,0)
        lcd.printString("   the System   ",0,1)
    else:
        lcd.printString("7. Exit to      ",0,0)
        lcd.printString("   Main Menu    ",0,1)

def load_playlist(): 
   output = run_cmd("mpc clear") 
   output = run_cmd("/home/pi/radio_playlist.sh") 
                             
def run_cmd(cmd): 
   p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT) 
   output = p.communicate()[0] 
   return output

def getKey():                             
   val = Arduino.analogRead(14)
   if val == 1023:
      return "NONE"
   elif val < 100:
      return "RIGHT"
   elif val < 150:
      return "UP"
   elif val < 330:
      return "DOWN"
   elif val < 510:
      return "LEFT"
   elif val < 750:
      return "SEL"
   else:
      return "KBD_FAULT"

load_playlist()
def getTrack():
   #L= [S.strip('\n') for S in os.popen('mpc').readlines()]        # Get the Track info from the stdout of the mpc command
   output = run_cmd("mpc current")
   station = output [0:16]                                           # Pick out the Station and Track info
   track =  output [-17:-1]
   lcd.printString(station + " "*(16 - len(station)), 0, 0)
   lcd.printString(track + " "*(16 - len(track)), 0, 1)

track_num = 1                                                     # Start off on Track number 1
os.system("mpc play "+str(track_num))                             # Tell the OS to Play it

while loop_radio == 1:
   getTrack()
   loop_menu = 1
   x = 1
   key = getKey()
   if key == "UP":
      track_num += 1
      if track_num > max_trax:
         track_num = max_trax
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "DOWN":
      track_num -= 1
      if track_num < 1:
         track_num = 1
      os.system("mpc play " + str(track_num))
      getTrack()
   elif key == "SEL":
      while loop_menu == 1:
           displaymenu()
           key = getKey()
           if key == "RIGHT":
                  os.system("mpc volume +2")
                  lcd.printString(16*" ", 0, 0)
                  lcd.printString(16*" ", 0, 1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME UP:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)
           elif key == "LEFT":
                  os.system("mpc volume -2")
                  lcd.printString(16*" ",0,0)
                  lcd.printString(16*" ", 0,1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME DOWN:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)
           elif key == "UP":
                 if x <= 1:
                     x = 7
                 else:
                    x = x - 1
           elif key == "DOWN":
                 if x >= 7:
                      x = 1
                 else:
                     x = x + 1       
           elif key == "SEL":
                 if x == 1:
                    display_ipaddr()
                    sleep(1)
               elif x == 2:
                     output = run_cmd("amixer -q cset numid=3 2")
                     lcd.printString("Audio OUT-->HDMI", 0, 0)
                     lcd.printString("output ", 0, 1)
                                sleep(.5)
                 elif x == 3:
                     output = run_cmd("amixer -q cset numid=3 1")
                     lcd.printString("Audio OUT->Analog", 0, 0)
                    lcd.printString("output ", 0, 1)
                                sleep(.5)
                 elif x == 4:
                     output = run_cmd("amixer -q cset numid=3 0")
                     lcd.printString("Audio OUT->  Auto", 0, 0)
                     lcd.printString("output ", 0, 1)
                                sleep(.5)
                 elif x == 5:
                     load_playlist()       
                        os.system('mpc play 1')
                 elif x == 6:
                     lcd.printString("Good Bye         ", 0, 0)
                     lcd.printString("Have a Nice Day  ", 0, 1)
                                output = run_cmd("mpc clear")
                                output = run_cmd("sudo shutdown now")
                elif x == 7:
                     loop_menu = 0
                                getTrack()
                                break
   elif key == "RIGHT":
                  os.system("mpc volume +2")
                  lcd.printString(16*" ",0,0)
                  lcd.printString(16*" ", 0,1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME UP:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)
   elif key == "LEFT":
                 os.system("mpc volume -2")
                  lcd.printString(16*" ", 0, 0)
                  lcd.printString(16*" ", 0, 1)
                  output = run_cmd("mpc volume")
                  lcd.printString("VOLUME DOWN:", 0, 0)
                  lcd.printString(output, 5, 1)
                        sleep(.25)
                        lcd.printString(16*" ",0,0)
                        lcd.printString(16*" ",0,1)

Comments

Similar projects you might like

Unlock your door with a knock

Project tutorial by Ashraf Nabil

  • 15,613 views
  • 10 comments
  • 50 respects

DIY Relay Outlet Arduino

Project tutorial by Ben Jones

  • 20,937 views
  • 16 comments
  • 24 respects

Uber Home Automation

Project in progress by Eric Tsai

  • 25,862 views
  • 3 comments
  • 113 respects

Magoo

Project in progress by 4 developers

  • 5,305 views
  • 12 comments
  • 27 respects

Arduino to Excel using V-USB

Project tutorial by Ray Burnette

  • 33,002 views
  • 6 comments
  • 32 respects

Magic Morse on Arduino

Project tutorial by Ray Burnette

  • 19,523 views
  • 7 comments
  • 23 respects
Add projectSign up / Login