Microbit-controlled radio / MP3 player

Here’s a quick project showing the power of David Whale’s bitio Python library. This gives Python on a Raspberry Pi, Mac or Windows PC access to the physical sensors on the BBC micro:bit. You can control a program on your computer using the buttons, touch and accelerometer sensors on the micro:bit, and use the micro:bit’s display too.

My default position with any bit of tech is: can I make a radio with it? And here the answer was yes I can, and in only about 10 minutes too!

This program allows me to change stations up and down using the A and B buttons on the micro:bit, increase the volume by titling to the right, lower the volume by tilting to the left and you can exit the program by touching the GND and 0 pins on the micro:bit. It could just as easily work as an mp3 player, it doesn’t have to play internet radio streams. The micro:bit displays the playlist number on the screen.

If you fancy trying this out, here’s what you need:

  • A computer such as a Raspberry Pi with Python installed.
  • Also the computer needs an audio player installing and configuring with some radio station URLs or mp3 files. I use mpc/mpd on the Raspberry Pi – see below.
  • Download bitio on the computer.
  • A BBC micro:bit and USB lead.
  • Some way of hearing the audio, through a TV or headphones or powered speakers plugged into the computer.

First install mpc and mpd which I use on the Raspberry Pi to play radio streams or mp3 files:

sudo apt-get install mpc mpd

(On a Mac you could use the afplay command or VLC on any computer to do the same thing).

If you’ve not used mpc before, open the mpd config file with nano like this:
sudo nano /etc/mpd.conf

Then edit these lines to remove some # signs (uncomment) and change the mixer_type from hardware to software so it looks like this:

audio_output {
type "alsa"
name "My ALSA Device"
device "hw:0,0" # optional
mixer_type "software" # optional
mixer_device "default" # optional
mixer_control "PCM" # optional
mixer_index "0" # optional
}

Now add some radio station URLs using the mpc add command. I added BBC 6music, BBC World Service News, FIP and Radio 4. For example to add FIP I typed
mpc add http://chai5she.cdn.dvmr.fr/fip-midfi.mp3

(NB: as of Feb 2020 Fip is at http://icecast.radiofrance.fr/fip-midfi.mp3)

You can find BBC radio URLs on my big list here.

You can add audio files instead of radio stations if you like, to make an MP3 player.

I added just 4 stations but you can add more or fewer, just tweak the if stationNumber < and > lines accordingly. They get added in order but you can check your playlist of stations or MP3 files by typing
mpc playlist

And you can change the order using the move command, for example to move station 4 to preset 2 just type:
mpc move 4 2

I then downloaded the bitio files as a ZIP, extracted them and put the Python program below in the same folder as the examples and ran it using IDLE - you could also run it from the command line. It will display 'radio rocks!' on the micro:bit display and then start playing station number 1. Use the A and B buttons to change channel, tilt left and right to control volume, touch pin 0 to exit the program.

The first time you use a micro:bit with bitio you need to drag a special .HEX file to the micro:bit and follow some steps to locate the device - this just involves unplugging and replugging it, and then it remembers your device while you are using it.

If you use this or have ideas for improving it, please let me know!

# micro:bit-controlled radio by Giles Booth @blogmywiki
# Requires bitio https://github.com/whaleygeek/bitio
# Also requires mpc/mpd installing and some audio files or URLs adding

import microbit
import time
import os

stationNumber = 1

running = True

microbit.display.scroll("radio rocks!")
os.system("mpc play 1")
microbit.display.show("1")

while running:
    x = microbit.accelerometer.get_x()

    if x < -300:
        print("left - volume down")
        os.system("mpc volume -10")
    elif x > 300:
        os.system("mpc volume +10")
        print("right - volume up")

    if microbit.button_a.was_pressed():
        print("Button A pressed - station down")
        stationNumber -= 1
        if stationNumber <1:
            stationNumber = 4
        os.system("mpc play "+str(stationNumber))
        microbit.display.show(str(stationNumber))     

    if microbit.button_b.was_pressed():
        print("Button B pressed - station up")
        stationNumber += 1
        if stationNumber >4:
            stationNumber = 1
        os.system("mpc play "+str(stationNumber))
        # you could use 'mpc next' if you don't know how many tracks/URLs are loaded
        microbit.display.show(str(stationNumber))

    if microbit.pin0.is_touched():
        print("Pin 0 touched")
        microbit.display.scroll("bye")
        running = False

    time.sleep(0.5)

os.system("mpc stop")
Posted in Raspberry Pi | Tagged , , , | 7 Comments

PyPlay for Raspberry Pi

Ages ago I made a simple Python program that would play audio files out one at a time on a Mac. What’s the big deal with that? Don’t lots of programs do that? Well, I don’t think so, at least not on a Mac. The key concept here is playing a file from a list – and then stopping. In radio (or the theatre I guess) this is almost always what you want to do, not automatically play the next track.

So PyPlay was born. It was written in Python 2 and used Apple’s afplay command so it didn’t need any other software or modules installing – you download the file, chuck it in a folder with some audio files and run it in the terminal by typing in python pyPlay.py – If there isn’t already a standard format M3U playlist file in the folder, it makes one for you (in an arbitrary order).

You play files by typing in its number in the list and pressing enter. It gives you an out-time for the track, but the display is not updated with the time or the time remaining – you have to keep your eye on another clock such as the one on your computer. You can tweak the
Raspberry Pi desktop clock to show seconds by right-clicking on it > Digital Clock Settings > change Clock Format to %X

You can have two consoles open at the same time so you can segue tracks by playing a second one while the first is just ending. So you can DJ using a Raspberry Pi, some sound files and a bit of code!

This new Raspberry Pi version is a bit more polished than the Mac version as it adds support for .OGG files and fixes a few bugs. It still sticks to the original principle of not requiring any modules installing you shouldn’t find on a normal Raspbian install. You should launch it in Python 2 from the Terminal command line. It uses omxplayer instead of afplay to play the audio and allows some additional controls. While a track is playing you can use the keyboard to:

- Change the volume using + and – keys
- Pause a track with the space bar (this renders the out time meaningless, however)
- Skip around inside a track using arrow keys. Left & right seek back and forward 30 seconds, up and down by 600 seconds. You can also speed up and slow down the audio with 1 and 2 but I wouldn’t recommend it! These also render the displayed out time meaningless.

There’s lots still to do with this – it is inspired by the widely-used BBC audio playout Windows program CoolPlay (for which I designed the splash screen) but provides none of that program’s useful features like showing the progress of a track, allowing you to hop around a playlist and, indeed, build and re-order playlists. I may work on these but these features require me to delve into either curses programming or creating a proper GUI. It would, of course, be trivial to add some GPIO to control it from physical buttons or even fader starts on a mixing desk.

Anyway here’s the code. I hope it may be useful for someone making a dirt cheap radio station, DJ setup or for school dramas or assemblies! (I tried uploading it to Github, but Github is being… a git.)

#!/usr/local/bin/python

# 5 Aug 17 version
# Modified to run on Raspberry Pi using omxplayer instead of afplay
# Found bug - cannot cope with brackets in file names - FIXED!
# - cannot cope with ampersands either! - FIXED
# - make titles longer - FIXED
# - add support for .OGG audio files - FIXED

# If using GUI change clock display to show seconds with %X format.

# PyPlay radio playout script by Giles Booth @blogmwiki
# Written in Python2. Should not require any other modules to be installed.
# Requires audio files in same directory as this script.
# Original version ran on Mac using afplay.

# V 4.1 has horrible kludge to cope with multiple backslashes in array
# Version 4 fixes bugs replacing escaped spaces in display names and
# copes with filenames with apostrophes.
# Version 3 fixes bug playing files with spaces in file names
# makes an M3U file from audio files in directory if no playlist.m3u file found
# also fixes a bug with out time when crossing hour.

import os
import os.path
import time
import subprocess
import re
import datetime

playlist = ""

# \033[7m is code for inverse video
# \033[0m is normal video
# \033[31m is red video

# function to display tracks, durations, playing status & out time
def showTracks():
    os.system('clear')
    t = str(datetime.datetime.now().time())
    t = t[0:8]
    print '\033[37;44mWelcome to PyPlay!     \t\t\tUpdated ',t,'\033[0m'
    print ''
    print '\033[0;30;47m  # File name                           Length  Status  Out time \033[0m'
    for z in range(len(trackList)):
        highlightOn = ""
        highlightOff = ""
        if "PLAYING" in trackList[z][4]:
            highlightOn = "\033[31;103m"
            highlightOff = "\033[0m"
        print highlightOn, leadingSpace(str(z+1)), trackList[z][1], "\t", timeLeadingSpace(trackList[z][3]), "\t", trackList[z][4], highlightOff
    print '\033[97;42m    KEYS:    q stop | - + vol | space pause | arrows seek        \033[0m'

# returns duration of track in seconds
def getTrackLength(thing):
    bumf = ""
    bumfList = []
    trackLength = ""
    snog = trackArray[thing]
    foo = "omxplayer -i " + snog

    try:
        bumf = subprocess.check_output(foo, shell=True, stderr=subprocess.STDOUT)
    except Exception, e:
        bumf = str(e.output) # horrible kludge to get round exceptions but capture text
    bumfList = bumf.split('\n')

    for line in bumfList:
#        print line # debug line
        if line.startswith('  Duration'):
            line_mins = int(line[15:17])
            line_secs = int(line[18:20])
            trackSecs = line_secs + (line_mins*60)

    return trackSecs

# returns string with out time in HH:MM:SS format
def getEndTime(tk):
    tkDuration = trackList[tk-1][2]
    timeNow = str(datetime.datetime.now().time())
    timeHour = timeNow[0:2]
    timeMin = timeNow[3:5]
    timeSec = timeNow[6:8]
    tH = int(timeHour)
    tM = int(timeMin)
    tS = int(timeSec)
    tkS = tkDuration % 60
    tkM = (tkDuration - tkS) / 60
    endSec = int(round(tS+tkS, 0))
    endMin = int(tM + tkM)
    endHour = int(tH)
    if endSec > 59:
        endMin += 1
        endSec = endSec % 60
    if endMin > 59:
        endHour += 1
        endMin = endMin % 60
    endHourString = leadingZero(str(endHour))
    endMinString = leadingZero(str(endMin))
    endSecString = leadingZero(str(endSec))
    endTime = endHourString + ":" + endMinString + ":" + endSecString
    return str(endTime)

# adds a leading 0 to single character strings
def leadingZero(n):
    if len(n) == 1:
            n = '0' + n
    return n

# adds a leading space to single character strings
def leadingSpace(n):
    if len(n) == 1:
            n = ' ' + n
    return n

# adds a leading space to times shorter than 10 minutes
def timeLeadingSpace(n):
    if len(n) == 4:
            n = ' ' + n
    return n

# makes strings a fixed length
def colform(txt, width):
    if len(txt) > width:
        txt = txt[:width]
    elif len(txt) < width:
        txt = txt + (" " * (width - len(txt)))
    return txt

# returns the track length in a string M:SS format
def displayDuration(s):
    disTime = int(s)
    sec = disTime % 60
    m = (disTime - sec)/60
    secString = leadingZero(str(sec))
    t = str(m) + ":" + secString
    return t

# sets playing status for all tracks to empty string
def clearStatus():
    for y in range(len(trackList)):
        trackList[y][4] = ''

# Trying omxplayer on Raspberry Pi
def playTrack(track):
    song = trackArray[track-1]
    trackString = "omxplayer " + song + " > /dev/null"  # stop omxplayer output appearing on screen whilst playing
    os.system(trackString)

# if no playlist.m3u file found, make one from audio files found in directory
# edit audioFileTypes list to add more file types as needed (but don't add 'aif' because reasons)
if not os.path.exists('playlist.m3u'):
    audioFileTypes = ['.mp3','.MP3','.wav','.WAV','.m4a','.M4A','.aiff','.AIFF','.ogg','.OGG']
    os.system('clear')
    print "No playlist.m3u file found so I am making you one with these files:"
    print
    dirList = os.listdir(".")
    newDir = []
    for x in range(len(dirList)):
        for q in audioFileTypes:
            if q in dirList[x]:
                print(dirList[x])
                newDir.append(dirList[x])
    fo = open("playlist.m3u", "w")
    fo.write("#EXTM3U\n\n")
    for item in newDir:
#        print item
        fo.write("%s\n" % item)
    fo.close()
    time.sleep(2)

#open the playlist file and read its contents into a list
playlist = open('playlist.m3u')
trackArray = playlist.readlines()

# clean up the track list array of metadata and \n characters
# iterate over list in reverse order as deleting items from list as we go
for i in range(len(trackArray)-1,-1,-1):
    if trackArray[i].startswith('\n') or trackArray[i].startswith('#'):
        trackArray.pop(i)
    repl = {" ": "\ ", "\'": "\\'","&": "\&","(": "\(",")": "\)"} # define desired replacements here
    # use these three lines to do the replacement
    repl = dict((re.escape(k), v) for k, v in repl.iteritems())
    pattern = re.compile("|".join(repl.keys()))
    newArrayName = pattern.sub(lambda m: repl[re.escape(m.group(0))], trackArray[i])
    trackArray[i] = newArrayName
    temp = trackArray[i].strip()
    trackArray[i] = temp

# horrible kludge to strip out multiple backslashes
for i in range(len(trackArray)-1,-1,-1):
    repl = {"\\\\\\": "\\"} # define desired replacements here
    # use these three lines to do the replacement
    repl = dict((re.escape(k), v) for k, v in repl.iteritems())
    pattern = re.compile("|".join(repl.keys()))
    newArrayName = pattern.sub(lambda m: repl[re.escape(m.group(0))], trackArray[i])
    trackArray[i] = newArrayName

# read tracks into array to hold track info in format:
# filename - display name - duration as float - display duration - track status
print '\nScanning audio files to calculate durations:'
trackList = []
for a in range(len(trackArray)):
    rep = {"\ ": " ", "\\'": "\'", "\&": "&","\(": "(","\)": ")"} # define desired replacements here
    # use these three lines to do the replacement
    rep = dict((re.escape(k), v) for k, v in rep.iteritems())
    pattern = re.compile("|".join(rep.keys()))
    newName = pattern.sub(lambda m: rep[re.escape(m.group(0))], trackArray[a])
    print a+1,newName
    thisTrackLength = getTrackLength(a)
    trackList.append([trackArray[a],colform(newName,30),thisTrackLength,displayDuration(thisTrackLength),"status"])

# the main program loop
while True:
    clearStatus()
    showTracks()
    trackNo = raw_input('\nWhich track # would you like to play? q to quit ')
    if trackNo == 'q':
        break
    elif trackNo == "":
        print 'You must enter a track number or q to quit'
        time.sleep(2)
    elif trackNo.isalpha():
        print 'Must be a number'
        time.sleep(2)
    elif int(trackNo) <1 or int(trackNo) > len(trackArray):
        print 'Not a valid track number'
        time.sleep(2)
    else:
        eT = getEndTime(int(trackNo))
        trackList[int(trackNo)-1][4] = 'PLAYING ' + eT
        showTracks()
        playTrack(int(trackNo))
Posted in radio, Raspberry Pi | Tagged , , , , | Leave a comment

RFID card kit for Raspberry Pi

Two videos (one short, one long) exploring the Monk Makes Clever Card kit for the Raspberry Pi. I really recommend this RFID card kit, it is excellent value and the supplied software is very thoughtfully designed – I made an internet radio that plays different stations when you present different cards in mere minutes!

Here’s a quick demo of the radio:

And here’s an in-depth look at the kit and how I made the radio:

Posted in radio, Raspberry Pi | Tagged , , | 2 Comments

Tide times on Raspberry Pi Inky pHAT display

Now updated with weather info – see end of this blog post!

Someone once said ‘information wants to be free’. Well, yes and no. If you’re looking for publicly-funded academic research papers or live train running information or potentially life-saving data like tide times, then forget it. (Little bit of a rant, there. Sorry.)

After my radio, I fancied making a gizmo to show high and low tide times on my Raspberry Pi’s Inky pHAT e-ink display. This turned out to be way harder than I expected, chiefly because UK tide time data does not seem to be syndicated as an RSS or other accessible data feed. There is a privately-run web site that appears to have an RSS feed, but all the tide times are contained in one XML tag, so it’s not very useful. Magic Seaweed have an API but it requires a key – I have asked for one as they have loads more lovely surf data.

So I decided to find out how to do screen-scraping in Python. I used this very nice guide which uses two Python modules, ‘requests’ (which I already had on my Pi) and ‘Beautiful Soup’ which I installed with
sudo apt-get install python3-bs4

You can get tide times on many different sites, I chose the Met Office almost at random but partly because I want to add weather info. Screen-scraping is, I have to say, a Hideous Kludge. (I think I saw Hideous Kludge at the Bull and Gate once…) If the Met Office reconfigure their site it any way, this program will probably stop working. It could also do with some error handling…

DISCLAIMER: this beta is provided for amusement only!
Do not rely on the tide times presented as code may be buggy.

So here we go – put the background image file (mine is shamelessly modified from the supplied Pimoroni one but you could add one of your own making) and a font of your choice in the same folder as this script, install Beautiful Soup, find your local seaside place geohash code on the Met Office web site and replace mine with it, and off you jolly well go.

If you want to use my retro 68k Mac font (which does look lovely on the Inky pHAT) you can download it here.

You can set cron to run this automatically – I would suggest running it every morning at 5am; the current version of Raspbian allows you to do this easily on the desktop (Raspberry > System Tools > Scheduled tasks). I think this would be a great project to run on a PiZeroW to make a little tide time gizmo for your beach house!

# A program to display tide times on Raspberry Pi with Inky pHAT e-ink display
# by Giles Booth - www.suppertime.co.uk/blogmywiki
# Updated 1 Aug 17 to fix bug when only 3 tides in 24 hr period.

# DISCLAIMER: this beta is provided for amusement only!
# Do not rely on the tide times presented as code may be buggy.
# This screen-scrapes the Met Office web site, may break at any time.
# -------------------------------------------------------------
# I did not need to install 'requests', it was already on Pi.
# I installed Beautiful Soup with 'sudo apt-get install python3-bs4'
# using tutorial at https://www.dataquest.io/blog/web-scraping-tutorial-python/
# Download your own .ttf font eg ChiKareGo.ttf from
# http://www.pentacom.jp/pentacom/bitfontmaker2/gallery/?id=3778
# and place it in same folder as this program.

# To do: add weather, wind direction, custom backdrop, fix 3 tide bug.

import requests
from bs4 import BeautifulSoup
import inkyphat
from PIL import Image, ImageFont

# Fetch Gwithian tide times from Met Office web site
# Find other geohash location codes on the site, eg
# Godrevy, Cornwall gbujv26hb
# Walton-on-Naze u10yuyqrf
# Gt Yarmouth u135pr5sv
page = requests.get("http://www.metoffice.gov.uk/public/weather/tide-times/gbujtpnch")

soup = BeautifulSoup(page.content, 'html.parser')
html = list(soup.children)[2]
body = list(html.children)[3]

# print location name in console - you could print this straight to Inky pHAT
location = soup.find_all('h2')[1].get_text()
print(location)

# print 1st date (today!)
today_date = soup.find_all('h3', class_='dayTitle')[0].get_text()
print(today_date)

# print tide times - needs work as there are not always 4 tides in each 24 hour period
for i in range (4):
    print(soup.find_all('td')[i].get_text(),soup.find_all('span', class_='tideTime')[i].get_text())

# replace with font of your choice
font = ImageFont.truetype("ChiKareGo.ttf", 16)
inkyphat.set_image("emptier-backdrop.png")

title = 'Gwithian ' + today_date
w, h = font.getsize(title)
x = (inkyphat.WIDTH / 2) - (w / 2)
inkyphat.text((x, 0), title, inkyphat.WHITE, font=font)
inkyphat.line((31, 15, 184, 15)) # Horizontal  line

tide_y = 16

for i in range (4):
    tide_line = soup.find_all('td')[i].get_text() + ' tide: ' + soup.find_all('span', class_='tideTime')[i].get_text()
    if not tide_line[0].isdigit():  # filter out spurious lines when only 3 tides in 24 hrs
        inkyphat.text((50, tide_y), tide_line, inkyphat.WHITE, font=font)
        tide_y += 16

inkyphat.show()

Updated version

I’ve since tweaked the code (inefficiently I know) to show wind direction, speed and general weather outlook. I’ve also made a new background image which allows for more text:

# A program to display tide times on Raspberry Pi with Inky pHAT e-ink display
# by Giles Booth - www.suppertime.co.uk/blogmywiki

# DISCLAIMER: this beta is provided for amusement only!
# Do not rely on the tide times presented as code may be buggy.
# This screen-scrapes the Met Office web site, may break at any time.
# -------------------------------------------------------------
# I did not need to install 'requests', it was already on Pi.
# I installed Beautiful Soup with 'sudo apt-get install python3-bs4'
# using tutorial at https://www.dataquest.io/blog/web-scraping-tutorial-python/
# Download your own .ttf font eg ChiKareGo.ttf from
# http://www.pentacom.jp/pentacom/bitfontmaker2/gallery/?id=3778
# and place it in same folder as this program.

import requests
from bs4 import BeautifulSoup
import inkyphat
from PIL import Image, ImageFont
import string

# Fetch Gwithian tide times from Met Office web site
# Find other geohash location codes on the site, eg
# Godrevy, Cornwall gbujv26hb
# Walton-on-Naze u10yuyqrf
# Gt Yarmouth u135pr5sv
page = requests.get("http://www.metoffice.gov.uk/public/weather/tide-times/gbujtpnch")

soup = BeautifulSoup(page.content, 'html.parser')
#html = list(soup.children)[2]
#body = list(html.children)[3]

# print location name in console - you could print this straight to Inky pHAT
location = soup.find_all('h2')[1].get_text()
print(location)

# print 1st date (today!)
today_date = soup.find_all('h3', class_='dayTitle')[0].get_text()
print(today_date)

# print tide times
for i in range (4):
    print(soup.find_all('td')[i].get_text(),soup.find_all('span', class_='tideTime')[i].get_text())

# replace with font of your choice
font = ImageFont.truetype("ChiKareGo.ttf", 16)
inkyphat.set_image("even-emptier-backdrop.png")

title = 'Gwithian ' + today_date
w, h = font.getsize(title)
x = (inkyphat.WIDTH / 2) - (w / 2)
inkyphat.text((x, 0), title, inkyphat.WHITE, font=font)
inkyphat.line((31, 15, 184, 15)) # Horizontal  line

tide_y = 16
for i in range (4):
    tide_line = soup.find_all('td')[i].get_text() + ' tide: ' + soup.find_all('span', class_='tideTime')[i].get_text()
    if not tide_line[0].isdigit():  # filter out spurious lines when only 3 tides in 24 hrs
        inkyphat.text((10, tide_y), tide_line, inkyphat.WHITE, font=font)
        tide_y += 16

# find wind speed and direction
wx = soup.find_all('div', class_="tideForecast")[0].get_text()
wxList = wx.splitlines()
windSpeed = wxList[17]
windDirection = wxList[13]
print('Wind',windSpeed,windDirection)
inkyphat.text((110, 16), 'Wind: '+windDirection+' '+windSpeed+' mph', inkyphat.WHITE, font=font)

# Find weather description
weather = soup.find(class_="tideForecast")
forecast_items = weather.find_all(class_="tideWxIcon")
outlook = forecast_items[0]
img = outlook.find("img")
desc = img['alt']
print('Outlook',desc)
inkyphat.text((110, 32), desc, inkyphat.WHITE, font=font)

inkyphat.show()
Posted in Raspberry Pi | Tagged , , , , | 2 Comments

InkyPhat Flotilla radio

I treated myself to a Pimoroni InkyPhat Raspberry Pi e-ink display – it’s small but good value compared with some other e-ink displays… and it has THREE colours: black, white – and red. It comes with some beautifully-designed examples such as a calendar, a local weather display and a badge-maker. Being an e-ink display, it retains its contents after the power goes and hence you can unplug it from the Pi and wear it!

Obviously the first thing I had to do was make a radio, so I tweaked my Flotilla radio so it only uses the rotary dial for volume and the 4-button touch panel to choose pre-set stations.

The display update is slow, I guess to ensure maximum quality – there’s none of the ghosting of old images I experienced in early e-book readers. It also forces you to listen to a few seconds of each station before changing channel. And I quite like the drama of the thing.

Making the artwork was a bit of a drag – you have to save images as PNG files with a very specific colour palette – 3 colours only and they must be in the right order. I hate GIMP at the best of times but it drove me mad as I kept getting images that looked ok on screen but swapped colours on the InkyPhat. Eventually it all came good.

I’m really looking forward to making more projects with this neat little colourful e-ink display.

Here’s the code – it assumes you have installed Flotilla and InkyPhat and needs Flotilla Touch and Dial modules. You will also need to have installed mpc and mpd and added 4 radio stations as described in my Flotilla radio project.

#!/usr/bin/env python

# simple internet radio with Flotilla and InkyPhat
# Script by Giles Booth x
# www.suppertime.co.uk/blogmywiki
# Always stop flotilla daemon before running Python with Flotilla
# with 'sudo service flotilla stop'

import os
import sys
import flotilla
import inkyphat
from PIL import Image, ImageFont

# Looks for the dock, and all of the modules we need
# attached to the dock so we can talk to them.

dock = flotilla.Client()
print("Client connected...")

while not dock.ready:
    pass

print("Finding modules...")
touch = dock.first(flotilla.Touch)
dial = dock.first(flotilla.Dial)

if touch is None or dial is None:
    print("Some Flotilla modules required were not found...")
    dock.stop()
    sys.exit(1)
else:
    print("Found. Running...")

os.system("mpc load")
dial_val = 0

inkyphat.set_image(Image.open("splash.png"))
inkyphat.show()

# Starts the loop going so it keeps working until we stop it
try:
    while True:

# volume control using dial
        new_dial_val = int(float(dial.data[0])/10.23)
        if new_dial_val != dial_val:
            dial_val = new_dial_val
            os.system("mpc volume " + str(dial_val))

# Looks for a Touch module and listens for an input

        if touch.one:
            os.system("mpc play 1")
            inkyphat.set_image(Image.open("logo-6music.png"))
            inkyphat.show()

        if touch.two:
            os.system("mpc play 2")
            inkyphat.set_image(Image.open("bbc-ws.png"))
            inkyphat.show()

        if touch.three:
            os.system("mpc play 3")
            inkyphat.set_image(Image.open("fip.png"))
            inkyphat.show()

        if touch.four:
            os.system("mpc play 4")
            inkyphat.set_image(Image.open("radio4.png"))
            inkyphat.show()

# This listens for a keyboard interrupt, which is Ctrl+C and can stop the program
except KeyboardInterrupt:
    os.system("mpc stop")
    inkyphat.paste(inkyphat.Image.new('P', (inkyphat.WIDTH, inkyphat.HEIGHT)))
    font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 36)
    print(dir(inkyphat.fonts))
    message = "goodbye"
    w, h = font.getsize(message)
    x = (inkyphat.WIDTH / 2) - (w / 2)
    y = (inkyphat.HEIGHT / 2) - (h / 2)
    inkyphat.text((x, y), message, inkyphat.RED, font)
    inkyphat.show()
    print("Stopping Flotilla...")
    dock.stop()

Here are the image files I made:

Posted in Raspberry Pi | Tagged , , , , , | Leave a comment