Wifi Router Webradio

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.

WL520GU with added serial port

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.

Wifi Radio LCD Display


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