{"id":254,"date":"2016-12-19T23:55:49","date_gmt":"2016-12-19T23:55:49","guid":{"rendered":"http:\/\/www.piboxproject.com\/?p=254"},"modified":"2016-12-20T00:02:15","modified_gmt":"2016-12-20T00:02:15","slug":"pibox-xm-radio-app-pixm-and-wifi-scanning-in-pnc","status":"publish","type":"post","link":"https:\/\/www.piboxproject.com\/index.php\/2016\/12\/19\/pibox-xm-radio-app-pixm-and-wifi-scanning-in-pnc\/","title":{"rendered":"PiBox: XM radio app (PiXM) and wifi scanning in PNC"},"content":{"rendered":"<div id=\"dslc-theme-content\"><div id=\"dslc-theme-content-inner\"><p>Back in October I started work on a new app for <a href=\"https:\/\/www.piboxproject.com\/\">PiBox<\/a>: an XM radio player.\u00a0 The hardware is an <a href=\"https:\/\/en.wikipedia.org\/wiki\/XM_PCR\">XMPCR<\/a>, a device sold in the early 2000&#8217;s that connected over USB to a PC.\u00a0 The device didn&#8217;t last long.\u00a0 I think there was some concern that people would steal the signals and rebroadcast.\u00a0 Something silly like that.\u00a0 But they only cost around $45 each back then.\u00a0 I got two, one each for my wife and I.\u00a0 As usual I didn&#8217;t have PC software for Linux so I wrote a GTK+ wrapper around a Perl script called <a href=\"http:\/\/www.graphics-muse.org\/archives\/source\/openxm.tar.gz\">OpenXM<\/a> that let me manage the radio.\u00a0 That project was called <a href=\"http:\/\/www.graphics-muse.org\/archives\/source\/ximbaradio-1.0.tar.gz\">XimbaRadio<\/a>.\u00a0 I wrote an article about it for <a href=\"http:\/\/www.linuxjournal.com\/article\/7487\">Linux Journal<\/a>.<\/p>\n<p>Flash forward to Halloween 2016 and the <a href=\"https:\/\/coloradospringsmakerfaire.com\/\">Maker Faires in Colorado Springs<\/a>.\u00a0 I got an itch to add some kind of audio playback device to go with the video player for <a href=\"https:\/\/www.piboxproject.com\/\">PiBox Media Center<\/a>.\u00a0 I have lots of audio ripped at home but it turns out writing a database handler for the ID3 tags was harder than doing the video lookups on <a href=\"https:\/\/www.themoviedb.org\/\">TheMovieDB<\/a> or the <a href=\"http:\/\/thetvdb.com\">TheTVDB<\/a>.\u00a0 So I&#8217;ve punted on playing my music for now.\u00a0 But the XMPCR&#8217;s were still around in a box in my office.\u00a0 So I dug them out and started digging in.<\/p>\n<h3>PIXM<\/h3>\n<div style=\"width: 330px\" class=\"wp-caption alignleft\"><a class=\"shutterset_\" title=\" \" href=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pixm.png\" data-image-id=\"588\" data-src=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pixm.png\" data-thumbnail=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pixm.png\" data-title=\"pixm\" data-description=\" \"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"ngg-singlepic ngg-left\" src=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pixm.png?resize=320%2C178\" alt=\"pixm\" width=\"320\" height=\"178\" \/><\/a><p class=\"wp-caption-text\">PiXM is an XM Radio app for PiBox. It manages an XMPCR connected over USB to the Raspberry Pi.<\/p><\/div>\n<p>The first thing I did was pull out the old Perl scripts.\u00a0 There is little support for scripting in PiBox because scripting languages are not my thing.\u00a0 Oh, I use them plenty.\u00a0 But I want PiBox Media Center to show what you can do with plain ol&#8217; C.\u00a0 Scripting is for kiddies.\u00a0 PiBox is for grown ups.\u00a0 Anyway, the perl scripts still work after all these years and I was able, after re-signing up the devices with SiriusXM, to use them to listen to pretty much any channel with the device connected to my laptop (not PiBox).\u00a0 The devices have an ordinary audio plug for output &#8211; there is no playback through the PC.\u00a0 But that&#8217;s not a major issue to me.\u00a0 I can always route the output back into the Pi and manage it that way if I really need to.<\/p>\n<p>So the devices still worked.\u00a0 Now I needed to look at my old GTK+ code.\u00a0 It also worked.\u00a0 Badly.\u00a0 Not because the libraries had changed but because it wasn&#8217;t a well written app and wouldn&#8217;t fit into the minimalist design of the PiBox Media Center UI.\u00a0 So I decided to start over.\u00a0 And the first thing I wanted to do was write my own serial protocol management to avoid calling Perl scripts.\u00a0 After all, <a href=\"http:\/\/www.xmfan.com\/viewtopic.php?t=6870&amp;sid=18085bac1e7ad8d0750ec3a324bf0b1a\">the device&#8217;s serial protocol<\/a> was very simplistic and there really wasn&#8217;t much code to port.\u00a0 There were even some <a href=\"http:\/\/www.michaelminn.com\/linux\/mmxmpcr\/\">example implementations<\/a>.<\/p>\n<p>Work on the protocol went quickly and I was able to get data into and out of the device without much trouble.\u00a0 The next step was to implement a UI.\u00a0 The UI needed to adhere to the same basic usage principles of the video player which uses just the arrow, tab, ESC and ENTER keys for navigation and selection.\u00a0 This wasn&#8217;t as hard as it seemed.\u00a0 I created two lists, one for categories and one for channels.\u00a0 Choosing a category showed the list of channels in that category.\u00a0 Tabbing between category and channels would display all channels.\u00a0 Searching used the same builtin GTK+ mechanism for trees (just type some letters).\u00a0 Easy peasy.\u00a0 Unlike the <a href=\"https:\/\/www.piboxproject.com\/wp-content\/uploads\/2016\/10\/videofe.png\">video player<\/a>, however, there are no graphics to display on the right side of the UI.\u00a0 Instead, it&#8217;s just a set of four fields for channel, category artist and title.<\/p>\n<p>In testing this layout I discovered some basic problems.\u00a0 The first was that the serial device, <span style=\"color: #0000ff;\">\/dev\/ttyUSB0<\/span>, is not accessible by default.\u00a0 I&#8217;m using <a href=\"https:\/\/git.busybox.net\/\">mdev<\/a> in PiBox and didn&#8217;t set it up properly to give non-root users access to the device.\u00a0 But before I remembered that was the problem (the app is not privileged so runs as a non-root user so I need to fix the mdev setup scripts)\u00a0 I added a device state icon to the menu bar.\u00a0 This bar is drawn with Cairo and is where you see the tab options for <em>Category<\/em> and <em>Channels<\/em>.\u00a0 The device state icon is green for available and red for unavailable.\u00a0 Makes it easier to identify hardware problems.<\/p>\n<div style=\"width: 330px\" class=\"wp-caption alignleft\"><a class=\"shutterset_\" title=\" The controls for PiXM: Categories and Channels are selected with the Tab key. The device status icon is green, showing the device is available. The Mute icon is shown unset. Pressing M will toggle the Mute state and update the icon.\" href=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pixm-controls.png\" data-image-id=\"589\" data-src=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pixm-controls.png\" data-thumbnail=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pixm-controls.png\" data-title=\"pixm-controls\" data-description=\" \"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"ngg-singlepic ngg-center\" src=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pixm-controls.png?resize=320%2C31\" alt=\"pixm-controls\" width=\"320\" height=\"31\" \/><\/a><p class=\"wp-caption-text\">PiXM Controls: The Categories and Channels are selected using the Tab key. The device status icon is green, showing the device is available. The Mute icon is not set. Pressing M will toggle the mute state of the device&#8217;s audio output.<\/p><\/div>\n<p>I also noticed that the device serial protocol allows for muting the output.\u00a0 Seemed like it might be nice to add that feature, so I added one additional key, M, to toggle the mute on the XMPCR.\u00a0 This violates my desire to keep all PiBox Media Center UI components (other than the PiBox Network Config app) to just the arrows, Tab, ENTER and ESC key.\u00a0 But since PiBox is using those nice <a href=\"https:\/\/smile.amazon.com\/gp\/product\/B003UE52ME\/ref=oh_aui_search_detailpage?ie=UTF8&amp;psc=1\">FAVI keyboards<\/a>, I figured what the heck.\u00a0 Whose gonna be annoyed?<\/p>\n<p>The majority of the app is plain ol&#8217; <a href=\"https:\/\/www.gtk.org\/\">GTK+ 2 widgets<\/a>.\u00a0 The control bar is a drawing area with <a href=\"https:\/\/cairographics.org\/\">Cairo<\/a> doing custom rendering.\u00a0 I use Cairo for much of the PiBox UI: PiClock, the video player (aka VideoFE) and the launcher use it extensively.\u00a0 Like the video player, the PiXM app does simple on-demand drawings in the drawing area.\u00a0 This isn&#8217;t exactly efficient or by design of GTK+.\u00a0 After working on the wifi scanner (see below) I realized I should have written my own widget to better deal with async issues inside the main GTK+ loop.\u00a0\u00a0 PiClock has such as widget, but it needs additional work based on lessons learned on the wifi scanner.<\/p>\n<h3>Wifi Scanner for PiBox Network Config<\/h3>\n<div style=\"width: 330px\" class=\"wp-caption alignleft\"><a class=\"shutterset_\" title=\" The scanner as implemented as part of the PiBox Network Config app.\" href=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pnc-scanner.png\" data-image-id=\"586\" data-src=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pnc-scanner.png\" data-thumbnail=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pnc-scanner.png\" data-title=\"pnc-scanner\" data-description=\" \"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"ngg-singlepic ngg-left\" src=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pnc-scanner.png?resize=320%2C179\" alt=\"pnc-scanner\" width=\"320\" height=\"179\" \/><\/a><p class=\"wp-caption-text\">The wifi scanner is implemented as part of the PiBox Network Config app. It should probably be set as optional since the app can be used to configure wired ethernet too.<\/p><\/div>\n<p>One of the major lessons learned from the Maker Faire was a need to solve my problems with PiBox acting as an access point for a local network of PiBox players.\u00a0 At home I had a setup of three PiBox Players playing movies from a PiBox Media Server.\u00a0 This worked fine there.\u00a0 But taking the same setup to the library (and Barnes and Noble for a separate Maker Faire event) showed that wifi performance was unacceptable.<\/p>\n<p>I&#8217;ve done <a href=\"http:\/\/www.howtogeek.com\/197268\/how-to-find-the-best-wi-fi-channel-for-your-router-on-any-operating-system\/\">lots of research<\/a> on <a href=\"https:\/\/www.cyberciti.biz\/tips\/linux-find-out-wireless-network-speed-signal-strength.html\">possible causes<\/a> for <a href=\"http:\/\/7signal.com\/wi-fi-learning-center\/top-wi-fi-issues-and-challenges\/\">poor wifi performance<\/a>.\u00a0 I first thought it was a bad Samba configuration since videos are accessed by players from a <a href=\"http:\/\/www.tldp.org\/HOWTO\/SMB-HOWTO-8.html\">Samba share<\/a> on the server.\u00a0 That helped, but didn&#8217;t solve the problem.\u00a0 Then I found that images used in the video player browser were huge.\u00a0 So I scaled them back and that helped a bunch with browsing the list of available videos.\u00a0 But it didn&#8217;t solve the issues related to video playback.<\/p>\n<p>So then I dug into wifi itself.\u00a0 I found that <a href=\"http:\/\/www.radio-electronics.com\/info\/wireless\/wi-fi\/80211-channels-number-frequencies-bandwidth.php\">channels 1, 6 and 11<\/a> are typically the default channels in routers because they apparently don&#8217;t overlap other channels as much the other channels overlap each other.\u00a0 Also, signal strength is important since choosing a channel where your signal strength is better than other networks on the same channel will help with throughput.\u00a0\u00a0 Choosing a channel with fewer other networks using it requires knowing which networks are using which channels.\u00a0 Same it true for signal strength.<\/p>\n<p>Which brings me to the discovery of Kevin Yuan&#8217;s <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.farproc.wifi.analyzer&amp;hl=en\">Wifi Analyzer for Android<\/a>.\u00a0 What a cool little app.\u00a0 And that&#8217;s coming from a guy who doesn&#8217;t use ANY apps.\u00a0 It shows an animated graph of wifi networks in the local area.\u00a0 So I looked into how you get the data for this kind of graph.\u00a0 Turns out you can get everything you need by looking at <span style=\"color: #000080;\">\/proc\/net\/wireless<\/span> and using <em>iwlist<\/em> and <em>iw<\/em>.\u00a0 More easy peasy.<\/p>\n<div style=\"width: 174px\" class=\"wp-caption alignleft\"><a class=\"shutterset_\" title=\" The scanner widget lists the local SSIDs with channels and signal strength on the right. Use of transparency in the graphs makes it possible to read the text even if the graphs overlay it.\" href=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pnc-scanner-only.png\" data-image-id=\"587\" data-src=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/pnc-scanner-only.png\" data-thumbnail=\"http:\/\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pnc-scanner-only.png\" data-title=\"pnc-scanner-only\" data-description=\" \"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"ngg-singlepic ngg-left\" src=\"https:\/\/i0.wp.com\/www.graphics-muse.org\/wp\/wp-content\/gallery\/pibox\/thumbs\/thumbs_pnc-scanner-only.png?resize=164%2C240\" alt=\"pnc-scanner-only\" width=\"164\" height=\"240\" \/><\/a><p class=\"wp-caption-text\">The scanner shows the set of SSIDs along with their channels and signal strengths as text on the right. The graphs are filled with semi-transparent coloring so the text can be read even of the graphs extend into the text area.<\/p><\/div>\n<p>With the data gathering solved, I needed to integrate a UI and a way to get the gathered data into the UI.\u00a0 One problem to solve is how to choose separate colors for each network.\u00a0 In the end I used the <a href=\"http:\/\/devmag.org.za\/2012\/07\/29\/how-to-choose-colours-procedurally-algorithms\/\">golden ratio<\/a>.\u00a0 Next is how to get the data, which can take several seconds to acquire, without interfering with the UI.\u00a0 So I put the data gathering into a background thread that made calls to the <em>pnc<\/em> (PiBox Network Config) library.\u00a0 The data was stored in that thread and was made available to the UI using mutexes.<\/p>\n<p>I first made the UI act like the control bar of PiXM but that didn&#8217;t work.\u00a0 The periodic updates caused lockups in the GTK+ main loop.\u00a0 So I switched to writing my own widget, just as I&#8217;d done with PiClock.\u00a0 This widget is far more complex and in doing the port I found bugs in PiClock.\u00a0 But using a widget solved the problem of GTK+ main loop lockups.<\/p>\n<p>Drawing the graphs is done with Cairo.\u00a0 If you look at the graph it looks like a bunch of parabolas.\u00a0 At first I looked into how to graph these.\u00a0 But the parabolas needed to be closed on the wide end in order to fill them.\u00a0 That&#8217;s when I realized the trick to graphing in Cairo:\u00a0 using masks.\u00a0 There was an example of <a href=\"https:\/\/www.cairographics.org\/manual\/cairo-Paths.html#cairo-arc\">how to create an ellipse by using transforms to fit the ellipse in a box<\/a>.\u00a0 The transform placed the center of the ellipse on the channel axis with the left side drawn off the left edge of the widget, making it only partially but annoyingly visible.\u00a0 The fix to that was to mask off the area to the left of the axis and THEN draw the axis.\u00a0 Cairo layers the drawing commands so the mask cuts out the left side of the ellipses and then the axis is drawn over the mask.\u00a0 More easy peasy.\u00a0 After many hours trying to find the trick.\u00a0 Silly me.\u00a0 It was in the documentation.\u00a0 The last place one would look.<\/p>\n<p>You might wonder why the graphs are drawn left to right instead of bottom to top.\u00a0 Simple:\u00a0 space.\u00a0 I have lots of vertical space here but not much horizontal space.\u00a0 So I just draw left to right.\u00a0 Seems okay to me.\u00a0 Comments welcome.<\/p>\n<h3>What&#8217;s Next<\/h3>\n<p>I need to return to PiClock and clean up it&#8217;s widget, adding custom layers to the Cairo rendering to allow for custom themes for the background, hands and overlay.\u00a0 The same needs to be added to the launcher so I can do things similar to what you see with the Roku front page.<\/p>\n<\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Finding the right wifi channel gets easier with the new wifi scanner added to PiBox Network Config.<\/p>\n","protected":false},"author":1,"featured_media":262,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"PiBox: XM radio app (PiXM) and wifi scanning in PNC","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[2],"tags":[],"class_list":{"0":"post-254","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-tech","8":"czr-hentry"},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.piboxproject.com\/wp-content\/uploads\/2016\/12\/scanner-featured-image.png?fit=737%2C434&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8du2Y-46","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/posts\/254","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/comments?post=254"}],"version-history":[{"count":3,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/posts\/254\/revisions"}],"predecessor-version":[{"id":259,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/posts\/254\/revisions\/259"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/media\/262"}],"wp:attachment":[{"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/media?parent=254"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/categories?post=254"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.piboxproject.com\/index.php\/wp-json\/wp\/v2\/tags?post=254"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}