Internet Radio – Buttons and Usb sound card

I have made some progress with the Raspberry Pi Internet Radio. It is time to get a good casing and mount the hardware!

The audio from an Raspberry Pi is of fairly low quality with very high noise and low volume. Crappy sound is a no no so I bought a usb sound card, Roccat Juke. It worked right out of the box. Just plugged it in at booted up the Pi.

A Roccat Juke usb soundcard attached to a Raspberry Pi 2.
Roccat Juke Usb sound card

Unfortunately mpc could no longer change the volume. After googling around I tried using the alsa command line mixer “amixer” to change volume. It took a lot of trials and errors before i got the hang of it. “Man amixer” gave a lot of info but i couldn’t sort out increasing/decreasing the volume by steps. The answer was to set the volume step to x+/x- instead of +x/-x. Rather obvious, but it took a long time to figure that out.

I added 5 buttons connected to GPIO pins. So no I can control volume and change radio station!

Rasberry Pi 2, a usb sound card and a breadboard
Pi and breadbord


An LCD-display on a breadboard displaying date and channal on an internet radio
Internet Radio display

I gave up on scrolling text. Scrolling through 45 characters with a rate of 0.3 chars/second takes  13.5 seconds. Since the routine that listens for button presses is in the same continuous loop as the scrolling routine I had to ditch the scrolling. Now I have to find a better solution. For the time being I will only show the station name and the date.

I guess that running threads is a better solution. Learning about threads have to wait until I have found a case for the radio and mounted everything.

Swedish radio have channels  names that often are longer than 16 characters. Ex. “Sveriges Radio P1”. Since the three channels i listens most to, P1, P2 and P3, displays as “Sveriges Radio P” I chose to remove “Sveriges Radio” from the string.

To get the volume information from amixer I am using a loooonnnnggg bash command. Not pretty!

"amixer -c 1 -- get Headphone Playback | tail -n 1 | cut -d \"[\" -f1 | cut -d \":\" -f2 | cut -d \" \" -f3")

If someone has a more elegant solution I would be grateful if you could point me in the right direction. (I guess i have to learn awk ;-D)




The source code to my internet radio:

# -*- coding: utf-8 -*-
# Example code from Adafruit that I used as a template
# for displaying info from mpc/mpd streaming
import os
import time
import Adafruit_CharLCD as LCD
import RPi.GPIO as GPIO
from subprocess import *
from datetime import datetime


GPIO.setup(5, GPIO.IN)
GPIO.setup(6, GPIO.IN)
GPIO.setup(13, GPIO.IN)
GPIO.setup(19, GPIO.IN)

# Raspberry Pi pin configuration:
lcd_rs        = 27  # Note this might need to be changed to 21 for older revision Pi's.
lcd_en        = 22
lcd_d4        = 25
lcd_d5        = 24
lcd_d6        = 23
lcd_d7        = 18
lcd_backlight = 4

# Define LCD column and row size for 16x2 LCD.
lcd_columns = 16
lcd_rows    = 2

lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7,
                                                        lcd_columns, lcd_rows, lcd_backlight)
showClock = True

def convertoutString(inString):
# Replaces åäö and ÅÄÖ with aa ae oe
   outString = inString
   outString = outString.replace("Å", "Aa")
   outString = outString.replace("å", "aa")
   outString = outString.replace("Ä", "Ae")
   outString = outString.replace("ä", "ae")
   outString = outString.replace("Ö", "Oe")
   outString = outString.replace("ö", "oe")
   outString = outString.replace("Sveriges Radio ", "")
   return outString

def scrollDisplay(text, intervall):
    # preparing the text so the lenght is a multiple of 16. 
    # The extra blank is for to be shure that there is a space between 
    # the begging and end of the text when scrolling.
    # To ensure that strings longer than 40 char is displayed correct
    # I only display the first 16 char
    message = text
    message = message + " "
    raknare = len(message) + ((16-len(message) % 16))
    lcd.message('%y%m%d %H:%M:%S \n'))

    # Adding blanks to make the string a multiple of 16
    # This assures that the scrolled line is empty before
    # iterating again
    message = message + " " * raknare
    for i in range(raknare-1):
    # Moving first charachter to the end of the string and then
    # writes the first 16 chars to LCD
        primus = message[:1]
        message = message[1:] + primus
        lcd.message('%y%m%d %H:%M:%S \n'))

def run_cmd(cmd):
    #Preparing to rund shell commands
    p = Popen(cmd, shell=True, stdout=PIPE)
    output = p.communicate()[0]
    return output

#replacing åäö
message = convertoutString(" Internetradio! \n      Busk      ")


#Getting radio station information from the MPD server
cmd = "mpc current | cut -d \":\" -f1"


while 1:
#Sending the mpc information to the LCD
  mpcstatus = run_cmd(cmd)
  mpcstatus = convertoutString(mpcstatus)
  lcd.message('%y%m%d %H:%M:%S \n') + mpcstatus)
  #scrollDisplay(mpcstatus, 0.3)

  # Listening for button pressed
  if (GPIO.input(5)==False):
    os.system('mpc prev')

  if (GPIO.input(6)==False):
    os.system('mpc next')

  if (GPIO.input(13)==False):
    os.system('amixer -c 1 -- set Headphone Playback 10-')
    mpcvolume = "Volym: " + run_cmd("amixer -c 1 -- get Headphone Playback | tail -n 1 | cut -d \"[\" -f1 | cut -d \":\" -f2 | cut -d \" \" -f3")

  if (GPIO.input(19)==False):
    os.system('amixer -c 1 -- set Headphone Playback 10+')
    mpcvolume = "Volym: " + run_cmd("amixer -c 1 -- get Headphone Playback | tail -n 1 | cut -d \"[\" -f1 | cut -d \":\" -f2 | cut -d \" \" -f3")


Leave a Reply

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