Over the last couple of months I have been contemplating building a music center for use in a recreational area at home. The options are always so many, with OpenELEC, Volumio and many more. I finally decided on Volumio as the software is starting to mature quite nicely and I have a couple of spare RPi’s to my use.
the build:
- Volumio from: http://volumio.org
- USB LCD device from: Manufacturer: Lcdmod Kit (Currently looking for a new supplier!)
- Case
installation steps:
- sudo su
- amixer cset numid=3 1
- apt-get update
- apt-get install lcdproc
- apt-get install python-setuptools
- easy_install lcd2usb
script:
radio.py
#!/usr/bin/python from lcd2usb import LCD, SMILE_SYMBOL from subprocess import Popen, PIPE from multiprocessing import Process import multiprocessing, os, subprocess, datetime, time, logging lcd = LCD() lcd.set_brightness(50) lcd.set_contrast(255) lcd.write(" ",0,0) lcd.write(" ",0,1) time.sleep(0.3) ; lcd.write("A",0,0) ; time.sleep(0.3) ; lcd.write("u",1,0) ; time.sleep(0.3) ; lcd.write("b",2,0) ; time.sleep(0.3) ; lcd.write("r",3,0) ; time.sleep(0.3) ; lcd.write("e",4,0) ; time.sleep(0.3) lcd.write("y",5,0) ; time.sleep(0.3) ; lcd.write("'",6,0) ; time.sleep(0.3) ; lcd.write("s",7,0) ; time.sleep(0.3) ; lcd.write(" ",8,0) ; time.sleep(0.3) ; lcd.write("P",9,0) ; time.sleep(0.3) ; lcd.write("i",10,0) time.sleep(0.3) ; lcd.write("R",11,0) ; time.sleep(0.3) ; lcd.write("a",12,0) ; time.sleep(0.3) ; lcd.write("d",13,0) ; time.sleep(0.3) ; lcd.write("i",14,0) ; time.sleep(0.3) ; lcd.write("o",15,0) time.sleep(1) lcd.write("S",0,1) ; time.sleep(0.3) ; lcd.write("t",1,1) ; time.sleep(0.3) ; lcd.write("a",2,1) ; time.sleep(0.3) ; lcd.write("r",3,1) ; time.sleep(0.3) ; lcd.write("t",4,1) ; time.sleep(0.3) ; lcd.write("u",5,1) time.sleep(0.3) ; lcd.write("p",6,1) ; time.sleep(0.3) ; lcd.write(" ",7,1) ; time.sleep(0.3) ; lcd.write("S",8,1) ; time.sleep(0.3) ; lcd.write("e",9,1) ; time.sleep(0.3) ; lcd.write("q",10,1) ; time.sleep(0.3) lcd.write("u",11,1) ; time.sleep(0.3) ; lcd.write("e",12,1) ; time.sleep(0.3) ; lcd.write("n",13,1) ; time.sleep(0.3) ; lcd.write("c",14,1) ; time.sleep(0.3) ; lcd.write("e",15,1) time.sleep(0) lcd.clear() lcd.goto(0, 0) lcd.write("") BLINK_SMILE = bytearray([0x00, 0x00, 0x0a, 0x00, 0x11, 0x0e, 0x00, 0x00]) #Write startdate to radio.log: dataFile = open('radio.log', 'w') date = datetime.datetime.now().strftime("%H:%M:%S") dataFile.write('Startup time: '+(date)+'\n') dataFile.close() #Define VOLUME Module: def volume(): volume_old = "" volume = Popen(["mpc","volume"], stdout=PIPE) volume_new, retval = volume.communicate() if not volume_new == volume_old: lcd.goto(6, 0) vol, vol_pers = volume_new.split('volume:') lcd.write("Vol:", 8, 0) lcd.write(vol_pers, 12, 0) volume_old = volume_new # Display the Date: def date_loop(): while(1): lcddate = datetime.datetime.now().strftime("%H:%M") lcd.write(lcddate,0 ,0) lcd.define_char(0, BLINK_SMILE) time.sleep(0.3) lcd.define_char(0, SMILE_SYMBOL) lcd.write('', 6, 0) date = datetime.datetime.now().strftime("%H:%M:%S") dataFile = open('radio.log', 'a') dataFile.write('Working...: '+(date)+'\n') dataFile.close() time.sleep(60) # Display the Name of the Song and scroll Left to Right, then Right to Left: def name_loop(): playing_old = "" volume_old = "" i = 0 while(1): line1 = Popen(["mpc","current","-f","%title%"], stdout=PIPE) playing, retval = line1.communicate() strlen = len(playing) - 16 revlen = strlen if not playing_old == playing: date = datetime.datetime.now().strftime("%H:%M:%S") dataFile = open('radio.log', 'a') dataFile.write('Song/Radio Changed...: '+(date)+'\n') dataFile.write('New Songname: '+(playing)+'\n') dataFile.close() while i < (strlen): lcd.write(" ",5,0) lcd.write(" Vol:",7,0) for i in range(len(playing) - 15): lcd.goto(0, 1) lcd.write(playing[i:i + 16]) # write 16 chars to display volume() time.sleep(0.5) else: while i > 1: lcd.write(" ",5,0) lcd.write(" Vol:",7,0) for i in reversed(range(len(playing) -16)): lcd.goto(0, 1) lcd.write(playing[i:i - (revlen)]) volume() i = (i + 1) time.sleep(0.5) else: lcd.write("o:----+==+----:o",0,1) lcd.write(" ",5,0) lcd.write(" Vol:",7,0) time.sleep(2) if __name__=='__main__': nameproc = multiprocessing.Process(target=name_loop) dateproc = multiprocessing.Process(target=date_loop) nameproc.start() dateproc.start() nameproc.join() dateproc.join() time.sleep(1)
Aubrey,
I have read your item at Volumio.org about your project. The funny is that iam doing the samething, a project based on Volumio
Last year bought a Raspi and tarted with the projects by Bob Brathome (great tutorials!) .I made de Adafruit and the 20×4 rotary version.
Besides that i have used the Pi plate radio, MusicBox and several other scripts/images and even your script with the Adafruit Pi Plate!
Finaly I decide to use Volumio as an “out of the box” OS with mpd and Web gui, so i could concentrate on learning Python and get all the
hardware working and make muy own script.
HARDWARE:
LCD display 16×2 (I2C) to show song/station info (maybe replace it with a OLED version)
IR-sensor
Rotary encoder (volume, stations and shutdown)
Future:
DAC (maybe)
Amplifier
Speakers
…..and of course a nice case
SOFTWARE:
Volumio 1.4 beta
LCDproc, i use a cheap lcd-backpack (LM1602 IIC) and had to find a modded driver to get it working.
Lirc, the remote is working but it doesnt react so good, it skips stations etc. so some tunning has to be done (no hurry)
I started testing with “LCDproc” untill i found this script:
http://www.forum-raspberrypi.de/Thread-mpd-und-lcd-16×2-anzeige
LCDproc has a widget for scrolling text!
I have added python-mpd2 so it is much easier to control MPC and retrieve songinfo!
So far….my script isnt finished and isnt perfect.
I am reading/learing about Python, Threads, Events etc. and with some inspiration from the scripts by http://www.bobrathbone.com,
http://usualpanic.com/2013/05/raspberry-pi-plate-internet-radio/,
http://thisoldgeek.blogspot.nl/2014/06/back-in-black-diy-raspberry-pi-boombox.html
to improve my skills and finally my script.
Kind regards Harold
LikeLike
#!/usr/bin/env python
# 2014-08-18 Volumebar test
import telnetlib
import time
import os
import subprocess
import mpd
import sys
import time
import re
from subprocess import Popen, PIPE, STDOUT
from mpd import MPDClient, MPDError, CommandError
from time import sleep, clock
client = MPDClient() # create client object
client.timeout = 10 # network timeout in seconds (floats allowed), default: None
client.idletimeout = None # timeout for fetching the result of the idle command is handled seperately, default: None
client.connect(“localhost”, 6600) # connect to localhost:6600
#client.crossfade(2) # testing
host=’127.0.0.1′;
port=’13666′;
data = “”
display=80 # 16 character x 5 dot = 80 pixels Volumebar
#—————————————
# Commandline
#—————————————
def run_cmd(cmd):
p = subprocess.Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
output = p.communicate()[0]
return output
#—————————————
# MPC Data
#—————————————
def mpc_info():
#Mostly use it as a webradio.
#Problem, when status = STOP there is no song-info, I have to add an extra check!!
song=client.currentsong()
if ‘name’ in song:
Station = song[‘name’]
else:
if ‘pos’ in song:
Nr = song[‘pos’]
Station = ‘Station ‘+str(int(Nr)+1) # no station name
if ‘title’ in song:
SongTitle = song[‘title’]
else:
SongTitle = ‘altijd weer hetzelfde liedje’ # no song title
Title=Station+’: ‘+SongTitle
return Title
def mpc_status():
status=client.status()
Status=status[‘state’]
return Status
def mpc_volume():
status=client.status()
Vol = status[‘volume’]
#Vol =int(float( status[‘volume’])/100*display) # Volumebar
#Volume = str(Vol) # Volumebar
return Volume
def mpc_stations():
Stations=run_cmd(“mpc | head -2 | tail -1 | awk ‘{print $2}’ | cut -c 2-“)
return Stations
def wlan_ip():
ip = run_cmd(“ip addr show wlan0 | cut -d/ -f1 | awk ‘/inet / {print $2}'”)
return ip
##function doesnt work!?
#—————————————
# LcdProc Widgets
#—————————————
#make connection
tn = telnetlib.Telnet(host, port)
tn.write(“hello\r”);
#create screen
data += tn.read_until(“\n”);
tn.write(“screen_add mpc_screen\n”);
data += tn.read_until(“\n”);
#turn-off heartbeat
tn.write(“screen_set mpc_screen 1 -heartbeat off\n”);
data += tn.read_until(“\n”);
#create string
tn.write(“widget_add mpc_screen 1 string\n”);
data += tn.read_until(“\n”);
#create scroller
tn.write(“widget_add mpc_screen 2 scroller\n”);
data += tn.read_until(“\n”);
#create hbar
tn.write(“widget_add mpc_screen 3 hbar\n”);
data += tn.read_until(“\n”);
#—————————————
# Variabelen
#—————————————
#ip_addr= wlan_ip()
#ip_addr = run_cmd(“ip addr show wlan0 | cut -d/ -f1 | awk ‘/inet / {print $2}'”) #doesnt work
## oldfashion commandline because function wlan_ip() doesnt work!!
cmd1 = “ip addr show wlan0 | cut -d/ -f1 | awk ‘/inet / {print $2}'”
process = subprocess.Popen(cmd4, stdout=subprocess.PIPE , shell=True)
os.waitpid(process.pid, 0)[1]
ip_addr = process.stdout.read().strip()
#when wifi-dongle has been removed this clause doesnt work!!
if ip_addr == ” :
ip_addr = ‘Geen Wifi’
else: ip_adrr=ip_addr
#At my workplace we use DHCP so the IP-adres changes daily
#show ip-addres on line 1 for 5 sec because my phone cant use volumio.local
tn.write(“widget_set mpc_screen 1 1 1 \”%s \” \n” % (ip_addr));
data += tn.read_until(“\n”);
time.sleep(5);
#run_cmd(“mpc volume=85″) #commandline
#client.setvol(85) #python-mpd2
volume = ”
volume_2 = ”
#—————————————
# Main
#—————————————
var = 1;
while var == 1 :
scroller = mpc_info()
volume = mpc_volume()
status = mpc_status()
#stations = mpc_stations()
cmd7 = “mpc | head -2 | tail -1 | awk ‘{print $2}’ | cut -c 2-” #gets the number of stations from mpc
process = subprocess.Popen(cmd7, stdout=subprocess.PIPE , shell=True)
os.waitpid(process.pid, 0)[1]
stations = process.stdout.read().strip()
if volume volume_2:
tn.write(“widget_set mpc_screen 1 1 1 \”VOLUME: %s \” \n” % (volume));
data += tn.read_until(“\n”);
mpc_vol2=mpc_vol
time.sleep(.5)
###TESTING VOLUME BAR
# show volumebar old value
#tn.write(“widget_set mpc_screen 3 1 1 %s \n” % (volume_2));
#data += tn.read_until(“\n”);
#time.sleep(.5)
# show volumebar new value
#tn.write(“widget_set mpc_screen 3 1 1 %s \n” % (volume));
#data += tn.read_until(“\n”);
#volume_2=volume
#time.sleep(.9)
# show volumebar value=0
#tn.write(“widget_set mpc_screen 3 1 1 0 \n”);
#data += tn.read_until(“\n”);
else:
tn.write(“widget_set mpc_screen 1 1 1 \”%s %s \” \n” % (status,stations));
data += tn.read_until(“\n”);
tn.write(“widget_set mpc_screen 2 1 2 16 2 m 8 \”%s \” \n” % (scroller));
data += tn.read_until(“\n”);
time.sleep(.5)
LikeLike
Thank you, Harold for your major input. I have ‘some’ problems with the RPi’s multitasking abilities and find that over time the LCD display gets corrupted… The think is that the script I supply is the best I can do 😉 – Please send a link of your builds as I will post it soonest!
PS – Bob Brathome’s stuff is DA BOMB!
Cheers out of Cape Town, South Africa
LikeLike