{"id":1148,"date":"2009-02-03T08:27:46","date_gmt":"2009-02-03T15:27:46","guid":{"rendered":"http:\/\/mightyohm.com\/blog\/?p=1148"},"modified":"2022-12-28T12:44:42","modified_gmt":"2022-12-28T20:44:42","slug":"building-a-wifi-radio-part-8-adding-a-tuning-control","status":"publish","type":"post","link":"https:\/\/mightyohm.com\/blog\/2009\/02\/building-a-wifi-radio-part-8-adding-a-tuning-control\/","title":{"rendered":"Building a Wifi Radio &#8211; Part 8, Adding a Tuning Control"},"content":{"rendered":"<p><em>This is the eighth part of an ongoing series about building a low cost, open source streaming internet radio based on the <a href=\"http:\/\/www.dpbolvw.net\/click-3238164-10440897?url=http%3A%2F%2Fwww.newegg.com%2FProduct%2FProduct.aspx%3FItem%3DN82E16833320023%26nm_mc%3DAFC-C8Junction%26cm_mmc%3DAFC-C8Junction-_-Network%2B-%2BWireless%2BRouters-_-ASUS-_-33320023&amp;cjsku=N82E16833320023\" target=\"_top\" rel=\"noopener\">ASUS WL-520gU Wireless Router<\/a><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.ftjcfx.com\/image-3238164-10440897\" border=\"0\" alt=\"\" width=\"1\" height=\"1\" \/>.\u00a0 If you haven\u2019t already, check out the previous parts (see the links at the end of this article) for some background about the project.<\/em><\/p>\n<p>In <a href=\"http:\/\/mightyohm.com\/blog\/2008\/12\/building-a-wifi-radio-part-7-building-an-lcd-display\/\">part seven<\/a>, we added an LCD status display for the radio that shows the stream name as well as the artist and title of the current track.\u00a0 In this part, we&#8217;ll add a tuning knob that lets us change stations without using a computer.<\/p>\n<p>It turns out that this is mostly a software exercise, made simple by taking advantage of the analog to digital converter function of the Atmel ATmega168 AVR that is controlling the LCD display.\u00a0 The addition of the tuner control turns the display circuit into a very simple user interface.\u00a0 Turn the knob and the station changes.\u00a0 The position of the knob determines what station the radio is &#8220;tuned&#8221; to, and when combined with a calibrated scale it will make it easy to change to any one of the several streaming radio stations stored as presets (favorites?) in the router.<\/p>\n<p>To give you an idea of how this works, here is a demo of the tuner control changing between ten preset stations I have set on the router.\u00a0 The tuner control is in the upper right hand corner of the breadboard.\u00a0 As I adjust the control, the music changes and LCD display updates to show the name of each new station.<\/p>\n<p><object width=\"500\" height=\"375\" data=\"http:\/\/www.flickr.com\/apps\/video\/stewart.swf?v=67090\" type=\"application\/x-shockwave-flash\"><param name=\"flashvars\" value=\"intl_lang=en-us&amp;photo_secret=4181c97c88&amp;photo_id=3238566442\" \/><param name=\"bgcolor\" value=\"#000000\" \/><param name=\"allowFullScreen\" value=\"true\" \/><param name=\"src\" value=\"http:\/\/www.flickr.com\/apps\/video\/stewart.swf?v=67090\" \/><param name=\"allowfullscreen\" value=\"true\" \/><\/object><\/p>\n<p>Is that cool or what?<\/p>\n<p>If you are interested in adding this functionality to the radio, keep reading and I&#8217;ll show you how.<\/p>\n<h3>Changes to the hardware:<\/h3>\n<h4>You will need:<\/h4>\n<ul>\n<li>The completed AVR-based LCD display from part seven<\/li>\n<li>A 1k-10k trimmer or potentiometer, linear taper<\/li>\n<li>Some hookup wire<\/li>\n<\/ul>\n<h4>Schematic:<\/h4>\n<p>Here is an updated schematic of the AVR circuit showing the potentiometer connected to ADC4 (pin 27).<\/p>\n<figure id=\"attachment_1154\" aria-describedby=\"caption-attachment-1154\" style=\"width: 499px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/mightyohm.com\/blog\/wp-content\/uploads\/2009\/02\/interface.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1154\" title=\"Wifi Radio User Interface Schematic\" src=\"http:\/\/mightyohm.com\/blog\/wp-content\/uploads\/2009\/02\/interface-499x314.png\" alt=\"Wifi Radio User Interface Schematic\" width=\"499\" height=\"314\" \/><\/a><figcaption id=\"caption-attachment-1154\" class=\"wp-caption-text\">click to enlarge<\/figcaption><\/figure>\n<h4>Firmware:<\/h4>\n<p>The AVR firmware has been significantly expanded, slightly reworked and cleaned up in some areas.<\/p>\n<p>The most important changes are:<\/p>\n<ul>\n<li>The addition of a serial transmit function so the AVR can talk to the router (based on the uart_putchar function)<\/li>\n<li>New code supporting the analog to digital converter (ADC) which reads the value of a potentiometer connected to ADC4.<\/li>\n<li>A new Timer1 overflow interrupt has been added, which occurs roughly every 0.5 seconds.\u00a0 The interrupt service routine (ISR) checks the position of the tuner control, and if it has changed, sends the value to the router.\u00a0 The ISR is towards the top of the file, see the SIGNAL (TIMER1_OVF_vect) section.<\/li>\n<\/ul>\n<p>The ADC range of the ATmega is 0 &#8211; 1024 for an input voltage from 0 to 5V.\u00a0 The AVR sends serial data in the format &#8220;Tuner: Value&#8221; back to the router when the tuner position changes by more than ADC_SENS counts (default is 5).\u00a0 The AVR waits for an &#8220;AVR Start!&#8221; command from the router before sending any data, this avoids filling up the serial receive buffer on the router before it&#8217;s ready to start processing data.\u00a0 An important consequence of this is that the AVR must be reset before running the control script on the router.<\/p>\n<p>You can download the source code and compiled .hex file <a href=\"http:\/\/mightyohm.com\/files\/wifiradio\/AVR_wifiradio_interface.zip\">here<\/a>.\u00a0 Flash it to the AVR using any compatible ISP programmer and you should be good to go.\u00a0 The source is commented fairly well so if you&#8217;re interested in learning how the interface works, take a look.\u00a0 You will need a copy of the <a href=\"http:\/\/www.atmel.com\/dyn\/resources\/prod_documents\/doc2545.pdf\">ATmega168 datasheet<\/a> to understand the register names and other architecture-specific parts of the code.\u00a0 Feel free to post in the comments with any questions.<\/p>\n<h4>Modifying the circuit:<\/h4>\n<p>This part is pretty simple &#8211; just wire the potentiometer as shown in the schematic.\u00a0 Most potentiometers have three terminals.\u00a0 The left terminal goes to ground, the right one to +5V, and the middle terminal to ADC4 on the AVR (pin 27).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"http:\/\/mightyohm.com\/files\/flickr\/3238589400_3134e598cc.jpg\" alt=\"Tuner control on breadboard\" width=\"500\" height=\"375\" \/><\/p>\n<h3>Tweaks to the OpenWrt configuration:<\/h3>\n<p>To make bidirectional communication with the AVR work, we have to change a couple config files on the router and disable some services that would otherwise get in the way.<\/p>\n<h4>\/etc\/config\/network<\/h4>\n<p>The first change is to modify the \/etc\/config\/network file so that we can always telnet or ssh into the router on a LAN port using the IP 192.168.1.1.\u00a0 The ability to access the router via ethernet is helpful in case we screw something up and lose the wireless connection or the router loses it&#8217;s IP address, etc.<\/p>\n<p>Modify the LAN section of \/etc\/config\/network to look like this (changes in bold):<\/p>\n<blockquote>\n<pre>#### LAN configuration\r\nconfig interface lan\r\n<strong>#option type \u00a0\u00a0\u00a0 bridge<\/strong>\r\noption ifname\u00a0\u00a0\u00a0 \"eth0.0\"\r\noption proto\u00a0\u00a0\u00a0 static\r\n<strong>option ipaddr\u00a0\u00a0\u00a0 192.168.1.1\r\noption netmask\u00a0\u00a0\u00a0 255.255.255.0<\/strong><\/pre>\n<\/blockquote>\n<p>Save changes, restart the router, and connect an ethernet <a href=\"http:\/\/en.wikipedia.org\/wiki\/Ethernet_crossover_cable\">crossover cable<\/a> (straight cable might work on some computers) to the router.\u00a0 Configure your desktop\/laptop computer with a static IP, like 192.168.1.185.\u00a0 Try to open a telnet connection (or ssh if you have set a password on the router) and see if you can log in.\u00a0 If not, don&#8217;t continue with the next steps until you can get this working.<\/p>\n<h4>\/etc\/inittab<\/h4>\n<p>We previously used the router&#8217;s serial port to get a login shell.\u00a0 Now that we&#8217;re trying to receive data from the AVR on the same serial port, we need to disable the login shell or it will capture the data before we can get to it.<\/p>\n<p>Edit \/etc\/inittab to look like this (changes in bold):<\/p>\n<blockquote>\n<pre>::sysinit:\/etc\/init.d\/rcS S boot\r\n::shutdown:\/etc\/init.d\/rcS K stop\r\n<strong>#tts\/0::askfirst:\/bin\/ash --login\r\n#ttyS0::askfirst:\/bin\/ash --login<\/strong>\r\ntty1::askfirst:\/bin\/ash --login<\/pre>\n<\/blockquote>\n<h4>\/etc\/sysctl.conf<\/h4>\n<p><a href=\"http:\/\/en.wikipedia.org\/wiki\/System_request\">Sysrq<\/a> is a fascinating and very low level debugging feature of the Linux kernel.\u00a0 It can be used to perform troubleshooting operations and reboot the system.\u00a0 Usually it is invoked with a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Magic_SysRq_key\">magic key combination<\/a> on a desktop computer, but in this case I found that it is easy to accidentally trip over the serial port when using an AVR.\u00a0 (The &#8220;break&#8221; RS-232 code triggers Sysrq, this probably has something to do with it.)<\/p>\n<p>Fortunately, it&#8217;s easy to disable by editing the \/etc\/sysctl.conf file and adding these lines:<\/p>\n<blockquote>\n<pre><strong># Disables the magic SysRq key\r\nkernel.sysrq = 0<\/strong><\/pre>\n<\/blockquote>\n<p>Reboot the router to apply the changes.\u00a0 Now we can get on with the good stuff!<\/p>\n<h3>Shell scripting magic:<\/h3>\n<p>The real action happens on the router, where a shell script waits for input from the router and changes the station accordingly.<\/p>\n<p>This script is called <a href=\"http:\/\/mightyohm.com\/files\/wifiradio\/interface.sh\">interface.sh<\/a> and can be downloaded to the router using wget as shown:<\/p>\n<blockquote>\n<pre>root@OpenWrt:~# <strong>cd ~<\/strong>\r\nroot@OpenWrt:~# <strong>wget http:\/\/mightyohm.com\/files\/wifiradio\/interface.sh<\/strong>\r\n...\r\nroot@OpenWrt:~# <strong>chmod ugo+x interface.sh<\/strong><\/pre>\n<\/blockquote>\n<p>The interface script calls an updated version of the display script from part 7, called <a href=\"http:\/\/mightyohm.com\/files\/wifiradio\/display2.sh\">display2.sh<\/a>:<\/p>\n<blockquote>\n<pre>root@OpenWrt:~# <strong>wget http:\/\/mightyohm.com\/files\/wifiradio\/display2.sh<\/strong>\r\n...\r\nroot@OpenWrt:~# <strong>chmod ugo+x display2.sh<\/strong><\/pre>\n<\/blockquote>\n<p>Once both scripts are downloaded, executable and located in \/root you can launch interface.sh as follows:<\/p>\n<blockquote>\n<pre>root@OpenWrt:~# <strong>.\/interface.sh<\/strong>\r\nvolume: 60%   repeat: on    random: off\r\nvolume: 60%   repeat: on    random: off\r\nadding: http:\/\/relay3.slayradio.org:8000\/\r\nadding: http:\/\/scfire-dtc-aa01.stream.aol.com:80\/stream\/1046\r\nadding: http:\/\/208.101.28.234:8004<\/pre>\n<p>&#8230; more stations here &#8230;<\/p>\n<pre>Tuner Position:  0\r\nNew station...\r\nhttp:\/\/relay3.slayradio.org:8000\/\r\n[playing] #1\/10   0:00\/0:00 (100%)\r\nvolume: 60%   repeat: on    random: off<\/pre>\n<\/blockquote>\n<p>The interface script adds ten presets to the router, shows the playlist, and then waits for valid tuner data from the AVR.\u00a0 Once it receives a &#8220;Tuner: value&#8221; line (which should occur shortly after the AVR receives a go signal from the script), the script prints the received tuner positon and changes to the requested station.\u00a0 It will then wait for new tuner data from the AVR and change the station when necessary.<\/p>\n<p>As you can see in the video, this works very well.\u00a0 Over a fast Wi-Fi connection, the time to change stations is almost instantaneous &#8211; very satisfying!<\/p>\n<p>That&#8217;s it for part eight.\u00a0 In part nine, I&#8217;ll add some finishing touches to the router configuration and start talking about enclosures.\u00a0 Stay tuned!<\/p>\n<p><strong>Update:<\/strong> There is a new <a href=\"http:\/\/mightyohm.com\/forum\/viewforum.php?f=2\">Wifi Radio Discussion Forum<\/a>, hop over there to ask questions about the project or see what other people are working on!\u00a0 (<em>4\/12\/09)<\/em><\/p>\n<p><strong>Update 2: <\/strong><a href=\"http:\/\/mightyohm.com\/blog\/2009\/05\/building-a-wifi-radio-part-9-a-few-odds-and-ends\/\">Part nine is now available.<\/a><em><br \/>\n<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the eighth part of an ongoing series about building a low cost, open source streaming internet radio based on the ASUS WL-520gU Wireless Router.\u00a0 If you haven\u2019t already, check out the previous parts (see the links at the end of this article) for some background about the project. In part seven, we added &hellip; <a href=\"https:\/\/mightyohm.com\/blog\/2009\/02\/building-a-wifi-radio-part-8-adding-a-tuning-control\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Building a Wifi Radio &#8211; Part 8, Adding a Tuning Control<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[5,10,443],"tags":[61,119,36,70,46,66,91,68,120,24,165,71,162],"class_list":["post-1148","post","type-post","status-publish","format-standard","hentry","category-electronics","category-microcontrollers","category-projects-2","tag-avr","tag-c","tag-diy","tag-embedded-linux","tag-lcd","tag-linux","tag-noisebridge","tag-openwrt","tag-programming","tag-project","tag-shell-script","tag-streaming-radio","tag-wifiradio"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pioCd-iw","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":333,"url":"https:\/\/mightyohm.com\/blog\/2008\/10\/building-a-wifi-radio-part-1-introduction\/","url_meta":{"origin":1148,"position":0},"title":"Building a Wifi Radio &#8211; Part 1, Introduction","author":"Jeff","date":"October 9, 2008","format":false,"excerpt":"This article is the first of a series that will document the development of a low cost, open source wireless streaming internet radio receiver.\u00a0 All construction details, including schematics, source code, and even the design process itself will be documented on this blog. Comments and (constructive) criticism are welcome. Click\u2026","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/mightyohm.com\/blog\/category\/electronics\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/mightyohm.com\/blog\/wp-content\/uploads\/2008\/10\/3567609195_26d2582df5_o.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/mightyohm.com\/blog\/wp-content\/uploads\/2008\/10\/3567609195_26d2582df5_o.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/mightyohm.com\/blog\/wp-content\/uploads\/2008\/10\/3567609195_26d2582df5_o.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/mightyohm.com\/blog\/wp-content\/uploads\/2008\/10\/3567609195_26d2582df5_o.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/mightyohm.com\/blog\/wp-content\/uploads\/2008\/10\/3567609195_26d2582df5_o.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/mightyohm.com\/blog\/wp-content\/uploads\/2008\/10\/3567609195_26d2582df5_o.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":1902,"url":"https:\/\/mightyohm.com\/blog\/2009\/05\/sneak-peak-at-my-finished-wifi-radio-project\/","url_meta":{"origin":1148,"position":1},"title":"Sneak peek at my finished Wifi Radio project!","author":"Jeff","date":"May 28, 2009","format":false,"excerpt":"While I'm busy working on part ten of my series on building a wireless router-based DIY streaming internet radio, I couldn't resist sharing a few photos of the finished project. If you want to see the radio in person, stop by Expo Hall Booth 166 at the Maker Faire in\u2026","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/mightyohm.com\/blog\/category\/electronics\/"},"img":{"alt_text":"Finished Wifi Radio","src":"https:\/\/i0.wp.com\/mightyohm.com\/files\/flickr\/3567609195_79760d88fe.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1887,"url":"https:\/\/mightyohm.com\/blog\/2009\/05\/building-a-wifi-radio-part-10-building-the-box\/","url_meta":{"origin":1148,"position":2},"title":"Building a Wifi Radio &#8211; Part 10, Building the Box","author":"Jeff","date":"May 29, 2009","format":false,"excerpt":"This is the tenth and final part of a series about building a low cost, open source streaming internet radio based on the ASUS WL-520gU Wireless Router.\u00a0 If you haven\u2019t already, check out the previous parts (see the links below) for some background about the project. Wow, we've come a\u2026","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/mightyohm.com\/blog\/category\/electronics\/"},"img":{"alt_text":"","src":"http:\/\/www.ftjcfx.com\/image-3238164-10440897","width":350,"height":200},"classes":[]},{"id":822,"url":"https:\/\/mightyohm.com\/blog\/2008\/12\/building-a-wifi-radio-part-7-building-an-lcd-display\/","url_meta":{"origin":1148,"position":3},"title":"Building a Wifi Radio &#8211; Part 7, Building an LCD Display","author":"Jeff","date":"December 18, 2008","format":false,"excerpt":"This is the seventh part of an ongoing series about building a low cost, open source streaming internet radio.\u00a0 If you haven\u2019t already, check out the previous parts (see the links at the end of this article) for some background about the project. In part six, we used OpenWrt's UNIX-style\u2026","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/mightyohm.com\/blog\/category\/electronics\/"},"img":{"alt_text":"","src":"http:\/\/www.lduhtrp.net\/image-3238164-10440897","width":350,"height":200},"classes":[]},{"id":1872,"url":"https:\/\/mightyohm.com\/blog\/2009\/05\/building-a-wifi-radio-part-9-a-few-odds-and-ends\/","url_meta":{"origin":1148,"position":4},"title":"Building a Wifi Radio &#8211; Part 9, A Few Odds and Ends","author":"Jeff","date":"May 27, 2009","format":false,"excerpt":"This is the ninth part of an ongoing series about building a low cost, open source streaming internet radio based on the ASUS WL-520gU Wireless Router.\u00a0 If you haven\u2019t already, check out the previous parts (see the links at the end of this article) for some background about the project.\u2026","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/mightyohm.com\/blog\/category\/electronics\/"},"img":{"alt_text":"","src":"http:\/\/www.ftjcfx.com\/image-3238164-10440897","width":350,"height":200},"classes":[]},{"id":712,"url":"https:\/\/mightyohm.com\/blog\/2008\/12\/building-a-wifi-radio-part-6-a-conversation-with-mpd\/","url_meta":{"origin":1148,"position":5},"title":"Building a Wifi Radio &#8211; Part 6, A Conversation with Mpd","author":"Jeff","date":"December 17, 2008","format":false,"excerpt":"This is the sixth part of an ongoing series about building a low cost, open source streaming internet radio.\u00a0 If you haven't already, check out the previous parts (see the links at the end of this article) for some background about the project. Let's review... It's been a few weeks\u2026","rel":"","context":"In &quot;Microcontrollers&quot;","block_context":{"text":"Microcontrollers","link":"https:\/\/mightyohm.com\/blog\/category\/microcontrollers\/"},"img":{"alt_text":"","src":"http:\/\/www.awltovhc.com\/image-3238164-10440897","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/posts\/1148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/comments?post=1148"}],"version-history":[{"count":38,"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/posts\/1148\/revisions"}],"predecessor-version":[{"id":15833,"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/posts\/1148\/revisions\/15833"}],"wp:attachment":[{"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/media?parent=1148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/categories?post=1148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mightyohm.com\/blog\/wp-json\/wp\/v2\/tags?post=1148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}