<?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/"
	>

<channel>
	<title>A Little Off</title>
	<atom:link href="http://www.bemasher.net/feed" rel="self" type="application/rss+xml" />
	<link>http://www.bemasher.net</link>
	<description>Code, Computers, Photography and Guns</description>
	<lastBuildDate>Mon, 30 Aug 2010 16:42:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Choosing an SSD</title>
		<link>http://www.bemasher.net/archives/836</link>
		<comments>http://www.bemasher.net/archives/836#comments</comments>
		<pubDate>Thu, 12 Aug 2010 06:02:27 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[A-Data]]></category>
		<category><![CDATA[G.SKILL]]></category>
		<category><![CDATA[matplotlib]]></category>
		<category><![CDATA[Newegg]]></category>
		<category><![CDATA[Patriot]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Read]]></category>
		<category><![CDATA[Sequential]]></category>
		<category><![CDATA[SSD]]></category>
		<category><![CDATA[Western Digital]]></category>
		<category><![CDATA[Write]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=836</guid>
		<description><![CDATA[Before I started my new job I had an inordinate amount of free time and for a majority of that time, nothing to spend it doing[1]. I was still thinking about my desktop wishlist[2] and about choosing a better SSD than the one I had previously selected[3]. A long time ago when I was following [...]]]></description>
			<content:encoded><![CDATA[<p>Before I started my new job I had an inordinate amount of free time and for a majority of that time, nothing to spend it doing<sup>[<a href="http://www.bemasher.net/archives/836#footnote_0_836" id="identifier_0_836" class="footnote-link footnote-identifier-link" title="Nothing worth-while anyway">1</a>]</sup>. I was still thinking about my desktop wishlist<sup>[<a href="http://www.bemasher.net/archives/836#footnote_1_836" id="identifier_1_836" class="footnote-link footnote-identifier-link" title="See previous post: Wishlist.">2</a>]</sup> and about choosing a better SSD than the one I had previously selected<sup>[<a href="http://www.bemasher.net/archives/836#footnote_2_836" id="identifier_2_836" class="footnote-link footnote-identifier-link" title="Western Digital SiliconEdge 128GB SSD">3</a>]</sup>.</p>
<p>A long time ago when I was following the HDD market since I was looking to buy some bulk storage I wrote a php script which loaded newegg's product list based on some search parameters you provided newegg's productlist.xml<sup>[<a href="http://www.bemasher.net/archives/836#footnote_3_836" id="identifier_3_836" class="footnote-link footnote-identifier-link" title="Which no longer exists in it&#039;s original form.">4</a>]</sup>. The script would then parse the list and produce a list sorted based on price per gigabyte. Which is useful when you're in the market for capacity<sup>[<a href="http://www.bemasher.net/archives/836#footnote_4_836" id="identifier_4_836" class="footnote-link footnote-identifier-link" title="Which I was.">5</a>]</sup>.</p>
<p>I decided to do more or less the same thing with SSD's except this time I did it in python since I'm rusty on PHP and I didn't want to mess with setting up a web server to test on. So I got started by doing a power search on newegg for the specific flavor of SSD I was looking for.</p>
<p>The search parameters are as follows:</p>
<ul>
<li>2.5" Form Factor</li>
<li>SATA II/III</li>
<li>120GB or Greater</li>
<li>Less than $300</li>
<li>Retail or OEM</li>
<li>Support TRIM Command</li>
</ul>
<p>As of this writing those particular search parameters narrows the result to 17 SSD's. Now comes the code. Before I started coding I needed some way to sort them according to what I thought was important. The metric is as follows:</p>
<p><center><img src="http://l.wordpress.com/latex.php?latex=%5Cfrac%7B%5Ctext%7BRead%7D%20%5Ctimes%20%5Ctext%7BWrite%7D%20%5Ctimes%20%5Ctext%7BCapacity%7D%7D%7B%7C%5Ctext%7BRead%7D%20-%20%5Ctext%7BWrite%7D%7C%20%5Ctimes%20%5Ctext%7BPrice%7D%7D&#038;bg=FFFFFF&#038;fg=2C2C29&#038;s=2" title="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{|\text{Read} - \text{Write}| \times \text{Price}}" style="vertical-align:-20%;" class="tex" alt="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{|\text{Read} - \text{Write}| \times \text{Price}}" /></center></p>
<p>After looking closer at the scores this produces I noticed that it <em>heavily</em> penalizes drives with huge differences between read and write speeds which effectively weeds out drives that still have acceptable read//write speeds. So I removed that section of the metric producing:</p>
<p><center><img src="http://l.wordpress.com/latex.php?latex=%5Cfrac%7B%5Ctext%7BRead%7D%20%5Ctimes%20%5Ctext%7BWrite%7D%20%5Ctimes%20%5Ctext%7BCapacity%7D%7D%7B%5Ctext%7BPrice%7D%7D&#038;bg=FFFFFF&#038;fg=2C2C29&#038;s=2" title="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{\text{Price}}" style="vertical-align:-20%;" class="tex" alt="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{\text{Price}}" /></center></p>
<p>The basic idea behind this scoring measure is that sequential read and write speeds are important, as well as capacity. Price and difference between sequential read//write are considered bad<sup>[<a href="http://www.bemasher.net/archives/836#footnote_5_836" id="identifier_5_836" class="footnote-link footnote-identifier-link" title="Although we&#039;re excluding read//write speed difference.">6</a>]</sup>. In the equation read and write refer to sequential read and write speeds. The ratio of these will produce a score of the SSD's overall performance for capacity, read//write speeds and price.</p>
<p>The code is relatively simple in purpose. Load the data and parse it into a dictionary then sort based on the metric above.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>, <span style="color: #dc143c;">re</span><br />
<br />
<span style="color: #808080; font-style: italic;"># url = &quot;</span><br />
<span style="color: #808080; font-style: italic;"># http://www.newegg.com/Product/ProductList.aspx?Submit=Property&amp;Subcatego </span><br />
<span style="color: #808080; font-style: italic;"># ry=636&amp;Description=&amp;Type=&amp;N=100008120&amp;IsNodeId=1&amp;srchInDesc=&amp;MinPrice=&amp;M </span><br />
<span style="color: #808080; font-style: italic;"># axPrice=&amp;OEMMark=1&amp;OEMMark=0&amp;PropertyCodeValue=4213:30854&amp;PropertyCodeVa </span><br />
<span style="color: #808080; font-style: italic;"># lue=4214:30848&amp;PropertyCodeValue=4214:39416&amp;PropertyCodeValue=4214:30849 </span><br />
<span style="color: #808080; font-style: italic;"># &amp;PropertyCodeValue=4214:39415&amp;PropertyCodeValue=4215:55552&amp;PropertyCodeV </span><br />
<span style="color: #808080; font-style: italic;"># alue=4215:41071&amp;PropertyCodeValue=4215:46319&quot;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># data = open(&quot;temp.html&quot;, &quot;w&quot;)</span><br />
<span style="color: #808080; font-style: italic;"># data.write(urllib2.urlopen(url).read())</span><br />
<span style="color: #808080; font-style: italic;"># data.close()</span><br />
raw = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;temp.html&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
item_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'&lt;div class=&quot;itemCell&quot;.*?&gt;(.*?)&lt;br class=&quot;clear&quot;.*?&lt;/div&gt;'</span><span style="color: black;">&#41;</span><br />
feature_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;&lt;li&gt;&amp;nbsp;(.*?)&lt;/li&gt;&quot;</span><span style="color: black;">&#41;</span><br />
feature_list_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'&lt;b&gt;(.*?)<span style="color: #000099; font-weight: bold;">\s</span>?<span style="color: #000099; font-weight: bold;">\#</span>?<span style="color: #000099; font-weight: bold;">\s</span>?:<span style="color: #000099; font-weight: bold;">\s</span>?&lt;/b&gt;<span style="color: #000099; font-weight: bold;">\s</span>?(.*?)&lt;/li&gt;'</span><span style="color: black;">&#41;</span><br />
speed_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(up to )?(<span style="color: #000099; font-weight: bold;">\d</span>+).*?MB/s&quot;</span><span style="color: black;">&#41;</span><br />
capacity_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(<span style="color: #000099; font-weight: bold;">\d</span>+)GB&quot;</span><span style="color: black;">&#41;</span><br />
price_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;&lt;/span&gt;<span style="color: #000099; font-weight: bold;">\$</span>&lt;strong&gt;(<span style="color: #000099; font-weight: bold;">\d</span>+)&lt;/strong&gt;&lt;sup&gt;.(<span style="color: #000099; font-weight: bold;">\d</span>+)&lt;/sup&gt;&quot;</span><span style="color: black;">&#41;</span><br />
<br />
item_list = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
valid = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'Read'</span>, <span style="color: #483d8b;">'Item'</span>, <span style="color: #483d8b;">'Interface'</span>, <span style="color: #483d8b;">'Capacity'</span>, <span style="color: #483d8b;">'Model'</span>, <span style="color: #483d8b;">'Write'</span>, <span style="color: #483d8b;">'Size'</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> item_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>raw<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; current = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; no_label = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; features = feature_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Size&quot;</span><span style="color: black;">&#93;</span> = features<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span> = features<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Interface&quot;</span><span style="color: black;">&#93;</span> = features<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> feature <span style="color: #ff7700;font-weight:bold;">in</span> feature_list_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current<span style="color: black;">&#91;</span>feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> = feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current<span style="color: black;">&#91;</span>feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> = feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Read&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>speed_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sequential Access - Read&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Write&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>speed_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sequential Access - Write&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>capacity_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> feature <span style="color: #ff7700;font-weight:bold;">in</span> current.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> feature <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">del</span> current<span style="color: black;">&#91;</span>feature<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>price_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Item&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.newegg.com/Product/Product.aspx?Item=%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Item&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; item_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
<span style="color: #008000;">sorted</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> item_list:<br />
&nbsp; &nbsp; ratio = <span style="color: black;">&#40;</span>item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Read&quot;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">*</span> item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Write&quot;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">*</span> item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> / <span style="color: black;">&#40;</span>item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Price&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">sorted</span><span style="color: black;">&#91;</span>ratio<span style="color: black;">&#93;</span> = item<br />
&nbsp; &nbsp; <br />
sort_order = <span style="color: #008000;">sorted</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
sort_order.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
sort_order.<span style="color: black;">reverse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> sort_order:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#print '\t'.join(map(lambda x: str(x), sorted[key].keys()))</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\t</span>'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>, <span style="color: #008000;">sorted</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span>.<span style="color: black;">values</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Now given that there is quite a lot of data to present and analyze all at once I've decided it would be easiest to just provide you with a pretty graph<sup>[<a href="http://www.bemasher.net/archives/836#footnote_6_836" id="identifier_6_836" class="footnote-link footnote-identifier-link" title="Scores have been normalized to 100%.">7</a>]</sup>:<br />
<center><img src="http://lh5.ggpht.com/_67X_BsG0Kiw/TGOKY0sqJKI/AAAAAAAAHyQ/nAVB8GIDJXQ/s800/Output.png"></img></center><br />
If you look closely at the scores of all the disks in the query, you'll notice that this is a noticeable gap between the top 3 and the rest. They are as follows:<br />
<center><br />
<table>
<tr>
<td>Manufacturer:</td>
<td>A-DATA</td>
<td>Patriot</td>
<td>G.Skill</td>
</tr>
<tr>
<td>Series:</td>
<td>S599</td>
<td>Inferno</td>
<td>Phoenix Series</td>
</tr>
<tr>
<td>Capacity:</td>
<td>128GB</td>
<td>120GB</td>
<td>120GB</td>
</tr>
<tr>
<td>Read:</td>
<td>280MB/s</td>
<td>285MB/s</td>
<td>285MB/s</td>
</tr>
<tr>
<td>Write:</td>
<td>270MB/s</td>
<td>275MB/s</td>
<td>275MB/s</td>
</tr>
<tr>
<td>Item:</td>
<td>N82E16820211471<sup>[<a href="http://www.bemasher.net/archives/836#footnote_7_836" id="identifier_7_836" class="footnote-link footnote-identifier-link" title="A-Data S599">8</a>]</sup></td>
<td>N82E16820220510<sup>[<a href="http://www.bemasher.net/archives/836#footnote_8_836" id="identifier_8_836" class="footnote-link footnote-identifier-link" title="Patriot Inferno">9</a>]</sup></td>
<td>N82E16820231372<sup>[<a href="http://www.bemasher.net/archives/836#footnote_9_836" id="identifier_9_836" class="footnote-link footnote-identifier-link" title="G.Skill Phoenix Series">10</a>]</sup></td>
</tr>
<tr>
<td>Price:</td>
<td>$295.99</td>
<td>$289.99</td>
<td>$299.00</td>
</tr>
</table>
<p></center><br />
I noticed that if you ignore capacity in the metric then the Patriot Inferno is the clear winner here. So as it turns out the Western Digital SiliconEdge I had selected when I first wrote the wishlist wasn't the best drive for my needs. But then I've always had a soft-spot for Western Digital. But now I'm convinced that the Patriot Inferno is the SSD I'll be getting unless by the time I get around to buying one there are better options<sup>[<a href="http://www.bemasher.net/archives/836#footnote_10_836" id="identifier_10_836" class="footnote-link footnote-identifier-link" title="Which there probably will be.">11</a>]</sup>.</p>
<ol class="footnotes"><li id="footnote_0_836" class="footnote">Nothing worth-while anyway</li><li id="footnote_1_836" class="footnote">See previous post: <a href="http://www.bemasher.net/archives/804">Wishlist</a>.</li><li id="footnote_2_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820250002&#038;cm_re=Western_Digital_Silicon_Edge-_-20-250-002-_-Product">Western Digital SiliconEdge 128GB SSD</a></li><li id="footnote_3_836" class="footnote">Which no longer exists in it's original form.</li><li id="footnote_4_836" class="footnote">Which I was.</li><li id="footnote_5_836" class="footnote">Although we're excluding read//write speed difference.</li><li id="footnote_6_836" class="footnote">Scores have been normalized to 100%.</li><li id="footnote_7_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820211471">A-Data S599</a></li><li id="footnote_8_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820220510">Patriot Inferno</a></li><li id="footnote_9_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820231372">G.Skill Phoenix Series</a></li><li id="footnote_10_836" class="footnote">Which there probably will be.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/836/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Matplotlib and Live Data: A Tale of Two Technologies</title>
		<link>http://www.bemasher.net/archives/813</link>
		<comments>http://www.bemasher.net/archives/813#comments</comments>
		<pubDate>Thu, 29 Jul 2010 04:46:53 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[DS18B20]]></category>
		<category><![CDATA[DS18S20]]></category>
		<category><![CDATA[DS18X20]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[Live]]></category>
		<category><![CDATA[matplotlib]]></category>
		<category><![CDATA[OneWire]]></category>
		<category><![CDATA[pySerial]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[temperature]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=813</guid>
		<description><![CDATA[Being unemployed over the summer is never usually a good thing for me. I get bored very easily if I don't have something to occupy myself with. This last bout of boredom led me to unpack some of my electronics. Dusted off my multimeter, Arduino and a digital thermometer I bought a little while ago. [...]]]></description>
			<content:encoded><![CDATA[<p>Being unemployed over the summer is never usually a good thing for me. I get bored very easily if I don't have something to occupy myself with. This last bout of boredom led me to unpack some of my electronics. Dusted off my multimeter, Arduino and a digital thermometer I bought a little while ago. Figured I could use these to solve one of my current problems.</p>
<p>Living in Laramie usually subjects people to harsh winters which leaves most housing developments without central air conditioning installed since, well it's never really needed except maybe one or two days over the summer where it gets above 85 <sup>o</sup>F. This summer has apparently been hotter than previous summers and It's left my condo in an "uncomfortable state". Mind you I'm used to living in hot weather so this isn't such a terrible thing to me, I'm used to it. </p>
<p>What I'm not used to is not having AC and it cooling off enough at night that it's worthwhile to open a few windows and stick a fan in one of them. Which leaves me with this problem: When is the optimal time to open the windows and turn on the fan to get my condo cooled off earliest//fastest?</p>
<p>In comes my Arduino + digital thermometer<sup>[<a href="http://www.bemasher.net/archives/813#footnote_0_813" id="identifier_0_813" class="footnote-link footnote-identifier-link" title="DS18S20 Digital Thermometer Datasheet">1</a>]</sup>. Once I rigged up the proper power//data connections on a breadboard for my Arduino I set out to find code for the thermometer. I've setup the thermometer with a sketch on my Arduino before I just didn't feel like wasting a few hours trying to do it from scratch again. Soon enough I found some code<sup>[<a href="http://www.bemasher.net/archives/813#footnote_1_813" id="identifier_1_813" class="footnote-link footnote-identifier-link" title="Temperature Measurement using the Dallas DS18B20 by Peter H. Anderson">2</a>]</sup> that worked perfectly. So I trimmed out some code I didn't need for the project and set it up to just write the temperature as fast as possible<sup>[<a href="http://www.bemasher.net/archives/813#footnote_2_813" id="identifier_2_813" class="footnote-link footnote-identifier-link" title="Somewhere in the range of 750ms between readings since it is in parasite mode, may change this later to run in non-parasite mode.">3</a>]</sup> to the serial port it's connected to.</p>
<p>After that I wrote a logging program on my desktop in Python to record temperatures sent via serial to my desktop. The program is incredibly simple and uses the pySerial library<sup>[<a href="http://www.bemasher.net/archives/813#footnote_3_813" id="identifier_3_813" class="footnote-link footnote-identifier-link" title="pySerial Python Library">4</a>]</sup> to read temperatures from the serial port of my desktop and append them to a temperature log. I used a simple windows command to do this since it wouldn't lock the file so I could read data from it simultaneously. There are still occasionally collisions with the processing program locking the file and the logger not being able to write the data to the file but these are rare enough that it's negligible in my situation.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> serial, <span style="color: #dc143c;">os</span><br />
<br />
ser = serial.<span style="color: black;">Serial</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:<br />
&nbsp; &nbsp; <span style="color: #dc143c;">os</span>.<span style="color: black;">system</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;echo %s&gt;&gt;out.txt&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>ser.<span style="color: #dc143c;">readline</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>The next step in this project was visualizing the data. I've used matplotlib<sup>[<a href="http://www.bemasher.net/archives/813#footnote_4_813" id="identifier_4_813" class="footnote-link footnote-identifier-link" title="matplotlib Python Library">5</a>]</sup> before and I was thinking this time I would like to see if I could write the program to update data live as it recieves it. My first foray into this goal was a miserable disaster. Most of the solutions I could find involved just setting up an infinite loop with a short time delay in it. Which works great except that it sleeps the thread running the plot which makes it impossible to resize the plot or do anything at all with the GUI for that matter. So obviosly this wouldn't work at all.</p>
<p>After poking around for different solutions to this and crashing my computer once from spawning an infinite number of instances of the plot I gave up for a bit, only to discover that there was an example in the documentation which wasn't obviously named. I quickly discovered the best way to do this. I even added some pretty annotations and such.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> gobject<br />
<span style="color: #ff7700;font-weight:bold;">import</span> matplotlib<br />
matplotlib.<span style="color: black;">use</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'GTKAgg'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> matplotlib.<span style="color: black;">pyplot</span> <span style="color: #ff7700;font-weight:bold;">as</span> plt<br />
<br />
current_pos = <span style="color: #ff4500;">0</span><br />
temps = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
pad = <span style="color: #ff4500;">5.0</span><br />
<br />
f = plt.<span style="color: black;">figure</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">vars</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Unpack variables that need to be persistent between</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions of this method.</span><br />
&nbsp; &nbsp; temps = <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current_pos = <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; pad = <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Open the data file and get any new data points since</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># the last time we read from this file</span><br />
&nbsp; &nbsp; data = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;out.txt&quot;</span>, <span style="color: #483d8b;">&quot;r&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data.<span style="color: black;">seek</span><span style="color: black;">&#40;</span>current_pos<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; new_temps = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> + <span style="color: #ff4500;">4.0</span>/<span style="color: #ff4500;">5.0</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">32.0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; data.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current_pos = data.<span style="color: black;">tell</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If we got new data then append it to the list of</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># temperatures and trim to 750 points</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>new_temps<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; temps.<span style="color: black;">extend</span><span style="color: black;">&#40;</span>new_temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; temps = temps<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">750</span>:<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">clear</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; f.<span style="color: black;">suptitle</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Live Temperature&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a = f.<span style="color: black;">add_subplot</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">111</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a.<span style="color: black;">grid</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; l, = a.<span style="color: black;">plot</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plt.<span style="color: black;">xlabel</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Time (Seconds)&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plt.<span style="color: black;">ylabel</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Temperature $^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get the minimum and maximum temperatures these are</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># used for annotations and scaling the plot of data</span><br />
&nbsp; &nbsp; min_t = <span style="color: #008000;">min</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; max_t = <span style="color: #008000;">max</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add annotations for minimum and maximum temperatures</span><br />
&nbsp; &nbsp; a.<span style="color: black;">annotate</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Min: %0.2f$^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>min_t<span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; xy=<span style="color: black;">&#40;</span>temps.<span style="color: black;">index</span><span style="color: black;">&#40;</span>min_t<span style="color: black;">&#41;</span>, min_t<span style="color: black;">&#41;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; xycoords=<span style="color: #483d8b;">'data'</span>, xytext=<span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span>, -<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; textcoords=<span style="color: #483d8b;">'offset points'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; bbox=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>boxstyle=<span style="color: #483d8b;">&quot;round&quot;</span>, fc=<span style="color: #483d8b;">&quot;0.8&quot;</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; arrowprops=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>arrowstyle=<span style="color: #483d8b;">&quot;-&gt;&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; shrinkA=<span style="color: #ff4500;">0</span>, shrinkB=<span style="color: #ff4500;">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; connectionstyle=<span style="color: #483d8b;">&quot;angle,angleA=0,angleB=90,rad=10&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; a.<span style="color: black;">annotate</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Max: %0.2f$^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>max_t<span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; xy=<span style="color: black;">&#40;</span>temps.<span style="color: black;">index</span><span style="color: black;">&#40;</span>max_t<span style="color: black;">&#41;</span>, max_t<span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; xycoords=<span style="color: #483d8b;">'data'</span>, xytext=<span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span>, <span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; textcoords=<span style="color: #483d8b;">'offset points'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; bbox=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>boxstyle=<span style="color: #483d8b;">&quot;round&quot;</span>, fc=<span style="color: #483d8b;">&quot;0.8&quot;</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; arrowprops=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>arrowstyle=<span style="color: #483d8b;">&quot;-&gt;&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; shrinkA=<span style="color: #ff4500;">0</span>, shrinkB=<span style="color: #ff4500;">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; connectionstyle=<span style="color: #483d8b;">&quot;angle,angleA=0,angleB=90,rad=10&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Set the axis limits to make the data more readable</span><br />
&nbsp; &nbsp; a.<span style="color: black;">axis</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>,<span style="color: #008000;">len</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span>, min_t - pad,max_t + pad<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">canvas</span>.<span style="color: black;">draw_idle</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Repack variables that need to be persistent between</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions of this method</span><br />
&nbsp; &nbsp; <span style="color: #008000;">vars</span> = <span style="color: black;">&#123;</span><span style="color: #ff4500;">0</span>: temps, <span style="color: #ff4500;">1</span>: current_pos, <span style="color: #ff4500;">2</span>: pad<span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span><br />
<br />
<span style="color: #008000;">vars</span> = <span style="color: black;">&#123;</span><span style="color: #ff4500;">0</span>: temps, <span style="color: #ff4500;">1</span>: current_pos, <span style="color: #ff4500;">2</span>: pad<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Execute update method every 500ms</span><br />
gobject.<span style="color: black;">timeout_add</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>, update, <span style="color: #008000;">vars</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Display the plot</span><br />
plt.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>This code generates a plot which updates every 500ms. This is based on an example in the matplotlib examples<sup>[<a href="http://www.bemasher.net/archives/813#footnote_5_813" id="identifier_5_813" class="footnote-link footnote-identifier-link" title="Animation example code: simple_anim_gtk.py">6</a>]</sup>. An example of the program's output can be seen below.</p>
<p><center><img src="http://lh4.ggpht.com/_67X_BsG0Kiw/TFEFttg0AlI/AAAAAAAAHxk/mwXxOtaC_tQ/s800/Output.png" /></center></p>
<p>I imagine that I could have made this simpler by not using the GTK libraries which are a pain to install since there are 3 or 4 modules you have to install in order to make all this work including the GTK+ runtime. I may come back later and post a version written using TK since it can be used without installing extra modules and stuff.</p>
<ol class="footnotes"><li id="footnote_0_813" class="footnote"><a href="http://datasheets.maxim-ic.com/en/ds/DS18S20.pdf">DS18S20 Digital Thermometer Datasheet</a></li><li id="footnote_1_813" class="footnote"><a href="http://www.phanderson.com/arduino/ds18b20_1.html">Temperature Measurement using the Dallas DS18B20 by Peter H. Anderson</a></li><li id="footnote_2_813" class="footnote">Somewhere in the range of 750ms between readings since it is in parasite mode, may change this later to run in non-parasite mode.</li><li id="footnote_3_813" class="footnote"><a href="http://pyserial.sourceforge.net/">pySerial Python Library</a></li><li id="footnote_4_813" class="footnote"><a href="http://matplotlib.sourceforge.net/">matplotlib Python Library</a></li><li id="footnote_5_813" class="footnote"><a href="http://matplotlib.sourceforge.net/examples/animation/simple_anim_gtk.html">Animation example code: simple_anim_gtk.py</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/813/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wishlist</title>
		<link>http://www.bemasher.net/archives/804</link>
		<comments>http://www.bemasher.net/archives/804#comments</comments>
		<pubDate>Fri, 23 Jul 2010 03:11:14 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[460]]></category>
		<category><![CDATA[920]]></category>
		<category><![CDATA[930]]></category>
		<category><![CDATA[Core i7]]></category>
		<category><![CDATA[Corsair]]></category>
		<category><![CDATA[DDR3]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[G.SKILL]]></category>
		<category><![CDATA[GeForce]]></category>
		<category><![CDATA[GTX]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[Newegg]]></category>
		<category><![CDATA[NVIDIA]]></category>
		<category><![CDATA[SSD]]></category>
		<category><![CDATA[Western Digital]]></category>
		<category><![CDATA[Wishlist]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=804</guid>
		<description><![CDATA[I've noticed recently that I tend to spend a lot of time shopping for things I can't afford when I don't have any excess income. I can't really tell if it's just because I'm bored a lot more often over the summer. Especially this one since I've been unemployed for the maojority of it so [...]]]></description>
			<content:encoded><![CDATA[<p>I've noticed recently that I tend to spend a lot of time shopping for things I can't afford when I don't have any excess income. I can't really tell if it's just because I'm bored a lot more often over the summer. Especially this one since I've been unemployed for the maojority of it so far<sup>[<a href="http://www.bemasher.net/archives/804#footnote_0_804" id="identifier_0_804" class="footnote-link footnote-identifier-link" title="I do have an interview coming up so wish me luck.">1</a>]</sup>.</p>
<p>As it stands there is a rather long list of things I intend on buying//upgrading//replacing in the future. First and foremost on this list is a new laptop since my current ASUS Eee-PC 1000H is driving me nuts. It's useful for... writing, and not even that sometimes. For the last year I've used it almost strictly for taking notes in class, which it does well enough. But using it for anything else is essentially impossible. I've found this to be even more true in the last few weeks since I've been spending every other weekend with my parents on their ranch or in Cheyenne. I've just been using it when I went since it's pretty impractical to take my desktop with me everytime. Especially considering a lot of the stuff I work on needs a decent amount of bandwidth and my parents' internet connection is satellite based on their ranch at least so it would be pointless to try and get any real work done.</p>
<p>I've essentially decided that my next laptop will be a 13" Macbook Pro. The main reason is that for the amount of money I intend on spending on a new laptop the Macbook Pro is far superior in both build quality and components to the equivelant Dell which is the manufacturer I've used for all my mobile computing needs until my netbook. Easy decision don't you think?</p>
<p>The next item on my list was building a new desktop. I only <strong>really</strong> need to replace the core components of my desktop since everything else is more or less in good working order. But that's boring so I've made an entire list of components including core and secondary components to build a new desktop, excluding optical drive and hard drives<sup>[<a href="http://www.bemasher.net/archives/804#footnote_1_804" id="identifier_1_804" class="footnote-link footnote-identifier-link" title="Again, excluding SSD from this list of parts I don&#039;t intend to buy.">2</a>]</sup></p>
<p>The first part I always start with when building a wishlist<sup>[<a href="http://www.bemasher.net/archives/804#footnote_2_804" id="identifier_2_804" class="footnote-link footnote-identifier-link" title="Always on Newegg.com, they&#039;re the de facto standard in online computer components.">3</a>]</sup> is the CPU and for this particular one it was a pretty simple choice. Intel's Core i7 series is pretty much the way to go when building a workstation. In this case there were only really two requirements I had for selecting the particular Core i7 I need for this build.</p>
<ul>
<li>$0 &lt; Price &lt; $500</li>
<li>Supports Triple Channel DDR3</li>
</ul>
<p>These requirements narrow down the selection to two processors.  The Core i7-920 and the Core i7-930. There are only two differences. The 930 is 2.8Ghz and the 920 is 2.66Ghz and the 930 is $10 cheaper than the 920, so it's pretty obvious which one is the one to go with.</p>
<p>Intel Core i7-930 Bloomfield 2.8Ghz LGA 1366 130W Quad-Core<br />
Model #: BX80601930<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16819115225">N82E16819115225</a><br />
Price: $289.99</p>
<p>The second component I select after the CPU is the motherboard. Now this is where it gets tricky because the restrictions I use for selecting a motherboard have a lot less to do with technical capabilities than they do with reliability and proper functionality. This is where newegg becomes the right place to shop. Their product review system is by far the best in the online tech shopping world. I tend to score motherboards based on the number of reviews they receive and the score of the review. This is of course after I've removed motherboards incompatible with the other components I intend on using in the system.</p>
<ul>
<li>LGA 1366</li>
<li>Intel X58</li>
<li>Intel ICH10R</li>
<li>ATX form factor</li>
</ul>
<p>The motherboard that comes out on top after these restrictions is an EVGA board.</p>
<p>EVGA E758-TR Intel X58</p>
<p>http://www.newegg.com/Product/Product.aspx?Item=N82E16813188046</p>
<p>Model #: 132-BL-E758-TR<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16813188046">N82E16813188046</a><br />
Price: $269.99 IMIR -$40.00: $229.99</p>
<p>Next up is system memory. This almost always follows from motherboard since some motherboards support odd RAM speeds and I tend to stick with standard speeds since they are a lot less prone to compatibility issues and just work. In this case the motherboard calls for DDR3 1333<sup>[<a href="http://www.bemasher.net/archives/804#footnote_3_804" id="identifier_3_804" class="footnote-link footnote-identifier-link" title="DDR3 SDRAM PC10666">4</a>]</sup>. I usually filter out for the specific kind of RAM I want which leaves me with a few dozen sets. Then I score based on CAS latency and price. I've used G.SKILL before and was pleased with it and in this case a G.SKILL set won on both price and CAS latency.</p>
<p>G.SKILL 3GB (3 x 1GB) DDR3 1333 (PC10666) Triple Channel<br />
Model #: F3-10666CL7T-3GBPK<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820231229">N82E16820231229</a><br />
Price: $84.99</p>
<p>Now you're probably thinking "Why does he only want 3GB that's puny!". There are some very good reasons for it. First of all I'm not really all that into 64-bit yet, I still have a few devices without 64-bit compatible drivers<sup>[<a href="http://www.bemasher.net/archives/804#footnote_4_804" id="identifier_4_804" class="footnote-link footnote-identifier-link" title="And will probably never be compatible for that matter.">5</a>]</sup>. For the most part 2GB of RAM has suited me just fine for nearly anything I've ever needed//wanted to do on my desktop until this point, why should I pile in twice or even three times that amount? Besides if I so desire I could just purchase a second set in the future. The only reason I might consider doing that is if I suddenly became obsessed with running a dozen virtual machines simultaneously<sup>[<a href="http://www.bemasher.net/archives/804#footnote_5_804" id="identifier_5_804" class="footnote-link footnote-identifier-link" title="Which I won&#039;t, so I won&#039;t.">6</a>]</sup>.</p>
<p>Next in line isn't exactly a component I <strong>need</strong> to buy, but I've been wanting to upgrade for a long time now and I figure a wishlist is the best place to do it. Ever since I saw an article on Gizmodo<sup>[<a href="http://www.bemasher.net/archives/804#footnote_6_804" id="identifier_6_804" class="footnote-link footnote-identifier-link" title="I think.">7</a>]</sup> about the new NVIDIA GeForce GTX 460 I've pretty much been set on that specific chipset. It was pretty easy to select a brand since they're all exactly the same price at this point and I only want the 768MB model. I've been wanting to do some CUDA development so here's my chance.</p>
<p>EVGA NVIDIA GeForce GTX 460 (Fermi) 768MB<br />
Model #: 768-P3-1360-TR<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16814130562">N82E16814130562</a><br />
Price: $199.99</p>
<p>Another component I consider to be core but isn't necessarily a core component is the storage device used for the OS. In the past I've strictly used HDD's for my desktop. But since I installed a Patriot 32GB SSD in my laptop I've fallen in love with SSD's for the OS//Programs drive. You might hear people moan and complain about SSD's being disproportionatly priced based on their capacity. Well I've got news for you, you don't buy SSD's for capacity, you buy them for speed. Anyone reasonably knowledgeable about computer components and their functionality would know that. I'm not interested in price per GB as quite a lot of people might be, at least not for SSD's<sup>[<a href="http://www.bemasher.net/archives/804#footnote_7_804" id="identifier_7_804" class="footnote-link footnote-identifier-link" title="The only component I consider price per GB on is standard HDD&#039;s.">8</a>]</sup>. I'm a lot more interested in price per MB/s sequential read-write. The particular disk that won in this case is one of the new Western Digital SSD's.</p>
<p>Western Digital SiliconEdge Blue 128GB SSD MLC 220/170 SR/SW<br />
Model #: SSC-D0128SC-2100<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820250002">N82E16820250002</a><br />
Price: $199.99</p>
<p>In case the title of that product doesn't make sense the drive is 220MB/s Sequential Read and 170MB/s Sequential Write.</p>
<p>Everything from this point on I consider to be secondary components as they don't directly do any computation or data transfer//storage.</p>
<p>For this build I've decided that even though I don't <strong>need</strong> to get a new case, I've added one to the list anyway since my current case is due for an upgrade, especially in regards to aesthetics. I've been oggling this particular case for quite a while now, since it replaced it's predecessor at least. This case won by a long shot in aesthetics and functionality.</p>
<p>Antec P183 Black Aluminum/Steel ATX-Mid<br />
Model #: P183<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16811129061">N82E16811129061</a><br />
Price: $179.99 IMIR -$25.00: $154.99</p>
<p>The next item due for an upgrade was actually necessary considering the major increase in power needs for the core components. I've always hated shopping for power supplies because there are far more factors to consider when it comes to selecting one that matches your needs and is of reasonable build quality. If you don't have a decent power supply you may as well just give up. In this case I stuck as close as possible to the power supply I have now. I was only really interested in making sure that there were enough PCI-e power connectors since my current PSU has none. I let the reviews do the majority of selecting for me in this case.</p>
<p>Corsair 650W (ATX|EPS)12V<br />
Model #: CMPSU-650TX<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16817139005">N82E16817139005</a><br />
Price: $119.99 IMIR -$30.00: $89.99</p>
<p>This power supply matched most closely to the one I had now, it's simple, doesn't have too many "certifications" and marketing nonsense tacked onto the name and the cables are sheathed in black mesh<sup>[<a href="http://www.bemasher.net/archives/804#footnote_8_804" id="identifier_8_804" class="footnote-link footnote-identifier-link" title="Which lends nicely to aesthetics should I ever decide to show someone my desktop&#039;s inards.">9</a>]</sup>.</p>
<p>Now I don't normally bother with purchasing a 3rd party heatsink//cooling system for my CPU but in this case I had heard mention of a self-contained water cooling system with radiator, pump and CPU waterblock from Corsair. So I checked it out and I am impressed. Since it is self-contained it removes a lot of the frustration with resevoirs and replacing the coolant on a regular basis.</p>
<p>Corsair H50 CPU Cooler<br />
Model #: CWCH50-1<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16835181010">N82E16835181010</a><br />
Price: $74.99</p>
<p>The last item in the list is more for interior neatness and organization. I've always hated just leaving components without a proper fastening inside the case. In this situation the SSD I select<sup>[<a href="http://www.bemasher.net/archives/804#footnote_9_804" id="identifier_9_804" class="footnote-link footnote-identifier-link" title="Like all SSD&#039;s.">10</a>]</sup> is 2.5" form factor, suitable for notebooks and less suitable for desktops. So I looked around for a set of 2.5" to 3.5" brackets to secure the drive in one of the HDD bays.</p>
<p>iStarUSA 2.5" to 3.5" HDD Bracket<br />
Model #: DIY-RP-HDD2.5<br />
Item #: <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16816215157">N82E16816215157</a><br />
Price: $5.99</p>
<p>The subtotal for the build excluding shipping and including all instant mail in rebates comes out to $1330.91. Pretty good wouldn't you say? For a decently beefy workstation that would likely last me another 5-6 years before upgrading again. I'm currently on the 5th year since a major overhaul of my current system an Intel Core 2 Duo based rig.</p>
<ol class="footnotes"><li id="footnote_0_804" class="footnote">I do have an interview coming up so wish me luck.</li><li id="footnote_1_804" class="footnote">Again, excluding SSD from this list of parts I don't intend to buy.</li><li id="footnote_2_804" class="footnote">Always on Newegg.com, they're the de facto standard in online computer components.</li><li id="footnote_3_804" class="footnote">DDR3 SDRAM PC10666</li><li id="footnote_4_804" class="footnote">And will probably never be compatible for that matter.</li><li id="footnote_5_804" class="footnote">Which I won't, so I won't.</li><li id="footnote_6_804" class="footnote">I think.</li><li id="footnote_7_804" class="footnote">The only component I consider price per GB on is standard HDD's.</li><li id="footnote_8_804" class="footnote">Which lends nicely to aesthetics should I ever decide to show someone my desktop's inards.</li><li id="footnote_9_804" class="footnote">Like all SSD's.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/804/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New Trigger for my 1911</title>
		<link>http://www.bemasher.net/archives/792</link>
		<comments>http://www.bemasher.net/archives/792#comments</comments>
		<pubDate>Sun, 11 Jul 2010 03:26:02 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[1911]]></category>
		<category><![CDATA[Brownells]]></category>
		<category><![CDATA[Brownells.com]]></category>
		<category><![CDATA[Charles Daly]]></category>
		<category><![CDATA[Competition]]></category>
		<category><![CDATA[Long]]></category>
		<category><![CDATA[M1911]]></category>
		<category><![CDATA[Match]]></category>
		<category><![CDATA[Trigger]]></category>
		<category><![CDATA[Wilson Combat]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=792</guid>
		<description><![CDATA[A couple of days ago after detail-stripping my 1911[1] I finally discovered what was causing the binding issues I was having. I knew already that being left handed was part of the problem but I also found out that the particular trigger fitted to my gun was especially slack compared to my brother's[2]. I found [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago after detail-stripping my 1911<sup>[<a href="http://www.bemasher.net/archives/792#footnote_0_792" id="identifier_0_792" class="footnote-link footnote-identifier-link" title="Charles Daly 1911">1</a>]</sup> I finally discovered what was causing the binding issues I was having. I knew already that being left handed was part of the problem but I also found out that the particular trigger fitted to my gun was especially slack compared to my brother's<sup>[<a href="http://www.bemasher.net/archives/792#footnote_1_792" id="identifier_1_792" class="footnote-link footnote-identifier-link" title="Kimber Desert Warrior">2</a>]</sup>.</p>
<p>I found out that when pulling the trigger at a specific angle<sup>[<a href="http://www.bemasher.net/archives/792#footnote_2_792" id="identifier_2_792" class="footnote-link footnote-identifier-link" title="The angle I&#039;m most acustomed to pulling at on a handgun">3</a>]</sup> the trigger pushes down against the frame and binds against it which fails release the sear and fire.</p>
<p>A few days ago I decided to go ahead and just order a new trigger to solve this problem. I found a Wilson Combat trigger<sup>[<a href="http://www.bemasher.net/archives/792#footnote_3_792" id="identifier_3_792" class="footnote-link footnote-identifier-link" title="Wilson Combat Trigger: http://shopwilsoncombat.com/Trigger-Competition-Match-Long-Pad/productinfo/1/">4</a>]</sup> on Brownells.com for $16.99<sup>[<a href="http://www.bemasher.net/archives/792#footnote_4_792" id="identifier_4_792" class="footnote-link footnote-identifier-link" title="http://www.brownells.com/.aspx/sid=36780/sku/Wilson__45_Trigger">5</a>]</sup> which I thought was a pretty good deal. It was a single-stack, long pad<sup>[<a href="http://www.bemasher.net/archives/792#footnote_5_792" id="identifier_5_792" class="footnote-link footnote-identifier-link" title="I opted for the long pad since I have long fingers.">6</a>]</sup> trigger which should be compatible with my 1911.</p>
<p>The trigger arrived today so I detail-stripped my gun again to install the trigger. I figured I would need to do a little bit of fitting myself since my 1911 isn't perfectly standard in all respects. I was lucky to discover that the new trigger had a larger pad<sup>[<a href="http://www.bemasher.net/archives/792#footnote_6_792" id="identifier_6_792" class="footnote-link footnote-identifier-link" title="Taller and wider.">7</a>]</sup> than the pad of the stock trigger which was good because you can always remove material, but you can't put it back. I hoped this would fix my slack and binding issues once and for all.</p>
<p>A quick trip to Ace hardware, $6.49 and an assorted pack of wet/dry sandpaper later I was back at home getting ready to fit the trigger to the frame. I started with 220 grit and did long strokes on both sides of the trigger alternating to keep an even amount of material removal. After about 80-100 strokes the trigger was exactly thick enough to fit properly in the frame. Next up was shaving off a little on both the top and bottom to finish the fit. 60-80 strokes later the trigger fit perfectly inside the frame there was hardly any slack like the stock trigger at all. I did 10-15 strokes on 400 grit and then 600 grit to smooth out the finish again.</p>
<p>After all this I reassembled the gun and installed the screw to prevent overtravel. Dry fired a few times and all seems to be perfect. This was an incredible improvement to my gun. Although the bow is a little longer than the one the gun came with and because of this the pad extends further into the trigger loop than I'd like. It also reveals the rivets used to secure the pad to the bow which is ugly but hey, it works.</p>
<p>Eventually I'll just upgrade and buy myself a decent handgun to begin with and hopefully will only need to replace one or two parts.</p>
<p><a href="http://lh4.ggpht.com/_67X_BsG0Kiw/TDlLqDN2OyI/AAAAAAAAHvY/RWl68kItrmg/s1600/DSC_6243.jpg"><img src="http://lh4.ggpht.com/_67X_BsG0Kiw/TDlLqDN2OyI/AAAAAAAAHvY/RWl68kItrmg/s400/DSC_6243.jpg" title="Wilson Combat trigger in Charles Daly 1911" width="400" height="266" /></a></p>
<ol class="footnotes"><li id="footnote_0_792" class="footnote">Charles Daly 1911</li><li id="footnote_1_792" class="footnote">Kimber Desert Warrior</li><li id="footnote_2_792" class="footnote">The angle I'm most acustomed to pulling at on a handgun</li><li id="footnote_3_792" class="footnote">Wilson Combat Trigger: <a href="http://shopwilsoncombat.com/Trigger-Competition-Match-Long-Pad/productinfo/1/">http://shopwilsoncombat.com/Trigger-Competition-Match-Long-Pad/productinfo/1/</a></li><li id="footnote_4_792" class="footnote"><a href="http://www.brownells.com/.aspx/sid=36780/sku/Wilson__45_Trigger">http://www.brownells.com/.aspx/sid=36780/sku/Wilson__45_Trigger</a></li><li id="footnote_5_792" class="footnote">I opted for the long pad since I have long fingers.</li><li id="footnote_6_792" class="footnote">Taller and wider.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/792/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kubota Bob Burgers</title>
		<link>http://www.bemasher.net/archives/790</link>
		<comments>http://www.bemasher.net/archives/790#comments</comments>
		<pubDate>Wed, 30 Jun 2010 00:02:43 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[burger]]></category>
		<category><![CDATA[hamburger]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=790</guid>
		<description><![CDATA[1lb Ground beef//chuck//sirloin (cow of any sort) 1/2 tsp Garlic Powder 1 tsp Onion Powder 1/2 tsp Black Pepper 1 tbsp Worchestershire Sauce 1 tbsp A1 Steak Sauce Mix ingredients thoroughly without ground beef. Then mix into ground beef. Make paddies, then cook to preference. Lightly salt on grill. Better flavor if you let it [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>1lb Ground beef//chuck//sirloin (cow of any sort)</li>
<li>1/2 tsp Garlic Powder</li>
<li>1 tsp Onion Powder</li>
<li>1/2 tsp Black Pepper</li>
<li>1 tbsp Worchestershire Sauce</li>
<li>1 tbsp A1 Steak Sauce</li>
</ul>
<p>Mix ingredients thoroughly without ground beef. Then mix into ground beef. Make paddies, then cook to preference. Lightly salt on grill. Better flavor if you let it "marinade" overnight. Makes 4x decently sized hamburgers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/790/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WriteMonkey and Markdown</title>
		<link>http://www.bemasher.net/archives/781</link>
		<comments>http://www.bemasher.net/archives/781#comments</comments>
		<pubDate>Mon, 28 Jun 2010 03:14:01 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Download Squad]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[WriteMonkey]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=781</guid>
		<description><![CDATA[Recently Download Squad had a post[1] about a practical way to get features and support for open-source programs, specifically through donations. The post was about a program called WriteMonkey which is a minimalistic writing program that the author had originally written about previously[2]. Think of the best code editing program you know of, mine is [...]]]></description>
			<content:encoded><![CDATA[<p>Recently Download Squad had a post<sup>[<a href="http://www.bemasher.net/archives/781#footnote_0_781" id="identifier_0_781" class="footnote-link footnote-identifier-link" title="Download Squad: Amazing software tip: Pay free software developers to get stuff fixed!">1</a>]</sup> about a practical way to get features and support for open-source programs, specifically through donations. The post was about a program called WriteMonkey which is a minimalistic writing program that the author had originally written about previously<sup>[<a href="http://www.bemasher.net/archives/781#footnote_1_781" id="identifier_1_781" class="footnote-link footnote-identifier-link" title="Download Squad: WriteMonkey is an unbelievable full-screen text editor">2</a>]</sup>. Think of the best code editing program you know of, mine is Notepad++<sup>[<a href="http://www.bemasher.net/archives/781#footnote_2_781" id="identifier_2_781" class="footnote-link footnote-identifier-link" title="Notepad++">3</a>]</sup>. Now take that program and refactor it specifically for writing articles or blog posts, you've just created WriteMonkey<sup>[<a href="http://www.bemasher.net/archives/781#footnote_3_781" id="identifier_3_781" class="footnote-link footnote-identifier-link" title="WriteMonkey">4</a>]</sup>.</p>
<p>Something that interested me about WriteMonkey was the Download Squad author's post specifically mentioned writing posts using Markdown<sup>[<a href="http://www.bemasher.net/archives/781#footnote_4_781" id="identifier_4_781" class="footnote-link footnote-identifier-link" title="Markdown">5</a>]</sup> syntax. Markdown is a simple plain-text syntax which is parsed into html removing the need to tediously enter html<sup>[<a href="http://www.bemasher.net/archives/781#footnote_5_781" id="identifier_5_781" class="footnote-link footnote-identifier-link" title="HTML: HyperText Markup Language, is the predominant markup language for web pages.">6</a>]</sup> as  you write. At first glance it didn't really seem like it would really help all that much when it came to writing blog posts. But I was completely wrong and am better off for it. Now the especially useful part is that WriteMonkey supports this completely as well as having a very useful shortcut for parsing and copying html straight from Markdown source. This is incredibly useful since I can then just go to my website and paste the resulting html into a blog post and hit save and be done with it.</p>
<p>As I looked through the program I realized, this is much much more than just a Markdown IDE. It includes all sorts of useful features like a "progress bar" which tells you how far along you are in a certain quota you specify in the preferences. This led me to write a little bit of SQL<sup>[<a href="http://www.bemasher.net/archives/781#footnote_6_781" id="identifier_6_781" class="footnote-link footnote-identifier-link" title="SQL: Structured Query Language">7</a>]</sup> to calculate the average word-count of posts in my blog. Excluding the outliers it came out to ~350 words per post. So I just set the quota to 350 words and it displays a bar at the top or bottom of the screen depending on what you choose showing your current progress on the quota.</p>
<p>It also does several other useful things like displaying current battery life as a percentage in the progress bar, showing the file you're writing in. There's also this feature called repository//main. This allows you to store text clippings in repository and then write the blog post in main. When exported as html the repository is ignored and only main is copied. Makes it useful to write notes and such in the middle of authoring a post to keep with everything you write and it's easy enough to switch between the two to make it useful. For this post I just made a list of points I wanted to cover.</p>
<p>After using WriteMonkey for an hour or so I think I've found the new environment I'll be writing all my posts in for the foreseeable future.</p>
<ol class="footnotes"><li id="footnote_0_781" class="footnote"><a href="http://www.downloadsquad.com/2010/06/25/amazing-software-tip-pay-free-software-developers-to-get-stuff/">Download Squad</a>: Amazing software tip: Pay free software developers to get stuff fixed!</li><li id="footnote_1_781" class="footnote"><a href="http://www.downloadsquad.com/2010/04/21/writemonkey-is-an-unbelievable-full-screen-text-editor/">Download Squad</a>: WriteMonkey is an unbelievable full-screen text editor</li><li id="footnote_2_781" class="footnote"><a href="http://notepad-plus-plus.org/">Notepad++</a></li><li id="footnote_3_781" class="footnote"><a href="http://writemonkey.com/">WriteMonkey</a></li><li id="footnote_4_781" class="footnote"><a href="http://daringfireball.net/projects/markdown/">Markdown</a></li><li id="footnote_5_781" class="footnote"><a href="http://en.wikipedia.org/wiki/Html">HTML</a>: HyperText Markup Language, is the predominant markup language for web pages.</li><li id="footnote_6_781" class="footnote"><a href="http://en.wikipedia.org/wiki/Sql">SQL</a>: Structured Query Language</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/781/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coping with a puny outbound bandwidth limit.</title>
		<link>http://www.bemasher.net/archives/779</link>
		<comments>http://www.bemasher.net/archives/779#comments</comments>
		<pubDate>Thu, 24 Jun 2010 02:31:14 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[p2p]]></category>
		<category><![CDATA[Reno]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[TCP Reno]]></category>
		<category><![CDATA[TCP Vegas]]></category>
		<category><![CDATA[tomato]]></category>
		<category><![CDATA[torrent]]></category>
		<category><![CDATA[Vegas]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=779</guid>
		<description><![CDATA[If you were unaware I recently moved to Laramie, WY. Which is a significantly smaller town//city//something-or-other than Tucson, AZ is by quite a lot. Anyway if you didn't know Wyoming existed there are a few basic facts about Wyoming I should explain so you'll know what I'm dealing with here. Wyoming is very very spacious [...]]]></description>
			<content:encoded><![CDATA[<p>If you were unaware I recently moved to Laramie, WY. Which is a significantly smaller town//city//something-or-other than Tucson, AZ is by quite a lot. Anyway if you didn't know Wyoming existed there are a few basic facts about Wyoming I should explain so you'll know what I'm dealing with here.</p>
<p>Wyoming is very very spacious and very sparse. Everything here is incredibly spread out. As such laying cable for connecting cities is generally expensive and still in the early stages of deployment. It is still possible to get broadband cable in the cities but if you don't live in the city and want broadband you're stuck with WiMax<sup>[<a href="http://www.bemasher.net/archives/779#footnote_0_779" id="identifier_0_779" class="footnote-link footnote-identifier-link" title="WiMax: Worldwide Interoperability for Microwave Access">1</a>]</sup> like wireless broadband which is pretty wide-spread here and effective since the terrain in most areas of the state permit line-of-sight wireless connections.</p>
<p>I went the broadband cable route since all of the experience I've had with Wifi stuff has been unreliable and I'm just a big fan of having a cable from one point to the next, there is a lot less downtime and possibility for interference.</p>
<p>Unfortunately having chosen broadband cable left me with two providers, Qwest and Bresnan. Qwest limits me to 3Mbps down and what i'm guessing is no more than 384Kbps up. Bresnan on the other hand provides 8Mbps/500Kbps which is better.</p>
<p>I'm consistently getting more and more frustrated with the emphasis broadband cable providers put on download speeds, upload speeds are getting to be just as important if not more important than inbound bandwidth. People are starting to learn that it's much much easier to share media and personal data online instead of the alternatives. By comparison I moved from Tucson where we had 20Mbps/3Mbps.</p>
<p>Now you can see where my problem is. 50KB/s up is pretty miserable compared to what I used to have. And you can imagine where my congestion comes in. If I saturate my outbound bandwidth Bresnan essentially ruins my inbound bandwidth. I recently discovered that Tomato the firmware I've installed on my router comes with TCP Vegas<sup>[<a href="http://www.bemasher.net/archives/779#footnote_1_779" id="identifier_1_779" class="footnote-link footnote-identifier-link" title="TCP Vegas: a TCP congestion control, or network congestion avoidance, algorithm that emphasizes packet delay, rather than packet loss, as a signal to help determine the rate at which to send packets. It was developed at the University of Arizona by Lawrence Brakmo and Larry L. Peterson.">2</a>]</sup> integrated.</p>
<p>Initially I couldn't find any proper documentation on what alpha, beta and gamma meant and how to tune them properly to help control my congestion problem. After several hours of searching and research I found only two configurations that seemed to provide people with some measure of congestion prevention: 3,3,2 and 2,6,2<sup>[<a href="http://www.bemasher.net/archives/779#footnote_2_779" id="identifier_2_779" class="footnote-link footnote-identifier-link" title="Alpha, Beta and Gamma respectively.">3</a>]</sup></p>
<p>So I switched TCP Vegas on while downloading the first Pioneer One episode<sup>[<a href="http://www.bemasher.net/archives/779#footnote_3_779" id="identifier_3_779" class="footnote-link footnote-identifier-link" title="A free TV Series designed specifically for P2P distribution.">4</a>]</sup> and reset all the connections since TCP Vegas only affects connections created since enabled. And immediately i noticed the saw-tooth that TCP Reno<sup>[<a href="http://www.bemasher.net/archives/779#footnote_4_779" id="identifier_4_779" class="footnote-link footnote-identifier-link" title="TCP Reno: a TCP Congestion Avoidance Algorithm">5</a>]</sup> causes a saw-tooth wave in throughput of outbound traffic which is very bad for maintaining throughput. TCP Vegas immediately smoothed out the connection and allowed for a sustained outbound rate with an oscillating inbound rate around the maximum throughput achievable while maintaining sustained outbound traffic. I've read that tuning TCP Vegas properly can eliminate the oscillation of inbound traffic but I haven't had much luck with actually getting this done.</p>
<p>Once TCP Vegas began to smooth things out I figured out that in order to optimize inbound throughput I could simply limit the outbound rate now that the congestion was eliminated. This increased the inbound rate significantly and everything has been running smoothly since then. I wish I knew more about the algorithm used and how to tune it but there doesn't seem to be much in the way of documentation anywhere.</p>
<ol class="footnotes"><li id="footnote_0_779" class="footnote"><a href="http://en.wikipedia.org/wiki/Wimax">WiMax</a>: Worldwide Interoperability for Microwave Access</li><li id="footnote_1_779" class="footnote"><a href="http://en.wikipedia.org/wiki/TCP_Vegas">TCP Vegas</a>: a TCP congestion control, or network congestion avoidance, algorithm that emphasizes packet delay, rather than packet loss, as a signal to help determine the rate at which to send packets. It was developed at the University of Arizona by Lawrence Brakmo and Larry L. Peterson.</li><li id="footnote_2_779" class="footnote">Alpha, Beta and Gamma respectively.</li><li id="footnote_3_779" class="footnote">A free TV Series designed specifically for P2P distribution.</li><li id="footnote_4_779" class="footnote"><a href="http://en.wikipedia.org/wiki/TCP_Reno#TCP_Tahoe_and_Reno">TCP Reno</a>: a TCP Congestion Avoidance Algorithm</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/779/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open-Source Print Server</title>
		<link>http://www.bemasher.net/archives/765</link>
		<comments>http://www.bemasher.net/archives/765#comments</comments>
		<pubDate>Wed, 16 Jun 2010 05:27:15 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[dd-wrt]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[Netgear]]></category>
		<category><![CDATA[Print Server]]></category>
		<category><![CDATA[Printer]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[tomato]]></category>
		<category><![CDATA[TomatoUSB]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[Wifi]]></category>
		<category><![CDATA[WNR3500L]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=765</guid>
		<description><![CDATA[One of the things I had always wanted to play with until I moved was a wireless router that was "deluxe" enough to have a USB port installed. Most of the time these sorts of routers expect that you're just going to plug an external hard drive into it and pretend like it's a full-fledged [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I had always wanted to play with until I moved was a wireless router that was "deluxe" enough to have a USB port installed.</p>
<p>Most of the time these sorts of routers expect that you're just going to plug an external hard drive into it and pretend like it's a full-fledged NAS becuase typically they manage to squeeze CIFS into the firmware that governs the router and for the most part this is good enough for the most basic of NAS needs. Except they tend to forget that throughput with such a simple processor is usually miserable. I've never actually tested any of this myself but all of the forums I've read on the subject seem to report that there is a throughput ceiling of around 5-6MB/s which is pretty bad.</p>
<p>The other purpose for the USB port that I bet people would get more use out of is the ability to use your router as a simple print server. The first reason this is a lot more practical is that nearly all consumer printers these days use USB for their interface. This means that essentially any printer that can be made to work for your current computer with USB can also be put behind a print server without too much trouble. The other way this is useful is for the growing number of laptops you'll find in any given household. Except for minority of people that do enough computer work that owning a desktop is a necessity most every house will mostly be comprised of laptops and all of them will likely communicate with Wifi.</p>
<p>Every time you need to print something from your laptop you'll have to take it back to wherever you've parked your printer and plug it in. But you'll also need to make sure that you plug it back into the same USB port you installed it with in the first place or your computer will go into full-retard mode and "Duhhh... new printer! I'll look for drivers for your awesome new printer."</p>
<p>Now you see where the real hassle is. But this is the point at which a lot of people go the wrong direction. The first thought a lot of people have<sup>[<a href="http://www.bemasher.net/archives/765#footnote_0_765" id="identifier_0_765" class="footnote-link footnote-identifier-link" title="If they&#039;re tech-savvy enough to realize that this is possible.">1</a>]</sup> is that they'll just solve this problem by throwing money at it which usually means shopping for and buying a printer with network capabilities built in.</p>
<p>The main problem with this is that, network attached printers are expensive, quite a lot more expensive than their non-network-aware brethren. The secondary problem is that a grand majority of home networks are made possible by DHCP<sup>[<a href="http://www.bemasher.net/archives/765#footnote_1_765" id="identifier_1_765" class="footnote-link footnote-identifier-link" title="Dynamic Host Configuration Protocol">2</a>]</sup> which divvies out IP addresses as devices connect to the network. This presents a problem when the main method for connecting to network attached printers involves knowing the printer's IP address, which can be problematic when your router arbitrarily hands out IP addresses on a regular basis. Every time the lease is up for your printer's IP address there is the possibility of that printer to get a new IP address which causes issues. So unless you are tech-savvy enough to setup static DHCP leases this will cause problems.</p>
<p>The next option for a lot of people is to shoehorn round peg into a square hole by buying a print server to make their current printer network friendly. See the above problem for why this isn't an optimal solution.</p>
<p>In comes the router with a USB port. I recently purchased a Netgear WNR3500L<sup>[<a href="http://www.bemasher.net/archives/765#footnote_2_765" id="identifier_2_765" class="footnote-link footnote-identifier-link" title="Netgear WNR3500L">3</a>]</sup> from newegg. If you're interested in my adventurous experience with installing Tomato on it see my previous<sup>[<a href="http://www.bemasher.net/archives/765#footnote_3_765" id="identifier_3_765" class="footnote-link footnote-identifier-link" title="3rd Party Router Firmware">4</a>]</sup> post about that.</p>
<p>Now you're probably wondering how on earth a router with a USB port is any better than a print server or a network attached printer. The reason it is better is that in typical household networks the router will have the same IP address no matter how you've got DHCP configured. For the most part your router lives at 192.168.1.1 or 192.168.0.1 and this will for most situations never change.</p>
<p>So given a router with a USB port and proper firmware to allow for print serving you can host your printer on your router which will almost always have the same IP address and you can do this all with one device instead of having to buy a separate device.</p>
<p>In my situation I got lucky. I bought the router originally only intending to install dd-wrt<sup>[<a href="http://www.bemasher.net/archives/765#footnote_4_765" id="identifier_4_765" class="footnote-link footnote-identifier-link" title="http://www.dd-wrt.com/">5</a>]</sup> on it. Later I found Tomato<sup>[<a href="http://www.bemasher.net/archives/765#footnote_5_765" id="identifier_5_765" class="footnote-link footnote-identifier-link" title="Tomato Firmware">6</a>]</sup> which looked like it would suit my needs a lot better than dd-wrt would. Except there was some initial stupidity on my part and eventually I got that all sorted out by installing a fork<sup>[<a href="http://www.bemasher.net/archives/765#footnote_6_765" id="identifier_6_765" class="footnote-link footnote-identifier-link" title="http://tomatousb.org/">7</a>]</sup> of the Tomato project which added USB support to Tomato.</p>
<p>For now the TomatoUSB fork only supports broadcom based routers like the original firmware but adds support for a few others which have USB ports. This is where I got lucky, I had never checked before I bought my router to see if it would be supported since I originally only intended on installing dd-wrt on it and it just happened to be supported.</p>
<p>Eventually I got around to unpacking my printer and decided to give it a try. While watching the USB section of the web interface of my router which at this point was running Tomato<sup>[<a href="http://www.bemasher.net/archives/765#footnote_7_765" id="identifier_7_765" class="footnote-link footnote-identifier-link" title="Which has in my opinion a much more beautiful interface that dd-wrt does.">8</a>]</sup>. I plugged in my printer's USB cable into my router and about 3 seconds later<sup>[<a href="http://www.bemasher.net/archives/765#footnote_8_765" id="identifier_8_765" class="footnote-link footnote-identifier-link" title="The default refresh time of pages that have dynamic content on Tomato.">9</a>]</sup> the printer showed up and it began serving the printer using raw data on port 9100 and with LPR<sup>[<a href="http://www.bemasher.net/archives/765#footnote_9_765" id="identifier_9_765" class="footnote-link footnote-identifier-link" title="Line Printer Remote">10</a>]</sup> queue lp0.</p>
<p>So that was easy... a little too easy. Lo' and behold, it was just that easy. All that was left to do was add the printer using a TCP/IP port with 192.168.1.1 as the address and use the driver that I had previously installed to use the printer via USB. That was pretty much all I had to do, it worked exactly as it was meant to the first time I tried it.</p>
<ol class="footnotes"><li id="footnote_0_765" class="footnote">If they're tech-savvy enough to realize that this is possible.</li><li id="footnote_1_765" class="footnote"><a href="http://en.wikipedia.org/wiki/DHCP">Dynamic Host Configuration Protocol</a></li><li id="footnote_2_765" class="footnote"><a href="http://www.netgear.com/Products/WirelessRouter/WirelessRoutersforWorkandPlay/WNR3500L.aspx">Netgear WNR3500L</a></li><li id="footnote_3_765" class="footnote"><a href="http://www.bemasher.net/archives/750">3rd Party Router Firmware</a></li><li id="footnote_4_765" class="footnote"><a href="http://www.dd-wrt.com/">http://www.dd-wrt.com/</a></li><li id="footnote_5_765" class="footnote"><a href="http://www.polarcloud.com/tomato">Tomato Firmware</a></li><li id="footnote_6_765" class="footnote"><a href="http://tomatousb.org/">http://tomatousb.org/</a></li><li id="footnote_7_765" class="footnote">Which has in my opinion a much more beautiful interface that dd-wrt does.</li><li id="footnote_8_765" class="footnote">The default refresh time of pages that have dynamic content on Tomato.</li><li id="footnote_9_765" class="footnote"><a href="http://en.wikipedia.org/wiki/Line_Printer_Remote">Line Printer Remote</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/765/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3rd Party Router Firmware</title>
		<link>http://www.bemasher.net/archives/750</link>
		<comments>http://www.bemasher.net/archives/750#comments</comments>
		<pubDate>Tue, 08 Jun 2010 23:35:35 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[3rd party]]></category>
		<category><![CDATA[broadcom]]></category>
		<category><![CDATA[dd-wrt]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[Netgear]]></category>
		<category><![CDATA[tomato]]></category>
		<category><![CDATA[WNR3500L]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/archives/750</guid>
		<description><![CDATA[Until Monday I'm without any kind of proper internet connection which means until this point I've just been using my phone to browse the internet and chat with friends, which is frustrating to say the least. This prompted me to do a little more research on 3rd party firmware for wireless routers. The first project [...]]]></description>
			<content:encoded><![CDATA[<p>Until Monday I'm without any kind of proper internet connection which means until this point I've just been using my phone to browse the internet and chat with friends, which is frustrating to say the least. This prompted me to do a little more research on 3rd party firmware for wireless routers.</p>
<p>The first project that comes to mind is obviously DD-WRT<sup>[<a href="http://www.bemasher.net/archives/750#footnote_0_750" id="identifier_0_750" class="footnote-link footnote-identifier-link" title="DD-WRT Firmware">1</a>]</sup> the most popular and probably the most powerful of them all right out of the box.  Before I moved here I researched and purchased a new router to use at my new place. I stumbled upon a Netgear router which seemed to match all the features I needed at a reasonable price. I've never really been a huge fan of Netgear routers but I checked that it was compatible at least with DD-WRT before I bought it. The router I'm talking about is a Netgear WNR3500L<sup>[<a href="http://www.bemasher.net/archives/750#footnote_1_750" id="identifier_1_750" class="footnote-link footnote-identifier-link" title="Netgear WNR3500L">2</a>]</sup> which includes:</p>
<ul>
<li>802.11n WiFi</li>
<li>4x 10/100/1000 Ethernet ports</li>
<li>1x USB 2.0 port</li>
</ul>
<p>I think grand total it was ~$90<sup>[<a href="http://www.bemasher.net/archives/750#footnote_2_750" id="identifier_2_750" class="footnote-link footnote-identifier-link" title="Newegg.com: Netgear WNR3500L">3</a>]</sup>. Anyway first thing I did was install DD-WRT which is standard practice for me. Ran exactly as intended except when I tried to set it up to act as a wifi client which failed miserably, I never did figure out how to make it do what I wanted. Everything else worked as intended. But I recently discovered a new firmware I wanted to try, which was Tomato<sup>[<a href="http://www.bemasher.net/archives/750#footnote_3_750" id="identifier_3_750" class="footnote-link footnote-identifier-link" title="Tomato Firmware">4</a>]</sup> another open-source project like DD-WRT.</p>
<p>Tomato is essentially a watered down version of DD-WRT. I think the only useful feature it's missing that DD-WRT has is virtual wifi interfaces, but that's not such a big deal. On the other hand though Tomato has the most polished bandwidth monitoring features of any other project I've ever seen or used. DD-WRT has essentially the same feature but it's much weaker and not nearly as thought out and well designed as Tomato's is.</p>
<p>My main gripe with Tomato is it's lack of community support. DD-WRT is so popular that just about any router you can get your hands on has a forum post somewhere about someone's woes with installing something on it and getting it working the way they needed it. Tomato isn't quite the same way. Also it appears that Tomato mostly only supports broadcom chipsets which is what my new router has.</p>
<p>Well anyway I just decided to download the latest version and try it out. Bad idea. I hadn't really considered that putting firmware on it that doesn't support USB would brick it. Figured USB just wouldn't work, WRONG. Got the firmware uploaded and reset it nothing. Nothing at all. So first thing I did was look up instructions for uploading a new firmware (one that I knew worked) using tftp. No luck, the router responds to pings for about 2 seconds immediately after booting but then ceases to respond. This was a good sign at least, means some basic features were still working properly. Also discovered that because Windows 7 implements CTCP instead of a simpler TCP protocol this breaks most ability to upload new firmware via tftp. So I downloaded an atftp.deb for my linux box and that didn't work either.</p>
<p>Eventually I stumbled upon an article about using a USB-TTL cable to unbrick the router. This article was mostly useless because all they were doing was using a USB serial adapter and dissecting the cable to work with the serial connection on the routers board, which I could just as easily have done with my arduino. But hidden deep in the comments was a far simpler trick than that. Only thing I needed to buy was a torx screw driver set to get the thing open. I looked up the chip used for storing settings and found that there were two pins on it that could be shorted to erase nvram (the structure responsible for storing all the router's settings).</p>
<p>So I busted open the router and proceeded to power on the router while shorting the two pins. No effect. I tried powering it on and then shorting the pins. No effect. Finally I tried shorting the pins exactly when the router responded to pings during that 1-2 second window. Success!</p>
<p>Then I fired up tftp and uploaded a modified version of Tomato to support USB and vaula! Tomato works properly on my router now. As well as the wifi client mode and wifi bridge mode. Anyway that occupied  several hours of tinkering where I would have otherwise been bored out of my mind.</p>
<ol class="footnotes"><li id="footnote_0_750" class="footnote"><a href="http://www.dd-wrt.com/">DD-WRT Firmware</a></li><li id="footnote_1_750" class="footnote"><a href="http://kb.netgear.com/app/products/model/a_id/12150">Netgear WNR3500L</a></li><li id="footnote_2_750" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16833122334">Newegg.com: Netgear WNR3500L</a></li><li id="footnote_3_750" class="footnote"><a href="http://www.polarcloud.com/tomato">Tomato Firmware</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/750/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FreeNAS Users Rejoice!</title>
		<link>http://www.bemasher.net/archives/735</link>
		<comments>http://www.bemasher.net/archives/735#comments</comments>
		<pubDate>Tue, 04 May 2010 06:06:10 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[freenas]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[Live]]></category>
		<category><![CDATA[Stick]]></category>
		<category><![CDATA[syslinux]]></category>
		<category><![CDATA[Thumbdrive]]></category>
		<category><![CDATA[unetbootin]]></category>
		<category><![CDATA[USB]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=735</guid>
		<description><![CDATA[Unetbootin[1] now supports FreeNAS! Take a look at these awesome little snippets of code: 1234567891011121314//distrolst.cpp if &#40;nameDistro == &#34;FreeNAS&#34;&#41; &#123; &#160; &#160; if &#40;isarch64&#41; &#123; &#160; &#160; &#160; &#160; cpuarch = &#34;amd64&#34;; &#160; &#160; &#125; else &#123; &#160; &#160; &#160; &#160; cpuarch = &#34;i386&#34;; &#160; &#160; &#125; &#160; &#160; instIndvfl&#40;&#34;memdisk&#34;, QString&#40;&#34;%1ubnkern&#34;&#41;.arg&#40;targetPath&#41;&#41;; &#160; &#160; if &#40;islivecd&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>Unetbootin<sup>[<a href="http://www.bemasher.net/archives/735#footnote_0_735" id="identifier_0_735" class="footnote-link footnote-identifier-link" title="http://unetbootin.sourceforge.net/">1</a>]</sup> now supports FreeNAS! Take a look at these awesome little snippets of code:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//distrolst.cpp</span><br />
<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>nameDistro <span style="color: #000080;">==</span> <span style="color: #FF0000;">&quot;FreeNAS&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>isarch64<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cpuarch <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;amd64&quot;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cpuarch <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;i386&quot;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; instIndvfl<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;memdisk&quot;</span>, QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%1ubnkern&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>targetPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>islivecd<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; downloadfile<span style="color: #008000;">&#40;</span>QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;http://downloads.sourceforge.net/sourceforge/lubi/FreeNAS-%1-LiveCD-%2.img.gz&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>cpuarch, relname<span style="color: #008000;">&#41;</span>, QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%1ubninit&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>targetPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; downloadfile<span style="color: #008000;">&#40;</span>QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;http://sourceforge.net/projects/freenas/files/stable/0.7/FreeNAS-%1-embedded-%2.img/download&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>cpuarch, relname<span style="color: #008000;">&#41;</span>, QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%1ubninit&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>targetPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//distrover.cpp</span><br />
distroselect<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>addItem<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;FreeNAS&quot;</span>, <span style="color: #008000;">&#40;</span>QStringList<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.4919&quot;</span> <span style="color: #000080;">&lt;&lt;</span><br />
unetbootin<span style="color: #008080;">::</span><span style="color: #007788;">tr</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&lt;b&gt;Homepage:&lt;/b&gt; &lt;a href=<span style="color: #000099; font-weight: bold;">\&quot;</span>http://freenas.org/<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;http://www.freenas.org&lt;/a&gt;&lt;br/&gt;&quot;</span><br />
&nbsp; &nbsp; <span style="color: #FF0000;">&quot;&lt;b&gt;Description:&lt;/b&gt; FreeNAS is an embedded open source NAS (Network-Attached Storage) distribution based on FreeBSD.&lt;br/&gt;&quot;</span><br />
&nbsp; &nbsp; <span style="color: #FF0000;">&quot;&lt;b&gt;Install Notes:&lt;/b&gt; The LiveCD version creates a RAM drive for FreeNAS, and uses a FAT formatted floppy disk or USB key for saving the configuration file. The embedded version allows installation to hard disk.&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span><br />
<span style="color: #FF0000;">&quot;0.7.4919&quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.4919_x64&quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.1.5024_Live&quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.1.4997_Live_x64&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p>Segue:<br />
I'm actually considering forking the unetbootin project to add support for a master distro list which can be updated remotely eliminating the requirement for users to download a new copy of the program if they wish to get the latest version of the list of pre-configured distros.</p>
<p>This has a little bit to do with the fact that I'll be required to take a few C++ courses at the University of Wyoming since Java is the standard language taught at the University of Arizona while I was there and I've never used C++ before. Can't be that hard right?</p>
<ol class="footnotes"><li id="footnote_0_735" class="footnote"><a href="http://unetbootin.sourceforge.net/">http://unetbootin.sourceforge.net/</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/735/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
