Sunday 5 July 2015

The Insomniacs Bedside Radio

If you ever have difficulty getting [back] to sleep, you may find that reading a book or listening to music for a while will make you sleepy.


That's OK if you sleep alone, but turning on a light to read a book or cranking up the volume on your MP3 player at 2am may make you very unpopular if you share your bed.


But maybe you can get away with listening via a pair of headphones, if you keep the volume turned down low on your radio.


With a partner that likes to listen to the BBC World Service when sleep seems illusive, I have had to put up with all sorts of disturbances, including sudden loud noises and repeated clicks as each button on our DAB radio is pushed in turn in an attempt to find the right station.

DAB reception is very poor in our area, so we can get a satisfactory signal one minute, then lose the station altogether the next (i.e. we are on the digital cliff edge).

There have also been problems using wired headphones, where the cable gets strained, and audio starts to crackle or cut in and out.

However, I think I've come up with a better solution.

Yes, its a Radio


Using a Raspberry Pi, Wifi dongle, 5 Volt power supply, bluetooth transmitter and bluetooth headphones I've created The Insomniacs Bedside Radio.

I could use any of the Raspberry Pi models for this, however I selected an old model B which has two USB ports. This means I can not only connect a wifi dongle, but also power the Bluetooth transmitter, rather than having to remove it every couple of days to recharge the internal battery.

The Raspberry Pi models with better power regulators are supposed to have better audio quality. If true, it may be wise to use a B+ or B2.

This particular internet radio only receives an audio stream from the BBC World Service, so there are no buttons to push and click in the middle of the night!

Once the headset is paired with the bluetooth transmitter, only the "volume +" and "Volume -" buttons on the headphones require any adjustment. And once the audio level is set for the one and only BBC stream that we are using, they don't really require much fiddling with.

My hardware list:-
  • Raspberry Pi model B with case
  • Edimax EW-7811-UN wifi dongle
  • 5V 1A USB power supply (inc lead)
  • BlueTooth transmitter eSynic AD2P with USB power cable
  • BlueTooth Headphones CLiPtec Air-Touch

The software


The software just follows on from what I used for my Radio Caroline internet radio. Its written in Python as I don't need a user interface and I want it to start up as quick as possible.

Writing the software should have been a 5 minute task. But Python is not my language of choice, and I hadn't given too much thought to the practicalities of an internet radio with virtually no user intervention.

Initially my program just started mplayer with the BBC stream for the World Service. The idea was that the Raspberry Pi would be on all the time, and we could just pick up the headphones hanging on the bed-head and put them on.

However, on the very first night we had a short power cut at around 1am. When power returned, the Raspberry Pi must have booted OK and started mplayer. But as the wifi router was still booting up there was no internet connection, so no BBC stream, and no way to recover!

On the second night the internet connection was lost a few times because BT seem to be struggling to keep our new green street boxes going!

So this is the current Python program (BBC-player.py) which I added to the /home/pi directory.

#BBC-player.py
#Single station internet radio player
#SteveDee
#4/7/15
#==========================================================

import os
import psutil
import time

PLAYER = "mplayer"
WORLD_SERVICE = "http://wsdownload.bbc.co.uk/worldservice/meta/live/shoutcast/mp3/eieuk.pls"    #48k mp3

bPlayerRunning = False

#Set volume
os.system('amixer  sset PCM,0 85%')

#Create a LOOP that runs & runs (...until you shutdown)
while True:
    #check if player is running
    for proc in psutil.process_iter():
        if proc.name() == PLAYER:
            bPlayerRunning = True
            #print 'found mplayer'
           
    if bPlayerRunning == False:
        #start radio
        #print 'starting...'
        os.system('mplayer -cache 128 -cache-min 16 -playlist ' + WORLD_SERVICE + ' &')
       
    bPlayerRunning = False    #reset flag
    time.sleep(10)
    #print 'end of loop'


Don't forget to install mplayer and python-psutil. The file: /etc/rc.local is then modified to run this automatically when the Pi boots up. Details are here but change the reference to point to /home/pi/BBC-player.py.

The program basically checks if the process "mplayer" is running. If not, it runs mplayer with the required string to load the BBC stream.

I set the volume to 85% so that the Bluetooth headphones can be set down to a low level (i.e. the headphone volume is set in steps, so we want the lowest settings to be quiet enough, yet still have the opportunity to crank it up!).

The #print statements are just for use when debugging on my Lubuntu laptop.

I'm not a Python fan


I had a big problem with the line:-

for proc in psutil.process_iter

I'd looked at several examples on the net where it was just used without brackets. However, it was not finding the mplayer process, and I eventually added the brackets:-

for proc in psutil.process_iter()

..and then it worked as expected.

When mplayer is run I get two mplayer processes ...I don't know why, but this doesn't seem to be a problem.

I can now disconnect/switch off the internet, and mplayer shuts down, with both mplayer processes disappearing from the system process list. When the internet recovers, mplayer is restarted.

The mplayer cache options (-cache & -cache-min) may not be necessary ...it was just trial & error. If you get audio breaks or stuttering, just experiment with these values. I didn't really notice a problem on the Pi, I was just trying to improve the situation when testing on my laptop.

The BBC have been messing around with their streaming service and have discontinued some formats earlier this year. So some of the suggested streams you will find on the internet no longer work.

Fortunately for us, this 48K World Service stream still works, providing adequate quality with a low overhead.

What next?


We will run with this prototype for a couple of weeks and see if there are any more issues.

I'll probably replace the Pi B with a B+ or B2 because they have more USB connectors. This will allow the unit to act as a charging point for the headphones, keeping all the bits in one place, at the head of the bed.

At the moment the Pi and Bluetooth transmitter are just laying under the bed. They need some kind of enclosure to prevent the ingress of dust and the likelyhood of mechanical damage. The transmitter button needs to remain accessible so we can pair the devices in case they have an identity crisis.

I also need to decide whether to tuck the box away inside a bed-side cabinet, or put it on display.

If it is going to be visible, I may as well build in a cheap display to show the current time (although I'd probably need to add a Real Time Clock to cater for power-cuts and internet problems).

No comments:

Post a Comment