<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Michael J. Hammel</title>
	<atom:link href="https://www.graphics-muse.org/wp/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://www.graphics-muse.org/wp</link>
	<description>Building a better today...because tomorrow is in question...</description>
	<lastBuildDate>Mon, 19 Feb 2024 22:58:41 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7</generator>

<image>
	<url>https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/cropped-miot-logo-black-on-white.png?fit=32%2C32&#038;ssl=1</url>
	<title>Michael J. Hammel</title>
	<link>https://www.graphics-muse.org/wp</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">3372994</site>	<item>
		<title>Thread Management with Mutexes and Semaphores</title>
		<link>https://www.graphics-muse.org/wp/?p=6346</link>
					<comments>https://www.graphics-muse.org/wp/?p=6346#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Wed, 20 May 2020 03:22:56 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PiBox]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[piboxd]]></category>
		<category><![CDATA[semaphores]]></category>
		<category><![CDATA[threads]]></category>
		<guid isPermaLink="false">https://www.graphics-muse.org/wp/?p=6346</guid>

					<description><![CDATA[<p>One of the most common patterns I&#8217;ve run into while working on PiBox has been threads that process inbound data via a queue.&#160; The pattern is simple enough. Initialize a thread to acquire data When data arrives, put it into a data structure Place the data structure on a queue Notify another thread to process [&#8230;]</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=6346">Thread Management with Mutexes and Semaphores</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?ssl=1"><img data-recalc-dims="1" fetchpriority="high" decoding="async" data-attachment-id="6364" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6364" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?fit=640%2C640&amp;ssl=1" data-orig-size="640,640" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="computer-bubble-head-colorized" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?fit=300%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?fit=640%2C640&amp;ssl=1" class="size-medium wp-image-6364 alignright" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?resize=300%2C300&#038;ssl=1" alt="" width="300" height="300" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?resize=300%2C300&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2020/05/computer-bubble-head-colorized.png?w=640&amp;ssl=1 640w" sizes="(max-width: 300px) 100vw, 300px" /></a>One of the most common patterns I&#8217;ve run into while working on <a href="http://www.piboxproject.com">PiBox</a> has been threads that process inbound data via a queue.&nbsp; The pattern is simple enough.</p>
<ol>
<li>Initialize a thread to acquire data
<ol>
<li>When data arrives, put it into a data structure</li>
<li>Place the data structure on a queue</li>
<li>Notify another thread to process queued data</li>
</ol>
</li>
<li>Initialize a thread to process data
<ol>
<li>Wait for data on the queue</li>
</ol>
</li>
</ol>
<p>Linux process threads can share data access but can&#8217;t, without help, guarantee data integrity.&nbsp; This means that one thread may be in the process of updating data while another is reading it.&nbsp; Typically data integrity of a shared data area is provided through the use of a <a href="http://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html"><em>mutex</em></a> (mutual exclusion lock).&nbsp; This is fine for many cases but the lock just stops a thread from accessing the data while another thread accesses it.&nbsp; What this doesn&#8217;t handle is synchronization of data availability.&nbsp;</p>
<p>For example, if thread 1 locks access to a link list to add a record and then releases the lock that doesn&#8217;t tell a separate thread how many links are there to be processed.&nbsp; So the second thread spins trying to pull links from the list.&nbsp; If the first thread has not put any links on the list then the second thread just spins again, very fast (unless you use some artificial delay).&nbsp; This is wasteful because it&#8217;s not synchronized.&nbsp; The second thread only wants to process the list if there is something on the list.&nbsp; The first thread has to tell the second thread that there is work to be done.</p>
<p>There are clever ways to do this with just mutexs where you lock both the list and a counter.&nbsp; But there is a simpler way of dealing with the problem.&nbsp; A way that doesn&#8217;t even require checking the value of the counter directly: a <a href="http://man7.org/linux/man-pages/man7/sem_overview.7.html"><em>semaphore</em></a>.&nbsp;</p>
<p>A semaphore is a communications mechanism between threads.&nbsp; One thread updating the semaphore (effectively adding one to the counter) is mutually exclusive to another thread reading the semaphore.&nbsp; Reading the semaphore is effectively like having the second thread asking <em>is there any more data I need to handle?</em>&nbsp; If not, the second thread can block until there is data, which happens when the first thread <em>posts</em> to the semaphore.&nbsp;</p>
<p>The semaphore is similar to <a href="http://man7.org/linux/man-pages/man2/poll.2.html">polling on a file descriptor</a> where the poll blocks until there is data to be read.&nbsp; With a semaphore the blocking happens until the semaphore has a value greater than zero.&nbsp; Breaking the block simply requires <em>posting</em> to the semaphore, which increases its value.</p>
<p>All of this is easier to show with code.&nbsp; First, we want code for adding a link to a list and code for removing a link.&nbsp; Think of the first as a thread reading data from the network.&nbsp; It takes the inbound data and places it in a structure that it then adds to the link list.&nbsp; This code locks access to the list and then adds data to it.</p>
<p><code>pthread_mutex_lock(queueMutex);</code></p>
<p><code>queueData(rawData);</code></p>
<p><code>pthread_mutex_unlock(queueMutex);</code></p>
<p>This code guarantees that adding the link will complete before another thread can check the link list.&nbsp; The second thread can get the link in a similar manner.</p>
<p><code>while( 1 ) {</code></p>
<p><code>&nbsp;&nbsp;&nbsp; pthread_mutex_lock(queueMutex);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; data_link&nbsp; = popData();</code></p>
<p><code>&nbsp;&nbsp;&nbsp; pthread_mutex_unlock(queueMutex);</code></p>
<p><code>}</code></p>
<p>The mutexes prevent the two threads from stepping on each other (and in reality the lock/unlock would actually happen in the popData() and queueData() functions but doing it as shown here doesn&#8217;t require writing the functions), a problem that gets bad when the link list has no members.&nbsp; But the second thread still needs to know when to try and pop data from the list otherwise the second thread will spin very fast and eat up CPU cycles.&nbsp; The first thread therefore needs to post a semaphore, which bumps the semaphore count by one.</p>
<p><code>pthread_mutex_lock(queueMutex);</code></p>
<p><code>queueData(rawData);</code></p>
<p><code>pthread_mutex_unlock(queueMutex);</code></p>
<p><code>sem_post(&amp;dataSem);</code></p>
<p>Remember that a semaphore call is effectively wrapped by a mutex preventing two threads from accessing the semaphore at the same time.&nbsp; The second thread now just needs to test the semaphore at the top of each loop.</p>
<p><code>while( 1 ) {</code></p>
<p><code>&nbsp;&nbsp;&nbsp; sem_wait(&amp;dataSem);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; pthread_mutex_lock(queueMutex);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; data_link&nbsp; = popData();</code></p>
<p><code>&nbsp;&nbsp;&nbsp; pthread_mutex_unlock(queueMutex);</code></p>
<p><code>}</code></p>
<p>Now the second thread blocks on the semaphore until has a value of least 1.&nbsp; When the semaphore has at least one, the wait returns and decrements that semaphore by one.&nbsp; Now there is synchronization between the two threads.&nbsp; The first thread can queue up as many links as it wants and the second will drain that list as long as there is at least one link.&nbsp; And the second thread doesn&#8217;t need to take up a lot of CPU cycles by spinning really fast when there is no data on the list.&nbsp; It only runs when there IS some data on the list!</p>
<p>Now, about that while(1) statement:&nbsp; This code is inside the function spawned by the <a href="http://man7.org/linux/man-pages/man3/pthread_create.3.html">thread creation</a>.&nbsp; So how do we exit the loop?&nbsp; Well, when the code that wants to shutdown needs to kill off that thread it can set a variable and post to the semaphore. So now that loop would look more like this.</p>
<p><code>while( isActive() ) {</code></p>
<p><code>&nbsp;&nbsp;&nbsp; sem_wait(&amp;dataSem);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; if ( !isActive() )</code></p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</code></p>
<p><code>&nbsp;&nbsp;&nbsp; pthread_mutex_lock(queueMutex);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; data_link&nbsp; = popData();</code></p>
<p><code>&nbsp;&nbsp;&nbsp; pthread_mutex_unlock(queueMutex);</code></p>
<p><code>}</code></p>
<p>The test of isActive is placed inside a thread-safe function that wraps reading and writing of the variable with a mutex as well.&nbsp; And the code that kills the thread just looks something like this.</p>
<p><code>setActive(FALSE);</code></p>
<p><code>sem_post(&amp;dataSem);</code></p>
<p>You might wonder why the semaphore was used for the link list and for the thread loop.&nbsp; Aren&#8217;t those unrelated?&nbsp; Why yes, they are.&nbsp; The semaphore doesn&#8217;t have any association with the link list.&nbsp; It&#8217;s just a counter we&#8217;re using to keep track of adding and removing link entries.&nbsp; But it&#8217;s a special counter because it&#8217;s thread-safe:&nbsp; adding to it and taking from it is guaranteed to be safe from any thread.&nbsp; And it can be used to block a read, one that wants to wait for some work to do.&nbsp; The semaphore a communication mechanism between the thread requesting work to be done and the thread that needs to do the work.&nbsp;</p>
<p>A more expansive example can be found in the <a href="https://gitlab.com/pibox/piboxd">piboxd</a> daemon&#8217;s <a href="https://gitlab.com/pibox/piboxd/-/blob/master/src/queueProcessor.c">queueProcessor</a> and <a href="https://gitlab.com/pibox/piboxd/-/blob/master/src/msgQueue.c">msgQueue</a> modules.&nbsp; The latter is used to manage link lists of data while the latter is used to processes data queued on one of those lists.&nbsp; The queueProcessor thread loop <a href="https://gitlab.com/pibox/piboxd/-/blob/master/src/queueProcessor.c#L687">waits on a semaphore</a> that is <a href="https://gitlab.com/pibox/piboxd/-/blob/master/src/msgQueue.c#L467">updated by the msgQueue</a> functions when data is added to a list.</p>
<p>So you see, dealing with threads is not just about locking access to data with mutexes.&nbsp; It&#8217;s also about communicating the changes to data via semaphores.&nbsp;</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=6346">Thread Management with Mutexes and Semaphores</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=6346</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6346</post-id>	</item>
		<item>
		<title>Where&#8217;s Michael?</title>
		<link>https://www.graphics-muse.org/wp/?p=6120</link>
					<comments>https://www.graphics-muse.org/wp/?p=6120#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Sun, 21 Jan 2018 03:39:44 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Boulder]]></category>
		<category><![CDATA[buyers agent]]></category>
		<category><![CDATA[flat-fee]]></category>
		<category><![CDATA[job hunting]]></category>
		<category><![CDATA[PiBox]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[VA loans]]></category>
		<category><![CDATA[western digital]]></category>
		<guid isPermaLink="false">https://www.graphics-muse.org/wp/?p=6120</guid>

					<description><![CDATA[<p>I'm not dead yet.  I'm feeling much better.</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=6120">Where’s Michael?</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.graphics-muse.org/wp/?attachment_id=6125" rel="attachment wp-att-6125"><img data-recalc-dims="1" decoding="async" data-attachment-id="6125" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6125" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?fit=906%2C842&amp;ssl=1" data-orig-size="906,842" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="wheresmichael" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?fit=300%2C279&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?fit=906%2C842&amp;ssl=1" class="alignleft size-thumbnail wp-image-6125" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?resize=150%2C150&#038;ssl=1" alt="" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2018/01/wheresmichael-1.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="(max-width: 150px) 100vw, 150px" /></a>My last post was nearly a year ago now.&nbsp; It isn&#8217;t that I ran out of things to say or that I wasn&#8217;t doing anything.&nbsp; In fact, just the opposite.&nbsp; I had too much to do.&nbsp; And none of it had to do with technology (unless you count job hunting).&nbsp; 2017 was a tough year.&nbsp; Not all bad, just very grueling.&nbsp; It started awful with the <a href="https://www.piboxproject.com/index.php/2017/03/29/pipics-slideshow-app-with-touchscreen-support/">passing of our oldest pup, Reba</a>, in February.&nbsp; Then I was laid off from my gig at Western Digital.&nbsp; That really wasn&#8217;t a completely bad thing.&nbsp; I had told my boss after the 2016 election that I was planning on leaving because my wife and I got fed up with the <a href="https://www.usatoday.com/story/news/nation/2014/08/05/mesa-arizona-most-conservative-big-city/13641061/">conservative nature of Colorado Springs</a>.&nbsp; He was very understanding.&nbsp; There was no option for remote work, unfortunately.&nbsp; So when WD was having a layoff he used that opportunity to get me a nice severance package to help me on my way.&nbsp; And it really was a good deal for me.&nbsp; I had plenty of cash to take my time and find someplace new.&nbsp;&nbsp; Which I started doing the first of April.</p>
<p>The problem with wanting to move is knowing you will have to sell your house.&nbsp; That means keeping it in a perpetual state of staging, waiting to put it on the market as soon as a job offer arrives.&nbsp; I interviewed all over, mostly targeting Seattle, Portland, Austin and Boulder.&nbsp; Lots of interest.&nbsp; Lots of interviews.&nbsp; No offers.&nbsp; I&#8217;m assuming (mostly, but not completely) because I was looking for relocation assistance.&nbsp; This went on till late August when <a href="https://www.netapp.com/us/index.aspx">NetApp</a> in Boulder made an offer.&nbsp; Perfect timing as the severance package was starting to run a bit lean.&nbsp; Time to get the house on the market.</p>
<p>Housing prices in Colorado are pretty high.&nbsp; Selling your house normally means hiring a realtor to market it for you.&nbsp; They get 3% of the sale price.&nbsp; Toss in the buyers agent and that&#8217;s another 3% out of our sale price.&nbsp; With really high housing prices that&#8217;s a really big chunk.&nbsp; Too big.&nbsp; So we started with a <a href="https://www.forsalebyowner.com/">For-Sale-By-Owner</a>.&nbsp; There&#8217;s a web site for that.&nbsp; And it&#8217;s not that hard to get started.&nbsp; But it&#8217;s hard to market.&nbsp; Turns out FSBO&#8217;s are not something realtors will look at much to bring you buyers.&nbsp; And you don&#8217;t end up in the MLS (a monopoly if ever there was one) so realtor&#8217;s don&#8217;t even know about you.&nbsp; <a href="https://www.zillow.com/">Zillow</a> will post it but marks it like it&#8217;s something to be wary of.&nbsp; We got one bite.&nbsp; And it was, as many are in military-based Colorado Springs, a VA loan.&nbsp;</p>
<p>Ugh.&nbsp; VA loans are difficult.&nbsp; The buyer has to bring a teeny-tiny amount as down payment, meaning they usually don&#8217;t have anything extra.&nbsp; VA inspections are tougher and any fixes come out of the seller&#8217;s pocket.&nbsp; No negotiation there.&nbsp; Screw it.&nbsp; No VA loans.&nbsp; And we dropped the FSBO.&nbsp; Time for a <a href="https://www.flatfeegroup.com/Colorado/index.php">flat-fee listing agent</a>.</p>
<p>A flat-fee agent charges a flat fee to list you in MLS.&nbsp; They don&#8217;t show your house.&nbsp; But for the savings that&#8217;s something we could do easily enough.&nbsp; Our agent did a great job, including providing a guiding hand through the whole sale process.&nbsp;&nbsp; Colorado, technically, doesn&#8217;t allow a flat-fee service with limited services but she gets around that by basically doing everything a normal listing agent would do &#8211; for way less.&nbsp; And so we sold our house.&nbsp; That took another 2 months to complete.&nbsp; In the mean time I&#8217;d started work in Boulder, was commuting up on Monday and back on Friday (lots of cheap hotel points accumulated) and helping the wife get the house ready.&nbsp; Then came the move.</p>
<p>We hired a truck but no movers.&nbsp; Our mistake.&nbsp; We found someone at the last minute, who managed to find two more guys who hired out for day work.&nbsp; They did a great job, but I worked 3 days straight (okay, a few hours sleep) filling the <em>truckS</em> (multiple, we needed a second one, we discovered as we&#8217;re loading the first).&nbsp; We got out about 1/2 hour before the signing of the sale, exhausted to the point of barfing.&nbsp; We drove both cars, dragging U-Hauls, with the dogs up to Superior, CO to a Residence Inn were we lived for a month trying to find a new home.&nbsp;&nbsp; About 5 weeks later, after much negotiating, we closed on a new home in south west Broomfield.&nbsp; Now we&#8217;re into late November, just before Thanksgiving.</p>
<p>We start unpacking and everything is going well.&nbsp; We&#8217;re still exhausted but gotta get settled in as quick as possible:&nbsp; my wife hasn&#8217;t been able to work since April!&nbsp; Her business is run out of the house and she has no space set up to work.&nbsp; Not to mention our daughter is coming to visit the first week of January. So we&#8217;re rushing to get everything done as the holidays fly towards us.&nbsp; We&#8217;re moving along, my week off from work for the end of the year is one day away and then:&nbsp; our Bailey, now the oldest surviving pup at 14, has a stroke.</p>
<p>The weird thing about dogs and strokes is that dogs recover from them much better than we do.&nbsp; Bailey was nearly lifeless four days before Christmas.&nbsp; Just her eyes moved.&nbsp; We didn&#8217;t have a vet yet.&nbsp; We scrambled to get her body into the back of the car, drove to one vet (my wife nixed) and then another.&nbsp; That vet examined her and said, &#8220;Let&#8217;s give her a chance.&#8221;&nbsp;&nbsp; He gave us meds, starting with steroids.&nbsp;&nbsp; A week later she was about 90% back to normal, but with an incontinence problem.&nbsp; It&#8217;s taken 3 more weeks, and trying a variety of drugs and hormones, to get that under control.&nbsp; And now she&#8217;s walking around better than before she had the stroke.&nbsp; We&#8217;re amazed, relieved, exhausted.&nbsp; That first week after the stroke I had to dead-lift a 90lb dog four or fives times a day to take her to potty or to the vet.&nbsp; On the bright side, I got in shape quick.</p>
<p>So here we are, the third week of January 2018 and all my wife and I can say about 2017 is:&nbsp; good riddance!&nbsp; 2018 will be better, though we know Bailey is old and may not see another new year.&nbsp; But she&#8217;s happy.&nbsp; And so are we.&nbsp; We&#8217;re out of Colorado Springs, into a dog friendly neighborhood with a new house and a great new job.&nbsp; Life is good.</p>
<p>So now, back to that <a href="https://www.graphics-muse.org/wp/?p=5910">list of things to do in 2017</a>&#8230;.</p>
<p>&nbsp;</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=6120">Where’s Michael?</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=6120</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6120</post-id>	</item>
		<item>
		<title>Migrating from HTTP to HTTPS with certbot</title>
		<link>https://www.graphics-muse.org/wp/?p=6069</link>
					<comments>https://www.graphics-muse.org/wp/?p=6069#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Thu, 06 Apr 2017 17:40:22 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Apache HTTP Server]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[virtual hosts]]></category>
		<category><![CDATA[web server]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=6069</guid>

					<description><![CDATA[<p>You are in a maze of twisty little configurations....</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=6069">Migrating from HTTP to HTTPS with certbot</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.graphics-muse.org/wp/?attachment_id=6086" rel="attachment wp-att-6086"><img data-recalc-dims="1" decoding="async" data-attachment-id="6086" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6086" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/04/ssl-lock-logo.png?fit=225%2C225&amp;ssl=1" data-orig-size="225,225" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ssl-lock-logo" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/04/ssl-lock-logo.png?fit=225%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/04/ssl-lock-logo.png?fit=225%2C225&amp;ssl=1" class="alignleft size-thumbnail wp-image-6086" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/04/ssl-lock-logo.png?resize=150%2C150&#038;ssl=1" alt="" height="150" width="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/04/ssl-lock-logo.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/04/ssl-lock-logo.png?w=225&amp;ssl=1 225w" sizes="(max-width: 150px) 100vw, 150px" /></a><a href="https://en.wikipedia.org/wiki/Colossal_Cave_Adventure">You are in a maze of twisty little configurations</a>&#8230;.</p>
<p>In 2014 Google announced plans for pushing <a href="https://www.youtube.com/watch?v=cBhZ6S0PFCY">HTTPS migration for all web sites</a>.&nbsp; The biggest draw for web site owners is that Google bumps up your rankings if you&#8217;re using HTTPS.&nbsp; There have been multiple extensions to this plan, from the <a href="https://www.eff.org/https-everywhere">EFF/Tor foundations HTTPS Everywhere Extension</a> to <a href="https://encryptallthethings.net/">EncryptAllThings</a>.&nbsp; Despite running multiple web domains, I&#8217;ve delayed joining the worldwide bandwagon jumping because I&#8217;m not that familiar with what is involved.&nbsp; I&#8217;m neither an expert in HTTPS nor an expert in configuring web servers.&nbsp; I also don&#8217;t care much about my rankings since I&#8217;m really not selling anything &#8211; I&#8217;m just sharing what I know.&nbsp; But the gist of it is this:&nbsp; if you run a web site, switch it from HTTP to HTTPS.&nbsp; It&#8217;s just one letter in a URL.&nbsp; Sounds simple enough, right?&nbsp; Oh, how I wish it was.</p>
<p>Migration from HTTP to HTTPS takes a number of steps.&nbsp; I just completed this task for all my domains, which run as virtual hosts under the Apache web server on my colocated server.&nbsp; There isn&#8217;t a simple list of things to do anywhere.&nbsp; There are <a href="http://www.google.com/search?q=Migrating+from+http+to+https">lots of lists of things to do under specific situations</a>.&nbsp; My situation is <em>CentOS</em> and <em>Apache</em>.&nbsp; Let me outline the steps here before I dive into the actual process.</p>
<ol>
<li>Get and install a certificate</li>
<li>Enable SSL on your web server</li>
<li>Enable SSL for your domains</li>
<li>Migrate web sites</li>
<li>Redirect HTTP</li>
<li>Validate your work</li>
<li>Take a vacation</li>
</ol>
<p>The last step you earn after completing the rest.&nbsp; Anyone who denies you this last step must be eliminated.&nbsp; You&#8217;ll understand why once you start down the twisty little configurations.</p>
<h2>Get a Certificate</h2>
<p>This article&#8217;s title suggests the main topic is <em>certbot</em>, the tool for acquiring and managing certificates, and the article introduction suggests using that tool is hard.&nbsp; Well, it is and it isn&#8217;t.&nbsp; It&#8217;s hard if you aren&#8217;t set up correctly and it&#8217;s hard to find out how to get set up correctly.&nbsp; It&#8217;s not hard once you&#8217;re set up.&nbsp; So let&#8217;s get set up.</p>
<p><a href="https://en.wikipedia.org/wiki/HTTPS">HTTPS</a> is the web protocol that wraps communications between a client, say a web browser, and a web server inside a nice layer of unintelligible gibberish that makes it harder for the bad hombres (no, not the ones Trump is trying to ship out, but actual bad guys)&nbsp; to sniff around your messages and extract useful tidbits.&nbsp; The protocol does this be running the stuff it would send through cryptographic algorithms to ensure privacy and integrity of the message while validating the authentication of the opposite end.&nbsp; To do all this neat stuff it needs two things on the server-side:&nbsp; an SSL certificate and a private key.</p>
<p>The private key is a secret.&nbsp; Only your hairdresser knows for sure&#8230; wait, that&#8217;s different.&nbsp; Only your server knows the secret.&nbsp; If you let it out to anyone else then it&#8217;s not a secret and all the encryption in the world won&#8217;t save your silly buns.&nbsp; <a href="http://www.imdb.com/character/ch0000143/quotes">So keep it secret, Frodo.&nbsp; Keep it safe</a>.</p>
<p>An SSL certificate contains authentication information along with a public key that matches with the private key.&nbsp; It is used by the client side to establish trust with the server and allow encryption to be used that both sides known how to decrypt.&nbsp;</p>
<p>To get these two magic files you need to talk with a Certificate Authority (CA).&nbsp; A CA is someone who can <em>sign</em> a certificate, making it something the world can trust.&nbsp; Who are these wizards of trust?&nbsp; No idea.&nbsp; But I know someone who does:&nbsp; <a href="https://certbot.eff.org/">certbot</a>.&nbsp; This is a handy little tool for Linux users (if you&#8217;re&nbsp; a Windows user and your reading my blog then you&#8217;ve lost your way).&nbsp; It&#8217;s a command line utility that will handle all the nasty bits of getting a CA to sign a certificate stating your little nest of websites is a clean and decent place to visit.&nbsp; Great.&nbsp; So how do we use it?</p>
<p>Well, all the googling in the world will tell you certbot is an automated system that just needs to be run like so:</p>
<p style="padding-left: 30px;"><em>sudo ./certbot-auto</em></p>
<p>This will query you for necessary credentials, including the list of domains you want covered by a single certificate, make the request to get a signed certificate and install it on your server.&nbsp; It will even update your Apache configuration files.&nbsp; After this, you&#8217;re one of the good guys again, right?</p>
<p>Not exactly.&nbsp; This command never worked out of the box for me.&nbsp; There were a couple of gotchas I need to pass along.&nbsp; First, make sure all your domains have proper DNS entries.&nbsp; If you have one (as I did) that had goofy third or fourth level resolvers configured then this aint gonna work.&nbsp; No how, no way.&nbsp; Fix that first.&nbsp;</p>
<p>Second, every web domain you have configured under Apache has a web root.&nbsp; This is the directory where your HTML files (or php or javascript or whatever) reside.&nbsp; If you try to run <em>certbot-auto</em> as described it fails because there is something missing from these web roots.&nbsp; What might that be?&nbsp; Google around &#8211; you won&#8217;t find it. But you can figure it out if you stop waiting for everything to be automatic and try something more manual, like this:</p>
<p style="padding-left: 30px;"><em>sudo certbot-auto certonly &#8211;webroot</em></p>
<p>This tells certbot that</p>
<ol>
<li>We only want the certificate files installed in a directory somewhere</li>
<li>but don&#8217;t update our Apache configurations</li>
</ol>
<p>What you get from this is an error message that looks like this:</p>
<pre style="padding-left: 30px;">Waiting for verification...
Cleaning up challenges
Failed authorization procedure. www.piboxproject.com (http-01): urn:acme:error:unauthorized :: The client lacks
sufficient authorization :: Invalid response from
http://www.piboxproject.com/<span style="color: #008000;">.well-known/acme-challenge</span>/UwffOaP-jo2Vs4NB-JceCq6UlspsD1KI3A6ZFveCuHA: "&lt;!DOCTYPE HTML
PUBLIC "-//IETF//DTD HTML 2.0//EN"&gt;
&lt;html&gt;&lt;head&gt;
&lt;title&gt;403 Forbidden&lt;/title&gt;
&lt;/head&gt;&lt;body&gt;
&lt;h1&gt;Forbidden&lt;/h1&gt;
&lt;p"</pre>
<p>Buried in here is the missing directory:&nbsp;<em> .well-known/acme-challenge</em>.&nbsp; So you need this directory in every web root.&nbsp; And it needs to be readable by the web server and writable by who ever is running certbot (in my case that was always the root user).&nbsp; The certbot tool stuffs a file in there that the remote server &#8211; the one handling generation of your certificates &#8211; can look retrieve.&nbsp;</p>
<p>So you create the missing directories and give them the proper permissions for every web root that will be associated with the certificate you&#8217;re requesting with certbot and you&#8217;ve fixed any DNS problems.&nbsp; Now you&#8217;re set up.&nbsp; So run the tool again. This time everything is hunky-dory and you escape certbot land none the worse for wear.&nbsp;&nbsp; What you end up with is a directory called <em>/etc/letsencrypt</em> that contains a bunch of directories and some files.&nbsp; Note that I said <em>some files</em>.&nbsp; Not just two.&nbsp; No, not just the key and the certificate.&nbsp; No.&nbsp; You get 14 files.&nbsp; Or maybe 18.&nbsp; I ran it multiple times so I&#8217;m not sure which.&nbsp; And no explanation as to why so many files.&nbsp; But we&#8217;ll come back to that later.</p>
<p>For now, you&#8217;re done with getting your certificate(s).</p>
<h2>Enable SSL on your web server</h2>
<p>Remember: I&#8217; m not an Apache expert.&nbsp; There may be (are likely) better ways of doing this.</p>
<p>Modern installations of Apache will have a configuration directory named <span style="color: #000080;"><em>/etc/httpd/conf.d</em></span>.&nbsp; Within this directory you will stuff your web domain configurations, one per domain with extras to redirect from variations on the main URL to the one you really want people using.&nbsp;</p>
<p>Within this directory make sure you have a file called <span style="color: #000080;"><em>ssl.conf</em></span>.&nbsp; It&#8217;s what enables SSL (re: HTTPS) on your server in general.&nbsp; But you need to update your virtual host configurations to actually use it.&nbsp; You do that by changing your VirtualHost lines that look like this:</p>
<p style="padding-left: 30px;"><em>&lt;VirtualHost www.my.domain&gt;</em></p>
<p>or</p>
<p style="padding-left: 30px;"><em>&lt;VirtualHost www.my.domain:80&gt;</em></p>
<p>to</p>
<p style="padding-left: 30px;"><em>&lt;VirtualHost www.my.domain:443&gt;</em></p>
<p>But wait!&nbsp; You don&#8217;t want to change your existing configurations.&nbsp; Make copies of the Apache virtual host configurations for your new :443 configurations.&nbsp; This is so you can support both HTTP and HTTPS while you complete the migration process. Also, because the HTTPS configurations will use a specific port you need to make sure your existing configurations include the :80 port.&nbsp; You can&#8217;t mix configurations that have and don&#8217;t have port specifications.&nbsp;</p>
<p>But don&#8217;t redirect from HTTP to HTTPS yet.&nbsp; You&#8217;re not ready, my young <a href="http://starwars.wikia.com/wiki/Padawan">padawan</a>.</p>
<h2>Enable SSL for your domains</h2>
<p>Now we get to figure out what all those files are that certbot installed.&nbsp; Remember I said there were something like 14 to 18 files generated.&nbsp; Well, only four have any meaning at this point.&nbsp;</p>
<ol>
<li><strong>cert.pem</strong>: server certificate only</li>
<li><strong>chain.pem</strong>: root and intermediate certificates only</li>
<li><strong>fullchain.pem</strong>: combination of server, root and intermediate certificates</li>
<li><strong>privkey.pem</strong>: private key</li>
</ol>
<p>If your next question is &#8220;<em>what is the difference between root, server and intermediate certificates</em>&#8221; then you&#8217;ve come to the wrong place.&nbsp; I have no idea. At this point in my twisty little configurations I don&#8217;t even care.&nbsp; I just want it to work.&nbsp; So moving on&#8230;.</p>
<p>These can all be found under <span style="color: #000080;"><em>/etc/letsencrypt/live/your.domain.com/</em></span>.&nbsp; Note that if you added multiple domains to a single cert then <span style="color: #000080;"><em>your.domain.com</em></span> is probably the first one you added to the certification generation process with <em>certbot</em>.&nbsp; Also, these files are just symbolic links to the real files.&nbsp; This is so you can update the certificates using certbot, which may change the names, without having to modify your Apache configurations.&nbsp; The latter just point to the files in the live directory.</p>
<p>Now if you&#8217;re a normal human you would probably spend some time Googling how to point your Apache configurations at these files.&nbsp; There are lots articles about how <em>certbot</em> will do this for you.&nbsp; Automatically.&nbsp; As long as everything is perfect and the sun is shining and the dog isn&#8217;t farting.&nbsp; But when does that happen?</p>
<p>There was no information I could find that worked completely correctly.&nbsp; Everything says to do this.</p>
<p style="padding-left: 30px;"><em> SSLEngine On<br />
SSLCertificateFile /etc/letsencrypt/live/www.piboxproject.com/fullchain.pem<br />
SSLCertificateKeyFile /etc/letsencrypt/live/www.piboxproject.com/privkey.pem<br />
</em></p>
<p>This works, but it&#8217;s not complete.&nbsp; We&#8217;ll see why a little later.</p>
<h2>Migrate web sites</h2>
<p>So now you&#8217;ve migrated the URLs so HTTPS will work.&nbsp; That&#8217;s just the first step.&nbsp; The next, and harder, step is migrating your web site.&nbsp; I run WordPress and wiki sites.&nbsp; The wiki sites had to be manually updated by searching for references to <em>http://&lt;domain&gt;</em> and editing the files manually to use HTTPS.&nbsp; Fortunately this didn&#8217;t take that long.</p>
<p>WordPress is a bit more involved.&nbsp; You need to update your theme, your database and any custom files.&nbsp; Fortunately there is a plugin that can help with this: <a href="https://wordpress.org/plugins/better-search-replace/">Better Search Replace</a>.&nbsp; This plugin allows you to specify a string to replace.&nbsp; So you just search for <em>http://&lt;domain&gt;</em> and replace it with <em>https://&lt;domain&gt;</em>.&nbsp; You can select the tables to process.&nbsp; I selected all of them.&nbsp; I ran this on 5 different WordPress databases and had no problems.</p>
<p>But updating the themes and non-database content is all manual.&nbsp; If you&#8217;ve got a modestly sized site you&#8217;re likely to find additional updates for a long time to come.&nbsp;</p>
<h2>Redirect HTTP</h2>
<p>So Apache is configured and the web sites updated.&nbsp; That&#8217;s a good start but we need to push a little harder on this and to do that we need to go back to the Apache configuration files.&nbsp; Now we need to add, just above the SSLConfigurationFile entry, the following.</p>
<p style="padding-left: 30px;"><em>RewriteCond %{HTTPS} off</em><br />
<em>RewriteCond %{HTTP_HOST} ^example\.com [NC]</em><br />
<em>RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]</em></p>
<p>These are used to map requests for any <em>http://&lt;domain&gt;</em> to your server to be remapped to the HTTPS URL instead.&nbsp; This is done to deal with anything you missed in the database or other web site content. But as much as you might hope, this isn&#8217;t the last edit to those files.</p>
<h2>Validate your work</h2>
<p>All the updates are in place (so we think).&nbsp; Time to test that you&#8217;re a good web citizen.&nbsp; Go to <a href="https://www.ssllabs.com/ssltest/">SSLLabs</a> site and type in your domain.&nbsp; Let it run for a bit &#8211; it&#8217;s doing lots of checking.&nbsp; When it&#8217;s done you get a grade.&nbsp; Anything less than an A and you have more work to do.&nbsp;</p>
<p>All the updates work but it <a href="https://www.ssllabs.com/ssltest/">fails validation from SSLLabs</a>.&nbsp; You get a message about the chain being incomplete and some errors related to some protocols.&nbsp; The following, added just above the <em>SSLProtocol</em> configuration line, should take care of the protocol errors. I got these from <a href="https://www.tummy.com">the folks who manage my colo server</a> so can&#8217;t say what they&#8217;re trying to do, or even if they are correct.&nbsp; But they&#8217;re pretty smart dudes.&nbsp; And dudettes.&nbsp;</p>
<p style="padding-left: 30px;"><em>SSLProtocol all -SSLv3</em><br />
<em>&nbsp;&nbsp;&nbsp; SSLHonorCipherOrder on</em><br />
<em>&nbsp;&nbsp;&nbsp; SSLCipherSuite &#8220;EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSSa !RC4&#8221;</em></p>
<p>A harder problem is the <a href="https://community.qualys.com/thread/16844-this-servers-certificate-chain-is-incomplete-grade-capped-to-b">incomplete chain</a> problem.&nbsp; The solution came from a <a href="https://www.certificat-ssl.info/tutoriels/corriger-erreur-ssllabs/this-server-certificate-chain-is-incomplete">non-english site</a>, which you can decipher fairly easily.&nbsp; You should also check out the <a href="https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcacertificatefile">Apache configuration documentation</a>.&nbsp; The gist is that we need to use a different set of Apache configurations that includes the <a href="https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcacertificatefile">SSLCACertificateFile</a> entry.</p>
<p><em>&nbsp;&nbsp;&nbsp; SSLCertificateFile /etc/letsencrypt/live/www.piboxproject.com/cert.pem</em><br />
<em>&nbsp;&nbsp;&nbsp; SSLCertificateKeyFile /etc/letsencrypt/live/www.piboxproject.com/privkey.pem</em><br />
<em>&nbsp;&nbsp;&nbsp; SSLCACertificateFile /etc/letsencrypt/live/www.piboxproject.com/fullchain.pem</em></p>
<p>Notice that <em>SSLCertificateFile</em> now points to the <em>cert.pem</em>, which is the server-only certificate.&nbsp; And the new <em>SSLCACertificateFile</em> points to the <em>fullchain.pem</em>, which is a bunch of certificates I can&#8217;t explain.&nbsp; Easy peasy, right?&nbsp;</p>
<p>Now run your domains through SSLLabs again.&nbsp; If you get an A then congratulations and yes, you&#8217;re the teacher&#8217;s pet.&nbsp; If you get anything else just remember: no refunds on your tuition turkey.</p>
<h2>What I skipped</h2>
<p>SEO.&nbsp; I didn&#8217;t care.&nbsp; I don&#8217;t have a godzillion (which is a google + 1) followers.&nbsp; And I&#8217;m not selling anything.&nbsp; So dealing with SEO isn&#8217;t an issue for me.&nbsp; If it is for you, continue rubbing your magic lantern. Something will come up.&nbsp; On the flip side, since switching to HTTPS the number of visitors on my sites has gone up.&nbsp; Okay, not a lot.&nbsp; But at my level any bump is a mountain.</p>
<p>Some of the SSL configuration options I put in the domain configuration files may be more appropriately placed in the <em>ssl.conf</em> file instead.&nbsp; I didn&#8217;t try this.&nbsp; I didn&#8217;t even look into this.&nbsp; By the time I figured out this might be an option I had run out of sweat and enchiladas were burning a hole in my stomach.&nbsp; I opted for Rolaids instead.</p>
<p>Certificate renewal.&nbsp; Look it up.&nbsp; Basically, those certificates don&#8217;t last forever.&nbsp; You need to renew them.&nbsp; Fortunately, by the time you get to this is it should be fairly simple.&nbsp; If you know how to set up a cron job.&nbsp; If you don&#8217;t, go find that lantern again.</p>
<p>That&#8217;s it.&nbsp; This wasn&#8217;t supposed to solve your problems.&nbsp; And it probably didn&#8217;t.&nbsp; But hopefully it gave you some pointers to get started at solving them. Good luck!!</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=6069">Migrating from HTTP to HTTPS with certbot</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=6069</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6069</post-id>	</item>
		<item>
		<title>Getting started with the Robo3D printer and OctoPrint</title>
		<link>https://www.graphics-muse.org/wp/?p=5968</link>
					<comments>https://www.graphics-muse.org/wp/?p=5968#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Mon, 30 Jan 2017 00:00:09 +0000</pubDate>
				<category><![CDATA[Art and Graphics]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[3D printer]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[GIMP]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[sd card]]></category>
		<category><![CDATA[USB camera]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=5968</guid>

					<description><![CDATA[<p>We&#8217;ve been thinking about getting into 3D printing here at the Hammel household.&#160; I&#8217;m looking at building small enclosures for the various embedded boards I work on.&#160; My wife is looking at creating components for the designs she works on for Vindicated Vinyl, her small business.&#160; After doing a bit of online research I purchased [&#8230;]</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=5968">Getting started with the Robo3D printer and OctoPrint</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.graphics-muse.org/wp/?attachment_id=6007" rel="attachment wp-att-6007"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="6007" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6007" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?fit=3264%2C2448&amp;ssl=1" data-orig-size="3264,2448" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1484576723&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170116_142523" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?fit=1024%2C768&amp;ssl=1" class="size-medium wp-image-6007 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?resize=300%2C225&#038;ssl=1" alt="" width="300" height="225" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142523.jpg?w=2340&amp;ssl=1 2340w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a> We&#8217;ve been thinking about getting into 3D printing here at the Hammel household.&nbsp; I&#8217;m looking at building small enclosures for the various embedded boards I work on.&nbsp; My wife is looking at creating components for the designs she works on for <a href="http://www.vindicatedvinyl.com/">Vindicated Vinyl</a>, her small business.&nbsp; After doing a bit of online research I purchased a <strong>Robo3D</strong> printer from <a href="http://www.bestbuy.com/">Best Buy</a>. They were selling it for $699 but the <a href="https://robo3d.com/">official website</a> was having a sale at $599, so Best Buy did a price match. Very cool.&nbsp;&nbsp; I chose this printer because of its price, its support for a variety of filaments and the size of its bed.&nbsp; Despite the fact that it&#8217;s sold as an off-the-shelf solution to 3D printing I had no expectations I could plug it in, turn it on and print.&nbsp; And I was right. I thought I&#8217;d share my earlier experiences with getting the printer set up and usable by both of us.&nbsp; Since both my wife and I will be using it I needed to set it up so it could be easily shared over a network.</p>
<h2>Unpacking</h2>
<p>The printer comes ready to use, for the most part.&nbsp; There is no assembly required.&nbsp; Opening the box you find a styrofoam hat with some cables and tools.&nbsp; The styrofoam was a very tight fit in the box.&nbsp; To get the printer out I had to flip the box over and let the whole thing slide out. There is also an SD card taped into a slot in the styrofoam.</p>
<div id="attachment_6027" style="width: 160px" class="wp-caption alignright"><a href="https://www.graphics-muse.org/wp/?attachment_id=6027" rel="attachment wp-att-6027"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6027" data-attachment-id="6027" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6027" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?fit=2448%2C2398&amp;ssl=1" data-orig-size="2448,2398" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1484576891&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170116_142811" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?fit=300%2C294&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?fit=1024%2C1003&amp;ssl=1" class="wp-image-6027 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142811-1.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6027" class="wp-caption-text">Upside down after sliding out of the box, note the square styrofoam inserts that must be removed after righting the machine.</p></div>
<p>Inside the packaging you&#8217;ll find a manual, a quick setup guide and some other paperwork.&nbsp; The first thing I did was register the printer via a text message, as per the instructions in the paperwork.&nbsp; I would have preferred to do it via my computer since my phone sucks.&nbsp; Don&#8217;t all phones suck?&nbsp; Anyway, all went well with the registration.&nbsp; So I moved on to unpacking the printer.&nbsp;</p>
<p>The printer has a big styrofoam hat and footer so those come off first.&nbsp; Then there are two large square styrofoam inserts inside the print area, plus two small mostly flat styrofoam inserts under the print bed.&nbsp; All of this comes out easily.&nbsp; There are two additional orange plastic pieces that must also be removed.&nbsp; These are labeled and easy to identify.&nbsp; These are not as easy to remove and require a little careful prying.&nbsp; Be careful not to yank on any wiring while doing this.</p>
<div id="attachment_6028" style="width: 160px" class="wp-caption alignleft"><a href="https://www.graphics-muse.org/wp/?attachment_id=6028" rel="attachment wp-att-6028"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6028" data-attachment-id="6028" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6028" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?fit=3264%2C2448&amp;ssl=1" data-orig-size="3264,2448" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1484576761&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170116_142601" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?fit=1024%2C768&amp;ssl=1" class="wp-image-6028 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170116_142601-1.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6028" class="wp-caption-text">The tools provided include: a glue stick, some plastic pads for the corners of the printer, a pair of tweezers, a small screwdriver and some lubricant in a plastic tube. There is also a large flat scraping blade.</p></div>
<p>There is also a set of tools in a plastic container.&nbsp; I didn&#8217;t use any of the tools initially.&nbsp; I tried some of the glue stick but found it didn&#8217;t matter much in my early testing.&nbsp; The scraping tools was very necessary as many of my initial trials required scraping off bad prints from the printer bed.</p>
<p>The packaging includes a power cable and a USB cable.&nbsp; It also includes a small spool of blue PLA.&nbsp; Note that the temperature setting for this PLA is printed on a label on the side of the spool.</p>
<h3>The SD Card</h3>
<p>Before attaching cables from the printer to a computer or power I thought it best to read the manual.&nbsp; The instructions point you to the SD card which contains a video explaining the setup.&nbsp; This video plays on Linux with VLC although it seemed to drop or corrupt a few frames.&nbsp; That was weird, but didn&#8217;t really bother me.</p>
<p>The video suggests you received a thumb drive and micro SD card.&nbsp; I got an SD card w/ micro SD insert.&nbsp; Not a big deal, but it was the first of a number of discrepancies.&nbsp; The biggest one relates to setting up the voltage for the printer.&nbsp; On the back there is a switch to allow choosing a voltage level.&nbsp; The video says the settings are either 230 volts or 115 volts.&nbsp; The physical switch is labeled 220 and 110.&nbsp; The default printed on paper covering the plug on the printer says the machine has been set to 230.&nbsp; The actual default was 110.&nbsp; Try not to let any of this confuse you.&nbsp; If you&#8217;re in the US, set it to 110 or 115, which ever is labeled on the actual switch.&nbsp;</p>
<p>Most of the video talks about using the provided <em>MatterControl</em> software.&nbsp; However, that isn&#8217;t available (without recompiling a bunch on non-C code which I didn&#8217;t feel like diving into unless required) for my Fedora platform so I skipped the rest of the video.&nbsp; It may have helped to watch it just to note that tasks they performed with the software.&nbsp; I probably needed to do the same tasks some other way, as you&#8217;ll see later.</p>
<div id="attachment_6032" style="width: 310px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6032" rel="attachment wp-att-6032"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6032" data-attachment-id="6032" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6032" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?fit=3264%2C2448&amp;ssl=1" data-orig-size="3264,2448" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1484578019&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;300&quot;,&quot;shutter_speed&quot;:&quot;0.05&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="robo3d-voltage" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?fit=1024%2C768&amp;ssl=1" class="wp-image-6032 size-medium" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?resize=300%2C225&#038;ssl=1" width="300" height="225" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-voltage.jpg?w=2340&amp;ssl=1 2340w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-6032" class="wp-caption-text">Don&#8217;t get confused with the voltage. In the US, it&#8217;s 110 or 115, depending on what your Robo3D actually says on the switch.</p></div>
<h2>Physical Setup</h2>
<p>I set the printer on a work table I built from a modified <a href="http://www.ana-white.com/2011/03/sturdy-work-bench">Ana White design</a>.&nbsp; The table isn&#8217;t quit flat and there are no feet adjustments on the printer to level it.&nbsp; The printer would wobble on the table if I manually rocked it. I thought about leveling with folded paper under one corner, the Maker way.&nbsp; But I actually forgot this step and when I did my first full print I noticed that the printer didn&#8217;t rock as the extruder and bed were moved.&nbsp; So leveling the printer itself might not be that important.&nbsp; However, see my discussion on the level the printer bed a little later.</p>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=6051" rel="attachment wp-att-6051"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="6051" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6051" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974.jpg?fit=2448%2C3264&amp;ssl=1" data-orig-size="2448,3264" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1485707702&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;200&quot;,&quot;shutter_speed&quot;:&quot;0.05&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;6&quot;}" data-image-title="20170129_163502" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974.jpg?fit=225%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974.jpg?fit=768%2C1024&amp;ssl=1" class="alignleft wp-image-6051 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974-150x150.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_163502-e1485733189974.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a>The printer bed moves front to back (the Y axis, I believe) and the extruder moves left/right and up/down.&nbsp; The bed needs about 25&#8243; back to front, including space for the bed to move fully back and fully front.</p>
<p>The printer connects to a computer using a USB cable.&nbsp; There is an SD card option but I didn&#8217;t try it because the goal was to share the printer with my wife.&nbsp; The USB connection on the printer is on the right side near the front.&nbsp; Note that the USB cable, which is about 4&#8242; 10&#8243; long, is probably too short if your computer is placed to the left of the printer.&nbsp; You may need a USB extension in that case.</p>
<p>A power switch is located in the back.&nbsp; I found it easier to use, and to see the small opening where the filament is threaded, if the printer was turned with the back facing me.&nbsp; That may affect how you connect the printer to the computer.&nbsp;</p>
<p>Of course the whole point of a 3D printer is to stack plastic until it looks like something you wanted.&nbsp; To do that you need to feed a filament of plastic into an extruder which melts the filament and stacks it on the printer bed.&nbsp; The filament is threaded through a hole at the top of the extruder.&nbsp; In the Robo3D the feed hole is small and encased by a small door with springs on screws.&nbsp; While it&#8217;s easy to feed into this hole the filament has to also be fed through a hole hidden inside that is apparently smaller.&nbsp; It&#8217;s very difficult to feed through both holes.&nbsp; After some failed prints I discovered the best way to feed the filament is to remove the two screws and springs (careful &#8211; the pop off from the springs) and remove the door.&nbsp; Then manually push the filament through the smaller, now visible hole till melted filament comes out the extruder (be sure the extruder has been heated to 180C before doing this &#8211; see the section on software).&nbsp; Then replace the door, screws and spring.&nbsp; In my opinion this is only real drawback to this printer&#8217;s design.&nbsp; It&#8217;s just not easy to see or access the feed hole for the filament.</p>
<p>Note that the physical setup I used included connecting the printer to a Raspberry Pi.&nbsp; More on that in the Software section.</p>
<h2>Software</h2>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=6043" rel="attachment wp-att-6043"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="6043" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6043" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?fit=3264%2C2448&amp;ssl=1" data-orig-size="3264,2448" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1485706579&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;400&quot;,&quot;shutter_speed&quot;:&quot;0.05&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170129_161619" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?fit=1024%2C768&amp;ssl=1" class="alignright size-medium wp-image-6043" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?resize=300%2C225&#038;ssl=1" alt="" width="300" height="225" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?w=2340&amp;ssl=1 2340w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>This is where things grind to a halt initially.&nbsp; At least if you&#8217;re a Linux user.&nbsp; Follow along, though.&nbsp; In the end it&#8217;s not that hard once you have the information you really need.&nbsp; Much of the work I&#8217;m going to describe might be easier if you connect the printer directly to your Windows or Mac boxes and use the provided MatterControl software.&nbsp; But I&#8217;m a Linux guy and the world doesn&#8217;t try to make things easy for us.&nbsp; That&#8217;s why we&#8217;re so smart.</p>
<p>The Robo3D wants to run <a href="http://www.mattercontrol.com/">MatterControl</a> for Mac.&nbsp; Mattercontrol is a <em>slicer</em>, which is what converts a 3D model (stl) into a format (g-code) that can be fed to the printer.&nbsp; The <a href="http://www.friday.com/bbum/2012/01/31/3d-printing-the-software-stack-is-kinda-broken/">3D printing stack</a> is a little confusing &#8211; no wonder some people have problems getting started.&nbsp; A <a href="http://community.robo3d.com/index.php?threads/octoprint-cura-profiles.7362/">good summary of the software stack</a> can be found on the Robo 3D forums.&nbsp; <a href="http://wiki.mattercontrol.com/Development/Running_on_Linux">MatterControl can run on Linux</a>.&nbsp; However you need to <a href="http://wiki.mattercontrol.com/Building_MatterControl">compile from source</a> for Fedora.&nbsp; This requires <a href="http://www.mono-project.com/docs/getting-started/install/linux/#centos-7-fedora-19-and-later-and-derivatives">Mono 4.4</a>.&nbsp; Fedora 22, which is what I&#8217;m using, is at 2.10.&nbsp; The overhead to get all that working seemed hardly worth the effort if I could find something a little more off-the-shelf.</p>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=6033" rel="attachment wp-att-6033"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="6033" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6033" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?fit=1291%2C748&amp;ssl=1" data-orig-size="1291,748" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cura" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?fit=300%2C174&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?fit=1024%2C593&amp;ssl=1" class="alignleft size-medium wp-image-6033" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?resize=300%2C174&#038;ssl=1" alt="" width="300" height="174" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?resize=300%2C174&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?resize=768%2C445&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?resize=1024%2C593&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/cura.png?w=1291&amp;ssl=1 1291w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>There are other slicer software solutions out there, such as <a href="https://ultimaker.com/en/products/cura-software">Cura</a>.&nbsp; Support for using Cura directly with <a href="https://robo3d.com/software/">Robo3D is coming</a>, apparently.&nbsp; This allows Cura to not just slice but feed the g-code to the printer and track its progress.&nbsp; But that setup would isolate the printer to either my wife&#8217;s Mac or my Linux box and make it less friendly to share.&nbsp; Fortunately you can use Cura on your desktop, Linux or Mac, separate from the printer.&nbsp; This allows you to model and slice on your desktop and just feed the g-code output to the printer through some other method.&nbsp; Since my solution will be web-based to share the printer with my wife this is the optimal workflow.</p>
<p>The Robo3D printer has been used with Cura to <a href="http://fatdragongames.proboards.com/thread/3567/robo-plus-cura-settings-updated">print custom pieces for DragonLock</a>, a 3D printed dungeon gaming terrain building system.&nbsp; Given the photos I saw I thought using Cura would be a better option for both my wife and myself.</p>
<p>In the end I opted for a version of <a href="http://octoprint.org/">OctoPrint</a> running on a Raspberry Pi, known as <a href="http://octoprint.org/download/">OctoPi</a>.&nbsp; OctoPrint is a web-based solution for managing 3D print jobs, including watching real-time progress.&nbsp; You upload the g-code file to OctoPrint and then print to your connected and configured printer.&nbsp; OctoPi is an image you copy to an SD card and then boot on a <a href="https://www.raspberrypi.org/">Raspberry Pi</a> that runs an instance of OctoPrint.&nbsp; Because of my <a href="https://www.piboxproject.com/">PiBox</a> project I have a few extra Pi&#8217;s lying around.</p>
<p>OctoPrint can be used to perform slicing of your 3D model using a variety of slicer software.&nbsp; In fact the default slicer is Cura.&nbsp; However, don&#8217;t try to use the OctoPi to do your slicing.&nbsp; It will be slow and probably can&#8217;t handle sequential requests very well.&nbsp; You&#8217;re better off doing slicing with Cura on your desktop.&nbsp; There are ready-made install packages of Cura for Windows, Mac and Debian-based Linux systems.&nbsp; Fedora, which is what I use, requires a little extra work.</p>
<p>Cura for Linux is only available in deb packaging, which is intended for use on Debian-based Linux distributions such as Ubuntu.&nbsp; Fortunately the Cura .deb file can be converted using <a href="http://linuxtinker.blogspot.com/2016/07/cura-212-on-fedora-2324.html">alien</a> (these instructions work for Fedora 22 too).&nbsp;</p>
<p>After installing the generated RPM file on Fedora 22 (at least) you need to <a href="https://ultimaker.com/en/community/22286-solved-cura-2-on-debian-sid">remove the libstdc++ installed by Cura</a>.&nbsp; Cura doesn&#8217;t list Robo3D as a supported printer so you add it as a custom printer.&nbsp; It will prompt for <a href="http://community.robo3d.com/index.php?threads/cura-settings.3617/">Machine Settings</a>, of which there are <a href="http://fatdragongames.proboards.com/thread/3567/robo-plus-cura-settings-updated">several variations</a> I found online.</p>
<h2>Configuration</h2>
<p>The OctoPi setup is based in some part on the <a href="https://www.raspbian.org/">Raspbian</a> distribution built for the Raspberry Pi.&nbsp; The instructions for it are brief and mostly complete.&nbsp; However, I had to manually edit <span style="color: #0000ff;">/etc/network/interfaces</span> to mimic like PiBox or it wouldn&#8217;t work. They have some clever naming schemes in their boot up that didn&#8217;t work for some reason. Where they had the following</p>
<pre style="padding-left: 30px;"><span style="color: #0000ff;">allow-hotplug wlan1</span>
<span style="color: #0000ff;">iface wlan1-raspbian inet manual</span>
<span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf</span></pre>
<p>I used the standard interface naming scheme</p>
<pre style="padding-left: 30px;"><span style="color: #0000ff;">auto wlan0</span>
<span style="color: #0000ff;">iface wlan0 inet dhcp</span>
<span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf</span></pre>
<p>I also used a simplistic setup for wpa_supplicant.conf</p>
<pre style="padding-left: 30px;"><span style="color: #0000ff;"># country=US</span>
<span style="color: #0000ff;"># ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev</span>
<span style="color: #0000ff;"># update_config=1</span>
<span style="color: #0000ff;">ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev</span>
<span style="color: #0000ff;">ap_scan=1</span>

<span style="color: #0000ff;">network={</span>
<span style="color: #0000ff;">&nbsp; ssid="Your SSID Here"</span>
<span style="color: #0000ff;">&nbsp; scan_ssid=1</span>
<span style="color: #0000ff;">&nbsp; proto=WPA2</span>
<span style="color: #0000ff;">&nbsp; key_mgmt=WPA-PSK</span>
<span style="color: #0000ff;">&nbsp; psk="Your Password here"</span>
<span style="color: #0000ff;">&nbsp; pairwise=TKIP</span>
<span style="color: #0000ff;">&nbsp; group=TKIP</span>
<span style="color: #0000ff;">}</span></pre>
<p>Using standard formats for the interfaces file worked better, probably because I missed a step in setting up the configuration file to set the interface naming (or the OctoPi team did).</p>
<h2>Setting the Z-offset</h2>
<p>My first set of prints failed completely.&nbsp; I kept getting a loud click.&nbsp; After some time I tried to force the filament through manually and found it to be stuck.&nbsp; The filament would not go through and would not pull out.&nbsp;&nbsp; I turned up the heat on the hot end, removed the screws on the filament feed intake and manually forced the filament through to clear any clog.&nbsp; Then I was able to pull it out manually.&nbsp; I clipped off the end and manually fed it through again.&nbsp; I adjusted the screws to be less tight than before.&nbsp; This cleared the filament path but didn&#8217;t produce any prints.&nbsp;</p>
<p>Then I got on the <a href="http://community.robo3d.com/index.php?taigachat/">ShoutBox</a> section of the Robo3D site and someone called <em>WheresWaldo</em> suggested adjusting the <strong>Z-offset</strong>.&nbsp; There is a <a href="http://community.robo3d.com/index.php?threads/revamped-m565-z-offset-set-it-and-forget-it.4748/">unique command (M565)</a> to do this so you can set this as the default for all your prints.</p>
<p>I experimented with different settings, adjusting the value and starting a print run, until I got to a Z-offset of 0.75 that seemed to work.&nbsp; And by work I mean print on the bed in smooth lines without globs of filament getting stuck to the extruder. But the print was only working on one side of the bed.&nbsp; The other side was not always printing.&nbsp; This made me think the bed was not leveled.&nbsp; A little more googling and I found the real solution to the Z-offset and bed leveling problem.</p>
<p>The following typed in the Terminal tab of OctoPrint should <a href="http://community.robo3d.com/index.php?threads/auto-bed-leveling.1590/page-3">level the bed</a>.</p>
<ol>
<li>Probe the bed: <span style="color: #339966;"><em>G28</em></span>.&nbsp; This tells you what the Z-Offset should be.&nbsp; Just enter the command in the terminal window and watch the output for the Z offset after the extruder stops moving.&nbsp; In my case it was <em>-0.73</em>.</li>
<li>Set and save the Z-offset:&nbsp; <em><span style="color: #339966;">M565 Z-0.73</span></em>&nbsp; This will store the Z offset in flash so you never need to set it again.</li>
<li>Level the bed: <span style="color: #339966;"><em>G29</em></span>&nbsp; This probes 9 different points on the bed based on your stored Z-offset so that the bed is leveled automatically as the print is running.</li>
</ol>
<p>These three are manual steps required when you first power on the printer.&nbsp; Although the Z-offset should be stored and reused on power up it doesn&#8217;t appear that it has any effect without doing all three steps each time.&nbsp; You can tell this is the case if, as you start a print, you hear a loud click.&nbsp; That click is the extruder trying to feed the filament but failing because there isn&#8217;t enough clearance between the tip and the bed.</p>
<h2>OctoPrint</h2>
<p>The Robo3D should be configured for use with the OctoPrint interface. The <em>Settings-&gt;Serial Connection</em> fields should be set to<strong> /dev/ttyACM0</strong> and baud rate of <strong>250000</strong> for the OctoPi.&nbsp; A printer profile should be created to set the size of the print area.&nbsp; The X, Y and Z volumes should be set, respectively, to</p>
<blockquote>
<p style="padding-left: 30px;"><span style="color: #3366ff;">X: 228</span></p>
<p style="padding-left: 30px;"><span style="color: #3366ff;">Y: 254</span></p>
<p style="padding-left: 30px;"><span style="color: #3366ff;">Z: 228</span></p>
</blockquote>
<p>And set the option for <em>Heated Bed</em>.</p>
<p>This requires&nbsp; : watching the progress in the g-code viewer.&nbsp; Restarting a print should start by reloading the g-code viewer.&nbsp; If the print starts but doesn&#8217;t set the desired temperatures then do it manually before you start the print.&nbsp; I use 200C for the hot end working with the stock blue PLA provided in the packaging and 60C for the bed.</p>
<table>
<tbody>
<tr>
<td style="text-align: center; vertical-align: top;">
<p><div id="attachment_6034" style="width: 160px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6034" rel="attachment wp-att-6034"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6034" data-attachment-id="6034" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6034" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?fit=576%2C903&amp;ssl=1" data-orig-size="576,903" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="octoprint-robo3d-profile" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?fit=191%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?fit=576%2C903&amp;ssl=1" class="wp-image-6034 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-profile.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6034" class="wp-caption-text">Create a printer profile to tell OctoPi the print area of the Robo3D.</p></div></td>
<td style="text-align: center; vertical-align: top;">
<p><div id="attachment_6035" style="width: 160px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6035" rel="attachment wp-att-6035"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6035" data-attachment-id="6035" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6035" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?fit=992%2C874&amp;ssl=1" data-orig-size="992,874" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="octoprint-robo3d-serial" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?fit=300%2C264&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?fit=992%2C874&amp;ssl=1" class="wp-image-6035 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/octoprint-robo3d-serial.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6035" class="wp-caption-text">Set the serial connection for the OctoPi to talk to the Robo3D.</p></div></td>
</tr>
</tbody>
</table>
<h2>First Print Attempts</h2>
<p>My initial attempts at printing were all cancelled quickly because it became apparent the filament wasn&#8217;t moving.&nbsp; Each attempt had to be scraped off the bed and restarted.&nbsp; This was fixed with the bed leveling process.&nbsp; Once I started my real first print I began to understand something that had confused me originally.</p>
<div id="attachment_6036" style="width: 160px" class="wp-caption alignleft"><a href="https://www.graphics-muse.org/wp/?attachment_id=6036" rel="attachment wp-att-6036"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6036" data-attachment-id="6036" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6036" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?fit=3264%2C2448&amp;ssl=1" data-orig-size="3264,2448" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1485201921&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170123_200522" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?fit=1024%2C768&amp;ssl=1" class="wp-image-6036 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170123_200522-1.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6036" class="wp-caption-text">See the ghost layer? You peel it off when you&#8217;re done printing. But this should have a solid surface, not look like a sponge.</p></div>
<p>The Robo3D (or perhaps the slicing program) lays down a ghost layer, almost like a halo, on the first layer it prints.&nbsp; It&#8217;s very thin and larger than the base of my print object.&nbsp; Once I let the printing continue to higher layers it became clear that this was just a base of some kind.&nbsp; I&#8217;m not clear yet why this is there &#8211; possibly to make removing the print easier &#8211; but don&#8217;t be fooled if you&#8217;re anxiously watching the start of the print and see this ghost layer get laid out.&nbsp; Let it run for a bit and the object should start taking shape.</p>
<p>When the print finished the bed moved all the way to the back, which is good considering that&#8217;s the side facing me.&nbsp; It made it easier to pull the object from the bed with the scraper.&nbsp; I pulled the print off and examined it.&nbsp; It was the right shape but a fairly unimpressive print with many holes and no solid surface.&nbsp; It looked more like a sponge than the bookmark it was supposed to be.&nbsp; Note that the model for this was provided as one of four models available download after registration from the Robo3D manufacturer .</p>
<p>Having never done this previously myself (although I&#8217;ve had a model printed for me at the local library) I concluded that the problem was with the way I sliced the model.&nbsp; I checked my Cura setup and found it to be on the Light infill setting.&nbsp; There are for infill settings: hollow, light, dense and solid.&nbsp; So I switched to solid and tried again.&nbsp; The result was actually worse.&nbsp;</p>
<p>So while I&#8217;m now able to print I have yet to figure out how to print well.&nbsp; I imagine this is akin to learning the difference between printing plain text and printing in CMYK with GIMP.&nbsp; I&#8217;ll need to check on the <a href="http://community.robo3d.com/index.php">Robo3D forums</a> or maybe a local Maker user group to get some help.&nbsp;</p>
<p>One other thing:&nbsp; a day or so passed between the first print and the second.&nbsp; When preparing the second print I did everything I&#8217;ve specified earlier and started the print.&nbsp; The extruder started to position itself and printed a small part of the ghost layer and then &#8230; <em>POP!</em>&nbsp; The filament flew out of the feed at the top of the extruder.&nbsp; It had snapped off.&nbsp; I had to disassemble the feed (those two screws again) to find the part stuck in the extruder.&nbsp; I pulled on it by hand and it broke again leaving a smaller piece to grab.&nbsp; I had the extruder heated to 200C and then used a pair of needle nose pliers to carefully pull the remainder out.&nbsp; It took awhile, but I think once it got hot enough and could stretch a little it finally came out.&nbsp; This is not a good sign.&nbsp; Either the extruder/feeder design is flawed or the filament is bad.&nbsp; I got both from Robo3D.&nbsp; I hope they can fix at least one of those problems.</p>
<table>
<tbody>
<tr>
<td style="text-align: center; vertical-align: top;">
<p><div id="attachment_6045" style="width: 160px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6045" rel="attachment wp-att-6045"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6045" data-attachment-id="6045" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6045" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?fit=2448%2C3264&amp;ssl=1" data-orig-size="2448,3264" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1485627051&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170128_181051" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?fit=225%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?fit=768%2C1024&amp;ssl=1" class="wp-image-6045 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181051-1.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6045" class="wp-caption-text">The snapped filament with the feeder screws removed.</p></div></td>
<td style="text-align: center; vertical-align: top;">
<p><div id="attachment_6044" style="width: 160px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6044" rel="attachment wp-att-6044"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6044" data-attachment-id="6044" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6044" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?fit=2448%2C3264&amp;ssl=1" data-orig-size="2448,3264" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1485627126&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;100&quot;,&quot;shutter_speed&quot;:&quot;0.016666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170128_181206" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?fit=225%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?fit=768%2C1024&amp;ssl=1" class="wp-image-6044 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170128_181206-1.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6044" class="wp-caption-text">The filament pulled from the feeder after it melted enough to get it out.</p></div></td>
<td style="text-align: center; vertical-align: top;">
<p><div id="attachment_6043" style="width: 160px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6043" rel="attachment wp-att-6043"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6043" data-attachment-id="6043" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6043" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?fit=3264%2C2448&amp;ssl=1" data-orig-size="3264,2448" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;LGLS740&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1485706579&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.2&quot;,&quot;iso&quot;:&quot;400&quot;,&quot;shutter_speed&quot;:&quot;0.05&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20170129_161619" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?fit=1024%2C768&amp;ssl=1" class="wp-image-6043 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/20170129_161619.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-6043" class="wp-caption-text">The second print, which should have been better than the first but was actually worse.</p></div></td>
</tr>
</tbody>
</table>
<h2>Tweaks</h2>
<p>The USB camera support on OctoPi is not working at the moment.&nbsp; Neither is the automatic update.&nbsp; I may need to reload that software to the SD card, setup and try again.&nbsp; Perhaps this is related to the bad prints, but somehow I don&#8217;t think so.</p>
<p>Some other suggestions I found online include an additional fan on the opposite side of the extruder and a LCD interface.&nbsp; Others have gone so far as to integrate the OctoPi directly into the printer with a single power switch.&nbsp; I have too many other projects on my plate to dive into those now, not the least of which is getting this thing to make a decent print.&nbsp; But let me know if you try them.</p>
<hr />
<h2>Update 2020</h2>
<p>Three years later and I&#8217;ve finally returned to 3D printing.&nbsp; I&#8217;m looking to see if I can print those <a href="https://getusppe.org/makers/face-shields/">face shields</a> (eg <a href="https://www.prusaprinters.org/prints/25857-prusa-protective-face-shield-rc3">Prusa design</a>) needed by doctors and nurses to treat Covid-19.&nbsp; Before I can do that I need to make the printer actually work.&nbsp; And I haven&#8217;t touched this printer since I wrote this article the first time.</p>
<div id="attachment_6334" style="width: 196px" class="wp-caption alignright"><a href="https://www.graphics-muse.org/wp/?attachment_id=6334" rel="attachment wp-att-6334"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6334" data-attachment-id="6334" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6334" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?fit=1579%2C2547&amp;ssl=1" data-orig-size="1579,2547" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="bookmark-2020" data-image-description="&lt;p&gt;A successful print from Robo3D via OctoPrint and Cura 3.6 on Linux.&lt;/p&gt;
" data-image-caption="&lt;p&gt;Proper print from Robo3D.&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?fit=186%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?fit=635%2C1024&amp;ssl=1" class="size-medium wp-image-6334" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?resize=186%2C300&#038;ssl=1" alt="" width="186" height="300" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?resize=186%2C300&amp;ssl=1 186w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?resize=768%2C1239&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?resize=635%2C1024&amp;ssl=1 635w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020.png?w=1579&amp;ssl=1 1579w" sizes="auto, (max-width: 186px) 100vw, 186px" /></a><p id="caption-attachment-6334" class="wp-caption-text">A proper print from Robo3D.</p></div>
<p>After refreshing my memory on how to get started (thanks to this article, no less) I upgraded to Cura 3.6 (latest available for Fedora 29) and OctoPrint 1.4.0, which I&#8217;m running directly on my desktop now (which has 32 cores and 32G memory, so why not?).&nbsp; Everything came up quickly and I was able to try printing again rather quickly but every print was worse than the first time.&nbsp; I was still getting that clicking sound and the extruder would clog up.&nbsp; I tried printing at higher temperatures, <a href="http://www.dragonflydiy.com/2014/06/nozzle-seasoning.html">seasoning the nozzle</a>, and <a href="https://help.robo3d.com/hc/en-us/articles/115000723592-Clogged-Hotend-R1-Plus">clearing the extruder path</a>.&nbsp; Nothing seemed to help.</p>
<p>Then I took a look at the nozzle head.&nbsp; It was sitting so close to the bed that even a piece of paper wouldn&#8217;t fit between them.&nbsp; I had set the Z-offset as described in this document but that didn&#8217;t seem to change anything.&nbsp; Turns out the problem was not just setting the firmware but also setting Cura&#8217;s Z-offset by adding the <a href="https://github.com/fieldOfView/Cura-ZOffsetPlugin">Z-offset plugin</a>.&nbsp; This is required because Cura was setting the Z-offset itself, irrespective of what I set in the firmware, and I needed to override it.&nbsp; The plugin can be installed directly from Cura.&nbsp; In Cura 3.6 and later (maybe in earlier versions) there is a Marketplace menu option.&nbsp; Look under there for the Featured Plugins and go to the end of the alphabetically sorted list.&nbsp; After installation you need to click on the Build Adhesion Plate setting where you&#8217;ll find an options box to enable the Z-offset.&nbsp; Once enabled you will find a new field under Build Adhesion Plate for setting the Z-offset.</p>
<p>More importantly, the Z-offset set in Cura needs to be different than my original experiments.&nbsp; After many experiments of cancelled prints, I found the setting needed to be set to&nbsp;<em><span style="color: #339966;">Z-1.0</span></em>&nbsp; which causes Cura to add the following line to the gcode.</p>
<blockquote><p><em>G0 F7200 X93.014 Y71.925 Z1.18 ;adjusted by z offset</em></p></blockquote>
<p>So it wants to set it to 0.18, but then adds 1.0 to it from my Z-offset setting.&nbsp; This is the setting I put in the firmware to, though it&#8217;s not clear if -1.0 or -1.8 should be used.&nbsp; Since MatterControl still doesn&#8217;t work with my version of Linux (and nothing on earth will get me to use Ubuntu) I&#8217;ll just use Cura and always set the Z-offset there so it embeds in the gcode file.&nbsp;</p>
<p>The result is I now have a working configuration to print the bookmarker model.&nbsp; Notice the raft printed around the bookmark.&nbsp; I&#8217;m not sure where that&#8217;s coming from &#8211; I think Cura may add it.&nbsp; For this print, which has some flimsy pieces where the bookmarker attaches to the book pages, this is helpful for pulling the print from the bed.&nbsp; You just have to cut all that off later.&nbsp;&nbsp; Seems like a lot of waste, so I&#8217;ll need to see if I can reduce the size of the raft somehow.</p>
<p>But at least the prints are working now.</p>
<h2>Update 2020.2</h2>
<p>The excess printing is called a raft and is a configuration item in Cura, under the <strong>Build Plate Adhesion</strong> setting as <em>Build Plate Adhesion Type</em>.&nbsp; The raft setting for this type prints extra support area for models that need it.&nbsp; But using the skirt setting, instead of raft, just prints a couple of circles around the outside edge of the model.&nbsp; This is done to prime the extruder before starting to print. Those extra circles are on the build plate but are not attached to the model.</p>
<p>The result is much better, at least for this model, as you can see in this picture.</p>
<div id="attachment_6336" style="width: 154px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=6336" rel="attachment wp-att-6336"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-6336" data-attachment-id="6336" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6336" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?fit=1149%2C2392&amp;ssl=1" data-orig-size="1149,2392" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="bookmark-2020-skirt" data-image-description="&lt;p&gt;Bookmark printed using the skirt build adhesion type setting in Cura.&lt;/p&gt;
" data-image-caption="&lt;p&gt;Bookmark printed using the skirt build adhesion type setting in Cura.&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?fit=144%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?fit=492%2C1024&amp;ssl=1" class="size-medium wp-image-6336" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?resize=144%2C300&#038;ssl=1" alt="Bookmark printed using skirt setting in Cura." width="144" height="300" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?resize=144%2C300&amp;ssl=1 144w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?resize=768%2C1599&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?resize=492%2C1024&amp;ssl=1 492w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/bookmark-2020-skirt.png?w=1149&amp;ssl=1 1149w" sizes="auto, (max-width: 144px) 100vw, 144px" /></a><p id="caption-attachment-6336" class="wp-caption-text">Bookmark printed using the skirt build adhesion type setting in Cura.</p></div>
<h2>Update 2020.3</h2>
<p>I&#8217;m finally getting the hang of the printer.&nbsp; Every print needs to be setup properly.&nbsp; The steps I have to take are as follows.&nbsp; These are all done through Octoprint.</p>
<ol>
<li>Raise the print head.&nbsp; I click on the Raise button in the Control tab twice.</li>
<li>Heat the head to 240 C.</li>
<li>Extrude until I see a clean stream of filament.&nbsp; This flushes any dried blobs from the head.</li>
<li>Home the print head X/Y.</li>
<li>Remove the filament flush and clean the print plate.&nbsp; Scrape any previous glue from the plate and wipe with a soft cloth, like a eye-glass lens cloth.&nbsp; Use Windex if necessary.&nbsp; Doesn&#8217;t have to be perfectly clean, but remove any large lumps that might get in the way of the print head.</li>
<li>Rub Elmers Washable School Glue Stick over the area of the print plate where the print will go.&nbsp; This is a bit of a guessing game for odd shaped prints.</li>
<li>Home the print head Z.</li>
<li>Use the Terminal tab to type: G28, M565 Z-0, G29 and wait for the print head to stop moving.&nbsp; In some cases it helps to change Z-0 to Z-0.1, like when you find the print head is too close to the surface while it is extruding.</li>
<li>Home the print head X/Y again.</li>
<li>Heat the bed to 60 C.</li>
</ol>
<p>Now I&#8217;m ready to print.&nbsp; It&#8217;s important that the model being printed, in the gcode, have the Z-offset properly set as this method relies on the model setting the Z-offset and NOT Octoprint!&nbsp; Note that I&#8217;m using Cura to slice my models and it has presets for the Robo3D R1+.&nbsp; Also note that it should be set to 210 C to print.&nbsp; That&#8217;s the optimal print temperature for PLA that came with the printer.&nbsp; Other filaments will have different temperatures but you can set this is Cura for each model you slice.</p>
<p>Finally, I thought I&#8217;d post an image showing the selection of filaments supported by the Robo3D R1+, which was taken from Amazon via Robo3D.&nbsp; This is just for reference when looking for compatible filaments.</p>
<p style="text-align: center;"><a href="https://www.graphics-muse.org/wp/?attachment_id=6339" rel="attachment wp-att-6339"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="6339" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=6339" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?fit=1500%2C1500&amp;ssl=1" data-orig-size="1500,1500" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="robo3d-filament-types" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?fit=300%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?fit=1024%2C1024&amp;ssl=1" class="aligncenter size-medium wp-image-6339" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?resize=300%2C300&#038;ssl=1" alt="" width="300" height="300" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?resize=300%2C300&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?resize=768%2C768&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?resize=1024%2C1024&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/robo3d-filament-types.jpg?w=1500&amp;ssl=1 1500w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p><p>The post <a href="https://www.graphics-muse.org/wp/?p=5968">Getting started with the Robo3D printer and OctoPrint</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=5968</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5968</post-id>	</item>
		<item>
		<title>First PiBox Meetup</title>
		<link>https://www.graphics-muse.org/wp/?p=5963</link>
					<comments>https://www.graphics-muse.org/wp/?p=5963#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Thu, 12 Jan 2017 03:42:12 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=5963</guid>

					<description><![CDATA[<p>The first official PiBox meetup has been scheduled for Wednesday, January 18, 2017 in room B2 at Library 21c.&#160; I&#8217;ll be doing a demo of the PiBox Media Center and going over the same slides I presented at the Colorado Springs Open Source Software Meetup.&#160; Then we&#8217;ll open it to general discussions on embedded systems [&#8230;]</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=5963">First PiBox Meetup</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5964" rel="attachment wp-att-5964"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5964" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5964" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?fit=1510%2C1008&amp;ssl=1" data-orig-size="1510,1008" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="large_meetup_logo" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?fit=300%2C200&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?fit=1024%2C684&amp;ssl=1" class="size-medium wp-image-5964 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?resize=300%2C200&#038;ssl=1" alt="" width="300" height="200" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?resize=300%2C200&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?resize=768%2C513&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?resize=1024%2C684&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/large_meetup_logo.png?w=1510&amp;ssl=1 1510w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>The first official PiBox meetup has been scheduled for <strong>Wednesday, January 18, 2017</strong> in room <strong>B2</strong> at <strong>Library 21c</strong>.&nbsp; I&#8217;ll be doing a demo of the PiBox Media Center and going over the same slides I presented at the Colorado Springs Open Source Software Meetup.&nbsp; Then we&#8217;ll open it to general discussions on embedded systems development.</p>
<p>The room only holds 10 people so get there early to get a seat!</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=5963">First PiBox Meetup</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=5963</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5963</post-id>	</item>
		<item>
		<title>Unit testing server protocols in C</title>
		<link>https://www.graphics-muse.org/wp/?p=4773</link>
					<comments>https://www.graphics-muse.org/wp/?p=4773#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Fri, 06 Jan 2017 06:13:00 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[PiBox]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[sourceforge]]></category>
		<category><![CDATA[web server]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=4773</guid>

					<description><![CDATA[<p>I&#8217;ve been porting a number of utilities in PiBox to provide library support for common functions.&#160; This includes a network configuration library &#8211; known as libpiboxnet &#8211; and a higher level library for PiBox specific functions.&#160; The code for the networking library was originally duplicated in two different apps with nearly identical functions.&#160; One of [&#8230;]</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=4773">Unit testing server protocols in C</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5945" rel="attachment wp-att-5945"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5945" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5945" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?fit=1041%2C948&amp;ssl=1" data-orig-size="1041,948" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="code-inspect" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?fit=300%2C273&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?fit=1024%2C933&amp;ssl=1" class="size-thumbnail wp-image-5945 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?resize=150%2C150&#038;ssl=1" alt="" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/code-inspect.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a>I&#8217;ve been porting a number of utilities in PiBox to provide library support for common functions.&nbsp; This includes a network configuration library &#8211; known as libpiboxnet &#8211; and a higher level library for PiBox specific functions.&nbsp; The code for the networking library was originally duplicated in two different apps with nearly identical functions.&nbsp; One of those is the PiBox daemon.&nbsp; This daemon accepts network packets for performing a variety of functions.&nbsp; Currently all packets are required to come from the localhost but later they will permit connections from remote apps like the new piboid Android app.</p>
<p>One of the most important tasks when writing a server library is unit testing the inbound message handling.&nbsp; So how can you do this?&nbsp; There are many testing infrastructures, but it&#8217;s actually pretty easy to do without one.&nbsp; For PiBox&#8217;s piboxd daemon I wanted to automate testing using ordinary BASH scripts.&nbsp; Before getting to the shell scripts let&#8217;s define the protocol that will be tested.</p>
<h2>Binary protocol format</h2>
<p>Before explaining the test method I should explain what I&#8217;m testing.&nbsp; There are three components to the server that need testing:</p>
<ol>
<li>The inbound connection handler that validates the message</li>
<li>The queue handler that is used to asynchronously handle the message</li>
<li>The message specific functions</li>
</ol>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5948" rel="attachment wp-att-5948"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5948" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5948" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/PacketFormat-large.png?fit=405%2C192&amp;ssl=1" data-orig-size="405,192" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="PacketFormat-large" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/PacketFormat-large.png?fit=300%2C142&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/PacketFormat-large.png?fit=405%2C192&amp;ssl=1" class="size-medium wp-image-5948 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/PacketFormat-large.png?resize=300%2C142&#038;ssl=1" alt="" width="300" height="142" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/PacketFormat-large.png?resize=300%2C142&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2017/01/PacketFormat-large.png?w=405&amp;ssl=1 405w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a>The server doesn&#8217;t get a lot of connections so it&#8217;s not implemented to be robust (a bug on its own).&nbsp; It handles each connection and attempts to read in the complete message.&nbsp; If it fails, it drops the connection and waits for the next message.&nbsp; If the message is complete it queues it for a separate thread to handle.</p>
<p>The incoming message is a self defined message.&nbsp; This means it has a small header with a payload size and the payload.&nbsp; The header is defined by the message protocol and contains a type and action.&nbsp; If the payload (or any other part of the message) does not arrive in time then the connection times out.</p>
<p>The header has to be validated for the protocol.&nbsp; If it fails the connection drops without reading the payload.&nbsp; The payload depends on the message type and action.&nbsp; The queue processor passes the message to its handler.&nbsp; If necessary, the inbound connection is kept open and passed along to the message handler who is responsible for cleaning up the connection.</p>
<p>The payload is shown with an alternate format that is used for specific commands where a tag and a filename are used.&nbsp; The use of the tag depends on the header where specific types require the tag and filename.</p>
<p>As you can see there isn&#8217;t much to this protocol.&nbsp; It&#8217;s pretty simple though there are a number of points of potential failure.&nbsp; Much of the protocol is handled in the header to perform various network setup.&nbsp;&nbsp; Configuration data is in the payload.&nbsp; Unknown types and actions are ignored.</p>
<p>Now that the design is defined it&#8217;s time to look at unit testing the inbound, queue and message handling.</p>
<h2>Send a packet with netcat</h2>
<p>There are probably other ways to do this (it&#8217;s software, there are 1000 solutions with at least half being sufficient) but I use <a href="http://netcat.sourceforge.net/">netcat</a>.&nbsp; The command line for all tests is simple:</p>
<p style="padding-left: 30px;"><code>nc -4 localhost $PIBOX_PORT &lt; servertest.dat</code></p>
<p>The <em>-4</em> option means use IPv4.&nbsp; Doing the tests on <em>localhost</em> is easier if I limit the protocol to IPv4.&nbsp; I&#8217;m not testing network connectivity, just the application layer protocol.&nbsp; The port depends on how I run the <strong>piboxd</strong> daemon.&nbsp; The redirection from stdin is used to pass the data to transfer to piboxd.&nbsp; It&#8217;s the protocol packet we&#8217;re testing.</p>
<h2>Build a packet with xxd</h2>
<p>The secret to protocol testing with netcat is building the packet to feed to it.&nbsp; The packet defined above uses single byte binary fields which are not easy to generate with ordinary shell scripts. &nbsp; Fortunately they are very easy to generate with xxd using a three part command.</p>
<p style="padding-left: 30px;"><code>printf "0: %s" $header | sed -E 's/0: (..)(..)(..)(..)/0: \4\3\2\1/' | xxd -r &gt; servertest.dat</code></p>
<p>The header value is a string representing the four bytes of the header in the protocol packet.&nbsp; The string is represented in LSB first, as in</p>
<p style="padding-left: 30px;"><code>00000201</code></p>
<p>This makes it easier to map to the protocol diagram.&nbsp; But on an Intel box the ordering needs to be reversed.&nbsp; This is accomplished with the sed command, which translates the string to this.</p>
<p style="padding-left: 30px;"><code>01020000</code></p>
<p>But this is a still a string.&nbsp; In order to pass it with netcat we need to make this a binary value.&nbsp; That&#8217;s where xxd comes in.&nbsp; Normally xxd is used to convert binary data into a human readable string.&nbsp; Using the -r option we can convert the string back into binary and send it to a temporary file, the one we&#8217;ll pass to netcat to run our test.</p>
<p>This is just an example of generating the header but the same process is used to generate the payload size and payload fields, appending them to the temporary file.</p>
<h2>Scripting the whole thing</h2>
<p>To script the tests I used two functions:&nbsp; <em>genMsg</em> and <em>sendIt</em>.&nbsp; The former is used to generate the temporary file used to run a test.&nbsp; The latter is used to send the message from the temporary file.&nbsp; Simple enough.&nbsp; In practice these functions used state variables to modify the message content in order to apply invalid formats.&nbsp; But a simple test might look like the following.</p>
<p style="padding-left: 30px;"><code> genMsg 00000201 webcam</code><br />
<code> NCOUT=1</code><br />
<code> sendIt</code><br />
<code> unset NCOUT</code></p>
<p>The genMsg function is handed the header and a payload.&nbsp; The NCOUT variable is used to save output from netcat to check for error messages.&nbsp; As the script expands many such variables are created to vary the tests.</p>
<h2>Extensions</h2>
<p>As more features were added to piboxd more unit tests were added to the script.&nbsp; This includes the ability to launch an netcat-based web server to receive replies from piboxd as well as sending and receiving multicast messages using <a href="http://sectools.org/tool/socat/">socat</a> (an alternative to netcat).&nbsp; I was even able to run piboxd with valgrind to check for leaks.</p>
<p>The scripts for testing piboxd are in the <a href="https://gitlab.com/pibox/piboxd/tree/master/tests">tests directory</a> but need to be run from the top of the source tree in order to find required data files.&nbsp; Feel free to check them out and let me know if you have additional ideas!</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=4773">Unit testing server protocols in C</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=4773</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4773</post-id>	</item>
		<item>
		<title>What to do in 2017</title>
		<link>https://www.graphics-muse.org/wp/?p=5910</link>
					<comments>https://www.graphics-muse.org/wp/?p=5910#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Fri, 30 Dec 2016 03:20:52 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PiBox]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[adafruit]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[toolchain]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[WebKit]]></category>
		<category><![CDATA[xmpcr]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=5910</guid>

					<description><![CDATA[<p>The value of an over-exuberant penchant for experimentation and fiddling should never be underestimated, if only because it helps measure the onset of age-associated mental debilitation.  In other words, everyone needs a hobby.  Or two.  Or ten.</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=5910">What to do in 2017</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5914" rel="attachment wp-att-5914"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5914" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5914" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/workaholic-at-computer.png?fit=492%2C504&amp;ssl=1" data-orig-size="492,504" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="workaholic-at-computer" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/workaholic-at-computer.png?fit=293%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/workaholic-at-computer.png?fit=492%2C504&amp;ssl=1" class="size-medium wp-image-5914 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/workaholic-at-computer.png?resize=293%2C300&#038;ssl=1" alt="" width="293" height="300" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/workaholic-at-computer.png?resize=293%2C300&amp;ssl=1 293w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/workaholic-at-computer.png?w=492&amp;ssl=1 492w" sizes="auto, (max-width: 293px) 100vw, 293px" /></a>Over on my <a href="https://www.graphics-muse.org/wiki/pmwiki.php">wiki</a> I have an area called <em>Project Cody</em>.&nbsp; The code name is for my youngest dog and a play on the word &#8220;code&#8221;.&nbsp;&nbsp; It&#8217;s a private area where I keep project plans I&#8217;m not ready to talk about or share with the public.&nbsp; Only a few choice compatriots have access (until the Russians get wind of it, I assume).</p>
<p>I keep a page in Project Cody with ideas for future projects.&nbsp; This past year I collected a bunch of ideas I want to work on, most of which are related to extending <a href="https://www.piboxproject.com">PiBox</a> in one manner or another.&nbsp; Some are related to protecting my web sites and servers. This doesn&#8217;t include continued work on <a href="http://redmine.graphics-muse.org/projects/pibox/issues?query_id=9">PiBox issues</a> nor does it include my plans for adding IoT support for managing devices via wifi.&nbsp; The IoT projects are part of my <a href="http://redmine.graphics-muse.org/projects/ironman/issues">IronMan</a> project &#8211; the idea that I can build Iron Man&#8217;s house using existing technologies.&nbsp; It&#8217;s not really much of a stretch.&nbsp; The real issue is getting glass that will act as a display, either directly or by electrically opaquing the substrate.&nbsp;</p>
<p>I&#8217;ve been working on ideas for Iron Man for some time.&nbsp; I already have the <a href="https://www.graphics-muse.org/wiki/pmwiki.php/Jarvis/Jarvis">Jarvis</a> project for accepting voice commands and evaluating them for basic control of the house by simply passing audio files to <a href="https://cloud.google.com/speech/">Google&#8217;s voice to text translator</a> (though that may not be the one I have implemented in Jarvis now) and then passing the text through a <a href="http://opennlp.apache.org/">natural language processor </a>to interpret the command.&nbsp; There really isn&#8217;t much to that project now except a proof of concept.&nbsp; And it doesn&#8217;t have <a href="http://goo.gl/K8OGo">Jarvis&#8217; voice</a>.&nbsp; Generating a realistic voice is a fairly time-consuming activity and I&#8217;ve so many other things that take precedent.&nbsp; But the basic structure is there.&nbsp; Extending it to do something useful won&#8217;t happen till I have some devices to control.</p>
<p>Which leads me to some of the technology plans I have for PiBox in 2017.&nbsp; Take these with a huge grain of salt.&nbsp; I fully expect my aging pups to occupy much of my time in 2017.</p>
<h3>Custom smartphone based on Raspberry Pi</h3>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5926" rel="attachment wp-att-5926"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5926" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5926" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?fit=518%2C498&amp;ssl=1" data-orig-size="518,498" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="piphone" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?fit=300%2C288&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?fit=518%2C498&amp;ssl=1" class="size-thumbnail wp-image-5926 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?resize=150%2C150&#038;ssl=1" alt="" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piphone.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a>I&#8217;m so frustrated with the bloat on my Android Phone.&nbsp; It worked fine when I bought it but automatic updates have pushed it to its limits, making most apps fail to start or crash after they do.&nbsp; It&#8217;s not like I have many apps on the thing.&nbsp; I don&#8217;t use the phone for anything other than the occasional text with my wife.&nbsp; You can blame the bloat on Android or the provider (Virgin Mobile) if you want.&nbsp; But the truth is that it makes sense for phone vendors to bloat the OS to force you into the next model.&nbsp; It&#8217;s a trick they learned from the PC world.&nbsp; And it&#8217;s crap.&nbsp; We should be able to build our own phones.</p>
<p>Fortunately, it&#8217;s possible to <a href="https://www.raspberrypi.org/blog/piphone-home-made-raspberry-pi-smartphone/">build</a> <a href="https://learn.adafruit.com/piphone-a-raspberry-pi-based-cellphone/overview">your own</a> phone.&nbsp; What&#8217;s important about this project is that</p>
<ul>
<li>it uses a Raspberry Pi Model B or B+, which is compatible with the Pi Zero, meaning I can improve the design.</li>
<li>it uses a Raspberry Pi, which means I can port PiBox to it.</li>
</ul>
<p>I&#8217;ll need to add touch screen support but I&#8217;d already experimented with that previously so it shouldn&#8217;t be a major effort.&nbsp; My launcher app will have to understand the size of the display in order to scale icons appropriately.&nbsp; It doesn&#8217;t do that now, but I think I know how to do it.&nbsp; And I&#8217;ll need to write all the basic phone apps:&nbsp; dialing, contact list, text messaging, etc.&nbsp; None of these are particularly hard.&nbsp; And no, I won&#8217;t be using scripting languages.&nbsp; It&#8217;ll all be done in C.</p>
<p>This isn&#8217;t a high priority, but it would be an interesting update to the launcher to see the same apps on a phone as on a TV or desktop monitor.</p>
<p><em><span style="color: #000080;">Update: 2017-03-09</span></em></p>
<p>I just finished adding display resolution identification and touchscreen support to libpibox, the launcher and a couple of apps.&nbsp; The library supports 9 touch regions or absolute coordinates.&nbsp; So the launcher works by touching an app icon while the apps use navigations (next, prev, pause, stop, etc) through the touch regions.&nbsp; I&#8217;ve also added the much needed scaling capabilities to the launcher to allow it to fit on just about any screen size.&nbsp; This support may not be fully sufficient for the small screen of a phone, but it works great on the <a href="https://www.amazon.com/Raspberry-Pi-7-Touchscreen-Display/dp/B0153R2A9I">7&#8243; official Raspberry Pi touchscreen</a>!&nbsp; And it may be enough for any small screen.&nbsp; Caveat: the launcher still requires X.org, so really tiny screens might not work well.</p>
<p><span style="color: #000080;"><em>Update: 2017-10-03</em></span></p>
<p>Still not working on this (because of the job change/move to Boulder-area issue) but I found this today:&nbsp; <a href="https://hackaday.io/project/19035-zerophone-a-raspberry-pi-smartphone/log/51839-project-description-and-frequently-asked-questions">ZeroPhone</a>.&nbsp; Someone beat me to the project, but that&#8217;s okay.&nbsp; I&#8217;m still interested in building my own.&nbsp; And putting the PiBox UI on it for ease of use, probably with a larger screen (like the original model).</p>
<h3>Echo Pi</h3>
<p><a href="http://www.instructables.com/id/Build-a-Raspberry-Pi-Powered-Amazon-Echo/?utm_source=newsletter&amp;utm_medium=email">Echo Pi</a> is a project I want to work with <a href="https://gitlab.com/xjarvis">Jarvis </a>(my experiment with &#8220;AI&#8221; software). It&#8217;s really just an omnidirectional microphone that can be used to acquire audio to feed to Jarvis.&nbsp; Put one of these in each room and I can talk to the butler without screaming.</p>
<h3>Bluetooth audio transmitter and receiver</h3>
<p>I want this so I can play audio in my trailer from PiBox without wires.&nbsp; I want to route audio to either the audio port or to a Bluetooth transmitter.&nbsp; This doesn&#8217;t solve my problem of routing the audio output from my XMPCR since it has to first be routed into the Pi.&nbsp; But it&#8217;s the end goal and it&#8217;s something I&#8217;ve wanted for some time.&nbsp; We can use <a href="http://www.instructables.com/id/BluetoothBox-for-Stereo-Headphones-and-Speakers/">wireless headphones</a> while we watch outdoor movies when camping.</p>
<h3>Smartwatch</h3>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5928" rel="attachment wp-att-5928"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5928" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5928" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?fit=531%2C562&amp;ssl=1" data-orig-size="531,562" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="mk_2" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?fit=283%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?fit=531%2C562&amp;ssl=1" class="size-thumbnail wp-image-5928 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?resize=150%2C150&#038;ssl=1" alt="" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/mk_2.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a>It was only a matter of time before smart phones went the Dick Tracy route, or as old dudes say, like Space Ghost.&nbsp; We don&#8217;t quite have Mr. Ghost&#8217;s <a href="http://webpages.charter.net/superheroes/space_ghost.htm#1.3">three button power bands</a> yet.&nbsp; So a <a href="http://makezine.com/projects/make-43/open-source-smartwatch/">smartwatch</a> (who makes up these names?) is as close as we get.&nbsp; This actually looks pretty simple.&nbsp; It&#8217;s unclear what software I&#8217;ll put it on it, however.&nbsp; A Pi Zero might fit but may have too high power requirements.&nbsp; I don&#8217;t know if I can port PiBox to an AVR (though I did something similar with the AVR toolchain once before).&nbsp;</p>
<h3>IoT controllers</h3>
<p>This is a high priority project for me.&nbsp; The goal is to extend PiBox to home automation, becoming a central controller (or distributed set of controllers) for managing my home.&nbsp; It starts with simple <a href="http://blog.nyl.io/esp8266-motor/">motor controls</a> for blinds and vents.&nbsp; But there is no reason it can&#8217;t also <a href="http://imgur.com/gallery/YxElS">manage the thermostat</a>.&nbsp;&nbsp; Eventually I want to be able to schedule light switches and <a href="http://www.instructables.com/id/DIY-alternative-to-commercial-smart-power-sockets/">outlets</a> to power on and off based on my schedules.&nbsp; This will eventually replace the home automation system I have now and finally get rid of the horrible management interface they provided.</p>
<h3>DIY Segway</h3>
<p><a href="https://www.graphics-muse.org/wp/?attachment_id=5929" rel="attachment wp-att-5929"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="5929" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5929" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/diy-segway.jpg?fit=192%2C257&amp;ssl=1" data-orig-size="192,257" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="diy-segway" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/diy-segway.jpg?fit=192%2C257&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/diy-segway.jpg?fit=192%2C257&amp;ssl=1" class="size-thumbnail wp-image-5929 alignleft" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/diy-segway.jpg?resize=150%2C150&#038;ssl=1" alt="" width="150" height="150"/></a>So my employer, WD, is moving to new offices this spring.&nbsp; The current office is about a 6 minute commute from my house down fairly busy streets.&nbsp; The new office is about a 3 minute commute and I only have to cross one busy intersection.&nbsp; Seems a waste to drive that far, but walking isn&#8217;t an option given Colorado winters.&nbsp; So what&#8217;s a techie to do?&nbsp; Build a <a href="http://www.instructables.com/id/Arduino-Segway/">Segway</a>, of course.&nbsp; It just needs to be a bit all-wheel drive given the route I have to take, but I think this will just meet those requirements.&nbsp; I just worry about the stability of the software.&nbsp; In this project, I&#8217;m less likely to be working on that than the others.</p>
<h3>Onion Pi</h3>
<p>This one isn&#8217;t really that important since I can do the same thing right on my laptop, but it might be interesting to see if I could put it in PiBox.&nbsp; I&#8217;m not sure why I would since browsing the Internet is not supported in PiBox (<a href="https://webkit.org/">WebKit</a> takes forever to build), but you never know.&nbsp;</p>
<p>The <a href="https://learn.adafruit.com/onion-pi/overview">Onion Pi</a> is a Raspberry Pi with Debian acting as a Tor proxy.&nbsp; The <a href="https://www.torproject.org/">Tor</a> component anonymizes (mostly) your online browsing.&nbsp; It doesn&#8217;t do much to prevent access to your computer (try running a firewall and use <a href="http://ipset.netfilter.org/">ipset</a> to block ranges of IP addresses for that) but it&#8217;s not a bad idea to keep people from snooping on your obsessive and highly unhealthy need to know what the Kardashian&#8217;s are doing.</p>
<h3>Two Factor Authentication everywhere</h3>
<p>This isn&#8217;t a PiBox thing.&nbsp; It&#8217;s a protect-my-systems-from-bad-dudes thing.&nbsp; I just want it because, well, everyone is pushing it and it kinda seems like a good idea.&nbsp; Except for having to use my smartphone to login to my Linux boxes.&nbsp; That seems sooooo counter-productive.&nbsp; I really hate smartphones.&nbsp; Except for the one I&#8217;m going to build myself, of course.</p>
<h3>HTTPS for all web services</h3>
<p>This is something I haven&#8217;t done yet because I don&#8217;t do financial transactions on any servers.&nbsp; But I hear the entire net is migrating into HTTPS so I guess I better do something for my array of domains.&nbsp; It doesn&#8217;t seem particularly difficult given the use of <a href="https://certbot.eff.org/">certbot</a>.&nbsp; But working with keys and certificates has always been a bit annoying to me.&nbsp; Perhaps because I just hate the idea that someone doing mischievous things forces me to do something I didn&#8217;t feel like doing.&nbsp; Bad guys are annoying.&nbsp; Can&#8217;t we all just get along?</p>
<h3>IPSet to block the annoyers</h3>
<p>I also plan on improving my internal security net for my home and public servers.&nbsp; I&#8217;ve already added <em>ipset</em> to block large IP ranges which has had a noticeable improvement in my public web servers.&nbsp; It also makes it pretty easy to block addresses trying to crack our email server.&nbsp; I&#8217;m sure I can&#8217;t keep them out.&nbsp; But I can make it particularly annoying to try.</p>
<h3>And then there is&#8230;</h3>
<p>I&#8217;ve also got notes on working on <a href="http://redmine.graphics-muse.org/issues/506">water harvesting</a> for my garden and <a href="http://redmine.graphics-muse.org/issues/507">power harvesting</a> for off-grid PiBox.&nbsp; But those still need better plans.&nbsp; I&#8217;d also like to do more work with <a href="http://www.instructables.com/id/SlimPanel/">solar power</a> to <a href="http://www.instructables.com/id/How-to-Make-12v-Battery-Charge/?utm_source=FEED_EMAIL&amp;utm_medium=email&amp;distinctId=MCXEKFQIJM08RXJ">charge batteries</a> and <a href="http://www.hydroponics-simplified.com/hydroponic-setups.html">hydro</a>&#8211; and <a href="http://newatlas.com/globe-hedron-rooftop-fish-farm/22492/">aquaponics</a>.&nbsp; I&#8217;ve experimented with hydroponics in over-winter gardens but these were mixed with plants from outside that were brought in, which led to bug infestations and a failed project.</p>
<p>And my back yard DIY vegetable planters needs to be migrated across the back yard so they&#8217;re out from under the now-too-tall trees and into the real sunlight &#8211; at least for the three-month growing season here in Colorado.&nbsp; And I need a new potting bench.&nbsp; And my wife wants new planters in the front yard.&nbsp; And the fence needs mending.&nbsp; And the porch needs painting.&nbsp; And the side yard needs to be re-graded.&nbsp; And the railroad ties in window wells are rotting and need replacing.&nbsp; And &#8230;.</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=5910">What to do in 2017</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=5910</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5910</post-id>	</item>
		<item>
		<title>PiBox @ Colorado Springs Open Source Meetup</title>
		<link>https://www.graphics-muse.org/wp/?p=5936</link>
					<comments>https://www.graphics-muse.org/wp/?p=5936#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Fri, 30 Dec 2016 03:15:07 +0000</pubDate>
				<category><![CDATA[PiBox]]></category>
		<category><![CDATA[colorado springs]]></category>
		<category><![CDATA[meetup]]></category>
		<category><![CDATA[Open Source]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=5936</guid>

					<description><![CDATA[<p>I&#8217;ll be covering the PiBox Development System and PiBox Media Center in overview, explaining what these are, how to use them and where they are going.&#160; I&#8217;ve got a set of slides and will demo the media center along with all the new features I added late this year.&#160; Basically it&#8217;ll be what I set [&#8230;]</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=5936">PiBox @ Colorado Springs Open Source Meetup</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ll be covering the PiBox Development System and PiBox Media Center in overview, explaining what these are, how to use them and where they are going.&nbsp; I&#8217;ve got a set of slides and will demo the media center along with all the new features I added late this year.&nbsp; Basically it&#8217;ll be what I set up for the Maker Faire, but with slides and a real demo.</p>
<div id="event-where-display" class="clearfix figureset-description">
<h3 class="big flush--bottom"><a title="" href="https://maps.google.com/maps?f=q&amp;hl=en&amp;q=5550+North+Union+Blvd%2C+Colorado+Springs%2C+CO%2C+80908%2C+us" target="_blank">East Library Community Room</a></h3>
<p class="event-where-address small">5550 North Union Blvd, Colorado Springs, CO</p>
<p class="event-where-address small">When:&nbsp; <em>Wednesday, January 4th, 6PM.</em></p>
</div><p>The post <a href="https://www.graphics-muse.org/wp/?p=5936">PiBox @ Colorado Springs Open Source Meetup</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=5936</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5936</post-id>	</item>
		<item>
		<title>PiBox: PiClock themes using Cairo</title>
		<link>https://www.graphics-muse.org/wp/?p=5881</link>
					<comments>https://www.graphics-muse.org/wp/?p=5881#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Mon, 19 Dec 2016 19:35:34 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PiBox]]></category>
		<category><![CDATA[PiClock]]></category>
		<category><![CDATA[GIMP]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[GTK+]]></category>
		<category><![CDATA[holiday]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[widget]]></category>
		<category><![CDATA[wifi]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=5881</guid>

					<description><![CDATA[<p>Themes with Cairo were always a goal, but never implemented.  Now, with PiClock, they are a reality.</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=5881">PiBox: PiClock themes using Cairo</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="attachment_5884" style="width: 160px" class="wp-caption alignleft"><a href="https://www.graphics-muse.org/wp/?attachment_id=5884" rel="attachment wp-att-5884"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-5884" data-attachment-id="5884" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5884" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?fit=1366%2C768&amp;ssl=1" data-orig-size="1366,768" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="piclock-notheme" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?fit=300%2C169&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?fit=1024%2C576&amp;ssl=1" class="wp-image-5884 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-notheme.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-5884" class="wp-caption-text">The original clock was primitive, mostly because I didn&#8217;t understand how to use images and transformations correctly, even though I&#8217;d used them in the PiBox launcher!</p></div>
<p>Having just completed work on a wifi scanner for <a href="https://gitlab.com/pibox/pibox-network-config">PiBox Network Config</a>, I decided to expand on the lessons learned with Cairo to add themes to <a href="https://gitlab.com/pibox/piclock">PiClock</a>.&nbsp; The original clock was a simple drawing of the clock face boundary with three hands.&nbsp; The biggest task there was to compute the end points of the lines drawn for each hand.&nbsp; Nothing complex there.</p>
<p>But there is no reason custom clock face images and hands can&#8217;t be used.&nbsp; The trick is learning to work with <a href="https://cairographics.org/">Cairo</a> layers (which happens without extra coding) and discovering how to properly rotate and position the hands.&nbsp; Turns out none of this is hard, but it was hard finding out how to use the Cairo API.</p>
<p>So the first thing to do for a theme is define what I wanted to display.&nbsp; There are five images you define for PiClock themes:&nbsp; <em>the clock face</em>, the <em>hour</em>, <em>minute</em> and <em>second</em> hands and an <em>overlay</em> image.&nbsp; The overlay allows you to add special effects like a glass cover.&nbsp; The theme needs a configuration file to specify these images.&nbsp; I chose to use a <a href="http://www.json.org/">JSON</a> format.&nbsp; Previously, PiBox apps used XML for configuration files but in the last year I&#8217;ve become a big fan of JSON due to its easy-to-read name/value pair format.&nbsp; Also, I&#8217;ve found a very simple to use and lightweight JSON library called <a href="https://github.com/kgabis/parson">Parson</a>.&nbsp; I&#8217;ve integrated this into <a href="https://gitlab.com/pibox/libpibox">libpibox</a> so all apps can use it.&nbsp;</p>
<p>The JSON format for PiClock themes is extremely simple.</p>
<p><code>{ </code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp; "theme": {</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "face":"&lt;Name of clock face file&gt;",</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "overlay":"&lt;Name of clock overlay file&gt;",</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "hour":"&lt;Name of hour hand file&gt;",</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "min":"&lt;Name of minute hand file&gt;",</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "sec":"&lt;Name of second hand file&gt;",</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "center":{</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "hour": { "x":n, "y":m },</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "min": { "x":n, "y":m },</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "sec": { "x":n, "y":m }</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },</code><br />
<code>&nbsp;&nbsp;&nbsp;&nbsp; } </code><br />
<code>}</code></p>
<p>The clock face has a dimension limit of 512&#215;512 which the code enforces.&nbsp; After experimentation on the PiBox hardware I found it was best to make faces at that size and not smaller, but I don&#8217;t enforce that.&nbsp; The center object defines the rotation point within each of the hands images as it cannot be assumed the hand rotates around its real center.&nbsp; Other than that, the theme is self explanatory.</p>
<p>Before I could parse the file I needed it to have a home.&nbsp; I use the -T option when testing PiBox apps which points the code at files within the source tree.&nbsp; In production the data files are stored under /etc/piclock/themes.&nbsp; Since there can be more than one theme there needs to be a top level file stating the currently selected theme.&nbsp;</p>
<p>Parsing the file requires a single line of Parson code, plus extracting a reference to access fields.</p>
<p style="padding-left: 30px;"><code>JSON_Value data = json_parse_file_with_comments(buf);</code><br />
<code>obj = json_value_get_object(data);</code></p>
<p>The data object is abstract.&nbsp; Fields can be extracted rather easily using the <em>dot</em> functions:</p>
<p style="padding-left: 30px;"><code>face = json_object_dotget_string(obj, "theme.face");</code><br />
<code> hour = json_object_dotget_string(obj, "theme.hour");</code><br />
<code> min = json_object_dotget_string(obj, "theme.min");</code><br />
<code> sec = json_object_dotget_string(obj, "theme.sec");</code><br />
<code> overlay = json_object_dotget_string(obj, "theme.overlay");</code></p>
<p>This extracts the filenames, which must be prefixed with the installation directory.&nbsp; Following this is an in depth evaluation of the configuration to make sure files exist, can be read into Cairo surfaces and have reasonable sizes with centers properly defined.</p>
<p>A clock theme is drawn by first drawing a black background (for any transparent regions in the images).&nbsp; The clock face is drawn over this.&nbsp; The surfaces for the face and hands are generated when the theme is read so that they can be reused every time the clock is updated.&nbsp; The hands are drawn over the face and the overlay over the hands.&nbsp; Those are the layers.&nbsp; As long as they are drawn in this order the layers are composited correctly.</p>
<p>Now for the important trick:&nbsp; translation and rotation.&nbsp; What was difficult to discover the use of <a href="http://stackoverflow.com/questions/35995607/gtk-cairo-load-png-rotate-and-copy-rectangle-to-surface/35996791#35996791">patterns and matrices</a> for the drawing operation.&nbsp; The pattern is effectively a copy of the original image surface.&nbsp; The pattern is first translated so its defined center is at the origin (0,0) at which point the rotation is applied.&nbsp; Then the pattern is moved to the center of the clock window.&nbsp; Obviously the face and overlay don&#8217;t need rotations, just the hands.&nbsp; Here is the generic handler for hands.</p>
<p><code>void draw_hand(GtkWidget *widget, cairo_t *cr, gint hand)<br />
{<br />
&nbsp;&nbsp;&nbsp; cairo_status_t&nbsp; rc;<br />
&nbsp;&nbsp;&nbsp; cairo_surface_t *image = NULL;<br />
&nbsp;&nbsp;&nbsp; cairo_pattern_t *pattern;<br />
&nbsp;&nbsp;&nbsp; gint&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width, height;<br />
&nbsp;&nbsp;&nbsp; gdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_x, offset_y;<br />
&nbsp;&nbsp;&nbsp; GtkPiclock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *piclock;<br />
&nbsp;&nbsp;&nbsp; GtkRequisition&nbsp; req;<br />
&nbsp;&nbsp;&nbsp; cairo_matrix_t&nbsp; matrix;</code></p>
<p><code>&nbsp;&nbsp;&nbsp; piclock = GTK_PICLOCK(widget);</code><br />
<code> &nbsp;&nbsp;&nbsp; req.width = gdk_window_get_width(widget-&gt;window);</code><br />
<code> &nbsp;&nbsp;&nbsp; req.height = gdk_window_get_height(widget-&gt;window);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; /*<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Setup based on the hand requested.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; switch( hand )<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case HAND_HOUR:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image = piclock-&gt;theme-&gt;hour_sf;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; degrees = -1*(double)piclock-&gt;hoursHand/60.0*360.0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_x = (double)piclock-&gt;theme-&gt;hour_pt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_y = (double)piclock-&gt;theme-&gt;hour_pt.y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case HAND_MIN:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image = piclock-&gt;theme-&gt;min_sf;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; degrees = -1*(double)piclock-&gt;minutesHand/60.0*360.0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_x = (double)piclock-&gt;theme-&gt;min_pt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_y = (double)piclock-&gt;theme-&gt;min_pt.y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case HAND_SEC:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; image = piclock-&gt;theme-&gt;sec_sf;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; degrees = -1*(double)piclock-&gt;secondsHand/60.0*360.0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_x = (double)piclock-&gt;theme-&gt;sec_pt.x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset_y = (double)piclock-&gt;theme-&gt;sec_pt.y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; if ( image == NULL )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</code></p>
<p><code>&nbsp;&nbsp;&nbsp; width = cairo_image_surface_get_width(image);<br />
&nbsp;&nbsp;&nbsp; height = cairo_image_surface_get_height(image);<br />
&nbsp;&nbsp;&nbsp; pattern = cairo_pattern_create_for_surface (image);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; /* translate the rotation point of the hand to the origin. */</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_matrix_init_identity (&amp;matrix);</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_matrix_translate (&amp;matrix, (double)offset_x, (double)offset_y);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; /* Rotate to the correct clock position. */</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_matrix_rotate (&amp;matrix, deg2rad(degrees));</code></p>
<p><code>&nbsp;&nbsp;&nbsp; /* Move to the center of the clock window */</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_matrix_translate (&amp;matrix,</code><br />
<code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -req.width/2,</code><br />
<code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -req.height/2);</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_pattern_set_matrix (pattern, &amp;matrix);</code></p>
<p><code>&nbsp;&nbsp;&nbsp; cairo_set_source (cr, pattern);</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_pattern_destroy (pattern);</code><br />
<code> &nbsp;&nbsp;&nbsp; cairo_paint(cr);</code><br />
<code> }</code></p>
<div id="attachment_5882" style="width: 160px" class="wp-caption alignleft"><a href="https://www.graphics-muse.org/wp/?attachment_id=5882" rel="attachment wp-att-5882"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-5882" data-attachment-id="5882" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5882" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?fit=1366%2C768&amp;ssl=1" data-orig-size="1366,768" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="piclock-test" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?fit=300%2C169&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?fit=1024%2C576&amp;ssl=1" class="wp-image-5882 size-thumbnail" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?resize=150%2C150&#038;ssl=1" width="150" height="150" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-test.png?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><p id="caption-attachment-5882" class="wp-caption-text">The test theme has a reflective overlay appliedover the face and hands.</p></div>
<p>After getting the window dimensions and accessing the previously created image surface, a pattern is created and a matrix initialized.&nbsp; Then the translation is done to move the configured center point to the origin.&nbsp; A rotation is applied and the pattern is moved to the center of the window.&nbsp; Once the pattern is set as a source for the main Cairo surface it can be destroyed and the main surface updated.</p>
<p>There are now two themes for PiClock.&nbsp; The first is a test theme that includes the overlay.&nbsp; This isn&#8217;t as clean as I&#8217;d like &#8211; the overlay doesn&#8217;t quite look like a reflective surface to me.&nbsp; The overlay is made from a couple of white to transparent radial gradients made with <a href="https://www.gimp.org/">GIMP</a>.&nbsp; Cairo composites transparency quite nicely, as can be seen with the clock hands.&nbsp;</p>
<p>Once the test theme was working I had to make one more theme, to prove that the design worked in general.&nbsp; So I created the roman theme, which is simply an old clock face with roman numerals.&nbsp; The hands were run through GIMP a few times to clean them up and remove colored areas around the hands that were an artifact of the poor original image.&nbsp;</p>
<div id="attachment_5883" style="width: 310px" class="wp-caption aligncenter"><a href="https://www.graphics-muse.org/wp/?attachment_id=5883" rel="attachment wp-att-5883"><img data-recalc-dims="1" loading="lazy" decoding="async" aria-describedby="caption-attachment-5883" data-attachment-id="5883" data-permalink="https://www.graphics-muse.org/wp/?attachment_id=5883" data-orig-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?fit=1366%2C768&amp;ssl=1" data-orig-size="1366,768" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="piclock-roman" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?fit=300%2C169&amp;ssl=1" data-large-file="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?fit=1024%2C576&amp;ssl=1" class="wp-image-5883 size-medium" src="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?resize=300%2C169&#038;ssl=1" width="300" height="169" srcset="https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?resize=300%2C169&amp;ssl=1 300w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?resize=768%2C432&amp;ssl=1 768w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?resize=1024%2C576&amp;ssl=1 1024w, https://i0.wp.com/www.graphics-muse.org/wp/wp-content/uploads/2016/12/piclock-roman.png?w=1366&amp;ssl=1 1366w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-5883" class="wp-caption-text">The roman theme doesn&#8217;t use an overlay, but the overlay image is required because I didn&#8217;t go to the length of allowing it to be optional. The the image is simply the size of the clock face image but is completely transparent.</p></div>
<p>The theme design worked perfectly on the second theme.&nbsp; I created it to spec and updated the default theme name, then ran PiClock.&nbsp; It displayed as shown.&nbsp; No code changes were required.&nbsp;&nbsp; I&#8217;ve got some videos of the clocks running, if anyone is interested in watching a clock ticking.</p>
<p><iframe loading="lazy" width="1170" height="878" src="https://www.youtube.com/embed/N07iSc6vCSQ?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><iframe loading="lazy" width="1170" height="878" src="https://www.youtube.com/embed/qUyAUNspHcQ?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>It&#8217;s not perfected quite yet, however.&nbsp; I need to add an option to cycle through themes.&nbsp; But its the holidays and I&#8217;ve already spent far too much time on PiBox so it&#8217;s time to let it go a bit and get back to the things that matter.&nbsp; At least for awhile.</p><p>The post <a href="https://www.graphics-muse.org/wp/?p=5881">PiBox: PiClock themes using Cairo</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=5881</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5881</post-id>	</item>
		<item>
		<title>PiBox: XM radio app (PiXM) and wifi scanning in PNC</title>
		<link>https://www.graphics-muse.org/wp/?p=5789</link>
					<comments>https://www.graphics-muse.org/wp/?p=5789#respond</comments>
		
		<dc:creator><![CDATA[mjhammel]]></dc:creator>
		<pubDate>Thu, 15 Dec 2016 03:13:47 +0000</pubDate>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[GTK+]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PiBox]]></category>
		<category><![CDATA[PiBox Network Config]]></category>
		<category><![CDATA[PiClock]]></category>
		<category><![CDATA[PiXM]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[XMPCR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[busybox]]></category>
		<category><![CDATA[colorado springs]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[linux journal]]></category>
		<category><![CDATA[Media Server]]></category>
		<category><![CDATA[Radio]]></category>
		<category><![CDATA[Roku]]></category>
		<category><![CDATA[routers]]></category>
		<category><![CDATA[signal]]></category>
		<category><![CDATA[Sirius]]></category>
		<category><![CDATA[ui components]]></category>
		<category><![CDATA[video playback]]></category>
		<category><![CDATA[video player]]></category>
		<category><![CDATA[wifi]]></category>
		<category><![CDATA[ximba]]></category>
		<category><![CDATA[xm radio]]></category>
		<category><![CDATA[xmpcr]]></category>
		<guid isPermaLink="false">http://www.graphics-muse.org/wp/?p=5789</guid>

					<description><![CDATA[<p>Back in October I started work on a new app for PiBox: an XM radio player.&#160; The hardware is an XMPCR, a device sold in the early 2000&#8217;s that connected over USB to a PC.&#160; The device didn&#8217;t last long.&#160; I think there was some concern that people would steal the signals and rebroadcast.&#160; Something [&#8230;]</p>
<p>The post <a href="https://www.graphics-muse.org/wp/?p=5789">PiBox: XM radio app (PiXM) and wifi scanning in PNC</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Back in October I started work on a new app for <a href="https://www.piboxproject.com/">PiBox</a>: an XM radio player.&nbsp; 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.&nbsp; The device didn&#8217;t last long.&nbsp; I think there was some concern that people would steal the signals and rebroadcast.&nbsp; Something silly like that.&nbsp; But they only cost around $45 each back then.&nbsp; I got two, one each for my wife and I.&nbsp; As usual I didn&#8217;t have PC software for Linux so I wrote a GTK+ wrapper around a Perl script called <a href="https://www.graphics-muse.org/archives/source/openxm.tar.gz">OpenXM</a> that let me manage the radio.&nbsp; That project was called <a href="https://www.graphics-muse.org/archives/source/ximbaradio-1.0.tar.gz">XimbaRadio</a>.&nbsp; I wrote an article about it for <a href="http://www.linuxjournal.com/article/7487">Linux Journal</a>.</p>
<p>Flash forward to Halloween 2016 and the <a href="https://coloradospringsmakerfaire.com/">Maker Faires in Colorado Springs</a>.&nbsp; 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>.&nbsp; 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>.&nbsp; So I&#8217;ve punted on playing my music for now.&nbsp; But the XMPCR&#8217;s were still around in a box in my office.&nbsp; So I dug them out and started digging in.</p>
<h3>PIXM</h3>
<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?ssl=1" data-image-id="588" data-src="https://www.graphics-muse.org/wp/wp-content/gallery/pibox/pixm.png" data-thumbnail="https://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&#038;ssl=1" 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>
<p>The first thing I did was pull out the old Perl scripts.&nbsp; There is little support for scripting in PiBox because scripting languages are not my thing.&nbsp; Oh, I use them plenty.&nbsp; But I want PiBox Media Center to show what you can do with plain ol&#8217; C.&nbsp; Scripting is for kiddies.&nbsp; PiBox is for grown ups.&nbsp; 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).&nbsp; The devices have an ordinary audio plug for output &#8211; there is no playback through the PC.&nbsp; But that&#8217;s not a major issue to me.&nbsp; I can always route the output back into the Pi and manage it that way if I really need to.</p>
<p>So the devices still worked.&nbsp; Now I needed to look at my old GTK+ code.&nbsp; It also worked.&nbsp; Badly.&nbsp; 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.&nbsp; So I decided to start over.&nbsp; And the first thing I wanted to do was write my own serial protocol management to avoid calling Perl scripts.&nbsp; 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.&nbsp; There were even some <a href="http://www.michaelminn.com/linux/mmxmpcr/">example implementations</a>.</p>
<p>Work on the protocol went quickly and I was able to get data into and out of the device without much trouble.&nbsp; The next step was to implement a UI.&nbsp; 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.&nbsp; This wasn&#8217;t as hard as it seemed.&nbsp; I created two lists, one for categories and one for channels.&nbsp; Choosing a category showed the list of channels in that category.&nbsp; Tabbing between category and channels would display all channels.&nbsp; Searching used the same builtin GTK+ mechanism for trees (just type some letters).&nbsp; Easy peasy.&nbsp; 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.&nbsp; Instead, it&#8217;s just a set of four fields for channel, category artist and title.</p>
<p>In testing this layout I discovered some basic problems.&nbsp; The first was that the serial device, <span style="color: #0000ff;">/dev/ttyUSB0</span>, is not accessible by default.&nbsp; 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.&nbsp; 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)&nbsp; I added a device state icon to the menu bar.&nbsp; This bar is drawn with Cairo and is where you see the tab options for <em>Category</em> and <em>Channels</em>.&nbsp; The device state icon is green for available and red for unavailable.&nbsp; Makes it easier to identify hardware problems.</p>
<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?ssl=1" data-image-id="589" data-src="https://www.graphics-muse.org/wp/wp-content/gallery/pibox/pixm-controls.png" data-thumbnail="https://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&#038;ssl=1" 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>
<p>I also noticed that the device serial protocol allows for muting the output.&nbsp; Seemed like it might be nice to add that feature, so I added one additional key, M, to toggle the mute on the XMPCR.&nbsp; 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.&nbsp; 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.&nbsp; Whose gonna be annoyed?</p>
<p>The majority of the app is plain ol&#8217; <a href="https://www.gtk.org/">GTK+ 2 widgets</a>.&nbsp; The control bar is a drawing area with <a href="https://cairographics.org/">Cairo</a> doing custom rendering.&nbsp; I use Cairo for much of the PiBox UI: PiClock, the video player (aka VideoFE) and the launcher use it extensively.&nbsp; Like the video player, the PiXM app does simple on-demand drawings in the drawing area.&nbsp; This isn&#8217;t exactly efficient or by design of GTK+.&nbsp; 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.&nbsp;&nbsp; PiClock has such as widget, but it needs additional work based on lessons learned on the wifi scanner.</p>
<h3>Wifi Scanner for PiBox Network Config</h3>
<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?ssl=1" data-image-id="586" data-src="https://www.graphics-muse.org/wp/wp-content/gallery/pibox/pnc-scanner.png" data-thumbnail="https://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&#038;ssl=1" 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>
<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.&nbsp; At home I had a setup of three PiBox Players playing movies from a PiBox Media Server.&nbsp; This worked fine there.&nbsp; But taking the same setup to the library (and Barnes and Noble for a separate Maker Faire event) showed that wifi performance was unacceptable.&nbsp;</p>
<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>.&nbsp; 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.&nbsp; That helped, but didn&#8217;t solve the problem.&nbsp; Then I found that images used in the video player browser were huge.&nbsp; So I scaled them back and that helped a bunch with browsing the list of available videos.&nbsp; But it didn&#8217;t solve the issues related to video playback.</p>
<p>So then I dug into wifi itself.&nbsp; 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.&nbsp; 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.&nbsp;&nbsp; Choosing a channel with fewer other networks using it requires knowing which networks are using which channels.&nbsp; Same it true for signal strength.</p>
<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>.&nbsp; What a cool little app.&nbsp; And that&#8217;s coming from a guy who doesn&#8217;t use ANY apps.&nbsp; It shows an animated graph of wifi networks in the local area.&nbsp; So I looked into how you get the data for this kind of graph.&nbsp; 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>.&nbsp; More easy peasy.</p>
<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?ssl=1" data-image-id="587" data-src="https://www.graphics-muse.org/wp/wp-content/gallery/pibox/pnc-scanner-only.png" data-thumbnail="https://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&#038;ssl=1" 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>
<p>With the data gathering solved, I needed to integrate a UI and a way to get the gathered data into the UI.&nbsp; One problem to solve is how to choose separate colors for each network.&nbsp; In the end I used the <a href="http://devmag.org.za/2012/07/29/how-to-choose-colours-procedurally-algorithms/">golden ratio</a>.&nbsp; Next is how to get the data, which can take several seconds to acquire, without interfering with the UI.&nbsp; So I put the data gathering into a background thread that made calls to the <em>pnc</em> (PiBox Network Config) library.&nbsp; The data was stored in that thread and was made available to the UI using mutexes.&nbsp;</p>
<p>I first made the UI act like the control bar of PiXM but that didn&#8217;t work.&nbsp; The periodic updates caused lockups in the GTK+ main loop.&nbsp; So I switched to writing my own widget, just as I&#8217;d done with PiClock.&nbsp; This widget is far more complex and in doing the port I found bugs in PiClock.&nbsp; But using a widget solved the problem of GTK+ main loop lockups.&nbsp;</p>
<p>Drawing the graphs is done with Cairo.&nbsp; If you look at the graph it looks like a bunch of parabolas.&nbsp; At first I looked into how to graph these.&nbsp; But the parabolas needed to be closed on the wide end in order to fill them.&nbsp; That&#8217;s when I realized the trick to graphing in Cairo:&nbsp; using masks.&nbsp; 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>.&nbsp; 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.&nbsp; The fix to that was to mask off the area to the left of the axis and THEN draw the axis.&nbsp; 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.&nbsp; More easy peasy.&nbsp; After many hours trying to find the trick.&nbsp; Silly me.&nbsp; It was in the documentation.&nbsp; The last place one would look.</p>
<p>You might wonder why the graphs are drawn left to right instead of bottom to top.&nbsp; Simple:&nbsp; space.&nbsp; I have lots of vertical space here but not much horizontal space.&nbsp; So I just draw left to right.&nbsp; Seems okay to me.&nbsp; Comments welcome.</p>
<h3>What&#8217;s Next</h3>
<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.&nbsp; 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><p>The post <a href="https://www.graphics-muse.org/wp/?p=5789">PiBox: XM radio app (PiXM) and wifi scanning in PNC</a> first appeared on <a href="https://www.graphics-muse.org/wp">Michael J. Hammel</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.graphics-muse.org/wp/?feed=rss2&#038;p=5789</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5789</post-id>	</item>
	</channel>
</rss>
