Raspberry Pi – Old-Timer case build – Volumio and USBLCD.

3

August 8, 2014 by aubreykloppers

Raspberry Pi – Old-Timer case build – Volumio and USBLCD.

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)

Advertisements

3 thoughts on “Raspberry Pi – Old-Timer case build – Volumio and USBLCD.

  1. Harold says:

    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

    Like

  2. Harold says:

    #!/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)

    Like

  3. 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

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: