This is basically the ASUS WL520GU based Webradio as Jeff Keyzer presents it on his webpage Mightyohm.com, only that I adapted the display related shell scripts to suit my LCD Display driver.
This is a great project and I would like to say thanks to Jeff for his great step by step instructions!
As a connector for the serial port, I used a mini DIN connector and socket which fits quite nicely to the side of the router.
The Soundcard I use is a cheap CM109 based USB sound dongle purchased at Dealextreme. I can not complain about the sound quality, at least there’s no hiss and other digital artifacts as other people experienced. The sound dongle got recognized by the firmware as a 48kHz device only, so I had to set the correct output format in /etc/mpd.conf
This is how the display looks like, as a housing I used some cable conduit where my display + electronics happened to fit right into. I just gave it a slash of black color, that was it. Buttons are some leftovers from another project I did, they will be replaced by black ones as soon as I find new cover lids.
As I wanted to keep the LCD display driver as general as possible, I opted to do all the text parsing and line wrapping related stuff straight in the linux box, therefore I changed the shell scripts responsible for the display output.
Update: (03/09/2010)
Wrote a new Interface script which allows to display a menu of all preset radiostations. By sending ‘MENU_’ over RS232 to the router, the display will now show the current station, any ‘BUTTON_’ command will cycle through the preset radiostations. One more ‘MENU_’ command will select the current station and start playing it.
This way, the station selection is performed in a much nicer way than previously with the Up/Down commands. The new script can be found in the project zip file and is named ‘interface3.sh’.
Here’s what I came up with:
Interface3.sh
#! /bin/sh - # interface3.sh - Wifi Radio User Interface Script # 01/29/09 Jeff Keyzer http://mightyohm.com # # Station Menu functionalities added by Steve Bidinger, Obsoletetechnology # www.obsoletetechnology.wordpress.com # 03/09/2010 # # This shell script sets up a playlist in mpd and changes playlist entries # based on the position of a tuner knob connected to an AVR on the router's # serial port. # # The script expects the AVR to send data at 19200 baud (8N1) to the router, # in the format "BUTTON_" and "MENU_", one line at a time. # # This script also launches display7.sh, the LCD display script. # # Sending "MENU" to the router will put the radio into Menu mode, additional # "BUTTON_" commends will scroll through the list of preset Stations. # Station can be selected by sending "MENU_" once more. # # For more information, visit # http://mightyohm.com/blog/tag/wifiradio/ # # This work is protected by the # Creative Commons Attribution-Share Alike 3.0 United States License. # http://creativecommons.org/licenses/by-sa/3.0/us/ # # NEW functions # For MENU Button and UP Button control # Some configuration settings VOLUME=100 STATIONS=15 MAXADC=15 trap 'kill $! ; exit 1' SIGINT # exit on ctrl-c, useful for debugging # kills the display.sh process before exiting stty 19200 -echo < /dev/tts/0 # set serial port to 9600 baud # so we can talk to the AVR # turn off local echo to make TX/RX directions # completely separate from each other # mpc setup mpc volume $VOLUME # adjust this to suit your speakers/amplifier mpc clear # clear current playlist # build a playlist, substitute your favorite radio stations here # the first line becomes station #1, and so on. mpc add http://streamingserver01.byte.fm:8000 # Byte.FM mpc add http://85.17.146.164:80/1 # Intergalactic FM 1 mpc add http://85.17.146.164:80/2 # Intergalactic FM 2 mpc add http://85.17.146.164:80/4 # Intergalactic FM 4 mpc add http://scfire-ntc-aa06.stream.aol.com:80/stream/1017 # Sky FM Roots Reaggea mpc add http://164.15.20.12:8000/stream.mp3 # Radio Campus BXL mpc add http://dradio.ic.llnwd.net/stream/dradio_dlf_m_a # Deutschlandfunk mpc add http://voxsc1.somafm.com:8090 # Soma FM Indie Pop Rocks mpc add http://dradio.ic.llnwd.net/stream/dradio_dwissen_m_a # Deutschlandfunk Wissen mpc add http://72.233.84.175:80 # Dubstep.FM mpc add http://voxsc1.somafm.com:2200 # Soma Fm PopTron mpc add http://voxsc1.somafm.com:8600 # SomaFm Sonic Universe mpc add http://dradio.ic.llnwd.net/stream/dradio_dkultur_m_a # Deutschlandfunk Kultur mpc add http://voxsc1.somafm.com:2020 # SomaFm Sonic Mission Control mpc playlist # show the resulting playlist oldstation=00 # var to keep track of what station we're playing value=1 # var for current Button position # build array with the radio station names # Arrays not implemented in busybox, declare as variables Station_1=ByteFM Station_2=Intergalactic_FM_1 Station_3=Intergalactic_FM_2 Station_4=Intergalactic_FM_4 Station_5=SkyFM_RootsReggae Station_6=RadioCampus_BXL Station_7=Deutschlandradio Station_8=SomaFM_IndiePopRocks Station_9=Deutschlandradio_Wissen Station_10=DubstepFM Station_11=SomaFm_PopTron Station_12=SomaFm_SonicUniverse Station_13=Deutschlandradio_Kultur Station_14=SomaFm_SonicMissionControl # Tell the Display uC we're ready to start doing stuff sleep 1 echo -n "LCD_START" > /dev/tts/0 sleep 1 echo -n "LCD_START" > /dev/tts/0 sleep 1 # launch LCD display routines in the background /root/display7.sh & # start mpd display routine # Start playing 1st stream in playlist mpc play $value while true # loop forever do inputline="" # clear input # Loop until we get a Menu command from the display until inputline=$(echo $inputline | grep -e "^MENU_") do inputline=$(head -n 1 < /dev/tts/0) # get input from serial port echo "$inputline" done # Now we are in MENU mode, show stations and navigate with BUTTON, exit with another MENU command echo "Menu Called, killing Display process" kill $! echo -en "\2" > /dev/tts/0 # Clear LCD # Display current Station echo "Current Station: Station_$value $(eval echo \$Station_$value)" echo "Current Station_$value : $(eval echo \$Station_$value)" > /dev/tts/0 # Loop until we get another Menu command from the display inputline="" # clear input until inputline=$(echo $inputline | grep -e "^MENU_") do inputline=$(head -n 1 < /dev/tts/0) # get input from serial port echo "$inputline" if [ ! -z "$(echo $inputline | awk '/BUTTON_/')" ] #Check for BUTTON command then echo "Button command received" echo -en "\2" > /dev/tts/0 # Clear LCD value=$(expr $value + 1) if [ $value = $STATIONS ] then echo "Resetting Counter" value=1 fi echo "$value" echo "Selected Station: Station_$value $(eval echo \$Station_$value)" echo "Station_$value : $(eval echo \$Station_$value)" > /dev/tts/0 fi done echo "Menu Exit Called, Restart Display process and MPC with new station" # Test if new station selected if [ "$value" -ne "$oldstation" ] then echo "New station selected: $value" echo "New station selected: $value" > /dev/tts/0 # Message to the user mpc play $value # Change to new station sleep 1 fi /root/display7.sh & # Restart Display routine oldstation=$value # remember what station we're on so we know # if we need to change stations next time around done
And here the shell script for the display:
Display7.sh
#! /bin/sh - # display7.sh - Wifi Radio LCD display routines, revision 7 # 01/29/08 Jeff Keyzer http://mightyohm.com # Adapted to PIC LCD Driver by: # 01/09/2010 Steve Bidinger https://obsoletetechnology.wordpress.com # Thanks to Jeff for this cool project! # This shell script queries mpd for current song information and sends # relevant bits of it to the serial port, where an PIC-based LCD display # is waiting. # # For more information, visit # http://mightyohm.com/blog/tag/wifiradio/ # # This work is protected by the # Creative Commons Attribution-Share Alike 3.0 United States License. # http://creativecommons.org/licenses/by-sa/3.0/us/ # trap 'exit 1' SIGINT # exit on ctrl-c, useful for debugging #stty 9600 -echo /dev/tts/0 # Clear LCD L_pointer=1 # Start value for LCD Character pointer EndPointer=$((countT - 1)) # determines end of loop i=0 # Loop Count variable Cspace=" " # Match pattern Character # Count down the lines and display line per line on lcd while [ $L_pointer -le $EndPointer ]; do echo "Lpointer: $L_pointer" # DEBUG echo "EndPointer: $EndPointer" # DEBUG Line1=$(expr substr "$title" $L_pointer $LINELENGHT) # Cut out 1 entire screen lenght echo "Line1 RAW: $Line1" # DEBUG # Find index of "space" character from right to left j=${#Line1} while [ $j -gt 0 ] do Testchar=$(expr substr "$Line1" $j 1) # get individual chars from right to left # echo "Testchar: $Testchar" # DEBUG if [$Testchar = $Cspace ]; then # find first matching char from right to left echo "Space Char found at index: $j" Cindex=$j j=1 # reset variable fi j=$(($j - 1)) done # Test lenght once more, if less than 40, there will be no break between lines j=${#Line1} echo "Line Char Count: $j" if [ $j -lt 40 ]; then echo "less than 40 chars in line" L_pointer=$((L_pointer + j )) # reposition pointer to end of current line else # test index position, if less than 10, do nothing if [ $Cindex -gt 10 ]; then echo "larger than 10" Line1=$(expr substr "$title" $L_pointer $Cindex) # Get data until last space char L_pointer=$((L_pointer + Cindex )) # re-position pointer else L_pointer=$((L_pointer + j )) # reposition pointer to end of current line fi fi # Here is the result of the processing echo "Line1 PROCESSED: $Line1" # test if first or 2nd line, 2nd line requires a clear screen command # i = odd -> first line, i = even -> second line if [ $((i % 2)) -eq 0 ]; then # first line echo -n $Line1 > /dev/tts/0 echo -ne "\r" > /dev/tts/0 # Carriage return charcount=${#Line1} # test if 1 line only if [ $charcount -lt 40 ]; then sleep 1 #echo -ne "\2" > /dev/tts/0 fi else # second line echo -n $Line1 > /dev/tts/0 sleep 2 echo -ne "\2" > /dev/tts/0 # Clear screen fi Line1="" # empty variable i=$((i + 1)) # increment i done return } # Begin of MPD polling Loop while true # loop forever do # get the name of the current song from the mpd server and remove 'Name:' nameraw=$(echo "currentsong" | nc localhost 6600 | grep -e "^Name: ") streamname=$(echo $nameraw | sed 's/Name: //') title=$streamname LCDwrite # call function # get artist/title of current song, check if exists, otherwise title = null titleraw=$(echo "currentsong" | nc localhost 6600 | grep -e "^Title: ") if [ -z "$titleraw" ] then titleraw="No Title" fi # remove the word "Title:" streamtitle=$(echo $titleraw | sed 's/Title: //') title=$streamtitle LCDwrite # call function done ------------------------------------------------------------------------------------------------------------
A few more thoughts:
As my display driver has 2 inputs left for more buttons, it would be nice to add a ‘Menu’ function to the router, which, when pressed would show a list of all preset stations. With ‘UP’ and ‘DOWN’, one could navigate and select the desired program by pressing ‘Menu’ once again. (Now implemented, see above!)
Script Download: here