Copyright 2009-2012 by djg. All Rights Reserved.

Wonky Gibbon Ramblings



Raspbery Pi: Copying SD card image to a smaller SD 0

Posted on January 19, 2014 by danny

Aaargh! So one of my Pi’s running AirPlay died. Or rather the SD card did. I bought a replacement and attempted to write the SD image to it in the usual way using Win32DiskImager. However it refused to write to it, saying that the image was bigger than the SD card.

Turns out that due to manufacturing errors, SD cards vary a little bit in capacity with dead bits hidden away. The new card had less capacity front than the old one.

So – I needed to find some way to burn the image to this card that was just a smidgen too small. This post was useful http://www.raspberrypi.org/phpBB3/viewtopic.php?t=19468&f=26

In the post some people talk about having to shrink the linux filesystem a little before cloning the card however, it turned out I’d never resized my partion up from 2GB to 4GB so I didn’t have this problem. The easiest solution in the end, proved to be to fix the problem using an Ubuntu install rather than Windows. The nice thing about Ubuntu is that like many linux distro’s it can be run direct from the install media without actually having to install it, either DVD or memory stick.

The steps to resolve the problem were as follows:
1) In Windows, download Ubuntu from http://www.ubuntu.com/download/desktop and burn to DVD (just to big to fit on a CD).

2) Then restart the laptop and let it boot the Ubuntu OS from the DVD.

3) Click on the dash icon and start typing the word “Terminal” so that it finds the terminal program. Double click and you get a command line.

4) Place the source SD card into the card reader slot and let Ubuntu mount it.

5) Type:

cd Desktop

6) Then type this command to make an image file on the desktop:

sudo dd if=/dev/sdb of=sdimage.img bs=4M

‘sudo’ gives root priveleges. ‘dd’ is a copying program, ‘if’ is the input file which is the sd card reader device, ‘of’ is the output image on the desktop and ‘bs’ is the block size.

This gives this output:

ubuntu@ubuntu:~/Desktop$ sudo dd if=/dev/sdb of=sdimage.img bs=4M
953+1 records in
953+1 records out
3998220288 bytes (4.0 GB) copied, 211.068 s, 18.9 MB/s

With 8GB of RAM on the laptop I was able to use the desktop effectively as a RAM disk. If you have less than this – you could try saving to your windows hard drive which Ubuntu will have mounted.

7) Take out the source SD card and replace it with the target one (which is a bit smaller) and execute this command:

sudo dd if=sdimage.img of=/dev/sdb bs=4M conv=notrunc,noerror

The aditional parameters at the end tell it to write the full size and allow it to continue when it runs out of space.

This gives this output:

ubuntu@ubuntu:~/Desktop$ sudo dd if=sdimage.img of=/dev/sdb bs=4M conv=notrunc,noerror
dd: writing `/dev/sdb': No space left on device
932+0 records in
931+0 records out
3904897024 bytes (3.9 GB) copied, 482.878 s, 8.1 MB/s

The 3.9GB at the end tells you that a little bit of the image was lost. Happily it is of course blank.

All of which results in a working SD card that the Raspberry Pi can boot. Sorted!

Raspberry Pi Does Sonos – Part 2 – Transmitting on AirPlay 2

Posted on December 30, 2013 by danny

In the first part, I talked a bit about setting up the Raspberry Pi as an AirPlay receiver; something that can receive audio streamed over a home’s wifi connection and play it.

Transmitting from Apple

Apple Devices already support AirPlay by default (not a shock – it’s an Apple invention). So to connect an ipad, iphone, itouch etc… is straightforward. You simply double swipe up in IOS7 and enable AirPlay in the control panel. Job done.

Transmitting from Windows

Windows can be made to talk to the Pi using a program called Tuneblade. This is an application (that if you’re streaming to Shairport as described in Part 1, is free) and can be downloaded from http://tuneblade.com/.

Once launched, Tuneblade can be accessed from your system tray and includes a volume control, so remember to turn it up! It streams the audio even if you mute the local audio output – which is handy if you don’t want to listen to your tiny PC speakers.

Transmitting from Android

On Android, some app’s (such as Streambels) support direct streaming to AirPlay – but many popular apps do not, for example, Spotify does not. Similarly, TuneIn the radio app doesn’t. So another solution is required, similar to that used on Apple devices. ie: redirect the entire audio stream of the device.

There are a number of Apps for Android that will stream the entire sound output of the phone to the Pi. For example, one called AirAudio and another called AirStream. Both of these have demonstration versions to allow you to test. However you will have to buy a licence for around £4 to get a permanent solution (ie: one that doesn’t switch itself off after 10 mins). I didn’t find a totally free alternative (and I’m not anti paying software developers in any case!!).

Whilst apps like Streambels that only stream their own audio channel don’t need root privileges, these other applications that give the greater flexibility of sending any audio on the device (such as that coming out of Spotify) by effectively snooping on other applications audio output – do require root access / super user privileges.

This gets you into the exciting area of device rooting. The process for this can be complicated and in many cases results in the device being wiped as one of the steps to do it. This was certainly the case for the house Nexus 7 though happily not my Motorola Atrix phone. Doing so, however gets this solution to work. In addition it also provides access to a variety of other very useful apps including backup tools that can backup application data as well as the install apk’s and much more. Rooting an android device is not for the feint hearted and comes with associated risks of bricking the device and invalidating your warranty. So something you do, at your own risk.

Transmitting to Multiple Zones

By setting up multiple Raspberry Pi’s around the house with different device names you can effectively zone the house into different audio areas. In addition many of these transmitting programs can broadcast to more than one AirPlay receiver at once. In our house, with our network setup, solely using Raspberry Pi’s, they seem somehow to sycnhronise which is very cool for parties!!!

Raspberry Pi Does Sonos – Part 1 – Making an AirPlay Receiver 0

Posted on December 30, 2013 by danny

Overview

So … I want Sonos. I want the ability to be able to select tunes from Spotify, my NAS drive, the radio, whatever – on a tablet and have it come out of my hifi without the tablet physically attached to it.

I could use Bluetooth. But the range is poor and the sound quality questionable.

But what if a Raspberry Pi could do the same thing? What if it could receive audio streamed over Wifi, from a tablet, or my phone, or a laptop etc?… turns out it can.

Apple’s AirPlay protocol is usually used by iTunes to allow it to communicate with Apple TV and is the backbone of the project. However as luck would have it, going beyond Apple and iTunes it is possible for other devices to use Airplay including a variety of Android apps and a few windows apps. There is also a linux project, shairport that allows linux devices to receive Airplay streams and play them.

This is the point I have to fess up and say that I should have written up the Raspberry Pi part of this as I was doing it – but hey ho, it’ a month later so this will lack detail but at least give a general overview.

The challenge with the Pi is simple enough: Get it running headless with shairport (which provides the audio listening service and outputs the audio through the Pi’s 3.5mm jack) running as a service from startup. And in fact, using the raspbian distribution this is relatively easy. However there were some issues: First, I quickly discovered that the Edimax micro USB wifi adapter I had, didn’t have the range to reach my router through a couple of walls. So I swapped it for a Ralink wifi usb adapter with a proper stick aerial I had lying around – but could I get the drivers to work? Could I hell!! Additionally, even without this problem and without launching a GUI, raspbian isn’t that quick to boot and I like quick booting!

For that reason I decided to do it again, using ArchLinux. ArchLinux boots fast and I knew from a previous project that the Ralink wifi adapter could be made to work.

Steps to Setup the Pi

So the steps to success on the Pi

  1. Install Archlinux
  2. Get Wifi Working
  3. Get a build environment working
  4. Download shairport package
  5. Compile
  6. Configure to get it working

To Install ArchLinux you can download an sd card image from here. And then bring the packages up to date using the instructions here. The most important section is that about updating the system. Don’t worry about installing additional software or a desktop environment.

Next – get the wifi working.
This page provides a guide to setting up wifi on ArchLinux. Personally I found the wpa_supplicant approach a real arse – in fact I didn’t get it working. By comparison the automatic Netctl approach mentioned, is very straightforward.

Now that the wifi is working, check that it can get a wifi signal from wherever in the house you tend to position the Pi. If you can’t and you’re using a micro adapter, you may need to change to an adapter with a larger / proper aerial.

Next, some development tools are required. The first command below installs gcc, make etc… the second provides support for git, which is where the shairport source repository is stored.

# sudo pacman -Sy base-devel
# sudo pacman git

My own efforts from this point got a certain distance, including a lot of mucking around with perl packages and cpan, but I was unable to unravel is completely. However, this blog post by Orson Tyrell – works extremely well.

At the end of this, you should have shairport installed and set to automatically startup at system boot.

You may well find that when you send a test signal it is very quiet.

If so, launch

# alsamixer

Set the volume to 100% or close and exit.
If you then call

# alsactl store

(you may need to use sudo) then this volume will be stored away and reused after a reboot.

In Part 2 – I’ll talk a bit about broadcasting to the Pi from other devices.

There were quite a lot of pages used in doing this, but the key ones were:
http://orsontyrell.blogspot.co.uk/2013/11/airplay-to-arch-linux-raspberry-pi-via.html
http://engineer.john-whittington.co.uk/2013/05/airpi-diy-airplay-speakers-using-shairport-and-a-raspberry-pi-updated/
And on raspbian
http://trouch.com/2012/08/03/airpi-airplay-audio-with-raspberry/
https://github.com/abrasive/shairport
… thanks to all.

Raspberry Pi Wireless Radio – Part 2 0

Posted on March 25, 2013 by danny

To control the Raspberry Pi radio, you’re going to need to connect a bunch of switches to the GPIO header block. How many switches and the functions they perform is up to you. For example you could use them as presets, or channel up/down. And don’t forget you’ll need something to control volume.

I purchased some ribbon cable, veroboard, tactile switches, an IDC connector and a bunch of resistors to make my control board (see pic below) but you could go a breadboard route at least initially to get something working. This post is an excellent introduction to the wiring required: http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/buttons_and_switches/

To interface with my external switch board (via the GPIO header block), I’m going to use Python.

Installing Python

Although installing python in itself was straightforward, finding information on how to install the gpio library was more challenging, most users having used it with raspbian or debian. In the case of archlinux it was clearly going to have to be compiled from scratch which given I haven’t compiled anything from scratch, was a bit daunting.

However, whilst standing on my own shoelaces and generally face planting, I stumbled across this post on the subject http://archlinuxarm.org/forum/viewtopic.php?f=31&t=4654 which outlines everything needed to install both python and the gpio library as well as a host of other development tools required along the way such as gcc and so forth.

First install the development tools you’re going to need (including things like gcc)

$ sudo pacman -Sy file base-devel abs git

Next download the gpio source code and unpack it

$ wget https://aur.archlinux.org/packages/ra/raspberry-gpio-python/raspberry-gpio-python.tar.gz
$ tar xf raspberry-gpio-python.tar.gz

Now run the make process that will create a package that can be imported by pacman, and import it

$ cd raspberry-gpio-python
$ makepkg -Acs --asroot
$ sudo pacman -U raspberry-gpio-python

By this point you now have Python 2 and 3 installed, plus a variety of other development tools and the gpio library.

NB: If at any point you see error message that look a bit like this:
error: failed retrieving file ‘libpulse-2.0-2-arm.pkg.tar.xz’ from mirror.archlinuxarm.org : The requested URL returned error: 404
the chances are that the package database in pacman is out of sync with what’s out on the internet. The following command will resync the database:

$ sudo pacman -Syy

If that doesn’t work try changing the download mirror

$ cd /etc/pacman.d
$ nano mirrorlist

Comment out the original mirror and remove a comment from one of the others, then save and update http://www.raspberrypi.org/phpBB3/viewtopic.php?f=28&t=12840

A Simple Python Radio Control Program

This simple program has three radio stations and two mp3s assigned to various input buttons, plus a volume up and a volume down.

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import os

def PlayRadio(station_url):
    os.system("mpc stop")
    os.system("mpc clear")
    os.system("mpc add " + station_url)
    os.system("mpc play")

def PlayMp3(mp3_file):
    os.system("mpc stop")
    os.system("mpc clear")
    os.system("mpc add " + mp3_file)
    os.system("mpc play")

def VolumeUp():
    os.system("mpc volume +2")

def VolumeDown():
    os.system("mpc volume -2")

def mainProg():
    # to use Raspberry Pi board pin numbers
    GPIO.setmode(GPIO.BCM)

    # set up unused GPIO as output channels and 0V
    # set up GPIO input with pull-down control
    #   (pull_up_down be PUD_OFF, PUD_UP or PUD_DOWN, default PUD_OFF)
    GPIO.setup(14, GPIO.OUT)
    GPIO.setup(15, GPIO.OUT)
    GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(8, GPIO.OUT)
    GPIO.setup(7, GPIO.OUT)

    GPIO.setup(2, GPIO.OUT)
    GPIO.setup(3, GPIO.OUT)
    GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(17, GPIO.OUT)
    GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(10, GPIO.OUT)
    GPIO.setup(9, GPIO.OUT)
    GPIO.setup(11, GPIO.OUT)

    # set RPi GPIO output pins low
    GPIO.output(14, GPIO.LOW)
    GPIO.output(15, GPIO.LOW)
    GPIO.output(8, GPIO.LOW)
    GPIO.output(7, GPIO.LOW)

    GPIO.output(2, GPIO.LOW)
    GPIO.output(3, GPIO.LOW)
    GPIO.output(17, GPIO.LOW)
    GPIO.output(10, GPIO.LOW)
    GPIO.output(9, GPIO.LOW)
    GPIO.output(11, GPIO.LOW)

    # look for inputs on RPi board pins
    prev_input = 0
    while True:
        #take readings
        this_cycle = 0
        input = GPIO.input(25)
        if ((prev_input == 0) and input):
            print ("Button 1 pressed")
            this_cycle = 25
            # ISA FM
            PlayRadio("http://80.13.146.243:8000/")
        input = GPIO.input(24)
        if ((prev_input == 0) and input):
            print ("Button 2 pressed")
            this_cycle = 24
            # LBC
            PlayRadio("http://ice-the.musicradio.com:80/LBC1152MP3Low")
        input = GPIO.input(23)
        if ((prev_input == 0) and input):
            print ("Button 3 pressed")
            this_cycle = 23
            # Fun Kids
            PlayRadio("http://icy-e-04.sharp-stream.com/funkids.mp3")
        input = GPIO.input(22)
        if ((prev_input == 0) and input):
            print ("Button 4 pressed")
            this_cycle = 22
            # Rock Lobster mp3 Test
            PlayMp3("LobsterTest.mp3")
        input = GPIO.input(27)
        if ((prev_input == 0) and input):
            print ("Button 5 pressed")
            # Beethoven mp3 Test
            PlayMp3("ClassicalTest.mp3")
            this_cycle = 27
        input = GPIO.input(18)
        if ((prev_input == 0) and input):
            print ("Button 6 pressed")
            VolumeUp()
            this_cycle = 18
        input = GPIO.input(4)
        if ((prev_input == 0) and input):
            print ("Buttpon 7 pressed")
            VolumeDown()
            this_cycle = 4

        prev_input = 0
        if (this_cycle > 0):
            prev_input = 1

        # software switch debounce
        time.sleep(0.05)
	
def main():
    mainProg()

if __name__ == "__main__":
    main()

From here you can really go to town. I followed this up with a web interface coded in Python and Django to allow button configuration and all sorts. Far to long to blog about here. But plenty of fun to be had!

References:
http://www.instructables.com/id/Pandoras-Box-An-Internet-Radio-player-made-with/step2/Setting-up-the-Pi/
http://www.instructables.com/id/Pandoras-Box-An-Internet-Radio-player-made-with/step7/Connecting-the-Pushbuttons/
http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/buttons_and_switches/ describes wiring
http://lwk.mjhosting.co.uk/?p=343 describes GPIO
http://elinux.org/RPi_Low-level_peripherals describes GPIO
http://pypi.python.org/pypi/RPi.GPIO/0.3.1a describes python programming with GPIO
http://docs.python.org/2/tutorial/index.html python for newbies
http://www.xatworld.com/radio-search/ for finding IP URLs for radio stations
http://www.codedefied.co.uk/2011/12/24/playing-bbc-radio-streams-with-mpd/ how to unpack BBC tokenised streams

Raspberry Pi Wireless Radio – Part 1 0

Posted on December 27, 2012 by danny

As with many such posts, this one is primarily a reminder to myself, should I need to repeat my steps at a later date. However, I hope they are of use to someone also as it was a number of days work.

You will need one raspberry pi and a wireless USB adapter based on the Realtek RTL8188CUS chipset such as the Edimax EW-7811Un micro-usb adapter (cheap as chips and available from Amazon).

Basic Setup

Download the Arch Linux ARM install (because it is very lightweight and boots in under 10 seconds), burn to an SD card and plugin to the Pi as per the instructions on the download page here.

Boot it up. If you don’t have a screen and usb keyboard available just plug it into a wired network. ssh is enabled by default so you can connect using Putty immediately, instead.

Follow the update instructions here (http://elinux.org/ArchLinux_Install_Guide) to bring it up to the most recent distribution.
Early on it talks about rc.conf which doesn’t exist in this distribution, there’s probably an alternative but as I didn’t need to change timezones, I wasn’t concerned.
The command pacman-key –init, does take A LONG time (like 10 minutes with no onscreeen feedback).

Wireless Networking

Plug in the Edimax EW-7811Un micro wireless USB adapter and reboot. Support for the Realtek RTL8188CUS chipset this is based on is built into the current distributions of Arch Linux for the Pi.
Install the netcfg package so that wireless can be configured from the command line

 # pacman -S netcfg

Then follow these instructions to configure wireless: https://wiki.archlinux.org/index.php/Netcfg
Use the example wireless-wpa script as the starting point.
After issuing this instruction in that post: # netcfg mynetwork you will see this error nl80211: ‘nl80211’ generic netlink not found. This isn’t actually a problem, this post describes why https://bbs.archlinux.org/viewtopic.php?pid=940669
To ensure wireless is restarted after a reboot of the Pi, the following command in that post must be executed

# systemctl enable netcfg@myprofile

Reboot and check that you can putty to the Pi over wifi.

In the event, that the wireless hardware doesn’t initialise fast enough (can happen), you may get an error like ‘wlan0 does not exist’. See the entry in this post https://wiki.archlinux.org/index.php/Netcfg_Troubleshooting to resolve.

You may find that a few days after doing this, the IP lease for the Pi expires on the router causing it to assign a new IP address to it. This can cause the Pi to no longer be able to connect to the router because it’s own expectation of what the IP lease should be, aren’t being met. This post https://bbs.archlinux.org/viewtopic.php?id=120230 should troubleshoot this.

Install and Configure Media Player

Now install mpd & mpc:

# pacman -S mpd mpc alsa-utils

Sound itself needs enabling at boot up. To do this you need to create a script in the directory called /etc/modules-load.d called snd_bcm2835.conf which looks like this:

# Load snd_bcm2835 at boot
snd_bcm2835

You also need to install initscripts:

# pacman -S initscripts

A lot of the challenge is in getting mpd configured correctly, when stuff doesn’t work, it’s usually due to this file not being setup quite right. Also the errors reported to the command prompt are often less than helpful so don’t forget to check the mpd.log file, sometimes that actually provides useful help. In general it is recommended you don’t run it as root but rather as a user with less all-encompassing rights.

Here’s my /etc/mpd.conf file:

music_directory		"~/music"
playlist_directory "~/mpd/playlists"
db_file "~/mpd/mpd.db"
log_file "~/mpd/mpd.log"
pid_file "~/mpd/mpd.pid"
state_file "~/mpd/mpdstate"
user "wonkygibbon"
bind_to_address		"127.0.0.1"
port				"6600"
input {
        plugin "curl"
}
audio_output {
	type		"alsa"
	name		"My ALSA Device"
	device		"hw:0,0"	# optional
}

The default input plugin is called “curl” and can be used to pick up streaming audio over the web.

For this to work, I needed to create the various files and directories that these point at. Hence, login as your user (in my case wonkygibbon), then do the following:

$ mkdir music
$ mkdir mpd
$ cd mpd
$ mkdir playlists
$ touch mpd.log mpd.pid mpdstate

Finally, start mpd, connect to a radio stream, and play it:

$ mpd
$ mpc add http://80.13.146.243:8000/
$ mpc play

The IP address is that of one of my favourite french stations – replace with whatever you want to listen to.

If you wish to test using mp3 files – you can copy them to the Pi using WinSCP (provides an ftp type interface from windows to the Pi using ssh – meaning you don’t need the Pi to be running an ftp server).

They need to be placed in the “music” folder you created earlier. Then update mpd’s music database using:

$ mpc update

Thanks primarily to the following sites as well as others to numerous to mention:
http://miro.oorganica.com/raspberry-pi-mpd/
https://wiki.archlinux.org/index.php/Music_Player_Daemon#Starting_mpd_as_a_user
http://crunchbang.org/forums/viewtopic.php?pid=182574
https://wiki.archlinux.org/index.php/Netcfg_Troubleshooting
https://bbs.archlinux.org/viewtopic.php?id=120230
Part 2 if/when it follows will focus on how to to add external switches to select channels and the bits of scripting required to respond to them.



↑ Top