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.
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!
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:
#!/usr/bin/python # -*- 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.setmode(GPIO.BCM) 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(datetime.now().strftime('%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 lcd.message(message[:16]) time.sleep(1) for i in range(raknare-1): # Moving first charachter to the end of the string and then # writes the first 16 chars to LCD lcd.clear() primus = message[:1] message = message[1:] + primus lcd.message(datetime.now().strftime('%y%m%d %H:%M:%S \n')) lcd.message(message[:16]) time.sleep(intervall) return def run_cmd(cmd): #Preparing to rund shell commands p = Popen(cmd, shell=True, stdout=PIPE) output = p.communicate() return output lcd.clear() #replacing åäö message = convertoutString(" Internetradio! \n Busk ") #print(message) lcd.message(message) time.sleep(1) lcd.clear() #Getting radio station information from the MPD server cmd = "mpc current | cut -d \":\" -f1" lcd.clear() while 1: #Sending the mpc information to the LCD mpcstatus = run_cmd(cmd) mpcstatus = convertoutString(mpcstatus) lcd.clear() lcd.message(datetime.now().strftime('%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') time.sleep(0.1) lcd.clear() if (GPIO.input(6)==False): os.system('mpc next') time.sleep(0.1) lcd.clear() 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") lcd.clear() lcd.message(mpcvolume) time.sleep(0.5) lcd.clear() 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") lcd.clear() lcd.message(mpcvolume) time.sleep(0.5) lcd.clear()