Archive for October, 2016

So now the real learning starts. I need to decide what I want the box to do, how to do it and then build it. Easy huh? The code that I reference here is also in my GitHub repo, it’s likely that these snippets get superseded as I figure out how the stuff works. I’m also using the excellent Fritzing to figure stuff out with the wiring, so it may pay to look at that as well if you want to design your own parts.

The other thing to note is that my switch circuits run from the GPIO Pin to GND – making the Pins use the PULL UP resistor in the Python code. If I had run the switches from Pin to 3.3V, PULL DOWN resistors would need to be declared.

As we are access the GPIO, all the python code will need to be run under sudo to gain access.

Use Case 1 – We must be able to turn the player On and Off via a switch

OK so after a lot of Googling it becomes apparent that all the normal method to deal with this – add on boards with switches – are inappropriate because of the X400. As the X400 provides power to the Pi, none of the aftermarket solutions will work.

Use Case 1 (Amended) – We must be able to turn the player On and Off

The answer (in theory) is to use the ‘reset’ switch header as an ON and to add a switch to the GPIO with some code to handle the OFF part.

There is a P6 header on the RPi boards that allows you to reset the device when it is shorted. While absolutely not suitable for a clean shutdown, it will restart the box if it is in a powered but shutdown state. The issue is that this header isn’t populated, so we will need to add some pins prior to connecting a switch of some kind. This means soldering the pin header to the board itself (gulp) and then connecting the new header pins to a switch. So that’s the ON part sorted.

For OFF, connecting a momentary switch to one of the GPIO Pins and then detecting it with some Python to trigger the appropriate shutdown command appears to be the easiest and safest method. This protects the SD card and ensures that everything is clean before shutting down. As power is still applied, we can use the new ON switch to restart when required.

usecase1
Simple shutdown switch
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Assumes switch is connected to GND - so uses PULL UP

import subprocess
import time
import os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

button = 20

GPIO.setup(button, GPIO.IN, GPIO.PUD_UP)

while True:
 button_state = GPIO.input(button)
 if button_state == GPIO.HIGH:
  pass
 else:
  print ("Shutdown")
 #os.system("sudo shutdown -h now") # Send shutdown command to os
 time.sleep(0.5)

Use Case 2 – Play, Pause, Next, Previous & Stop

So after some more Googling it seems that I can use the MPC client (the Music Player Daemon command line bit) to control playback from the command line. As Volumio includes this part, simply issuing commands allows us to control things via the terminal.

 mpc play

mpc pause

mpc stop

Issuing just

mpc

Will return a list of commands you can use.

So we’re back to the GPIO with an additional 5 4 momentary switches, each of which then uses Python to issue the appropriate mpc command.

** UPDATE **

Oops. While working on building the device modes (see Part 5), I realised that GPIO Pin 17 (Board Pin11) is already claimed by the IR receiver on the X400. This means that I have now lost my ‘play’ button. The solution is to remove GPIO 17 from the code and change the GPIO 27 (Board Pin13) from

mpc pause

To

mpc toggle

Which, unsurprisingly, toggles play/pause. The other advantage is 1 less button to fit somewhere on the final case!

usecase2

Play/Pause, Stop, Previous & Next

Python Code:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Assumes switch is connected to GND - so uses PULL UP

import os
import subprocess
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

#Define GPIO Pins that have buttons
play_pause = 27 #Play/pause mpc toggle
stop = 22 #mpc stop
prev_track = 18 #mpc prev
next_track = 23 #mpc next

power_off = 20 # sudo halt now

#Configure PULL Up and pin connections
GPIO.setup(play_pause, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(stop, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(prev_track, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(next_track, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(power_off, GPIO.IN, GPIO.PUD_UP)

#Begin loop to wait for button press
while True:
 if GPIO.input(play_pause) == GPIO.LOW:
  print ("Play/Pause")
  subprocess.call(['mpc', 'toggle' ])
 elif GPIO.input(stop) == GPIO.LOW:
  print ("Stop")
  subprocess.call(['mpc', 'stop' ])
 elif GPIO.input(prev_track) == GPIO.LOW:
  print ("Previous")
  subprocess.call(['mpc', 'prev' ])
 elif GPIO.input(next_track) == GPIO.LOW:
  print ("Next")
  subprocess.call(['mpc', 'next' ])
 elif GPIO.input(power_off) == GPIO.LOW:
  print ("Shutdown")
  #os.system("sudo shutdown -h now") # Send shutdown command to os
 else:
  #print ("Nothing")
  pass

 time.sleep(0.25)
Parts List (so far):

Wire – whatever is appropriate to you setting!

2x 1 row pin headers

Momentary contact switch x1 – for ON

Momentary contact switch x1 – for OFF

Momentary contact switch x54 – Media shuttle commands

Links & Refs:

GitHub: https://github.com/nwootton/HiFiPi

Reset Switch – http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi

Advertisements

In the previous two parts I’ve looked at building something a little more capable for audio playback. What I’ve built works brilliantly with headphones, but isn’t in any way  suitable for use by ‘normal’ people and definitely not with small children around.

So I decided to look at following the herd and try to build the new music player in an old enclosure. After much eBay hunting, I found several nice radios that could be refactored. My issue with them was the size.

If I want to build a stereo radio I need 2 speakers (obvious huh?), but most of these radios are mono, so adding a second speaker either means running two tiny speakers or modifying the case to allow for a second speaker. Either way two speakers take up space and the X400 is already considerably bigger than the HiFiBerry or equivalent board.

If I go the whole hog and try to include some form of interface/screen then a repurposed radio chassis is completely unsuitable. I can try and find a large (think valve type) radio from before the modern radio. These are generally quite large but come with wooden cases that can make the end product look gorgeous. This scenario gives me the opposite problem. The end product would be far too big to sit in the kitchen, it would be more appropriate for the dining room or somewhere as a centre-piece.

The X400 is rated to drive 2x 20W speakers, I had originally planned to buy some car speakers from eBay once I had the rough dimensions of the enclosure I wanted them to go into. So everything really hung off of finding a decent box to put it in.

Being a total novice at this stuff, I decided that it makes more sense to try and build something, learning as I go. I’d have to be prepared to completely get it wrong, throw away stuff and to start again. Once I’d figured things out, maybe then I could build the ‘final’ version.

With this in mind I decided I would get a broken Roberts Colourstream internet radio. While big and modern, it has a couple of decent speakers and a touch screen that I hoped I could re-use. The case should be big enough to fit everything inside and it is already configured for stereo.

roberts_colourstream

Roberts Colourstream Internet DAB Radio

The previous owner had attempted to ‘fix’ the device – resulting in the guts basically being supplied in a separate bag, but that was just one less thing for me to do. Removing the facia allowed me to get to the speakers and after a couple of minutes work  I had stripped the plugs off the speakers and had wired them directly into the X400. A boot of the Pi and suddenly we have music from the speakers.

The next part is figuring out what I want to do, how to do it and what parts are needed!