One of the neat things about this board is that it uses only two pins on the R-Pi GPIO header to control: the 16×2 Character LCD; up to 3 backlight pins; and 5 keypad buttons. It uses an MCP23017-E/SPI2C port expander chip to make this happen.

The best part is you don’t really lose those two pins either, since you can still add I2C based sensors, RTCs, etc and have them share the I2C bus.

In this post, we update our original Raspberry Pi Internet Radio project using this cool Pi Plate. Our new radio shares many of the features of the original radio and adds: compact size; a color-changing LCD display; and more buttons for an improved user interface.

The Software

Once again, we’re using the Adafruit Occidentalis Linux distribution for the R-Pi. Three python classes from Adafruit handle all of the heavy-lifting for the LCD display, I2C bus, and MCP23017 port expander. We did have to make a few small changes to the Adafruit python classes to allow us to read all the buttons at once. You’ll find the details below.

Programming this beauty turned out to be a little trickier than the previous radio. The Pi Plate uses a serial interface to the R-Pi that’s quite a bit slower than a directly connected LCD. Polling for button changes in the same loop that handles the LCD made the buttons feel somewhat unresponsive. The solution was to move the LCD display to a separate worker thread and to use a Python queue to pass update messages. You’ll see the details in the source code below.

The Radio Play List

The radio play list / channel line-up is loaded dynamically from a file called radio_playlist.sh. This file is processed twice by the radio.py program. The first time it is executed as a shell script and the second time it is read as a text file to load the channel display names.

Don’t forget to change the Linux file permissions on this file to allow execute access.

Post navigation

125 thoughts on “Radio Pi Plate”

I had been struggling with my own program to do exactly this with no python or programming skills – managed to get mine working but no were as functional or nice as yours. (i did use Mplayer not MPC, as I could not get bbc live radio to work with MPC)

But I am having one problem with your script.
LCD.readButtons – I get an error, that doesn’t exist at all in my Adafruit_CharLCDPlate .py typed to change it to LCD.buttonPressed but doesnt seem that simple.

Are you using an old GIT version of CharLCDPlate or is there something else i am missing?

Hope you can help – your program would get me a home run with the wife!

I have tried to duplicate your Pi Plate radio.I have been able to get
to the point where the radio is functioning with the first station loaded
and displayed on the LCD. My remaining problem relates to the push buttons; I can’t get them to work. Do you have a working radio.py and
the associated Adafruit files? If you can send me a set of working files
for the Pi Plate radio I would be grateful. I am new to python and trying
to learn.

A great little radio project using the raspberry pi and Adafruit’s nice RGB Character lcd plate!
A big thanks to Sheldon for his help in obtaining the original class files for this project.
Works great! Nice Canadian Halifax Radio Stations to listen too!
Regards Barry

The versions of the Adafruit classes available via Git (as of July 2) don’t work with the current version of radio.py. (The buttons won’t respond) Replacing the new Adafruit files with the three that Sheldon has used instantly resolves the issue. Ask Sheldon to send you the zip of his versions after you’ve used LCDtest.py to confirm that all buttons on your plate are working correctly. Otherwise, this is a great project. Now I have to buy another Pi to play with, this one is now my Internet Radio. Thanks, Sheldon

Thanks for the work on this. I’ve been looking for a project of interest to dabble in python on the RPi.
I’m getting the following error when I try to run. I’ve reloaded everything and applied the mods as described, but I’m still getting the same error. I’m wondering if something is out-of-date.
Thanks,
erf

The LCD plate version is working nicely now. To eliminate pops when changing streams, install and configure PulseAudio following the directions in the link below. No changes to Sheldon’s instructions are required, but the pops are gone after the change.

Thanks for the info on what needs to be changed, I’m looking forward to the updated blog entry. Have you added any more features? This was my first project with the Pi. I learned how to solder and now learning python due to this project. Thanks for making it possible.

Thanks very much for your detailed overview on how you got this running. I think I am close to success but I am getting the following error when kicking off with ‘sudo python radio.py’. Any suggestions?

I’m pretty sure i have installed every thing as i should of done. I have run LCDtest.py and Adafruit_CharLCDPlate.py and the screen and buttons all seem to be working all ok. But i get this error message when attempting to run radio.py.

I emailed you a copy of the “radio” script I use in /etc/init.d to run the program automatically on start-up. When I get a chance, I’ll update this post to add a section on starting the program automatically.

I suspect a possible problem with your radio_playlist.sh file. I emailed a ZIP archive with all of the files I used. Please try the radio_playlist.sh file from this ZIP as a replacement for yours to see if it helps. Also, remember the radio_playlist.sh file is run as a Linux shell command so you’ll need to set execute permissions.

it´s work very god ,
and yes the problem was in the file radio_playlist.sh ,i changed by your file and now everything works 100%
can I also have the script to launch the radio.py on boot ! ,I already tried all ways and I can not do boot .

I was just wondering if there was any way of adding some code in so that the station info (i.e. what song is playing) can be scrolling on the second line of the LCD screen. I do not have a clue where to start or if its even possible.

Great Project. Newbie at this (still learning at 61!).Have got LCD display and buttons all working OK. However no music output and following error message when selecting a station:- “song number greater than playlist length”
Any help you can give me would be much appreciated.
Best Regards
John

Try running “sudo radio_playlist.sh” as a Linux terminal command to see if the shell script will run okay by itself. I sent you an email with a zip archive containing the files I used for comparison to your playlist.

I found that I had to change the absolute reference to the location of radio_playlist.sh on lines 133 and 136 of radio.py from
“/home/pi/projects/radio/radio_playlist.sh” to its location on my system to make the “song number greater than playlist length” error go away.

Thanks! Great project!

(Now if only I could be sure that I really soldered the pi plate together properly… display is a little flaky — I am afraid to push any buttons for fear of disturbing it….)

Love this I have been using a RPI as a internet radio using ssh or ampache to listen to radio for a while this is a great improvement in that I do not need another device to control it. Only thing I would change and my do some research on doing is getting the stream data to post up on an update from mpd through an mpc command or “watch -n 1 mpc” which I use in ssh to see whats playing on the streams that update for each song. I do not know python but it looks like its approachable with the very basic programming knowledge that I have.
which gives you this for SOG:

South of Gilman St.: Dead Kennedys – I Fought The Law
[playing] #4/14 33:12/0:00 (0%)
volume: 92% repeat: on random: off single: off consume: off

Have got it scrolling through the menus, but am having the same problem of “song number greater than playlist length” error and no audio. Have tried to chmod the radio_playlist.sh file without any joy.

Thanks Sheldon
Cheers for the email and files along with the tips.
I think I was able to get it going by cleaning up the radio_playlist.sh. I think I must have picked up
and added some invisibles. I ran the script through a text cleaner as your script would run and mine wouldn’t.
Anyway after scrubbing my playlist to Unix format all is beautiful.

Hi Jim,
already read this comment by Sheldon:
For those of you having problems with the latest versions of the Adafruit classes, you can work around them by replacing “LCD.readButtons()” with “LCD.buttons()” in lines 165 and 169 of radio.py

Adafruit has rewritten the CharLCDPlate and I2C classes and done a kick-ass job of speeding things up. My modifications to these classes are no longer required!

Check that you are using the latest libraries from Adafruit…
cheers,
Simon

Hey there, thanks for your great work!
Unfortunately it seems, that the new python classes from Adafruit aren’t working for me. Radio is starting and playing, but the buttons don’t work and the LCD is only showing the first radio station.
Could you please upload the python classes you are using?

Sheldon, I’m having the same issues as some others with the ‘song number greater than playlist length’. Tried creating a new file, changing permissions and still not working. The rest of the radio.py and the LCD all work, and the titles under # in the playlist all work on the display and can be scrolled through. Any help or tips are appreciated, it’s a great project and I have it ‘almost’ working.

Hi all
First thing is to say thanks for all the comments, as it has solved sevral of my faults getting the wifi radio up and running..
Just to give an update on my headaches getting it working,
I started the radio project with the Pi Plate at the begining of december, and tried so many things to get it working, I could run the test program fine, but not the radio… nothing… just errors..
A big thanks to you lot and sevral errors later including the buttons error, it now works as far as the buttons and the display works fine.
But I get no sound…. (i have tried mpc add, and play, this works fine)
Now for the strange bit…
If i remove the hashbang ( #! /bin/sh ) at the begining of the playlist, it plays the first 3 tracks on the play list in any order, but not any more, unless I duplicate an entry at the end, and this one plays as well..??? (I didn’t think it would read the list correctly with out the hashbang …?? desperation….) I did set the file permissions correctly.
If I keep the hashbang I get the error “song number greater than playlist length.” (and no music)
Any ideas ……

Another thing I did wrong, was to de-crackle the audio by installing pulse audio, this worked ok but made it slugish, (this could have been due to the so many things I installed trying to get it to work)

I then read an update to reanable alsa and disable pulse audio and update the files and op system. (big mistake)
This took ages and then locked up…. on a reboot it had killed the boot elf.. a quick copy over from a backup and it was working.. sort of.
with lotts of errors.
So A wipe and reinstall, a quick reconfig and i’m back up and running in just over an hour, (pew)
I still have the same problems outlined earlyer.. (help)..

Hi all
just to update readers,
Thanks to sheldon for his help I have got it up and running,
It turned out I had compiled the file in dos so had the wrong file extention type,
Once I had used the correct format it and worked fine..

Great post. I think the usage of threads/queues to delink the display from the reading of the buttons was a great enhancement over similar projects (I was using Adafruit’s Pandora radio – but am now sold on this).
The issues I faced were
1) The Adafruit_CharLCDPlate changes didn’t work. Then I read the posts below the main article and was able to fix it. Could I request that a note to that be put in the main article
2) The default raspbian install did not seem to have mpd/mpc which I fixed by an apt-get install. The article assumes an Occidentalis distrib.

I haven’t had much time to spend on this – but I do have some big plans for a V2.0.
I’m building a vintage radio project around a 1940 Addison wooden tube radio using a combination of a RPi and an Arduino. The Arduino will drive an OLED display and include a rotary encoder for channel selection along with a micro-servo to move the old radio dial (just for fun). I’ve worked out the interrupt-driven encoder code and have some of the hardware built on a prototype board. … Figuring out where to cut the wooden case to add the OLED display will be next.

Thanks for sharing your efforts with us. I have done everything except playing with class files and i’m still getting a
station on the lcd and buttons not working. Could you please send me the class files so I can give that a try.

I’d love to see your observations on V2.0 once you finish. I’ll just be making minor mods to your code to make the following changes
(a) Have some config (or ini) file which keeps track of the volume / station # across a device reboot. Otherwise it always seems to come up at full volume on station 1.
(b) Add some optional extras like occasionally scrolling the current time on the screen, give a temp display etc.

An update to my problems,
The play list not displaying or reading correctly was due to a typo (a , instead of a .) by me very early on in the listing, but didn’t show up till I had more than 20 entries… strange… But sorted..

Still having a 30 to 40 second delay from user name to pass word prompt when logging on to via http://ftp..

Many thanks as always to sheldon for all his help,
This project is now my main radio i tend to listen to, and I will be building a second..
Best use of a raspberry pi to date…

Hi I just found your page and bought the pi 512 and the LCD screen, i managed to make it display the left right up down slect etc..
However i could not download your file and install it… it says could not find file radio.py what i am doing wrong.
Please can you help me i am a newbie in linux and pi.

Very cool Sheldon, i do furniture restoration for a living and we get some interesting radios come through at times. I have played with my setup a little and added IrRemote and sleep timer function through the remote. I have not looked at keeping your playlist in line with MPC at all though. Remote just passes commands to MPC but in all reality it could pass the commands to the PiRadio to make a neater package. I am also using cron for my morning wake-up.

Amazing job man, your scripts have traveled to France where I’ve successfully made it work almost out from the box, thanks to all the replyz !!
I’ve witnessed a weird thing though, the display keep some letters @ the end of the upper line …. is there a way to refresh the display ?
Thanks again for your great share !
John

It utilises a scrolling text display from the station, which looks and is very useful as quite a few stations don’t ID or state what’s playing, as I have now got over 40 to go at.
What I would like to know is do you think it would be possible to just import just the scrolling info line to the second display line of your program , as I like your program layout and ease of use and don’t want to change that.
Ideas ???

Wonder if you or anyone knows of a way to set the wifi user name and password (or have more than one set) without using a pc,
As I would like to take my wifi radio to and from my works, and just need to be able to plug in and go.

I really like what you done here but I need your help with how to set this up. I have no experience with python but a little with linux and the command line. I have set up the Adafruit and it works OK but I don’t want to be tide to the pandora web site. What I need to know is just where do I put the python scripts (what folder) to make it work? Sorry if you have covered this already. I just found your site and haven’t gone read all the comments yet.

Just something I noticed, and may be of help.
I finally got around to getting a HDMI to VGA adapter, and watching the radio working live , not via ftp.
Upon booting I noticed afsck warning, telling me it hadn’t been shut down properly,
I also noticed after shutting the radio down I could still type and command directly.
So to be on the safe side I added the -H switch to line 278 …….. output = run_cmd(“sudo shutdown now -h”)
This seems to shut down better and also flash the green led 10 times,
Which I found to be a nice indicator it was shut down and safe to pull the power.
As I have found the little radio to be so useful I wouldn’t want to corrupt the sd card. (better safe than sorry)

Just like some other fans of your project I would like to have the LCD showing some extra info.
I was searching around and at the raspberry forum i found some info about python-mpd2. I have installed the library and it works great, any easy way to get the info.

I suspect you may have SFTP’ed the radio_playlist.sh file from Windows to Linux as a “text” file and not a “binary” file. The radio_playlist.sh file must have UNIX line terminators and not Windows/DOS line terminators (LF and not CRLF). Try running radio_playlist.sh from a terminal command line to see if it runs without errors.

This has been answered a number of times in the comments. Try searching the comments for “readButtons” …

“For those of you having problems with the latest versions of the Adafruit classes, you can work around them by replacing “LCD.readButtons()” with “LCD.buttons()” in lines 165 and 169 of radio.py Adafruit has rewritten the CharLCDPlate and I2C classes and done a kick-ass job of speeding things up. My modifications to these classes are no longer required!”

Hi All
Has anyone tried to scroll the second line with the station info,
As I have followed several links and all I seem to do no matter what I try is kill the radio program,
I have also been trying to mod the pi plate files so I can use a rotary encoder as the channel selector to no avail.
(as I have now got over 60 channels and two Pi radios)

Electronics and soldering I can do in my sleep, but python is twisting my melons….
Can anyone throw me a line and point me in the right direction..

Hi, I’ve had a crack at modifying you work. I don’t use the volume control, as I hook up to a stereo, so I’ve swapped them for a play and stop button. You can get rid of the references to Adafruit_I2C and Adafruit_MCP230xx. You don’t use them.

Also, I don’t think you licence notice is valid. Without the copyright notice and the actual text of the BSD licence it’s not valid. But I think that is a good thing. Even an open source licence imposes restrictions, and for something like this, that is a learning tool, I think it’s better to let people do whatever they want with it, much like the work that you reference at the top of your script. The community is strong enough that the information will get shared, and a licence just scares people off.

Anyway, here is my version of your code.
#!/usr/bin/python

# radio.py, version 2.1 (RGB LCD Pi Plate version)
# February 17, 2013
# Written by Sheldon Hartling for Usual Panic
# BSD license, all text above must be included in any redistribution
#

# —————————-
# START THE MUSIC!
# —————————-
# Start music player
LCD_QUEUE.put(PLAYLIST_MSG[STATION – 1], True)
run_cmd(“mpc volume +100″) # sets the volume to maximum. This is good if you want to output to a line in, but might be a bit loud if you are going to use headphones.
mpc_play(STATION)
countdown_to_play = 0

# Need to add some code that lets us remember if MPC was playing or not, and choose the colour accordingly until then, just make it white
LCD.backlight(LCD.WHITE)
LCD_QUEUE.put(PLAYLIST_MSG[STATION – 1], True)

I made ​​the change line 165 and 168 (not 169), so the program now displays correctly.
But I have a problem with audio, no sound on the “headphone” output even if I validate this output in the “Menu”.
Buttons “up” and “down” does not display the volume. The buttons work properly because they act in the “Menu”.

If I test the command “mpc play” outside of your script, the sound works correctly.

I think my problem is no sound because my “radio_playlist.sh” file does not have proper permissions “775”
For the “volume” I realized that when you press the “up” button and “down” there is no display on the display.
I would like to test the code “song info, artist” who is on this link:http://didtheypush.blogspot.nl/2013/10/raspyfi-and-adafruit-16 × 2-char-lcd-plate.html

Could you send me your startup script? If possible.

Your work is excellent, and I hope you find the time to change your script to display scrooling current title and artist name.

The “radio_playlist.sh” file is executed by the program as a shell script. It must be a properly formatted shell script (with LF UNIX line terminators and not CRLF Windows line terminators) and you must have execute permissions. A “chmod 755″ usually does the trick.

The “song number greater than playlist length” error is most often caused by problems with the “radio_playlist.sh” file. This file is executed by the program as a shell script and it must have proper Linux/UNIX line terminators and execute permissions. A “chmod 755″ usually does the trick.