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

<channel>
	<title>Everett&#039;s Projects</title>
	<atom:link href="http://everettsprojects.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://everettsprojects.com</link>
	<description>A place to present the useless things I do in my spare time</description>
	<lastBuildDate>Mon, 17 Jun 2013 13:55:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='everettsprojects.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Everett&#039;s Projects</title>
		<link>http://everettsprojects.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://everettsprojects.com/osd.xml" title="Everett&#039;s Projects" />
	<atom:link rel='hub' href='http://everettsprojects.com/?pushpress=hub'/>
		<item>
		<title>Designing a secure(ish) login script with PHP and MySQL</title>
		<link>http://everettsprojects.com/2013/02/17/designing-a-secureish-login-script-with-php-and-mysql/</link>
		<comments>http://everettsprojects.com/2013/02/17/designing-a-secureish-login-script-with-php-and-mysql/#comments</comments>
		<pubDate>Sun, 17 Feb 2013 20:53:15 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[login script]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Server]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=667</guid>
		<description><![CDATA[If you just want to see the final product in action, then you can click here. If you want the source code right away, click here. This project has taken me much longer to complete than I originally expected it would. I guess I just wanted to make sure that it functioned in a sane [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=667&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://ejrob.files.wordpress.com/2013/02/login.png"><img class="aligncenter size-large wp-image-788" alt="Login" src="http://ejrob.files.wordpress.com/2013/02/login.png?w=594&#038;h=300" width="594" height="300" /></a></p>
<p style="text-align:center;"><a href="http://everett.x10.mx/phplogin/">If you just want to see the final product in action, then you can click here.</a></p>
<p style="text-align:center;"><a href="http://everett.x10.mx/phplogin/phpLogin.zip">If you want the source code right away, click here.</a></p>
<p>This project has taken me much longer to complete than I originally expected it would. I guess I just wanted to make sure that it functioned in a sane and relatively secure manner. I usually don&#8217;t feel compelled to reinvent the wheel, but I wanted a good project that I could use to learn PHP and MySQL, and a login script turns out to be a solid project which incorporates all of that. I set out to make sure my login script wasn&#8217;t a piece of junk by design, which means that I did a little research to make sure I wasn&#8217;t doing anything inherently insecure. This doesn&#8217;t mean that it is secure, and I really wouldn&#8217;t recommend using my scripts in an actual project, since they are not rigorously tested. Furthermore, because I am too cheap to pay for a proper webhost, my site has no SSL certificate and hence no HTTPS, which is a major security hole. If someone happened to eavesdrop on your connection they could easily steal your session or your password. For this reason, it is a good idea to not register on my example page using credentials that you&#8217;ve used in other places. This is also why I decided to call my project secureish in the title. Regardless of these potential issues, I am pleased with the final result, which incorporates all of the following:</p>
<p><strong>Principles:</strong></p>
<ul>
<li><span style="line-height:13px;">Never store passwords in plaintext</span></li>
<li>Store DB login credentials in a config file to be required when needed</li>
<li>Don&#8217;t send passwords in plain sight: Use POST instead of GET so that they&#8217;re not in the URL</li>
<li>Use a secure hashing algorithm and always use salt
<ul>
<li>bcrypt/blowfish</li>
</ul>
</li>
<li>Secure from SQL injection by sanitizating user input via prepare with <em>PHP Data Objects</em> (PDO)
<ul>
<li>Use PDO instead of MySQL extension which is supposed to be deprecated eventually</li>
</ul>
</li>
<li>Incorporate session control</li>
<li><span style="color:#333333;">Change Password option</span></li>
<li><span style="color:#333333;">A means of recovering the account with a one time use URL sent to email the account was registered with</span>
<ul>
<li><span style="color:#333333;">Expires after a short period</span></li>
<li><span style="color:#333333;">Expires after use</span></li>
</ul>
</li>
<li>Have forms return meaningful error messages if input is not valid</li>
<li>Preserve data that a user has entered into a form in the event an issue occurs during registration. Having to re-enter the entire form always sucks</li>
<li>Make the forms and pages look vaguely modern: not something that passed off as okay in 1996.
<ul>
<li>Placeholders.js is used to make the placeholder attributes work in older or useless browsers like Internet Explorer.</li>
</ul>
</li>
</ul>
<p><strong>Features it could have, but I didn&#8217;t bother implementing:</strong></p>
<ul>
<li><span style="line-height:13px;">Email verification of account to prevent lots of spam accounts from cluttering up the users table in the database</span></li>
<li>JavaScript mechanism to tell the user in real time if their username or email is already taken right on the registration form</li>
</ul>
<p><strong>The code and how it works:</strong></p>
<p>If you just want the source code, <a href="http://everett.x10.mx/phplogin/phpLogin.zip">I have them all zipped up and ready to go</a>. The config.inc.php and request_reset.php files will need to be updated with your own site specific information, such as base URLs and database login credentials.</p>
<p>Because it would take a lot of words to describe the interactions between all of the files, I&#8217;ve decided to condense that information into a flow chart. The index.php page is assumed to be the starting point and coloured blue to reflect this.</p>
<p><a href="http://ejrob.files.wordpress.com/2013/02/flowchart3.png"><img class="aligncenter size-large wp-image-807" alt="flowchart" src="http://ejrob.files.wordpress.com/2013/02/flowchart-coloured.png?w=594&#038;h=459" width="594" height="459" /></a></p>
<p>I have left a few of the files out of the flow chart so it didn&#8217;t get too busy. These are the config.inc.php which stores the credentials necessary to access the database, the logout.php page, and the cron_purge.php file which removes time expired password reset tokens from the table that contains them. I have the cron job set up to run every hour.</p>
<p>Normally I would use the source code tags to post my code directly on this blog, but there are a lot of files required to make this work, and I feel that posting the source code for each one of them directly to this blog with the source code tags will be far too cluttered. Hopefully it isn&#8217;t any great inconvenience to download the zip file containing all of the code, and if it is then you have my apologies.</p>
<p>Once you have all of the files, it is necessary to set up the MySQL database. I am assuming your server or webhost already has this installed and that a database user has already been created. All we need to do in that case then, is create our tables. There are two tables, the users table which stores emails, usernames, and password hashes, and the passwordReset table which manages the tokens used to reset a forgotten password.</p>
<p>To create the users table, enter the following query using phpMyAdmin or an equivalent tool:</p>
<blockquote><p>CREATE TABLE `users` (<br />
`id` int(11) NOT NULL AUTO_INCREMENT,<br />
`username` varchar(32) NOT NULL,<br />
`email` varchar(254) NOT NULL,<br />
`password_hash` varchar(64) NOT NULL,<br />
PRIMARY KEY (`id`),<br />
UNIQUE KEY `username` (`username`),<br />
UNIQUE KEY `email` (`email`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=latin1</p></blockquote>
<p>To create the passwordReset table, we simply enter this query the same way we did for the users table:</p>
<blockquote><p>CREATE TABLE `passwordReset` (<br />
`userid` int(11) NOT NULL,<br />
`UUID` varchar(32) NOT NULL,<br />
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,<br />
PRIMARY KEY (`userid`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=latin1</p></blockquote>
<p>And that&#8217;s all there is too it. If you have those PHP files in a public directory of your web server and the tables created in MySQL,then you should be good to go.</p>
<p>Lastly, I&#8217;ve done my best to make this site look nice on a variety of browsers on multiple operating systems (Various combinations of Chrome, Firefox, Internet Explorer, and Opera on any one of Linux, Windows and Mac OS X for those who are interested), but consistency in rendering can be a real problem. I make no guarantees that it will look just right in any particular browser or operating system.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/667/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/667/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=667&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2013/02/17/designing-a-secureish-login-script-with-php-and-mysql/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2013/02/login.png?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2013/02/login.png?w=150" medium="image">
			<media:title type="html">Login</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2013/02/login.png?w=594" medium="image">
			<media:title type="html">Login</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2013/02/flowchart-coloured.png?w=594" medium="image">
			<media:title type="html">flowchart</media:title>
		</media:content>
	</item>
		<item>
		<title>Arduino: Super Graphing Data Logger</title>
		<link>http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/</link>
		<comments>http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/#comments</comments>
		<pubDate>Mon, 31 Dec 2012 07:39:39 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sensors and Data Logging]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[data logging]]></category>
		<category><![CDATA[ethernet]]></category>
		<category><![CDATA[Highcharts]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[javaScript]]></category>
		<category><![CDATA[Photosensor]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=670</guid>
		<description><![CDATA[Sections: Introduction The Results How to Make One For Yourself HC.htm EEPROM_config SGDL Introduction What is the Super Graphing Data Logger (SGDL)? It is an Arduino project that integrates data logging and the graphing of this data online using little more than an Arduino with the appropriate shields and sensors. &#160; It differs from similar [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=670&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p style="text-align:left;"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/zoomeddaylight/" rel="attachment wp-att-714"><img class="size-large wp-image-714 aligncenter" alt="The intensity of natural light in my basement." src="http://ejrob.files.wordpress.com/2012/12/zoomeddaylight.png?w=594&#038;h=210" width="594" height="210" /></a><br />
<strong>Sections:</strong></p>
<ol>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#results">The Results</a></li>
<li><a href="#gettingStarted">How to Make One For Yourself</a>
<ul>
<li><a href="#HChtm">HC.htm</a></li>
<li><a href="#EEPROM">EEPROM_config</a></li>
<li><a href="#SGDL">SGDL</a></li>
</ul>
</li>
</ol>
<div id="introduction">
</p>
<p><strong>Introduction</strong></p>
<p>What is the Super Graphing Data Logger (SGDL)? It is an Arduino project that integrates data logging and the graphing of this data online using little more than an Arduino with the appropriate shields and sensors. &nbsp; It differs from similar projects in that it doesn&#8217;t require a separate server or system to collect the data or to run script for the actual plot. Between the Arduino and the user&#8217;s browser, everything is taken care of. </p>
<p>Some time back I came across this neat javaScript based library for plotting and graphing called Highcharts JS. It didn&#8217;t take long for me to realize that charting with javaScript is very convenient for projects in which the server is limited in it&#8217;s capabilities, such as when using an Arduino with the Ethernet shield. Since the user&#8217;s browser does all the heavy lifting, the Arduino only needs to serve the files which is something it is perfectly capable of. This is especially true now that the Ethernet and SD libraries included in 1.0 support opening of multiple files simultaneously amongst other things.&nbsp;Thus the use of Highcharts allows us to create beautiful interactive charts based on data logged by the Arduino using nothing but the Arduino (and your browser, and a public javaScript CDN).
</p></div>
<div id="results">
</p>
<p><strong>The Results</strong></p>
<p>The best way to appreciate the final product is to actually&nbsp;play with it. While I&#8217;m not going to open up my home network and Arduino to the big wide internet, I have mirrored the pages and datafiles it produces on the webhost I used for my <a title="Has the world ended yet? A first attempt at web&nbsp;development" href="http://everettsprojects.com/2012/12/16/has-the-world-ended-yet-a-first-attempt-at-web-development/">Has the World Ended Yet?</a> project. <strong><span style="color:#ff9900;"><a href="http://everett.x10.mx/SGDL/index.html"><span style="color:#ff9900;">You can find them here</span></a></span></strong>. These won&#8217;t be updated with new datapoints like the actual Arduino version will be, but they should at least give a fair impression of how the project looks and feels without the need to actually implement it.</p>
<p>For those who are unsure what they are looking at, I&#8217;ll offer a quick interpretation:</p>
<div id="attachment_717" class="wp-caption aligncenter" style="width: 428px"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/fileslist-2/" rel="attachment wp-att-717"><img class="size-full wp-image-717" alt="The list of data files available for graphing." src="http://ejrob.files.wordpress.com/2012/12/fileslist1.png?w=594"   /></a><p class="wp-caption-text">The list of data files available for graphing.</p></div>
<p>Going to the above page, we see that we are presented with a very basic list of the data files that can be selected from. Clicking any of them will cause &nbsp;the graph for that datafile to be loaded (much more quickly than the Arduino can manage).</p>
<div id="attachment_713" class="wp-caption aligncenter" style="width: 604px"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/wholechart/" rel="attachment wp-att-713"><img class="size-large wp-image-713" alt="A graph for the first week of data collected." src="http://ejrob.files.wordpress.com/2012/12/wholechart.png?w=594&#038;h=208" width="594" height="208" /></a><p class="wp-caption-text">A graph for the first week of data collected.</p></div>
<p>This chart for the 25-12-12.CSV file is already complete, and won&#8217;t have any new data added to it in the future, because the files for subsequent weeks have already been made. There is a lot to see though. The two data points that are at 1000 on the y-axis are from when I pointed a bright flashlight directly at the photo sensor. All of the data points between 300 and 400 on the y-axis are the result of the basement lights being on. The abnormally large gaps in the data are periods when the Arduino was powered off because I was still tweaking and developing it. Finally, the short humps that occur everyday are the result of natural light&nbsp;coming&nbsp;through one of the basement windows. By zooming in on one of them, we can see even more detail:</p>
<div id="attachment_714" class="wp-caption aligncenter" style="width: 604px"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/zoomeddaylight/" rel="attachment wp-att-714"><img class="size-large wp-image-714" alt="The intensity of natural light in my basement." src="http://ejrob.files.wordpress.com/2012/12/zoomeddaylight.png?w=594&#038;h=210" width="594" height="210" /></a><p class="wp-caption-text">The intensity of natural light in my basement.</p></div>
<p>The first thing we notice is that the levels rise from zero to about 65 before falling and&nbsp;levelling&nbsp;out at close to 35 for two hours. This is followed by a another small increase before it ultimately decreases down to a value of ~10 where it levels out. That middle valley where the light levels are equal to 35 is due to the shadow cast &nbsp;on the basement window by our neighbour&#8217;s house to the south of us. The levelling out of the light intensity at 10 after all the daylight has&nbsp;disappeared&nbsp;is because a light out in the hallway is usually on in the evening. It is eventually turned off for the night, causing the light levels to drop to zero where they will usually remain until the next morning. I must admit, I&#8217;m impressed that the cheap $1.00 photoresistor is capable of capturing this level of detail, and that these trends are so easily interpreted from the graphs.
</p></div>
<div id="gettingStarted">
</p>
<p><strong>How to Make One For Yourself</strong></p>
<p>To replicate this project, a few things are necessary. You&#8217;ll obviously need an Arduino capable of connecting over Ethernet and storing files on an SD card. In my case, this is achieved through the use of an Uno with the <a href="http://www.arduino.cc/en/Main/ArduinoEthernetShield">Ethernet shield</a>. Presumably an <a href="http://arduino.cc/en/Main/ArduinoBoardEthernet">Arduino Ethernet model</a>&nbsp;will also work fine, though I have not personally tested it. Other non official Ethernet shields and SD card adapters may also work if they use the same libraries, though I make no&nbsp;guarantees. For the more adventurous, it may be possible to adapt my code to achieve the same functionality using a <a href="http://arduino.cc/en/Main/ArduinoWiFiShield">Wifi shield</a>. You will also need a data source of some sort. For my project I chose to use a very cheap photoresistor, which I rigged up on a <a href="https://www.sparkfun.com/products/8886">small perf board</a> to plug directly into the 5v, gnd, and A0 pins of my Arduino (or more precisely, &nbsp;the headers on the Ethernet shield). It is set up in such a way that the minimum recordable light intensity is zero, while the maximum is 1024.</p>
<table>
<tbody>
<tr>
<td>
<p><div id="attachment_677" class="wp-caption aligncenter" style="width: 310px"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/dscf2941/" rel="attachment wp-att-677"><img class="size-medium wp-image-677 " alt="The photo sensor board fits like a charm." src="http://ejrob.files.wordpress.com/2012/12/dscf2941.jpg?w=300&#038;h=225" width="300" height="225" /></a><p class="wp-caption-text">The photo sensor board fits like a charm.</p></div></td>
<td>
<p><div id="attachment_675" class="wp-caption aligncenter" style="width: 222px"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/dscf2931/" rel="attachment wp-att-675"><img class=" wp-image-675        " alt="DSCF2931" src="http://ejrob.files.wordpress.com/2012/12/dscf2931.jpg?w=212&#038;h=225" width="212" height="225" /></a><p class="wp-caption-text">One header is bent to reach A0.</p></div></td>
</tr>
</tbody>
</table>
<p>The pins on the male headers don&#8217;t quite line up, so I intentionally used extra long ones and added a slight S-curve to the one that goes to A0. This can be seen in better detail above. For those who are interested, the circuit is very simple:</p>
<div id="attachment_691" class="wp-caption aligncenter" style="width: 310px"><a href="http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/circuit/" rel="attachment wp-att-691"><img class="size-medium wp-image-691 " alt="The circuit." src="http://ejrob.files.wordpress.com/2012/12/circuit.jpg?w=300&#038;h=290" width="300" height="290" /></a><p class="wp-caption-text">The circuit.</p></div>
<p>Before we get started, we need to make sure our SD card is good to go. It should be formatted as a FAT16 or FAT32 filesystem, <a href="http://arduino.cc/en/Reference/SDCardNotes">the details of which are available on the official Arduino website</a>. Once that is done, we need to ensure two things are present in the root directory of the card: the HC.htm file, and a data/ directory for our datafiles. The data directory is easily made with the same computer that was used to format the card provided one has an SD card reader of some sort. The HC.htm simply consists of the following code:</p>
<div id="HChtm">
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
        &lt;title&gt;Super Graphing Data Logger!&lt;/title&gt;

        &lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js&quot;&gt;&lt;/script&gt;
        &lt;script type=&quot;text/javascript&quot;&gt;
function getDataFilename(str){
    point = str.lastIndexOf(&quot;file=&quot;)+4;

    tempString = str.substring(point+1,str.length)
    if (tempString.indexOf(&quot;&amp;&quot;) == -1){
    return(tempString);
    }
    else{
        return tempString.substring(0,tempString.indexOf(&quot;&amp;&quot;));
    }
        
}

query  = window.location.search;

var dataFilePath = &quot;/data/&quot;+getDataFilename(query);

$(function () {
    var chart;
    $(document).ready(function() {
    
        // define the options
        var options = {
    
            chart: {
                renderTo: 'container',
                zoomType: 'x',
                spacingRight: 20
            },
    
            title: {
                text: 'Light levels recorded by the Arduino'
            },
    
            subtitle: {
                text: 'Click and drag in the plot area to zoom in'
            },
    
            xAxis: {
                type: 'datetime',
                maxZoom: 2 * 3600000
            },
    
            yAxis: {
                title: {
                    text: 'Light Levels (0 - 1024)'
                },
                min: 0,
                startOnTick: false,
                showFirstLabel: false
            },
    
            legend: {
                enabled: false
            },
    
            tooltip: {
                formatter: function() {
                        return '&lt;b&gt;'+ this.series.name +'&lt;/b&gt;&lt;br/&gt;'+
                        Highcharts.dateFormat('%H:%M - %b %e, %Y', this.x) +': '+ this.y;
                }
            },
    
            plotOptions: {
                series: {
                    cursor: 'pointer',
                    lineWidth: 1.0,
                    point: {
                        events: {
                            click: function() {
                                hs.htmlExpand(null, {
                                    pageOrigin: {
                                        x: this.pageX,
                                        y: this.pageY
                                    },
                                    headingText: this.series.name,
                                    maincontentText: Highcharts.dateFormat('%H:%M - %b %e, %Y', this.x) +':&lt;br/&gt; '+
                                        this.y,
                                    width: 200
                                });
                            }
                        }
                    },
                }
            },
    
            series: [{
                name: 'Light Levels',
                marker: {
                    radius: 2
                }
            }]
        };
    
    
        // Load data asynchronously using jQuery. On success, add the data
        // to the options and initiate the chart.
        // http://api.jquery.com/jQuery.get/
        jQuery.get(dataFilePath, null, function(csv, state, xhr) {
            var lines = [],
                date,
    
                // set up the two data series
                lightLevels = [];
    
            // inconsistency
            if (typeof csv !== 'string') {
                csv = xhr.responseText;
            }
    
            // split the data return into lines and parse them
            csv = csv.split(/\n/g);
            jQuery.each(csv, function(i, line) {
    
                // all data lines start with a double quote
                line = line.split(',');
                date = parseInt(line[0], 10)*1000;
    
                lightLevels.push([
                    date,
                    parseInt(line[1], 10)
                ]);
                
            });
    
            options.series[0].data = lightLevels;
    
            chart = new Highcharts.Chart(options);
        });
    });
    
});
        &lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;p style=&quot;text-align:center;&quot;&gt;Please allow the chart to load, it may take up to 30 seconds &lt;/p&gt;
        &lt;hr/&gt;
&lt;script src=&quot;http://cdnjs.cloudflare.com/ajax/libs/highcharts/2.3.5/highcharts.js&quot;&gt;&lt;/script&gt;

&lt;!-- Additional files for the Highslide popup effect --&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.highcharts.com/highslide/highslide-full.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.highcharts.com/highslide/highslide.config.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;http://www.highcharts.com/highslide/highslide.css&quot; /&gt;

&lt;div id=&quot;container&quot; style=&quot;min-width: 400px; height: 400px; margin: 0 auto&quot;&gt;&lt;/div&gt;

    &lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
<p>You will need to edit this file first to make sure it points towards the preferred &nbsp;location of your highcharts.js files. You can leave this as the public CDN: <a href="http://cdnjs.cloudflare.com/ajax/libs/highcharts/2.3.5/highcharts.js">http://cdnjs.cloudflare.com/ajax/libs/highcharts/2.3.5/highcharts.js</a>, change it to point towards your own webhost, or it&nbsp;can even be on the Arduino&#8217;s SD card (this will be slow). It is not necessary to create a datafile before hand, the SGDL sketch will take care of that when it decides to record its first data point. Before we get that far though, it is necessary to make sure we have configured the EEPROM memory for the SGDL sketch. This is very easily accomplished using a separate sketch, which I have called EEPROM_config. This sketch (along with SGDL itself) requires an extra library called <a href="http://playground.arduino.cc/Code/EEPROMWriteAnything">EEPROMAnything</a>, which needs to be added to the Arduino&#8217;s libraries folder wherever one&#8217;s sketchbook folder is. While you&#8217;re at it, you should also add the <a href="http://playground.arduino.cc/Code/Time">Time library</a> which we need for SGDL.</p>
<div id="EEPROM">
<pre class="brush: cpp; title: ; notranslate">
/* ************************************************************************
 * ***            Super Graphing Data Logger - EEPROM config            ***
 * ************************************************************************
 * Everett Robinson, December 2012.
 *
 * The following extra non standard libraries were used, and will need to be
 * added to the libraries folder:
 * - EEPROMAnything: http://playground.arduino.cc/Code/EEPROMWriteAnything
 *
 * This sketch helps you set the values in EEPROM which are necessary for
 * Super Graphing Data Logger. It should only need the be run once before
 * the first time you set up SGDL, or in the unlikely event that the EEPROM
 * becomes corrupted.
 *
 * Please ensure that the values in configuration config are appropriate for
 * your project before uncommenting the EEPROM_writeAnything(0, config); line.
 *
 */

#include &lt;EEPROM.h&gt;
#include &lt;EEPROMAnything.h&gt;

typedef struct{
    unsigned long newFileTime;
    char workingFilename[19];
  } configuration;

//This is a one off thing, so everything is in setup
void setup(){
  Serial.begin(9600);
  
  //Create the config struct to write to EEPROM, change values as appropriate
  //Make sure your filename is not too long for the workingFilename char array 
  configuration config = {1356912000L,&quot;/data/25-12-12.csv&quot;};
  //Write the values to the EEPROM
  //EEPROM_writeAnything(0, config);       //Uncomment when you're sure everything is correct
  configuration config2;                   //Create a second config struct for verification
  EEPROM_readAnything(0,config2);
  Serial.print(&quot;The value read from EEPROM for newFileTime is: &quot;);
  Serial.println(config2.newFileTime);
  Serial.print(&quot;The value read from EEPROM for workingFilename is: &quot;);
  Serial.println(config2.workingFilename);
  Serial.println(&quot;If those values are correct then everything went as planned. Otherwise,&quot;);
  Serial.println(&quot;please double check that the values declared for the struct config are&quot;);
  Serial.println(&quot;correct and that that EEPROM_writeAnything line is uncommented.&quot;);
}


void loop(){
}
</pre>
</div>
<p>I have intentionally commented out the write line so that no one&nbsp;writes junk to the EEPROM by accident. While the EEPROM has a life of ~100,000 write cycles, I&#8217;d rather not waste any of them. Please review the sketch carefully and ensure you&#8217;ve adjusted it accordingly before uploading it to the Arduino. The most important thing is to ensure that your newFileTime is something sensible (in the near future most of all).</p>
<p>Now that that&#8217;s all taken care of, we&#8217;re ready to get SGDL all set up! The code will need a few adjustments for your own specific setup, mostly in regards to the Ethernet MAC and IP addresses. I trust that anyone making use of this code already knows how to configure their router to work with the Arduino, and that they can find the appropriate local IP address to update this sketch with.&nbsp;You may also wish to change the timeserver IP address to one that is geographically closer to yourself.</p>
<p>I currently have my code set up to make a measurement every 10 minutes, and to create a new data file every week. You are welcome to change those parameters, just be aware that the current data file management names files using a dd-mm-yy.csv date format, so the new file interval should be at least 24 hours. Another concern, is that the shorter the measurement interval and the longer the new data file interval is, the larger the files will be. Because the Arduino is not especially powerful, this will have consequences for the loading times of each chart.</p>
<div id="SGDL">
<pre class="brush: cpp; title: ; notranslate">
/* ************************************************************************
 * ***                    Super Graphing Data Logger                    ***
 * ************************************************************************
 * Everett Robinson, December 2012. More at: http://everettsprojects.com
 *
 * This sketch relies on the SD and ethernet libraries in arduino 1.0 or newer.
 * The following extra non standard libraries were also used, and will need to
 * be added to the libraries folder:
 * - Time: http://playground.arduino.cc/Code/Time
 * - EEPROMAnything: http://playground.arduino.cc/Code/EEPROMWriteAnything
 *
 * If this is your first time setting up this project, please go get the
 * EEPROM_config sketch from http://everettsprojects.com so that you can 
 * configure the config struct in the EEPROM memory. Usage of the EEPROM 
 * is needed to make the project resiliant against a temporary loss of power.
 *
 * You must also ensure that you have the HC.htm file in the root directory
 * of your SD card, as well as a data directory where the datafiles will be
 * stored.
 *
 * This sketch combines the functionality of an existing fileserver example
 * which can be found at http://www.ladyada.net/learn/arduino/ethfiles.html
 * with the Datalogger example that comes with the new SD library from 1.0,
 * as well as some code from the UdpNtpClient example that cones with the
 * ethernet library. 
 *
 * Added to all of these are some tricks to make it manage and serve up the
 * datafiles in conjunction with a page which uses highcharts JS to graph it.
 * This is basically accomplished using the arduino by itself. Because I
 * actually host the highcharts.js files externally, this is true more in
 * theory than in actual practice, but oh well. It should work just fine to
 * have the highcharts.js file on the arduino's SD card, though loading the 
 * page will be painfully slow.
 *
 * Some of the code this was derived from may or may not be under a GPL
 * licence; I'm not entirely sure. I suppose anyone using this should treat 
 * it like it is too, but I don't really care too much.
 * Also if one intends to use this for commercial applications, it may be
 * necessary to purchase a license for Highcharts.
 *
 * Changes:   -------------------------------------------------------------
 * January 2013: Updated so that the dd-mm-yy.csv file format is properly 
 * followed, all single digit days, months, and years will have a leading 
 * zero now. 
 *
 */

#include &lt;SD.h&gt;
#include &lt;Ethernet.h&gt;
#include &lt;EthernetUdp.h&gt;
#include &lt;SPI.h&gt;
#include &lt;string.h&gt;
#include &lt;Time.h&gt;
#include &lt;EEPROM.h&gt;
#include &lt;EEPROMAnything.h&gt;
#include &lt;avr/pgmspace.h&gt;

/************ ETHERNET STUFF ************/
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x4C, 0x64 };
byte ip[] = { 192,168,1, 100 };
EthernetServer server(80);

/************** NTP STUFF ***************/
unsigned int localPort = 8888;          // local port to listen for UDP packets
IPAddress timeServer(132, 163, 4, 101); //NIST time server IP address: for more info
                                        //see http://tf.nist.gov/tf-cgi/servers.cgi

const int NTP_PACKET_SIZE= 48; //NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
EthernetUDP Udp;

/*** DATA LOGGER AND TIMER CONTROLS ****/
const int analogPin = 0;
unsigned long lastIntervalTime = 0; //The time the last measurement occured.
#define MEASURE_INTERVAL 600000     //10 minute intervals between measurements (in ms)
unsigned long newFileTime;          //The time at which we should create a new week's file
#define FILE_INTERVAL 604800        //One week worth of seconds

//A structure that stores file config variables from EEPROM
typedef struct{                     
    unsigned long newFileTime;      //Keeps track of when a newfile should be made.
    char workingFilename[19];       //The path and filename of the current week's file
} configuration;
  
configuration config;               //Actually make our config struct


// Strings stored in flash mem for the Html Header (saves ram)
prog_char HeaderOK_0[] PROGMEM = &quot;HTTP/1.1 200 OK&quot;;            //
prog_char HeaderOK_1[] PROGMEM = &quot;Content-Type: text/html&quot;;    //
prog_char HeaderOK_2[] PROGMEM = &quot;&quot;;                           //

// A table of pointers to the flash memory strings for the header
PROGMEM const char *HeaderOK_table[] = {   
  HeaderOK_0,
  HeaderOK_1,
  HeaderOK_2
};

// A function for reasy printing of the headers  
void HtmlHeaderOK(EthernetClient client) {
  
    char buffer[30]; //A character array to hold the strings from the flash mem
    
    for (int i = 0; i &lt; 3; i++) {
      strcpy_P(buffer, (char*)pgm_read_word(&amp;(HeaderOK_table[i]))); 
      client.println( buffer );
    }
} 
  
  
// Strings stored in flash mem for the Html 404 Header
prog_char Header404_0[] PROGMEM = &quot;HTTP/1.1 404 Not Found&quot;;     //
prog_char Header404_1[] PROGMEM = &quot;Content-Type: text/html&quot;;    //
prog_char Header404_2[] PROGMEM = &quot;&quot;;                           //
prog_char Header404_3[] PROGMEM = &quot;&lt;h2&gt;File Not Found!&lt;/h2&gt;&quot;; 

// A table of pointers to the flash memory strings for the header
PROGMEM const char *Header404_table[] = {   
  Header404_0,
  Header404_1,
  Header404_2,
  Header404_3
};

// Easy peasy 404 header function
void HtmlHeader404(EthernetClient client) {
  
    char buffer[30]; //A character array to hold the strings from the flash mem
    
    for (int i = 0; i &lt; 4; i++) {
      strcpy_P(buffer, (char*)pgm_read_word(&amp;(Header404_table[i]))); 
      client.println( buffer );
    }
} 


void setup() {
  Serial.begin(9600);
  
  pinMode(10, OUTPUT);          // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);       // but turn off the W5100 chip! 
  
  // see if the card is present and can be initialized:
  if (!SD.begin(4)) {
    Serial.println(&quot;Card failed, or not present&quot;);
    // don't do anything more:
    return;
  }
  Serial.println(&quot;card initialized.&quot;);
  
  // The SD card is working, start the server and ethernet related stuff!
  Ethernet.begin(mac, ip);
  server.begin();
  Udp.begin(localPort);
  EEPROM_readAnything(0,config); // make sure our config struct is syncd with EEPROM
}


// A function that takes care of the listing of files for the
// main page one sees when they first connect to the arduino.
// it only lists the files in the /data/ folder. Make sure this
// exists on your SD card.
void ListFiles(EthernetClient client) {
  
  File workingDir = SD.open(&quot;/data&quot;);
  
  client.println(&quot;&lt;ul&gt;&quot;);
  
    while(true) {
      File entry =  workingDir.openNextFile();
       if (! entry) {
         break;
       }
       client.print(&quot;&lt;li&gt;&lt;a href=\&quot;/HC.htm?file=&quot;);
       client.print(entry.name());
       client.print(&quot;\&quot;&gt;&quot;);
       client.print(entry.name());
       client.println(&quot;&lt;/a&gt;&lt;/li&gt;&quot;);
       entry.close();
    }
  client.println(&quot;&lt;/ul&gt;&quot;);
  workingDir.close();
}

// A function to get the Ntp Time. This is used to make sure that the data
// points recorded by the arduino are referenced to some meaningful time
// which in our case is UTC represented as unix time (choosen because it 
// works simply with highcharts without too much unecessary computation).
unsigned long getTime(){
  sendNTPpacket(timeServer); // send an NTP packet to a time server

  // wait to see if a reply is available
  delay(1000);  
  if ( Udp.parsePacket() ) {  
    // We've received a packet, read the data from it
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord &lt;&lt; 16 | lowWord;  
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;  
    // return Unix time:
    return epoch;
  }
}

// send an NTP request to the time server at the given address,
// necessary for getTime().
unsigned long sendNTPpacket(IPAddress&amp; address){
  
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay &amp; Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:         
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}


// How big our line buffer should be for sending the files over the ethernet.
// 75 has worked fine for me so far.
#define BUFSIZ 75

void loop(){
  if ((millis() % lastIntervalTime) &gt;= MEASURE_INTERVAL){ //Is it time for a new measurement?
     
    char dataString[20] = &quot;&quot;;
    int count = 0;
    unsigned long rawTime;
    rawTime = getTime();

    while((rawTime == 39) &amp;&amp; (count &lt; 12)){     //server seems to send 39 as an error code
      delay(5000);                              //we want to retry if this happens. I chose
      rawTime = getTime();                      //12 retries because I'm stubborn/persistent.
      count += 1;                               //NIST considers retry interval of &lt;4s as DoS
    }                                           //attack, so fair warning.
    
    if (rawTime != 39){                         //If that worked, and we have a real time
      
      //Decide if it's time to make a new file or not. Files are broken
      //up like this to keep loading times for each chart bearable.
      //Lots of string stuff happens to make a new filename if necessary.
      if (rawTime &gt;= config.newFileTime){
        int dayInt = day(rawTime);
        int monthInt = month(rawTime);
        int yearInt = year(rawTime);
        char newFilename[18] = &quot;&quot;;
        char dayStr[3];
        char monthStr[3];
        char yearStr[5];
        char subYear[3];
        strcat(newFilename,&quot;data/&quot;);
        itoa(dayInt,dayStr,10);
        if (dayInt &lt; 10){
          strcat(newFilename,&quot;0&quot;);
        }
        strcat(newFilename,dayStr);
        strcat(newFilename,&quot;-&quot;);
        itoa(monthInt,monthStr,10);
        if (monthInt &lt; 10){
          strcat(newFilename,&quot;0&quot;);
        }
        strcat(newFilename,monthStr);
        strcat(newFilename,&quot;-&quot;);
        itoa(yearInt,yearStr,10);
        //we only want the last two digits of the year
        memcpy( subYear, &amp;yearStr[2], 3 );
        strcat(newFilename,subYear);
        strcat(newFilename,&quot;.csv&quot;);
        
        //make sure we update our config variables:
        config.newFileTime += FILE_INTERVAL;
        strcpy(config.workingFilename,newFilename);
        //Write the changes to EEPROM. Bad things may happen if power is lost midway through,
        //but it's a small risk we take. Manual fix with EEPROM_config sketch can correct it.
        EEPROM_writeAnything(0, config); 
      }
        
      //get the values and setup the string we want to write to the file
      int sensor = analogRead(analogPin);  
      char timeStr[12];
      char sensorStr[6];
      
      ultoa(rawTime,timeStr,10); 
      itoa(sensor,sensorStr,10);
      
      strcat(dataString,timeStr);
      strcat(dataString,&quot;,&quot;);
      strcat(dataString,sensorStr);
      
      //open the file we'll be writing to.
      File dataFile = SD.open(config.workingFilename, FILE_WRITE);
  
      // if the file is available, write to it:
      if (dataFile) {
        dataFile.println(dataString);
        dataFile.close();
        // print to the serial port too:
        Serial.println(dataString);
      }  
      // if the file isn't open, pop up an error:
      else {
        Serial.println(&quot;Error opening datafile for writing&quot;);
      }
    }
    else{
      Serial.println(&quot;Couldn't resolve a time from the Ntp Server.&quot;);
    }
    //Update the time of the last measurment to the current timer value
    lastIntervalTime = millis();
  }
  //No measurements to be made, make sure the webserver is available for connections.
  else{
    char clientline[BUFSIZ];
    int index = 0;
    
    EthernetClient client = server.available();
    if (client) {
      // an http request ends with a blank line
      boolean current_line_is_blank = true;
      
      // reset the input buffer
      index = 0;
      
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          
          // If it isn't a new line, add the character to the buffer
          if (c != '\n' &amp;&amp; c != '\r') {
            clientline[index] = c;
            index++;
            // are we too big for the buffer? start tossing out data
            if (index &gt;= BUFSIZ) 
              index = BUFSIZ -1;
            
            // continue to read more data!
            continue;
          }
          
          // got a \n or \r new line, which means the string is done
          clientline[index] = 0;
          
          // Print it out for debugging
          Serial.println(clientline);
          
          // Look for substring such as a request to get the root file
          if (strstr(clientline, &quot;GET / &quot;) != 0) {
            // send a standard http response header
            HtmlHeaderOK(client);
            // print all the data files, use a helper to keep it clean
            client.println(&quot;&lt;h2&gt;View data for the week of (dd-mm-yy):&lt;/h2&gt;&quot;);
            ListFiles(client);
          }
          else if (strstr(clientline, &quot;GET /&quot;) != 0) {
            // this time no space after the /, so a sub-file!
            char *filename;
            
            filename = strtok(clientline + 5, &quot;?&quot;); // look after the &quot;GET /&quot; (5 chars) but before
            // the &quot;?&quot; if a data file has been specified. A little trick, look for the &quot; HTTP/1.1&quot;
            // string and turn the first character of the substring into a 0 to clear it out.
            (strstr(clientline, &quot; HTTP&quot;))[0] = 0;
            
            // print the file we want
            Serial.println(filename);
            File file = SD.open(filename,FILE_READ);
            if (!file) {
              HtmlHeader404(client);
              break;
            }
            
            Serial.println(&quot;Opened!&quot;);
                      
            HtmlHeaderOK(client);
            
            int16_t c;
            while ((c = file.read()) &gt; 0) {
                // uncomment the serial to debug (slow!)
                //Serial.print((char)c);
                client.print((char)c);
            }
            file.close();
          }
          else {
            // everything else is a 404
            HtmlHeader404(client);
          }
          break;
        }
      }
      // give the web browser time to receive the data
      delay(1);
      client.stop();
    }
  }
}
</pre>
</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/670/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/670/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=670&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/12/31/arduino-super-graphing-data-logger/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/12/zoomeddaylight.png?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/12/zoomeddaylight.png?w=150" medium="image">
			<media:title type="html">zoomedDaylight</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/zoomeddaylight.png?w=594" medium="image">
			<media:title type="html">The intensity of natural light in my basement.</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/fileslist1.png" medium="image">
			<media:title type="html">The list of data files available for graphing.</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/wholechart.png?w=594" medium="image">
			<media:title type="html">A graph for the first week of data collected.</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/zoomeddaylight.png?w=594" medium="image">
			<media:title type="html">The intensity of natural light in my basement.</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/dscf2941.jpg?w=300" medium="image">
			<media:title type="html">The photo sensor board fits like a charm.</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/dscf2931.jpg?w=300" medium="image">
			<media:title type="html">DSCF2931</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/circuit.jpg?w=300" medium="image">
			<media:title type="html">The circuit.</media:title>
		</media:content>
	</item>
		<item>
		<title>Has the world ended yet? A first attempt at web development</title>
		<link>http://everettsprojects.com/2012/12/16/has-the-world-ended-yet-a-first-attempt-at-web-development/</link>
		<comments>http://everettsprojects.com/2012/12/16/has-the-world-ended-yet-a-first-attempt-at-web-development/#comments</comments>
		<pubDate>Mon, 17 Dec 2012 05:53:48 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Doomsday]]></category>
		<category><![CDATA[End of World]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=650</guid>
		<description><![CDATA[Despite the sheer nuttiness of it, everyone keeps going on about the end of the world as &#8220;predicted&#8221; by the Mayan calendar. National Geographic even had and entire day devoted to it. Building on that theme, I decided to make a very convenient (and pretty much useless) webpage that helps you figure out if the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=650&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Despite the sheer nuttiness of it, everyone keeps going on about the end of the world as &#8220;predicted&#8221; by the Mayan calendar. National Geographic even had and entire day devoted to it. Building on that theme, I decided to make a very convenient (and pretty much useless) <a href="http://everett.x10.mx/end-of-the-world.php">webpage</a> that helps you figure out if the world has in fact ended: <a href="http://everett.x10.mx/end-of-the-world.php">http://everett.x10.mx/end-of-the-world.php</a>. This project was really simple, didn&#8217;t involve a lot of code or design, and was basically thrown together over the course of an hour and a half. It turns out PHP is extremely easy if your host is already configured for it, and I&#8217;m looking forward to doing some more web development related stuff both with PHP and other languages or tools. The HTML side of the page was also relatively straightforward. I&#8217;m impressed by what&#8217;s possible design wise using modern HTML and CSS3. My inspiration on that front was this amazing site: <a href="http://www.tubalr.com/">http://www.tubalr.com/</a></p>
<p style="text-align:center;"><a href="http://everett.x10.mx/end-of-the-world.php" rel="attachment wp-att-651"><img class="size-medium wp-image-651 aligncenter" alt="screenshot" src="http://ejrob.files.wordpress.com/2012/12/screenshot.png?w=300&#038;h=180" width="300" height="180" /></a></p>
<p style="text-align:left;">It works as the page implies, by polling google.com for a response. If google is down, then it is assumed the world has ended, and the result is <span style="color:#000000;">&#8220;<span style="color:#ff0000;"><strong>Yes.</strong></span>&#8221; </span>in big red letters. The PHP that does the trick is a slightly modified version of what&#8217;s posted at the following site: <a href="http://css-tricks.com/snippets/php/check-if-website-is-available/">http://css-tricks.com/snippets/php/check-if-website-is-available/</a>. The background is not mine, but I&#8217;ve left attribution on the image, and you can find the originals here: <a href="http://m3-f.deviantart.com/gallery/?offset=24#/d3b4qgn">http://m3-f.deviantart.com/gallery/?offset=24#/d3b4qgn</a>.</p>
<p style="text-align:left;">And because I see no reason not to release it, here is the entire source code for the page:</p>
<pre class="brush: php; title: ; notranslate">
 &lt;?php
   function Visit($url){
     $agent = &quot;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)&quot;;$ch=curl_init();
     curl_setopt ($ch, CURLOPT_URL,$url );
     curl_setopt($ch, CURLOPT_USERAGENT, $agent);
     curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt ($ch,CURLOPT_VERBOSE,false);
     curl_setopt($ch, CURLOPT_TIMEOUT, 5);
     curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE);
     curl_setopt($ch,CURLOPT_SSLVERSION,3);
     curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
     $page=curl_exec($ch);
     //echo curl_error($ch);
     $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     curl_close($ch);
     if($httpcode&gt;=200 &amp;&amp; $httpcode&lt;300) return true;
     else return false;
   }
   if (Visit(&quot;http://www.google.com&quot;)){
     $answer = &quot;No.&quot;;
     $colour = &quot;green&quot;;
   }
   else{
     $answer = &quot;Yes.&quot;;
     $colour = &quot;red&quot;;
   }
?&gt;

&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Has the World Ended Yet?&lt;/title&gt;
&lt;style&gt;
  a:link {color:#FFFFFF;}
  a:visited {color:#FFFFFF;}

html {
  overflow-y: scroll;
  background: url(/backgrounds/eow.jpg) no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;

}

body {
  font-family: 'Open Sans', sans-serif;
  font-size: 24px;
  color: #fff;
  padding-bottom: 20px;
}

#main
{
  text-align: center;
  margin-top: 50px;
  margin-bottom: 20px;
  background: #000;
  background: rgba(0, 0, 0, 0.85);
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  -ms-border-radius: 5px;
  -o-border-radius: 5px;
  border-radius: 5px;
  -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
  -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
  border: solid 1px #000;
  width:800px;
  margin-left:auto;
  margin-right:auto;
}
#result
{
  font-family: 'Open Sans', sans-serif;
  font-size: 112px;
  color: &lt;?=$colour?&gt;;
}

#disclaimer
{
  font-family: 'Open Sans', sans-serif;
  font-size: 12px;
  color: #fff;
  margin-top: 80px;
  margin-left: 100px;
  margin-right: 100px;
  margin-bottom: 50px;
}
&lt;/style&gt;

  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;main&quot;&gt;
        &lt;H1&gt;Has the world ended yet? &lt;sup&gt;*&lt;/sup&gt;&lt;/H1&gt;
        &lt;br&gt;
        &lt;div id=&quot;result&quot;&gt;
            &lt;b&gt; &lt;?=$answer?&gt;&lt;/b&gt;
        &lt;/div&gt;
        &lt;div id=&quot;disclaimer&quot;&gt;
            &lt;sup&gt;*&lt;/sup&gt; Does not actually check if the world has ended. Result is based on the assumption that if Google.com is not responding, the world has probably ended. &lt;br&gt;&lt;br&gt; &lt;a href=&quot;http://everettsprojects.com&quot;&gt;http://everettsprojects.com/&lt;/a&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/650/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/650/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=650&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/12/16/has-the-world-ended-yet-a-first-attempt-at-web-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/12/screenshot.png?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/12/screenshot.png?w=150" medium="image">
			<media:title type="html">screenshot</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/12/screenshot.png?w=300" medium="image">
			<media:title type="html">screenshot</media:title>
		</media:content>
	</item>
		<item>
		<title>Velo Orange Temple Bell!</title>
		<link>http://everettsprojects.com/2012/06/02/velo-orange-temple-bell/</link>
		<comments>http://everettsprojects.com/2012/06/02/velo-orange-temple-bell/#comments</comments>
		<pubDate>Sat, 02 Jun 2012 19:04:33 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Bicycles]]></category>
		<category><![CDATA[Bell]]></category>
		<category><![CDATA[LHT]]></category>
		<category><![CDATA[Surly]]></category>
		<category><![CDATA[Velo Orange]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=473</guid>
		<description><![CDATA[My Surly Long Haul Trucker has fairly thick handle bars and I never had much luck finding a bell that would fit. Lacking a bell turns out to be a huge problem on Calgary pathways, which are regularly populated by slow and often oblivious pedestrians. For a while now I have relied on verbal warnings, [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=473&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>My Surly Long Haul Trucker has fairly thick handle bars and I never had much luck finding a bell that would fit. Lacking a bell turns out to be a huge problem on Calgary pathways, which are regularly populated by slow and often oblivious pedestrians. For a while now I have relied on verbal warnings, though these often frighten and confuse people more than anything. The typical verbal warning is &#8220;on your left&#8221;, which has the unfortunate effect of causing some people to actually move left into your path. After enough incidents like this I decided to do some research and find a bell that would work with my LHT. I ended up finally settling on a <a href="http://store.velo-orange.com/index.php/brass-temple-bell-1018.html">beautiful brass bell from Velo Orange</a>. Velo Orange also makes the <a href="http://store.velo-orange.com/index.php/spacer-bell-mount.html">special spacer / stem mount </a>that I used to attach it to my bike.</p>
<div id="attachment_595" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3257.jpg"><img class="size-medium wp-image-595" title="DSCF3257" src="http://ejrob.files.wordpress.com/2012/05/dscf3257.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The spacer mount, bell and all other components.</p></div>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p>All of the components can be seen on the right, including some of the extra hardware that came with the spacer mount.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_596" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3263.jpg"><img class="size-medium wp-image-596" title="DSCF3263" src="http://ejrob.files.wordpress.com/2012/05/dscf3263.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The stem of my Surly LHT</p></div>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p>The stem of my bike, where the bell will be mounted can be seen on the left. I decided to replace the 2nd spacer from the top with the special spacer mount because this kept the bell clear of any other components on my bike.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_598" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3268.jpg"><img class="size-medium wp-image-598" title="DSCF3268" src="http://ejrob.files.wordpress.com/2012/05/dscf3268.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The spacer mount replaces one of the original ones</p></div>
<p><span style="color:#ffffff;">.</span></p>
<p>After detaching the handlebars, the spacer mount replaces the second spacer from the top. The diameter of the steering tube on my bike is 1 1/8&#8243; and so that was the size of spacer I purchased. Your bike may have a 1&#8243; diameter tube, and so I strongly recommend measuring this value before making a purchase.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_600" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3277.jpg"><img class="size-medium wp-image-600" title="DSCF3277" src="http://ejrob.files.wordpress.com/2012/05/dscf3277.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Make sure everything&#8217;s aligned right before tightening</p></div>
<p>Before tightening the handle bars back on, it is necessary to make sure everything is aligned correctly. The easiest way to do this is to press a straight edge up against the arms of the fork and then align the handlebars to be parallel to this. This may require an extra set of hands, and I strongly recommend finding someone to help if possible. It is also necessary to apply some downward force on the point where the stem of the handlebars attaches to the steering tube of the fork when tightening everything back up. This prevents the spacers from rotating freely, and keeps the bell at the angle you installed it.</p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_605" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/spacer_diag_temple.jpg"><img class="size-medium wp-image-605" title="spacer_diag_temple" src="http://ejrob.files.wordpress.com/2012/05/spacer_diag_temple.jpg?w=300&#038;h=300" alt="" width="300" height="300" /></a><p class="wp-caption-text">An instructional diagram of the parts</p></div>
<p>Attaching the bell to the spacer mount isn&#8217;t too difficult, and the diagram to the right shows all of the components necessary as well as the order they go on. The easiest way to do this is to place all the washers and other pieces onto the screw so that they are roughly centred on it. You then screw the bell partially onto the appropriate end and insert the other end into the hole on the spacer. Twisting the bell to tighten it further will now simultaneously tighten both ends, and firmly attach the bell to the bike. Use good judgement when tightening; you do not want to strip the screw or damage any components.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p>At this point you are done, and the bell is good to go. Below are a few pictures of the bell on my LHT, taken from different angles to give a good sense of how it looks and fits onto the bike.</p>
<table style="margin:auto;">
<tbody>
<tr>
<td>
<p><div id="attachment_601" class="wp-caption aligncenter" style="width: 280px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3280.jpg"><img class=" wp-image-601 " title="DSCF3280" src="http://ejrob.files.wordpress.com/2012/05/dscf3280.jpg?w=270&#038;h=203" alt="" width="270" height="203" /></a><p class="wp-caption-text">The final result: angle one</p></div></td>
<td>
<p><div id="attachment_602" class="wp-caption aligncenter" style="width: 280px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3281.jpg"><img class=" wp-image-602 " title="DSCF3281" src="http://ejrob.files.wordpress.com/2012/05/dscf3281.jpg?w=270&#038;h=203" alt="" width="270" height="203" /></a><p class="wp-caption-text">The final result: angle two</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_603" class="wp-caption aligncenter" style="width: 280px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3286.jpg"><img class=" wp-image-603 " title="DSCF3286" src="http://ejrob.files.wordpress.com/2012/05/dscf3286.jpg?w=270&#038;h=203" alt="" width="270" height="203" /></a><p class="wp-caption-text">The final result: angle three</p></div></td>
<td>
<p><div id="attachment_604" class="wp-caption aligncenter" style="width: 280px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3289.jpg"><img class=" wp-image-604 " title="DSCF3289" src="http://ejrob.files.wordpress.com/2012/05/dscf3289.jpg?w=270&#038;h=203" alt="" width="270" height="203" /></a><p class="wp-caption-text">The final result: angle four</p></div></td>
</tr>
</tbody>
</table>
<p>I have also used my phone to shoot a short video of the bell in action. The video quality is poor, though the audio is decent enough to get an idea of what the bell sounds like:</p>
<p>&nbsp;<br />
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='420' height='315' src='http://www.youtube.com/embed/ju6ZWBl26Mc?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/473/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=473&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/06/02/velo-orange-temple-bell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/05/dscf3289.jpg?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3289.jpg?w=150" medium="image">
			<media:title type="html">DSCF3289</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3257.jpg?w=300" medium="image">
			<media:title type="html">DSCF3257</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3263.jpg?w=300" medium="image">
			<media:title type="html">DSCF3263</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3268.jpg?w=300" medium="image">
			<media:title type="html">DSCF3268</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3277.jpg?w=300" medium="image">
			<media:title type="html">DSCF3277</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/spacer_diag_temple.jpg?w=300" medium="image">
			<media:title type="html">spacer_diag_temple</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3280.jpg?w=300" medium="image">
			<media:title type="html">DSCF3280</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3281.jpg?w=300" medium="image">
			<media:title type="html">DSCF3281</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3286.jpg?w=300" medium="image">
			<media:title type="html">DSCF3286</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3289.jpg?w=300" medium="image">
			<media:title type="html">DSCF3289</media:title>
		</media:content>
	</item>
		<item>
		<title>BeagleBone: Making a Home Media Server</title>
		<link>http://everettsprojects.com/2012/05/24/beaglebone-making-a-home-media-server/</link>
		<comments>http://everettsprojects.com/2012/05/24/beaglebone-making-a-home-media-server/#comments</comments>
		<pubDate>Thu, 24 May 2012 07:07:36 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[BeagleBone]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[rtorrent]]></category>
		<category><![CDATA[rutorrent]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=465</guid>
		<description><![CDATA[There are plenty of products available to the person who wants a functioning NAS out of the box, though I&#8217;ve never really been that type. By using a versatile board like the BeagleBone as a home media server, I can make a project that is more than a simple networked storage solution. It also affords [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=465&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There are plenty of products available to the person who wants a functioning NAS out of the box, though I&#8217;ve never really been that type. By using a versatile board like the BeagleBone as a home media server, I can make a project that is more than a simple networked storage solution. It also affords me the opportunity to learn about administration of a Linux server. While I could teach myself these skills by implementing a home media server using an old desktop, the amount of electricity consumed would be at least an order of magnitude higher and in any case my old desktop recently gave up the ghost. The information contained here is specifically intended for use on a BeagleBone, though I wouldn&#8217;t be the least bit surprised if it was useful to someone trying to achieve the same effect with a different platform. It is also important to not that I accept no liability for damages or issues that occur as a result of following my directions either on a BeagleBone or other hardware. I am very sorry if such an event should take place however, and would appreciate knowing about it so that I could correct this guide asap.</p>
<p>This guide is broken into major steps for the convenience of anyone wishing to follow it:</p>
<ol>
<li><a href="#installingUbuntu">Installing Ubuntu and some basic configuration</a></li>
<li><a href="#sshLockdown">Locking down SSH</a></li>
<li><a href="#rtorrent">Getting rtorrent and rutorrent running</a></li>
<li><a href="#samba">Installing and configuring Samba</a></li>
<li><a href="#maintenance">Updating and maintaining the system</a></li>
</ol>
<div id="installingUbuntu">
<p style="text-align:center;">*****</p>
<h3>Installing Ubuntu and some basic configuration</h3>
<p>To start it&#8217;s necessary to get your preferred Linux distribution running on the BeagleBone. I chose Ubuntu mainly because I found an easy and ready to install image, though the fact that it is compiled to take advantage of the hard float capabilities in this arm processor was also a factor. The following instructions were up to date when I utilized them, though it&#8217;s entirely possible that a newer image has been created in the meantime and you should use that one if possible. You will also need a microSD card to write the image to (I used a 4GB card, though a 2GB card or greater should work).</p>
<p>Credit goes to <a href="http://elinux.org/BeagleBoardUbuntu#Demo_Image">http://elinux.org/BeagleBoardUbuntu#Demo_Image</a> as the basis for this portion of my guide.</p>
<p>The first thing we need to do is download the operating system image that we will write to the microSD card:</p>
<blockquote><p>wget <a href="http://rcn-ee.net/deb/rootfs/precise/ubuntu-12.04-r1-minimal-armhf.tar.xz" rel="nofollow">http://rcn-ee.net/deb/rootfs/precise/ubuntu-12.04-r1-minimal-armhf.tar.xz</a></p></blockquote>
<p>This image needs to be unpacked before we write it to the SD card:<em><br />
</em></p>
<blockquote><p>tar xJf ubuntu-12.04-r1-minimal-armhf.tar.xz<br />
cd ubuntu-12.04-r1-minimal-armhf</p></blockquote>
<p>We need to know where to install this image , and even though it is likely /dev/mmcblk0 we should check anyway:</p>
<blockquote><p>sudo ./setup_sdcard.sh &#8211;probe-mmc</p></blockquote>
<p>In the output a line like <strong>Disk /dev/mmcblk0: 3957 MB, 3957325824 bytes </strong>should be seen. If there is only one line starting with <strong>Disk /dev/mmcblk</strong>&#8230; then that is the SD card we want, and that&#8217;s the location you should use. If there are more than one of these <strong>/dev/mmcblk</strong> lines, then you must figure out which one belongs to the SD card you want to write to, otherwise you may overwrite something important.</p>
<p>Having figured out where the SD card is mounted, we will run the script to write the contents of our image to it:</p>
<blockquote><p>sudo ./setup_sdcard.sh &#8211;mmc /dev/mmcblk0 &#8211;uboot bone</p></blockquote>
<p>Where <strong>/dev/mmcblk0</strong> may be something else if you found the SD card to be mounted somewhere else in the previous step.<br />
At this point you only have to insert the microSD card and plug it into the BeagleBone to get started. Because the board lacks a way to hook up a display it is easiest to insert an ethernet cable and remotely SSH into it with <strong>the user &#8220;ubuntu&#8221; and the password &#8220;temppwd&#8221;</strong></p>
<blockquote><p>ssh ubuntu@&lt;Local IP Address&gt;</p></blockquote>
<p>I have managed to use the DHCP reservation functionality on my home router to ensure that the BeagleBone has a fixed local IP address, and I strongly encourage you to do the same if possible. Because this process varies by router manufacturer and model, I cannot offer much guidance in this regard. <a href="http://lifehacker.com/5822605/how-to-set-up-dhcp-reservations-so-you-never-have-to-check-an-ip-address-again">This guide</a> may be of some help.</p>
<p>Our first step after logging in should be to change the password for this account:</p>
<blockquote><p>passwd</p></blockquote>
<p>This will ask for the current password, and the one you wish replace it with twice. The next two steps will create a new user account with a better name (just replace &lt;username&gt; with your preference) and give it administrative privileges. These steps are cosmetic, and are unnecessary if you just wish to use the account &#8220;ubuntu&#8221;.</p>
<blockquote><p>sudo adduser &lt;username&gt;</p>
<p>sudo usermod -aG admin &lt;username&gt;</p></blockquote>
<p>The next two commands will allow us to change the host name for the BeagleBone to something other than &#8220;omap&#8221; and are also optional as they are purely cosmetic.</p>
<blockquote><p>sudo nano /etc/hostname</p></blockquote>
<p>You should change the first line of this file to whatever you&#8217;d like as a new host name (don&#8217;t use spaces) and then press CTRL-o to save the changes and CTRL-x to exit. We will also need to change the following file:</p>
<blockquote><p>sudo nano /etc/hosts</p></blockquote>
<p>The word <strong>omap</strong> in the second line of this file should be replaced with the same host name we just used.</p>
<p>I encountered perl locale errors when I tried doing various things later on, which may still be an issue. To fix them you want to check that <strong>/etc/default/locale</strong> contains a few things:</p>
<blockquote><p>sudo nano /etc/default/locale</p></blockquote>
<p>You should find the following lines within, though they do not necessarily need to be US english:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8:en
LC_ALL=en_US.UTF-8
</pre>
<p>If any of these lines are not present, then you should add them (substituting in another language pack such as en_GB if you&#8217;re so inclined.)</p>
<p>Before proceeding, it is also a good idea to make sure all of the packages on your system are up to date:</p>
<blockquote><p>sudo apt-get update<br />
sudo apt-get upgrade</p></blockquote>
<blockquote><p>sudo reboot</p></blockquote>
</div>
<div id="sshLockdown">
<p style="text-align:center;">*****</p>
<h3>Locking down SSH</h3>
<p>Credit goes to <a href="http://www.debian-administration.org/articles/530">http://www.debian-administration.org/articles/530</a> as the basis for this portion of my guide.<br />
We need to generate a set of public and private keys on the computer you wish to SSH into the BeagleBone from. It is important to make sure you are running this locally on the client computer, not through SSH on the BeagleBone:</p>
<blockquote><p>ssh-keygen</p></blockquote>
<p>You will then be prompted for a password to protect the key we just generated. This password is not transmitted in any way to the system were are using SSH to access, but rather to decrypt the key on your local machine. If you leave the password blank it will not encrypt this key and make it so that anyone with the right file permissions can see it.<br />
Now we want to install the key on the BeagleBone:</p>
<blockquote><p>ssh-copy-id -i .ssh/id_rsa.pub &lt;username&gt;@&lt;local IP address&gt;</p></blockquote>
<p>If this was successful, we should be able to SSH into the BeagleBone without entering a password.<br />
We should then check that we only installed the key we intended to:</p>
<blockquote><p>nano ~/.ssh/authorized_keys</p></blockquote>
<p>You should see only one line in the file.</p>
<p>Next, it is a good idea to disable password authentication and limit the users who can access the board via SSH.<br />
You <strong>do not</strong> want to do this by disabling password authentication for the chosen account as outlined in the debian-administration.org article; this runs the risk of breaking your ability to use sudo and can leave you without root access. I may or may not have made this error first hand. It&#8217;s not fun. We achieve the desired effect by editing <strong>/etc/ssh/sshd_config</strong> .</p>
<blockquote><p>sudo nano /etc/ssh/sshd_config</p></blockquote>
<p>First things first, it&#8217;s never a bad idea to disable root login. This isn&#8217;t really necessary on an Ubuntu system since there is no functioning root password and everything is done using sudo, but we&#8217;re better safe than sorry. Find the line beginning with <strong>PermitRootLogin</strong> and change it to <strong>no</strong>:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">PermitRootLogin no</pre>
<p>We also want to disable password authentication by finding the line <strong>#PasswordAuthentication yes</strong>, changing it to <strong>no</strong>, and uncommenting it by removing the <strong>#</strong>:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">PasswordAuthentication no</pre>
<p>Because we do not need X11-forwarding for our purposes you may also wish to change that line to:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">X11Forwarding no</pre>
<p>And to limit the users allowed to SSH into the BeagleBone we want to add the following line to the end of the file, using the username we created earlier in the place of &lt;username&gt;:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">AllowUsers &lt;username&gt;</pre>
<p>Finally, to finish our lockdown of SSH, we need to restart it so that the changes can take effect:</p>
<blockquote><p>sudo service ssh restart</p></blockquote>
</div>
<div id="rtorrent">
<p style="text-align:center;">*****</p>
<h3>Getting rtorrent and rutorrent running</h3>
<p>This portion of my guide has been mainly adapted from <a href="http://forums.rutorrent.org/index.php?topic=256.0">http://forums.rutorrent.org/index.php?topic=256.0</a>.</p>
<p>First we want to install a large number of packages:</p>
<blockquote><p>sudo apt-get install apache2 apache2.2-common apache2-utils autoconf automake autotools-dev binutils build-essential bzip2 ca-certificates comerr-dev cpp cpp-4.6 dpkg-dev file g++ g++-4.6 gawk gcc gcc-4.6 libapache2-mod-php5 libapache2-mod-scgi libapr1 libaprutil1 libc6-dev libcppunit-dev libcurl3 libcurl4-openssl-dev libexpat1 libidn11 libidn11-dev libkdb5-6 libgssrpc4 libkrb5-dev libmagic1 libncurses5 libncurses5-dev libneon27 libpcre3 libpq5 libsigc++-2.0-dev libsqlite0 libsqlite3-0 libssl-dev libstdc++6-4.6-dev libsvn1 libtool libxml2 linux-libc-dev lynx m4 make mime-support ntp ntpdate openssl patch perl perl-modules php5 php5-cgi php5-cli php5-common php5-curl php5-dev php5-geoip php5-sqlite php5-xmlrpc pkg-config python-scgi screen sqlite ssl-cert subversion ucf unrar zlib1g-dev pkg-config unzip htop screen libwww-perl curl</p></blockquote>
<p>Several of these packages are probably already installed, though it does not hurt to make sure. Some of the packages in this long list have been updated to newer versions since the guide I have adapted thus from was written. If any appreciable length of time has passed since I wrote this, then you are well advised to check if any of these packages need to have their version numbers changed. If this is the case, then apt-get is likely to spit out some error messages about certain packages being missing. The specific packages I updated were: <strong>cpp-4.6, g++-4.6, gcc-4.6, libstdc++6-4.6-dev, libkdb5-6, and libneon27</strong>. Here&#8217;s a quick way to check the version numbers for <a href="http://packages.ubuntu.com/">packages in the ubuntu repository online</a>.</p>
<p>Having everything we need, our next step is to configure apache:</p>
<blockquote><p>a2enmod ssl<br />
a2enmod auth_digest<br />
a2enmod scgi</p></blockquote>
<p>We need to make sure that apache has SCGI support enabled so that the rutorrent webui will work:</p>
<blockquote><p>sudo nano /etc/apache2/apache2.conf</p></blockquote>
<p>You then need to paste the following at the end of the file:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
SCGIMount /RPC2 127.0.0.1:5000
servername localhost
</pre>
<p>To make sure everything we&#8217;ve done takes effect it is a good idea to restart the server:</p>
<blockquote><p>sudo reboot</p></blockquote>
<p>To make sure everything is working, on your client machine type the local ip address assigned to your BeagleBone into the address bar of your browser:</p>
<blockquote><p>http:// &lt; Local IP Address&gt;</p></blockquote>
<p>You should see the following:</p>
<p><a href="http://ejrob.files.wordpress.com/2012/05/working-apache.png"><img class="aligncenter size-medium wp-image-522" title="working apache" src="http://ejrob.files.wordpress.com/2012/05/working-apache.png?w=300&#038;h=167" alt="" width="300" height="167" /></a></p>
<p>Because our rutorrent front end to rtorrent will be password protected, we need to have HTTPS functionality eneabled. To achieve this we need an SSL certificate. This process will ask for a lot of information which you can fill in however you see fit, though it&#8217;s a good idea to use the domain name your BeagleBone will be connected to if you have one:</p>
<blockquote><p>openssl req $@ -new -x509 -days 365 -nodes -out /etc/apache2/apache.pem -keyout /etc/apache2/apache.pem<br />
chmod 600 /etc/apache2/apache.pem</p></blockquote>
<p>This is a self signed certificate, meaning your browser will probably spit out a warning the first time you connect. Just ignore the warning and store the exception, and this won&#8217;t happen again. Our next step is to protect our apache webserver with a username and password:</p>
<blockquote><p>sudo htdigest -c /etc/apache2/passwords gods &lt;webusername&gt;</p></blockquote>
<p>This username, &lt;webusername&gt;, and password can be whatever you like. It can even be the same user and password we used earlier when setting sup the system. I personally decided to use a different username and password because it offers a slight security advantage in that if someone figures out the password to our rutorrent and apache setup, they still don&#8217;t have the password for root privileges through the operating system account we made earlier. It is unlikely that this scenario would ever happen since we made access through ssh only possible using key authentication, though it&#8217;s not much of a hassle for a little added security (Besides, I know you&#8217;ll just save the webusername and password in your browser anyway).</p>
<p>We also need to configure apache using the <strong>/etc/apache2/sites-available/default</strong> file:</p>
<blockquote><p>sudo nano /etc/apache2/sites-available/default</p></blockquote>
<p>You want to replace the contents of this file with the following, where the two instances of &lt;Local IP Address&gt; are replaced by the address of your BeagleBone on the local network:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&lt;VirtualHost *:80&gt;
	ServerAdmin webmaster@localhost

	DocumentRoot /var/www/
	&lt;Directory /&gt;
		Options FollowSymLinks
		AllowOverride None
	&lt;/Directory&gt;
	&lt;Directory /var/www/&gt;
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
	&lt;/Directory&gt;

	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	&lt;Directory &quot;/usr/lib/cgi-bin&quot;&gt;
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	&lt;/Directory&gt;

	ErrorLog /var/log/apache2/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog /var/log/apache2/access.log combined

	Alias /doc/ &quot;/usr/share/doc/&quot;
	&lt;Directory &quot;/usr/share/doc/&quot;&gt;
		Options Indexes MultiViews FollowSymLinks
		AllowOverride None
		Order deny,allow
		Deny from all
		Allow from 127.0.0.0/255.0.0.0 ::1/128
	&lt;/Directory&gt;

	&lt;Location /rutorrent&gt;
		AuthType Digest
		AuthName &quot;gods&quot;
		AuthDigestDomain /var/www/rutorrent/ http://&lt;Local IP Address&gt;/rutorrent

		AuthDigestProvider file
		AuthUserFile /etc/apache2/passwords
		Require valid-user
		SetEnv R_ENV &quot;/var/www/rutorrent&quot;
	&lt;/Location&gt;

&lt;/VirtualHost&gt;

&lt;VirtualHost *:443&gt;
	ServerAdmin webmaster@localhost

	SSLEngine on
	SSLCertificateFile /etc/apache2/apache.pem

	DocumentRoot /var/www/
	&lt;Directory /&gt;
		Options FollowSymLinks
		AllowOverride None
	&lt;/Directory&gt;
	&lt;Directory /var/www/&gt;
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
	&lt;/Directory&gt;

	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	&lt;Directory &quot;/usr/lib/cgi-bin&quot;&gt;
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	&lt;/Directory&gt;

	ErrorLog /var/log/apache2/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog /var/log/apache2/access.log combined

	Alias /doc/ &quot;/usr/share/doc/&quot;
	&lt;Directory &quot;/usr/share/doc/&quot;&gt;
		Options Indexes MultiViews FollowSymLinks
		AllowOverride None
		Order deny,allow
		Deny from all
		Allow from 127.0.0.0/255.0.0.0 ::1/128
	&lt;/Directory&gt;
	&lt;Location /rutorrent&gt;
		AuthType Digest
		AuthName &quot;gods&quot;
		AuthDigestDomain /var/www/rutorrent/ http://&lt;Local IP Address&gt;/rutorrent

		AuthDigestProvider file
		AuthUserFile /etc/apache2/passwords
		Require valid-user
		SetEnv R_ENV &quot;/var/www/rutorrent&quot;
	&lt;/Location&gt;
&lt;/VirtualHost&gt;
</pre>
<p>We then want to run the following to get apache running https:</p>
<blockquote><p>sudo a2ensite default-ssl<br />
sudo /etc/init.d/apache2 reload</p></blockquote>
<p>If everything worked as intended, then going to <strong><a href="https://&#038;lt" rel="nofollow">https://&#038;lt</a>; Local IP Address&gt;</strong> should show us the same page we saw earlier.</p>
<p>Unlike the guide I adapted these instructions from, I have decided not to install the Webmin configuration utilities for a couple of reasons. The first is that I wanted this project to help develop my skills as a Linux administrator, and a graphical GUI to change everything does not really fit that goal. The second reason is that the BeagleBone is not a powerful computer, and so I would prefer not to weigh it down with things that are not absolutely necessary.</p>
<p>Now that we have apache up and running with all the necessary bells and whistles, we can proceed to install and configure rtorrent and the rutorrent webui. At the time the guide I used as my starting point was written, the version of rtorrent in the Ubuntu repositories wasn&#8217;t complied with xmlrpc support, which was needed for rutorrent to work. This has long been fixed, and so you can probably just install the packages <strong>libxmlrpc-core-c3-dev</strong> and <strong>rtorrent</strong>. I can&#8217;t offer any guidance in this regard because I decided to compile the latest versions of these packages from source, mostly because I could. The compilation process will take a fair amount of time; likely more than an hour.</p>
<p>First things first, we need the sources for each of these packages:</p>
<blockquote><p>cd ~/<br />
mkdir source<br />
cd source<br />
svn co <a href="https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced/" rel="nofollow">https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced/</a> xmlrpc-c<br />
wget <a href="http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz" rel="nofollow">http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz</a><br />
wget <a href="http://libtorrent.rakshasa.no/downloads/rtorrent-0.9.2.tar.gz" rel="nofollow">http://libtorrent.rakshasa.no/downloads/rtorrent-0.9.2.tar.gz</a><br />
tar -xvzf libtorrent-0.13.2.tar.gz<br />
tar -xvzf rtorrent-0.9.2.tar.gz<br />
rm *.tar.gz</p></blockquote>
<p>This simply downloads the sources, unpacks the archives and deletes the archive files once we have. These packages may be updated to newer versions by the time you read this, and you can change version numbers accordingly.</p>
<p>The first package we need to build is xmlrpc-c:</p>
<blockquote><p>cd xmlrpc-c<br />
./configure &#8211;disable-cplusplus<br />
make<br />
sudo make install</p></blockquote>
<p>Once this has completed we will do the same for libtorrent, the backend of rtorrent:</p>
<blockquote><p>cd ../libtorrent-0.13.2<br />
./autogen.sh<br />
./configure<br />
make<br />
sudo make install</p></blockquote>
<p>And finally, we will compile rtorrent itself:</p>
<blockquote><p>cd ../rtorrent-0.9.2<br />
./autogen.sh<br />
./configure &#8211;with-xmlrpc-c<br />
make<br />
sudo make install</p>
<p>sudo ldconfig</p></blockquote>
<p>Next we need an rtorrent configuration file, which we will save as ~/.rtorrent.rc:</p>
<blockquote><p>nano ~/.rtorrent.rc</p></blockquote>
<p>and replace any contents with the following:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
# This is an example resource file for rTorrent. Copy to
# ~/.rtorrent.rc and enable/modify the options as needed. Remember to
# uncomment the options you wish to enable.
#
# Based on original .rtorrent.rc file from http://libtorrent.rakshasa.no/
# Modified by Lemonberry for rtGui http://rtgui.googlecode.com/
#
# This assumes the following directory structure:
#
# /Torrents/Downloading - temporaray location for torrents while downloading (see &quot;directory&quot;)
# /Torrents/Complete - Torrents are moved here when complete (see &quot;on_finished&quot;)
# /Torrents/TorrentFiles/Auto - The 'autoload' directory for rtorrent to use.  Place a file
#           in here, and rtorrent loads it #automatically.  (see &quot;schedule = watch_directory&quot;)
# /Torrents/Downloading/rtorrent.session - for storing rtorrent session information
#

# Maximum and minimum number of peers to connect to per torrent.
#min_peers = 40
max_peers = 100

# Same as above but for seeding completed torrents (-1 = same as downloading)
min_peers_seed = -1
max_peers_seed = -1

# Maximum number of simultanious uploads per torrent.
max_uploads = 10

# Global upload and download rate in KiB. &quot;0&quot; for unlimited.
download_rate = 0
upload_rate = 0

# Default directory to save the downloaded torrents.
directory = &lt;directory torrents will download to by default&gt;

# Default session directory. Make sure you don't run multiple instance
# of rtorrent using the same session directory. Perhaps using a
# relative path? (We disregard this because of our startup script later)
session = /home/&lt;username&gt;/.session

# Watch a directory for new torrents, and stop those that have been
# deleted.
#schedule = watch_directory,5,5,load_start=/home/downloads/&lt;username&gt;/watch/*.torrent
#schedule = untied_directory,5,5,stop_untied=

# Close torrents when diskspace is low. */
schedule = low_diskspace,5,60,close_low_diskspace=100M

# Stop torrents when reaching upload ratio in percent,
# when also reaching total upload in bytes, or when
# reaching final upload ratio in percent.
# example: stop at ratio 2.0 with at least 200 MB uploaded, or else ratio 20.0
#schedule = ratio,60,60,stop_on_ratio=200,200M,2000

# When the torrent finishes, it executes &quot;mv -n  ~/Download/&quot;
# and then sets the destination directory to &quot;~/Download/&quot;. (0.7.7+)
# on_finished = move_complete,&quot;execute=mv,-u,$d.get_base_path=,/home/downloads/&lt;username&gt;/complete/ ;d.set_directory=/home/downloads/&lt;username&gt;/complete/&quot;

# The ip address reported to the tracker.
#ip = 127.0.0.1
#ip = rakshasa.no

# The ip address the listening socket and outgoing connections is
# bound to.
#bind = 127.0.0.1
#bind = rakshasa.no

# Port range to use for listening.
port_range = 55995-56000

# Start opening ports at a random position within the port range.
#port_random = yes

scgi_port = 127.0.0.1:5000

# Check hash for finished torrents. Might be usefull until the bug is
# fixed that causes lack of diskspace not to be properly reported.
#check_hash = no

# Set whetever the client should try to connect to UDP trackers.
#use_udp_trackers = no

# Alternative calls to bind and ip that should handle dynamic ip's.
#schedule = ip_tick,0,1800,ip=rakshasa
#schedule = bind_tick,0,1800,bind=rakshasa

# Encryption options, set to none (default) or any combination of the following:
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
#
# The example value allows incoming encrypted connections, starts unencrypted
# outgoing connections but retries with encryption if they fail, preferring
# plaintext to RC4 encryption after the encrypted handshake
#
encryption = allow_incoming,try_outgoing

# Enable DHT support for trackerless torrents or when all trackers are down.
# May be set to &quot;disable&quot; (completely disable DHT), &quot;off&quot; (do not start DHT),
# &quot;auto&quot; (start and stop DHT as needed), or &quot;on&quot; (start DHT immediately).
# The default is &quot;off&quot;. For DHT to work, a session directory must be defined.
#
dht = disable

# UDP port to use for DHT.
#
# dht_port = 6881

# Enable peer exchange (for torrents not marked private)
#
peer_exchange = no

#
# Do not modify the following parameters unless you know what you're doing.
#

# Hash read-ahead controls how many MB to request the kernel to read
# ahead. If the value is too low the disk may not be fully utilized,
# while if too high the kernel might not be able to keep the read
# pages in memory thus end up trashing.
#hash_read_ahead = 10

# Interval between attempts to check the hash, in milliseconds.
#hash_interval = 100

# Number of attempts to check the hash while using the mincore status,
# before forcing. Overworked systems might need lower values to get a
# decent hash checking rate.
#hash_max_tries = 10

# Max number of files to keep open simultaniously.
#max_open_files = 128

# Number of sockets to simultaneously keep open.
#max_open_sockets =

# Example of scheduling commands: Switch between two ip's every 5
# seconds.
#schedule = &quot;ip_tick1,5,10,ip=torretta&quot;
#schedule = &quot;ip_tick2,10,10,ip=lampedusa&quot;

# Remove a scheduled event.
#schedule_remove = &quot;ip_tick1&quot;
</pre>
<p>There are a couple of lines you must replace with your own specific information. The first is <strong>directory = &lt;directory torrents will download to by default&gt;</strong> and the second is <strong>session = /home/&lt;username&gt;/.session</strong> . I also encourage you to do a little research so that you can change other settings to suit your purposes.</p>
<p>We need to make sure the directories we just told rtorrent to use exist. Because it would be silly to have your media stored on the same SD card containing the OS, I&#8217;ve attached an external USB hard drive to the BeagleBone and set my <em>directory = &lt;directory torrents will download to by default&gt;</em> line to point towards there. Since this is external media, we&#8217;ll need it to auto mount whenever the board reboots so that rtorrent will always be able to find it. We&#8217;ll start by making the directories for rtorrent and for the drive to be mounted to:</p>
<blockquote><p>cd ~<br />
sudo mkdir .session<br />
sudo mkdir /media/&lt;mount directory name&gt;</p></blockquote>
<p>I am mounting it in <strong>/media</strong> because that is the standard place to place such things in ubuntu, though you could just as well mount it in <strong>/mnt</strong> or another directory you have made. To achieve automagical mounting we will edit <strong>/etc/fstab</strong> after backing up the original:</p>
<blockquote><p>sudo cp /etc/fstab /etc/fstab.backup</p></blockquote>
<p>We&#8217;re going to mount the usb hard drive using the <strong>uuid</strong> rather than the /dev/sda path because it is a better way of identifying the drive we actually want. To find this uuid we need to run:</p>
<blockquote><p>ls -l /dev/disk/by-uuid</p></blockquote>
<p>One of the lines should have something like <strong>../../sda1</strong> listed in yellow, and a corresponding alphanumeric code in blue. The blue code is the uuid, which you should copy. We can now go ahead and edit <strong>/etc/fstab</strong> :</p>
<blockquote><p>sudo nano /etc/fstab</p></blockquote>
<p>We want to add a specific line to the end:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
UUID=&lt;uuid&gt;     /media/&lt;mount directory name&gt; auto defaults 0 0
</pre>
<p>where <strong>&lt;uuid&gt;</strong> is the value we copied earlier, and <strong>/media/&lt;mount directory name&gt;</strong> is where we decided to mount the drive. If you happen to know the file system in use on your usb drive you may wish to change the <strong>auto</strong> in the above line to the proper filesystem. For ext4 this is just &#8220;<strong>ext4</strong>&#8221; and for ntfs (<em>oh god, why?</em>) it would be &#8220;<strong>ntfs-3g</strong>&#8220;, each without quotes. If using ntfs it may be necessary to install the ntfs-3g package.</p>
<p>Now that fstab has been modified, we want Ubuntu to recognize the changes:</p>
<blockquote><p>sudo mount -a</p></blockquote>
<p>And we will also make ourselves the owner of the external drive mount point:</p>
<blockquote><p>sudo chown -R &lt;username&gt;:&lt;username&gt; /media/&lt;mount directory name&gt;</p></blockquote>
<p>If everything went well, then we should find that rtorrent starts up without any issues:</p>
<blockquote><p>rtorrent</p></blockquote>
<p>Any problems should be noted in rtorrent with an error that should help direct you towards a solution. I got a warning about xmlrpc, though a little research showed this was just an advisory and nothing to actually be worried about. You can now quit rtorrent by pressing CTRL-q.</p>
<p>We also want rtorrent to start up automatically in such a way that it will also keep running when we are not logged in via ssh. This is accomplished using a startup script (which I have left unmodified for the original guide) that makes use of screen.</p>
<blockquote><p>sudo nano /etc/init.d/rtorrent</p></blockquote>
<p>Paste the follwing into that file. The only change necessary is to replace <strong>&lt;username&gt;</strong> in the <strong>line user=&#8221;&lt;username&gt;&#8221;</strong> with the user we created earlier:</p>
<pre class="brush: bash; gutter: false; title: ; notranslate">
#!/bin/sh
#############
###&lt;Notes&gt;###
#############
# This script depends on screen.
# For the stop function to work, you must set an
# explicit session directory using ABSOLUTE paths (no, ~ is not absolute) in your rtorrent.rc.
# If you typically just start rtorrent with just &quot;rtorrent&quot; on the
# command line, all you need to change is the &quot;user&quot; option.
# Attach to the screen session as your user with
# &quot;screen -dr rtorrent&quot;. Change &quot;rtorrent&quot; with srnname option.
# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com
##############
###&lt;/Notes&gt;###
##############

#######################
##Start Configuration##
#######################
# You can specify your configuration in a different file
# (so that it is saved with upgrades, saved in your home directory,
# or whateve reason you want to)
# by commenting out/deleting the configuration lines and placing them
# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would
# have written them here (you can leave the comments if you desire
# and then uncommenting the following line correcting the path/filename
# for the one you used. note the space after the &quot;.&quot;.
# . /etc/rtorrent.init.conf

#Do not put a space on either side of the equal signs e.g.
# user = user
# will not work
# system user to run as
user=&quot;&lt;username&gt;&quot;

# the system group to run as, not implemented, see d_start for beginning implementation
# group=`id -ng &quot;$user&quot;`

# the full path to the filename where you store your rtorrent configuration
config=&quot;`su -c 'echo $HOME' $user`/.rtorrent.rc&quot;

# set of options to run with
options=&quot;&quot;

# default directory for screen, needs to be an absolute path
base=&quot;`su -c 'echo $HOME' $user`&quot;

# name of screen session
srnname=&quot;rtorrent&quot;

# file to log to (makes for easier debugging if something goes wrong)
logfile=&quot;/var/log/rtorrentInit.log&quot;
#######################
###END CONFIGURATION###
#######################
PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
DESC=&quot;rtorrent&quot;
NAME=rtorrent
DAEMON=$NAME
SCRIPTNAME=/etc/init.d/$NAME

checkcnfg() {
    exists=0
    for i in `echo &quot;$PATH&quot; | tr ':' '\n'` ; do
        if [ -f $i/$NAME ] ; then
            exists=1
            break
        fi
    done
    if [ $exists -eq 0 ] ; then
        echo &quot;cannot find rtorrent binary in PATH $PATH&quot; | tee -a &quot;$logfile&quot; &gt;&amp;2
        exit 3
    fi
    if ! [ -r &quot;${config}&quot; ] ; then
        echo &quot;cannot find readable config ${config}. check that it is there and permissions are appropriate&quot; | tee -a &quot;$logfile&quot; &gt;&amp;2
        exit 3
    fi
    session=`getsession &quot;$config&quot;`
    if ! [ -d &quot;${session}&quot; ] ; then
        echo &quot;cannot find readable session directory ${session} from config ${config}. check permissions&quot; | tee -a &quot;$logfile&quot; &gt;&amp;2
        exit 3
    fi
}

d_start() {
  [ -d &quot;${base}&quot; ] &amp;&amp; cd &quot;${base}&quot;
  stty stop undef &amp;&amp; stty start undef
  su -c &quot;screen -ls | grep -sq &quot;\.${srnname}[[:space:]]&quot; &quot; ${user} || su -c &quot;screen -dm -S ${srnname} 2&gt;&amp;1 1&gt;/dev/null&quot; ${user} | tee -a &quot;$logfile&quot; &gt;&amp;2
  # this works for the screen command, but starting rtorrent below adopts screen session gid
  # even if it is not the screen session we started (e.g. running under an undesirable gid
  #su -c &quot;screen -ls | grep -sq &quot;\.${srnname}[[:space:]]&quot; &quot; ${user} || su -c &quot;sg \&quot;$group\&quot; -c \&quot;screen -fn -dm -S ${srnname} 2&gt;&amp;1 1&gt;/dev/null\&quot;&quot; ${user} | tee -a &quot;$logfile&quot; &gt;&amp;2
  su -c &quot;screen -S &quot;${srnname}&quot; -X screen rtorrent ${options} 2&gt;&amp;1 1&gt;/dev/null&quot; ${user} | tee -a &quot;$logfile&quot; &gt;&amp;2
}

d_stop() {
    session=`getsession &quot;$config&quot;`
    if ! [ -s ${session}/rtorrent.lock ] ; then
        return
    fi
    pid=`cat ${session}/rtorrent.lock | awk -F: '{print($2)}' | sed &quot;s/[^0-9]//g&quot;`
    if ps -A | grep -sq ${pid}.*rtorrent ; then # make sure the pid doesn't belong to another process
        kill -s INT ${pid}
    fi
}

getsession() {
    session=`cat &quot;$1&quot; | grep &quot;^[[:space:]]*session[[:space:]]*=&quot; | sed &quot;s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//&quot; `
    echo $session
}

checkcnfg

case &quot;$1&quot; in
  start)
    echo -n &quot;Starting $DESC: $NAME&quot;
    d_start
    echo &quot;.&quot;
    ;;
  stop)
    echo -n &quot;Stopping $DESC: $NAME&quot;
    d_stop
    echo &quot;.&quot;
    ;;
  restart|force-reload)
    echo -n &quot;Restarting $DESC: $NAME&quot;
    d_stop
    sleep 1
    d_start
    echo &quot;.&quot;
    ;;
  *)
    echo &quot;Usage: $SCRIPTNAME {start|stop|restart|force-reload}&quot; &gt;&amp;2
    exit 1
    ;;
esac

exit 0
</pre>
<p>Finally we will make the owner of the file the root, make it executable, and have it startup at boot.</p>
<blockquote><p>sudo chown root:root /etc/init.d/rtorrent<br />
sudo chmod a+x /etc/init.d/rtorrent<br />
cd /etc/init.d<br />
sudo update-rc.d rtorrent defaults</p></blockquote>
<p>If everything has worked out then running the following should startup rtorrent in a screen session:</p>
<blockquote><p>sudo /etc/init.d/rtorrent start</p></blockquote>
<p>Which we will verify by running htop. We should find a few rtorrent processes and a screen process which belong to the user we created earlier. To quit htop hit the &#8220;q&#8221; key on your keyboard.</p>
<p>The last step is to get rutorrent up and running. rutorrent is just a web interface, and so we will put it in <strong>/var/www</strong> so that the apache webserver we installed and configured earlier can serve it up to us.</p>
<blockquote><p>cd /var/www<br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/rutorrent" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/rutorrent</a></p></blockquote>
<p>We will also install a bunch of plugins to extend to functionality of rutorrent and to make it more like a native program running on the client machine itself:</p>
<blockquote><p>cd rutorrent/plugins<br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/erasedata" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/erasedata</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/create" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/create</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/trafic" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/trafic</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/edit" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/edit</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/retrackers" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/retrackers</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/cookies" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/cookies</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/search" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/search</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/scheduler" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/scheduler</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/autotools" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/autotools</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/datadir" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/datadir</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/tracklabels" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/tracklabels</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/geoip" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/geoip</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/ratio" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/ratio</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/seedingtime" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/seedingtime</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/diskspace" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/diskspace</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/data" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/data</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/rss" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/rss</a><br />
sudo svn checkout <a href="http://rutorrent.googlecode.com/svn/trunk/plugins/throttle" rel="nofollow">http://rutorrent.googlecode.com/svn/trunk/plugins/throttle</a></p></blockquote>
<p>The diskspace plugin watches the root directory by default, and that is no good since we&#8217;re using an external drive for our torrent download location. To fix this we need to edit one line in the file <strong>/var/www/rutorrent/conf/config.php</strong>:</p>
<blockquote><p>sudo nano /var/www/rutorrent/conf/config.php</p></blockquote>
<p>We need to find the line that begins <strong>$topDirectory</strong> and change it to the following:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
$topDirectory = '/media/&lt;mount directory name&gt;';
</pre>
<p>Finally, we have to change the ownership of these files and folders so that the web server can make use of them:</p>
<blockquote><p>cd /var/www<br />
sudo chown -R www-data:www-data rutorrent<br />
sudo chmod -R 777 rutorrent</p></blockquote>
<p>If everything went as expected, then going to <strong><a href="https://&lt;local" rel="nofollow">https://&lt;local</a> IP Address&gt;/rutorrent</strong> should prompt us for a username and password (this is the one we created for the webserver, &lt;webusername&gt;, and is not necessarily the user account we created for the OS). After logging in, we should see the empty rutorrent webgui:</p>
<p><a href="http://ejrob.files.wordpress.com/2012/05/rutorrentwebui.png"><img class="aligncenter size-medium wp-image-550" title="rutorrentWebui" src="http://ejrob.files.wordpress.com/2012/05/rutorrentwebui.png?w=300&#038;h=187" alt="" width="300" height="187" /></a></p>
<p>At this point we&#8217;re essentially finished with this part of the guide unless you wish to install an FTP server. For my purposes I am content with using sftp, which is built into SSH, though the <a href="http://forums.rutorrent.org/index.php?topic=256.0">original source for this portion of the guide</a> also includes instructions for setting up a true FTP server using Pure-FTPd. There are also instructions to enable a multi-user rtorrent setup, though I have not pursued those either since I don&#8217;t have any need for it. Since we are finished with rtorrent and rutorrent, you can now start adding your torrents to it. You should make sure to point rutorrent to the right directory  if you add any torrents that you already have the data for and are seeding so that it won&#8217;t redownload the entire thing.</p>
</div>
<div id="samba">
<p style="text-align:center;">*****</p>
<h3>Installing and configuring Samba</h3>
<p>Samba is a very convenient application to have running for a home media server as it allows us to have very easy access to the files from other computers on the local network. To install samba:</p>
<blockquote><p>sudo apt-get install samba</p></blockquote>
<p>We also need to make a samba password for our samba user (the same Ubuntu user we made earlier):</p>
<blockquote><p>smbpasswd -a &lt;username&gt;</p></blockquote>
<p>The next step in setting samba up is to change some things in the configuration file, <strong>/etc/samba/smb.conf</strong>:</p>
<blockquote><p>sudo nano /etc/samba/smb.conf</p></blockquote>
<p>The first thing to ensure is that the following line is present and uncommented (it should be below ####### Authentication #######):</p>
<pre class="brush: plain; title: ; notranslate">
security = user
</pre>
<p>This will ensure that the only people who can access samba shares are those with a valid ubuntu account on the BeagleBone. The next step is to ensure that only people on the local network can access the samba shares which we achieve by adding the following lines under #### Networking ####:</p>
<pre class="brush: plain; title: ; notranslate">
# Added for extra security, only addresses on the local network can connect.
    hosts allow = 127.0.0.1 192.168.1.0/24
    hosts deny = 0.0.0.0/0
</pre>
<p>You may need to change 192.168.1.0/24 to something else depending on your router and local area network addresses (192.168.0.0/24 is another common one).</p>
<p>The last things we need to do in this config file are to setup the shares themselves. We will comment out any of the lines pertaining to printers because the BeagleBone is not attached to any. The end result is that those lines should appear as follows:</p>
<pre class="brush: plain; title: ; notranslate">
;[printers]
;   comment = All Printers
;   browseable = no
;   path = /var/spool/samba
;   printable = yes
;   guest ok = no
;   read only = yes
;   create mask = 0700

# Windows clients look for this share name as a source of downloadable
# printer drivers
;[print$]
;   comment = Printer Drivers
;   path = /var/lib/samba/printers
;   browseable = yes
;   read only = yes
;   guest ok = no

</pre>
<p>We also want to enable a share for our attached usb drive by adding the following lines to the end of the file with &lt;mount directory name&gt; and &lt;username&gt; are replaced by the appropriate values we used earlier:</p>
<pre class="brush: plain; title: ; notranslate">
# Share for the external media hard drive
[media]
        comment = External Drive connected to BeagleBone.
        path = /media/&lt;mount directory name&gt;
        read only = no
        browseable = yes
        valid users = &lt;username&gt;
</pre>
<p>This makes the entire usb hard drive available to the user we created earlier and no one else.</p>
<p>That&#8217;s it for samba, and we can enable the changes by restarting the samba processes:</p>
<blockquote><p>sudo restart smbd<br />
sudo restart nmbd</p></blockquote>
</div>
<div id="maintenance">
<p style="text-align:center;">*****</p>
<h3>Updating and maintaining the system</h3>
<p>There are a few basic things we need to do to keep our new home media server functioning in tiptop shape, and the first is keeping it up to date. For the most part, this can be done through the ubuntu repositories:</p>
<blockquote><p>sudo apt-get update<br />
sudo apt-get upgrade</p></blockquote>
<p>The kernel is a slightly more difficult matter because the one that works with the TI omap processors isn&#8217;t upstreamed to the repositories yet. To update the kernel you need to get the one built by <a href="https://github.com/RobertCNelson/stable-kernel">Robert C Nelson.</a> Luckily you shouldn&#8217;t need to do this very often, except in the case of security patches and important bug fixes. To make this process as easy as possible someone has already created a simple script to do all of the work for you. I have made the necessary changes to configure it to work with the BeagleBone running Ubuntu 12.04.<br />
First we will create a scripts directory to store it, then create the file using nano:</p>
<blockquote><p>mkdir ~/scripts<br />
cd scripts<br />
nano update-kernel-bone.sh</p></blockquote>
<p>You then want to paste the following into this file:</p>
<pre class="brush: bash; title: ; notranslate">
############################################################################
## This is a script obtained from http://elinux.org/BeagleBoardUbuntu     ##
## It updates the kernel on the BeagleBone using Robert C Nelsons Sources ##
## https://github.com/RobertCNelson/stable-kernel                         ##
############################################################################

export DIST=precise #(options are lucid/maverick/natty/oneiric/precise/squeeze/wheezy)
export ARCH=armhf   #(options are armel/armhf (armhf only for precise))

#Beagle/Panda
#export BOARD=omap

#BeagleBone
export BOARD=omap-psp

wget http://rcn-ee.net/deb/${DIST}-${ARCH}/LATEST-${BOARD}
wget $(cat ./LATEST-${BOARD} | grep STABLE | awk '{print $3}')
/bin/bash install-me.sh
</pre>
<p>Using this script is a simple as moving into the scripts directory and running it:</p>
<blockquote><p>cd ~/scripts<br />
sudo bash update-kernel-bone.sh</p></blockquote>
<p>Before updating the kernel, it is a good idea to make a backup of the system so it can be restored if something goes amiss. The easiest way I have found of backing up the operating system itself is to use <strong>dd</strong> to clone the microSD card. To do this you need to remove the microSD card from the BeagleBone after shutting it down:</p>
<blockquote><p>sudo poweroff</p></blockquote>
<p>After removing the card you want to insert it into another computer, the one you used to write the card in the first place should work just fine. Running the following command will copy the entire contents of the card to a file called sdcard.img into the home directory of this computer:</p>
<blockquote><p>sudo dd if=/dev/mmcblk0 of=~/sdcard.img</p></blockquote>
<p>If there are other SD cards inserted into this computer, then the location /dev/mmcblk0 may be incorrect. Make sure you are copying the contents of the correct SD card before you assume you have a valid backup. You can also change the location the image is copied to some other directory if you wish. This process will take a few minutes to complete, and when it is done you should have an image that can be copied back to the card using the command:</p>
<blockquote><p>sudo dd if=~/sdcard.img of=/dev/mmcblk0</p></blockquote>
<p>Hopefully this will never be necessary, though we&#8217;re always better off safe than sorry.</p>
<p>If you have another USB hard drive, you may wish to backup the contents of the one on the BeagleBone to it. The easiest way to do this is through rsync using SSH. On your computer (not the BeagleBone, the one we use to ssh into it) you just run the following command with necessary changes to fit your system:</p>
<blockquote><p>rsync -avv &#8211;progress -e ssh &lt;username&gt;@&lt;Local IP Adress&gt;:/media/&lt;mount directory name&gt;/ &lt;the path to the backup drive on the local computer&gt;</p></blockquote>
<p>The amount of time this takes will depend on the amount of data that is present on the BeagleBone&#8217;s drive but not on the destination drive.</p>
</div>
<p style="text-align:center;">*****</p>
<p><strong><br />
And with all that we should be done. I&#8217;ve tried my very best to keep this guide free of any errors, but some are sure to have snuck through. If you notice any, then I will be very grateful if you point them out so I can get them fixed. Once again, I accept no liability for damages or issues that occur as a result of following my directions either on a BeagleBone or other hardware.<br />
</strong></p>
<p style="text-align:center;">*****</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/465/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=465&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/05/24/beaglebone-making-a-home-media-server/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/05/rtorrent-startup-script.png?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/05/rtorrent-startup-script.png?w=150" medium="image">
			<media:title type="html">rtorrent startup script</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/working-apache.png?w=300" medium="image">
			<media:title type="html">working apache</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/rutorrentwebui.png?w=300" medium="image">
			<media:title type="html">rutorrentWebui</media:title>
		</media:content>
	</item>
		<item>
		<title>Beaglebone: Making a Case</title>
		<link>http://everettsprojects.com/2012/05/13/beaglebone-making-a-case/</link>
		<comments>http://everettsprojects.com/2012/05/13/beaglebone-making-a-case/#comments</comments>
		<pubDate>Sun, 13 May 2012 19:41:34 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[BeagleBone]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[case]]></category>
		<category><![CDATA[DIY]]></category>
		<category><![CDATA[Recyling]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=387</guid>
		<description><![CDATA[I recently purchased a BeagleBone with the intent of using it to make a home server and media box that could run constantly without costing a small fortune when the power bill arrived. I originally intended to make this project using a raspberry pi, though they&#8217;re having serious issues satisfying the demand, and I have [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=387&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://ejrob.files.wordpress.com/2012/05/dscf3155.jpg"><img class="aligncenter size-full wp-image-400" title="DSCF3155" src="http://ejrob.files.wordpress.com/2012/05/dscf3155.jpg?w=594&#038;h=445" alt="" width="594" height="445" /></a></p>
<p>I recently purchased a <a href="http://beagleboard.org/bone">BeagleBone</a> with the intent of using it to make a home server and media box that could run constantly without costing a small fortune when the power bill arrived. I originally intended to make this project using a raspberry pi, though they&#8217;re having serious issues satisfying the demand, and I have other projects a raspberry pi can be put to use on that would make better use of its video capabilities.</p>
<p>The first thing I wanted to tackle when my BeagleBone arrived was creating some sort of enclosure. For those who&#8217;d rather shop than build, there are options available, though I&#8217;ve always been a more DIY kind of person. In regards to DIY BeagleBone cases, there are obvious solutions like an Altoids tin which the board fits into perfectly. This is not necessarily as simple as it seems though, since the Altoids tin can conduct electricity and could cause a short circuit if one isn&#8217;t careful. I considered this, and decided to pursue a different approach inspired by <a href="http://www.recomputepc.com/">these computers</a>. This had the added benefit of reusing the shipping box my BeagleBone arrived in, and effectively eliminates the risk of a short occurring. In summary; it is simply several layers of corrugated cardboard glued together with plain white glue, a set of self adhesive rubber feet, and some 1/2 inch 4-40 screws, nuts and nylon standoffs. At each step I also traced a rough template for that layer (seen below) which may be of use to anyone who wishes to replicate this project.</p>
<table style="margin:auto;">
<tbody>
<tr>
<td>
<p><div id="attachment_388" class="wp-caption aligncenter" style="width: 169px"><a href="http://ejrob.files.wordpress.com/2012/05/beaglebone-case-template-print-at-95.png"><img class=" wp-image-388  " title="beaglebone case template print at 95%" src="http://ejrob.files.wordpress.com/2012/05/beaglebone-case-template-print-at-95.png?w=159&#038;h=216" alt="" width="159" height="216" /></a><p class="wp-caption-text">The Basic Template</p></div></td>
<td>
<p><div id="attachment_404" class="wp-caption aligncenter" style="width: 176px"><a href="http://ejrob.files.wordpress.com/2012/05/scan0081.jpg"><img class=" wp-image-404  " title="SCAN0081" src="http://ejrob.files.wordpress.com/2012/05/scan0081.jpg?w=166&#038;h=216" alt="" width="166" height="216" /></a><p class="wp-caption-text">Rough guide for layers 1 &#8211; 4</p></div></td>
<td>
<p><div id="attachment_405" class="wp-caption aligncenter" style="width: 177px"><a href="http://ejrob.files.wordpress.com/2012/05/scan0082.jpg"><img class=" wp-image-405  " title="SCAN0082" src="http://ejrob.files.wordpress.com/2012/05/scan0082.jpg?w=167&#038;h=216" alt="" width="167" height="216" /></a><p class="wp-caption-text">Rough guide for layers 5 &#8211; 7</p></div></td>
</tr>
</tbody>
</table>
<div id="attachment_390" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3108.jpg"><img class="size-medium wp-image-390" title="DSCF3108" src="http://ejrob.files.wordpress.com/2012/05/dscf3108.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The beginning of my template</p></div>
<p>I started by cutting the shipping box into several pieces for each of the layers in the case. I used the outline of an Altoids tin as the basis of my template since I knew the BeagleBone would fit snugly within that. This outline was scanned into my computer and modified it to create a general template with an inner area large enough for the BeagleBone.</p>
<p>For the base we need two layers; the bottom piece with large holes cut which will accommodate the tips of the screws and the nuts, and the upper piece which has holes just large enough for the screws and a notch for the USB client. I did not realize this notch was necessary until after I had already glued these two pieces together, and had to cut it in with an Xacto knife after the fact.</p>
<div id="attachment_391" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3115.jpg"><img class="size-medium wp-image-391 " title="DSCF3115" src="http://ejrob.files.wordpress.com/2012/05/dscf3115.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The two bottom most layers of the case, along with a couple template stencils.</p></div>
<p>To make the upper layer, I used my base template to trace both the outlines onto the cardboard, but did not cut out the inner area. Instead I centred the BeagleBone in the centre with the screws and nylon standoffs attached and firmly pressed down on the screws until they made light indentations on the cardboard. Using a nail with the same approximate diameter as the screws I then punched holes into the cardboard at these points so that the computer could be firmly attached when the case was finished.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_393" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3125.jpg"><img class="size-medium wp-image-393" title="DSCF3125" src="http://ejrob.files.wordpress.com/2012/05/dscf3125.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Letting the glue set</p></div>
<p>Next, it was necessary to glue these two pieces together, which was accomplished with a judicious amount of white glue (the kind you&#8217;ve probably used in elementary school). Once the glue became tacky, I wrapped a few elastic bands around them to keep them firmly pressed together and left them to dry for about half an hour.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_394" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3126.jpg"><img class="size-medium wp-image-394" title="DSCF3126" src="http://ejrob.files.wordpress.com/2012/05/dscf3126.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Cutting out the next set of layers</p></div>
<p>While the glue set, I went to work cutting out several pieces for the remaining layers, which were all derived from the base template with the inner area also removed. To remove the centres, I simply used the Xacto knife again with extra care around the rounded corners. I then cut out portions of these to make layers 3 and 4. Only one copy of the 3rd layer was necessary, while layer 4 needed to be repeated several times (the number of times will depend on the thickness of the cardboard used).</p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_395" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3127.jpg"><img class=" wp-image-395" title="DSCF3127" src="http://ejrob.files.wordpress.com/2012/05/dscf3127.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Building up the walls of the case</p></div>
<p>Like the two base layers, each of these remaining layers was glued to the base one at a time and the glue was allowed to set before the next layer was added. A set of plastic clamps were used because these layers have significant portions cut out it is not possible to use the elastic bands to hold them in place. This process should be repeated until the walls of the case come high enough to clear the Ethernet port on the BeagleBone.</p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div id="attachment_397" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3140.jpg"><img class="size-medium wp-image-397" title="DSCF3140" src="http://ejrob.files.wordpress.com/2012/05/dscf3140.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The case with the fifth layer added</p></div>
<p>After all this had been accomplished it was necessary to add a copy of the fifth layer to the top, which was simply one of the pieces I cut out earlier without any modifications. In my haste I neglected to double check that the walls of my case were high enough, and the fifth layer did not quite clear the Ethernet jack. I fixed this by cutting out the portion of layer 5 that stretched across the open area for these ports. This modification of the case can be seen in the image at the top of this post. It was also necessary to create a lid for the case, which was made by gluing together one copy of layer 6 and one of layer 7. I also had to cut a notch out of layer 6 to accommodate the Ethernet jack. If the correct number of copies of layer 4 are added, these modifications should be unnecessary.</p>
<div id="attachment_402" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3163.jpg"><img class="size-medium wp-image-402" title="DSCF3163" src="http://ejrob.files.wordpress.com/2012/05/dscf3163.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Some basic hardware holds the board firmly in place.</p></div>
<p>After finishing the case the last step was to firmly attach the BeagleBone to it using the nuts and washers. The nuts should be gently hand tightened so that they will not come undone while at the same time not crushing or damaging the cardboard where they connect. At this time I also added the rubber feet to the bottom of the case so that it would lift the cardboard off the surface and prevent it from sliding around.</p>
<p>Below are several images of the finished case, including a little bit of decoration I added to the lid a couple days later. I made it using a stencil based on <a href="https://upload.wikimedia.org/wikipedia/commons/7/7b/Recycling_symbol.svg">this image</a>, which I simply shaded in using a green felt marker. At the end of it all The case is not the most beautiful or elegant way to house a BeagleBone, though the fun I had designing and making it myself all while recycling the packing material makes up for that in strides. I also enjoy the texture the corrugated cardboard gives to the case, which is best seen in the profile view below. Lastly, the ease with which it can be decorated and customized to your liking is definitely another nice touch. All things considered, I am extremely pleased with how this project turned out.</p>
<table style="margin:auto;">
<tbody>
<tr>
<td>
<p><div id="attachment_399" class="wp-caption aligncenter" style="width: 250px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3146.jpg"><img class=" wp-image-399 " title="DSCF3146" src="http://ejrob.files.wordpress.com/2012/05/dscf3146.jpg?w=240&#038;h=180" alt="" width="240" height="180" /></a><p class="wp-caption-text">A side profile of the case</p></div></td>
<td>
<p><div id="attachment_401" class="wp-caption aligncenter" style="width: 250px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3157.jpg"><img class=" wp-image-401 " title="DSCF3157" src="http://ejrob.files.wordpress.com/2012/05/dscf3157.jpg?w=240&#038;h=180" alt="" width="240" height="180" /></a><p class="wp-caption-text">With the lid on</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_403" class="wp-caption aligncenter" style="width: 250px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3168.jpg"><img class=" wp-image-403 " title="DSCF3168" src="http://ejrob.files.wordpress.com/2012/05/dscf3168.jpg?w=240&#038;h=180" alt="" width="240" height="180" /></a><p class="wp-caption-text">The case and board in action</p></div></td>
<td>
<p><div id="attachment_442" class="wp-caption aligncenter" style="width: 250px"><a href="http://ejrob.files.wordpress.com/2012/05/dscf3175.jpg"><img class=" wp-image-442 " title="DSCF3175" src="http://ejrob.files.wordpress.com/2012/05/dscf3175.jpg?w=240&#038;h=180" alt="" width="240" height="180" /></a><p class="wp-caption-text">Decorative elements can be added too</p></div></td>
</tr>
</tbody>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/387/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=387&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/05/13/beaglebone-making-a-case/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/05/dscf3155.jpg?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3155.jpg?w=150" medium="image">
			<media:title type="html">DSCF3155</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3155.jpg" medium="image">
			<media:title type="html">DSCF3155</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/beaglebone-case-template-print-at-95.png?w=221" medium="image">
			<media:title type="html">beaglebone case template print at 95%</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/scan0081.jpg?w=230" medium="image">
			<media:title type="html">SCAN0081</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/scan0082.jpg?w=231" medium="image">
			<media:title type="html">SCAN0082</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3108.jpg?w=300" medium="image">
			<media:title type="html">DSCF3108</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3115.jpg?w=300" medium="image">
			<media:title type="html">DSCF3115</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3125.jpg?w=300" medium="image">
			<media:title type="html">DSCF3125</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3126.jpg?w=300" medium="image">
			<media:title type="html">DSCF3126</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3127.jpg?w=300" medium="image">
			<media:title type="html">DSCF3127</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3140.jpg?w=300" medium="image">
			<media:title type="html">DSCF3140</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3163.jpg?w=300" medium="image">
			<media:title type="html">DSCF3163</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3146.jpg?w=300" medium="image">
			<media:title type="html">DSCF3146</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3157.jpg?w=300" medium="image">
			<media:title type="html">DSCF3157</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3168.jpg?w=300" medium="image">
			<media:title type="html">DSCF3168</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/05/dscf3175.jpg?w=300" medium="image">
			<media:title type="html">DSCF3175</media:title>
		</media:content>
	</item>
		<item>
		<title>Nyan</title>
		<link>http://everettsprojects.com/2012/04/02/nyan/</link>
		<comments>http://everettsprojects.com/2012/04/02/nyan/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 23:41:38 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[nyan]]></category>
		<category><![CDATA[nyancat]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=318</guid>
		<description><![CDATA[This is a really simple modification of an existing program found here. All I have done is included a system call to mplayer that loads a short 27 second .wav file of the nyan cat background music and loops it for as long as the program is running. Obviously this requires one to have the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=318&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p style="text-align:center;"><a href="http://ejrob.files.wordpress.com/2012/04/nyan1.png"><img class="size-full wp-image-324 aligncenter" title="nyan" src="http://ejrob.files.wordpress.com/2012/04/nyan1.png?w=594&#038;h=380" alt="" width="594" height="380" /></a></p>
<p>This is a really simple modification of an existing program <a href="https://github.com/klange/nyancat">found here.</a> All I have done is included a system call to mplayer that loads a short 27 second .wav file of the nyan cat background music and loops it for as long as the program is running. Obviously this requires one to have the .wav file in the same directory as the binary, and to have mplayer installed. Alternatively, there is always the option to modify the source to call some other method of playing the audio file.</p>
<p>The argument passed to the nyancat binary to toggle the terminal title off was changed to <strong>-l</strong> so that the <strong>-s</strong> argument could be used for enabling the background music.</p>
<p>To rebuild the binary from the source  just put the following into your terminal while in the directory containing the readme:</p>
<p style="padding-left:30px;"><strong>make &amp;&amp; cd src</strong></p>
<p>Then to start the program with sound:</p>
<p style="padding-left:30px;"><strong>./nyancat -s</strong></p>
<p>An archive of the files necessary to experience the nyany awesomeness yourself can be <a href="http://dl.dropbox.com/u/54318573/Nyan/nyancat.zip">downloaded here</a>.</p>
<p>I initially debated whether or not to post this here, given it is such a trivial change, but decided I might as well since some one somewhere will be interested.</p>
<p style="text-align:center;">***</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/318/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=318&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/04/02/nyan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/04/nyan1.png?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/04/nyan1.png?w=150" medium="image">
			<media:title type="html">nyan</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/04/nyan1.png" medium="image">
			<media:title type="html">nyan</media:title>
		</media:content>
	</item>
		<item>
		<title>Terrarium! Nature in a Candy Jar.</title>
		<link>http://everettsprojects.com/2012/03/17/terrarium/</link>
		<comments>http://everettsprojects.com/2012/03/17/terrarium/#comments</comments>
		<pubDate>Sat, 17 Mar 2012 20:08:14 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Plants & Stuff]]></category>
		<category><![CDATA[Terrarium]]></category>

		<guid isPermaLink="false">http://everettsprojects.com/?p=272</guid>
		<description><![CDATA[This post is different from all of my previous projects which are primarily electronics oriented, and it isn&#8217;t even a new project per say. I started this terrarium last year using a glass jar that originally contained some candy, and filled it with compost and moss. It worked well at first, but eventually the moss [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=272&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This post is different from all of my previous projects which are primarily electronics oriented, and it isn&#8217;t even a new project per say. I started this terrarium last year using a glass jar that originally contained some candy, and filled it with compost and moss. It worked well at first, but eventually the moss stopped growing and started to turn brown despite the fact that I kept it adequately watered. I left the jar in this state for a fairly long time until I noticed a small centipede living inside of it a few weeks ago. Upon closer inspection I noticed several other insects and invertebrates including small snails, a worm, and some small flies. Feeling bad about letting their tiny habitat descend into such a decrepit state, and realizing I couldn&#8217;t just release them outside at this time of year, I decided to try and revive my Terrarium.</p>
<a href="http://everettsprojects.com/2012/03/17/terrarium/#gallery-272-1-slideshow">Click to view slideshow.</a>
<p>I have a few hypotheses for why my initial attempts at this project failed, one of the first being my use of water directly from my household taps. Like most municipalities, our water is chlorinated for public health reasons, and it is a definite possibility that the frequent influx of chlorine into such a small and contained ecosystem was harming it&#8217;s inhabitants. To correct for this, I&#8217;ve decided to use the water from our temporary indoor aquarium that houses the fish we normally have in our backyard pond during the summer. This has the added benefit of giving my terrarium a boost in available nutrients.</p>
<p>A second possibility is that despite my best efforts to keep the terrarium adequately moist without drowning it, I misjudged and either under- or over-watered it. I haven&#8217;t implemented a proper solution for this potential issue yet, but it has led me to consider a future Arduino project that can quantitatively measure the soil moisture of my terrarium, and eliminate the need for subjective and qualitative assessments. Luckily for me, someone has already worked out <a href="http://www.cheapvegetablegardener.com/2009/11/how-to-make-cheap-soil-moisture-sensor-2.html">a functional and cost effective solution</a> for this.</p>
<p>The last issue I though of was that by only including moss in my Terrarium, there was a lack of biodiversity that made it susceptible to excessive growth by micro organisms or fungus. This seemed to be supported by the fact that some of the dead moss eventually started to turn an odd white color, with a slight change in its visual texture. To fix this, I simply decided to throw in some bird seed. I know from our backyard feeder that the seeds the birds cast away or don&#8217;t eat grow into a variety of grasses and grains during the spring and summer.</p>
<p>From the pictures I&#8217;ve taken over the past couple weeks the birdseed is clearly growing well, and the moss is starting to turn green again. It&#8217;s already clear that the jar will be too small for the grasses, let alone the sunflower to grow to full size. Hopefully they will be able to survive in the limited space. It is still too early to say whether this second attempt at making a terrarium out of a candy jar will work out, but my hopes are high, and I intend to post updates later on. I am also getting excited about the possibility of extending this project by building some sort of web enabled monitoring system with the previously mentioned moisture sensor, and perhaps a temperature and light sensor if possible.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/272/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=272&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/03/17/terrarium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/03/march16a.jpg?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/03/march16a.jpg?w=150" medium="image">
			<media:title type="html">March 16</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>
	</item>
		<item>
		<title>Vetinari&#8217;s Clock &#8211; A Clock that Ticks Irregularly</title>
		<link>http://everettsprojects.com/2012/01/21/vetinaris-clock-a-clock-that-ticks-irregularly/</link>
		<comments>http://everettsprojects.com/2012/01/21/vetinaris-clock-a-clock-that-ticks-irregularly/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 02:32:54 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Clocks]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[PIC Microcontrollers]]></category>
		<category><![CDATA[Terry Pratchett]]></category>
		<category><![CDATA[Vetinari]]></category>

		<guid isPermaLink="false">http://ejrob.wordpress.com/?p=165</guid>
		<description><![CDATA[I saw this sort of project posted on Hackaday a few months ago, originally using an Arduino, and quickly went to work building my own. It worked well when plugged into the USB port of my computer, and I was excited to hook it up to some batteries and see how long it would run [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=165&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p style="text-align:center;"><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='480' height='360' src='http://www.youtube.com/embed/EJFM901fKv8?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span></p>
<p style="text-align:left;">I saw this sort of project posted on Hackaday a few months ago, <a href="http://hackaday.com/2011/10/06/vetinari-clock-will-drive-you-insane/">originally using an Arduino</a>, and quickly went to work building my own. It worked well when plugged into the USB port of my computer, and I was excited to hook it up to some batteries and see how long it would run (knowing full well that the Arduino was probably going to run them dry fairly quickly). It made it about 36 hours before the clip of 5 AA batteries was drained, and so I decided to try and rig it up with a 9V wall adapter power supply. Unfortunately, for reasons I am still unsure of, the whole thing would stop ticking after exactly 38 seconds and I quickly gave up in frustration. Luckily for me, Simon Inns came up with <a href="http://www.waitingforfriday.com/index.php/Vetinari's_Clock">a version using a PIC microcontroller</a> that runs much longer on only 2 AA batteries. Having never used PIC microcontrollers, I decided this was a good opportunity to learn something about them and used some money received at Christmas to order the parts and tools necessary for my own version of this clock.</p>
<div id="attachment_169" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2825.jpg"><img class="size-medium wp-image-169" title="DSCF2825" src="http://ejrob.files.wordpress.com/2012/01/dscf2825.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The components necessary to make it work</p></div>
<p style="text-align:left;">Each clock requires a PCB, a PIC 12F683 microcontroller, two Schottkey diodes (1N5819), two 47Ω resistors, two 22pF capacitors, one 100nF capacitor, a 32.768 kHz crystal, and a 6 pin 0.1″ header of some sort for programming (I used a male right angle header). It is also a good idea to use a DIP socket for the PIC microcontroller, so that it can easily be removed if necessary. Using the Cadsoft Eagle schematics and board files supplied by Simon Inns, I slightly rerouted one of the traces so that it would pass the DRC Bot (an automated program to check that prototype boards conform to the rules) at BatchPCB.com and ordered a couple of the boards. I was pleasantly surprised when they arrived and I found 4 boards, all of which appeared to be in perfect condition. Altogether, the materials necessary for a single clock cost less than $20 (not including the tools to program the PIC or the shipping fees).</p>
<div class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2833.jpg"><img class="wp-image-171 " title="DSCF2833" src="http://ejrob.files.wordpress.com/2012/01/dscf2833.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The PCB with components soldered in plac</p></div>
<p style="text-align:left;">I started by soldering everything to the PCB which was straight forward, though the capacitors I purchased were different from the ones originally used by Simon Inns, and I had to bend the leads to make them fit. The picture to the right shows all of the components soldered into place, with the exception of the leads for the clock and battery clip. It is also important to make sure the Diodes are installed in the correct direction, or else they will not properly protect the microcontroller from the flyback voltage that is generated by the solenoid in the clock mechanism.</p>
<p style="text-align:left;">Next it is necessary to dissect the clock, and hook up the solenoid that drives it to our circuitry instead of the little board that normally drives it. In theory this is simply done by cutting the traces to the little pads near the bottom where the solenoid attaches, and then soldering our own wires to it, though the board inside the clock is cheap, and the copper pad itself delaminated from the board almost immediately upon trying this.</p>
<div id="attachment_178" class="wp-caption alignright" style="width: 280px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2857.jpg"><img class=" wp-image-178 " title="DSCF2857" src="http://ejrob.files.wordpress.com/2012/01/dscf2857.jpg?w=270&#038;h=203" alt="" width="270" height="203" /></a><p class="wp-caption-text">The left copper pad has delaminated from the board</p></div>
<div id="attachment_176" class="wp-caption alignleft" style="width: 280px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2843.jpg"><img class=" wp-image-176  " title="DSCF2843" src="http://ejrob.files.wordpress.com/2012/01/dscf2843.jpg?w=270&#038;h=203" alt="" width="270" height="203" /></a><p class="wp-caption-text">The guts of the clock mechanism</p></div>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<div class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2858.jpg"><img class=" wp-image-179 " title="DSCF2858" src="http://ejrob.files.wordpress.com/2012/01/dscf2858.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Everything rewired to the battery contacts, and hot glued</p></div>
<p>Not to be defeated, I simply rerouted the thin wires of the solenoid to the large copper pads that were formerly the contact points for the battery, and made all of my connections there. I followed that with plenty of hot glue to keep everything firmly in place, and then went about putting the clock mechanism back together. Unfortunately for me I neglected to double check that everything was functioning before I glued it, which caused some issues later. Lesson learned: check your solder joints BEFORE you smother them in glue.</p>
<div id="attachment_181" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2864.jpg"><img class="size-medium wp-image-181" title="DSCF2864" src="http://ejrob.files.wordpress.com/2012/01/dscf2864.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">All of the clockwork put back in place.</p></div>
<p style="text-align:left;"><span style="color:#ffffff;">.</span></p>
<p style="text-align:left;">In order to reassemble the clock, I had to cut a notch in the housing to make space for the leads I had just soldered on, and I also trimmed off most of the plastic that formed the original battery holder, since it was no longer necessary. After replacing the back plate and soldering the battery leads (make sure the polarity is correct!) and the clock leads in place on the PCB, I then hot glued everything to the back of the clock and stuck in a couple of batteries.</p>
<p style="text-align:left;"><span style="color:#ffffff;">.</span></p>
<div id="attachment_174" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2840.jpg"><img class="size-medium wp-image-174" title="DSCF2840" src="http://ejrob.files.wordpress.com/2012/01/dscf2840.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The original clock used with the arduino, now being run by the same circuit on a breadboard</p></div>
<p style="text-align:left;"><span style="color:#ffffff;">.</span></p>
<p style="text-align:left;">This was the point at which I realized something had gone wrong, since the clock was not ticking like the one I had already assembled using a breadboard. At first I was worried that one of the components on the PCB had been fried, but my trusty multimeter assured me otherwise when I saw pulses of voltage at the point where the clock leads had been soldered onto the PCB. This was were I realized that the problem must exist at the solder joints in the clock, which I had already hot glued. Oops! Luckily I already had a functioning clock mechanism from back when I assembled my power hungry Arduino version, which I had already hooked up to the breadboard version seen left. I cut the leads between the clock and the PCB, and swapped out the broken clock mechanism for the functioning one. Since both clocks were the same, this was a trivial task (thankfully).</p>
<div id="attachment_183" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2870.jpg"><img class="size-medium wp-image-183" title="DSCF2870" src="http://ejrob.files.wordpress.com/2012/01/dscf2870.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The functioning clock, with swapped clock mechanism</p></div>
<p style="text-align:left;">Finally the clock was assembled and functioning, and I used some more hot glue to hold everything in place, including all of the wires. I also strategically positioned the PCB so the 6 pin programming headers would face downwards for easy access. Uploading the program the PIC is fairly easy, and I accomplished it without any issues by using the PICKit 3 with Microchip&#8217;s MPLAB X IDE. At the same time, I decided to re-brand the clock (no name dollar store brands don&#8217;t cut it) using some stickers I got when I ordered the components. I have had the clock running on a fresh pair of AA batteries since January 11th, 2012, and while it fell behind the clock on my computer by 10 seconds in the first two days, it has maintained accurate time since. My plan now is to leave it on my wall and test how long it runs on a pair of batteries and to compare that to the back of the envelope calculation I did earlier, which predicted at least 60 days for lower capacity batteries. While I have not yet noticed any brain mushification as a result of the clock, it seems like it disrupts my sleep slightly by causing me to wake more often during the night. We&#8217;ll see whether the batteries or my patience for poor sleep give out first.</p>
<div id="attachment_184" class="wp-caption aligncenter" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2012/01/dscf2871.jpg"><img class="size-medium wp-image-184  alignleft" title="DSCF2871" src="http://ejrob.files.wordpress.com/2012/01/dscf2871.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">Re-branded and fully functioning!</p></div>
<p>While over simplified, the circuit is basically 2 47Ω resistors in series, for a total of 94Ω.</p>
<p>It operates at 3V, so the current draw is 3V/94Ω = 0.0319A = 31.9mA.</p>
<p>But the clock mechanism is only powered for 30ms for each tick, which on average occur once per second, so the average current draw is 31.9mA * 30ms/1000ms = 0.957mA.</p>
<p>The PIC microcontroller draws 11μA at 32kHz, which is essentially negligible in such a rough calculation.</p>
<p>Rounding the average current draw up to 1mA, and assuming a cheap set of AA batteries with 1500mAh capacity, the clock should theoretically run for 1500 hours, which works out to 62.5 days. For a  better set of batteries with 2500mAh capacity, we get 2500 hours of operation, or about 104 days. In either case, two AA batteries every 2 to 3 months is far better than 5 AA batteries every 36 hours.</p>
<p><strong>EDIT: The clock managed to go for about 5 months on a pair of batteries before it became noticeably slow. It was 10 minutes behind the correct time when I finally replaced its batteries.</strong></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/165/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=165&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2012/01/21/vetinaris-clock-a-clock-that-ticks-irregularly/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2012/01/dscf2871.jpg?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2871.jpg?w=150" medium="image">
			<media:title type="html">DSCF2871</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2825.jpg?w=300" medium="image">
			<media:title type="html">DSCF2825</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2833.jpg?w=300" medium="image">
			<media:title type="html">DSCF2833</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2857.jpg?w=300" medium="image">
			<media:title type="html">DSCF2857</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2843.jpg?w=300" medium="image">
			<media:title type="html">DSCF2843</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2858.jpg?w=300" medium="image">
			<media:title type="html">DSCF2858</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2864.jpg?w=300" medium="image">
			<media:title type="html">DSCF2864</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2840.jpg?w=300" medium="image">
			<media:title type="html">DSCF2840</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2870.jpg?w=300" medium="image">
			<media:title type="html">DSCF2870</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2012/01/dscf2871.jpg?w=300" medium="image">
			<media:title type="html">DSCF2871</media:title>
		</media:content>
	</item>
		<item>
		<title>Solar Powered Robot Bugs!</title>
		<link>http://everettsprojects.com/2011/12/27/solar-powered-robot-bugs/</link>
		<comments>http://everettsprojects.com/2011/12/27/solar-powered-robot-bugs/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 09:03:12 +0000</pubDate>
		<dc:creator>Everett</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Kits]]></category>
		<category><![CDATA[Robotics]]></category>
		<category><![CDATA[Solarbotics]]></category>

		<guid isPermaLink="false">http://ejrob.wordpress.com/?p=74</guid>
		<description><![CDATA[This is not a project in which I spent much time designing or planning things myself, but I had a lot of fun with it, and it let me try out my brand new Hakko soldering station. It simply entails the assembly of the Photopopper Photovore robot kit from Solarbotics.com . What is a Photopopper [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=74&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<div id="attachment_92" class="wp-caption aligncenter" style="width: 600px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2781.jpg"><img class="wp-image-92 " title="DSCF2781" src="http://ejrob.files.wordpress.com/2011/12/dscf2781.jpg?w=590&#038;h=445" alt="" width="590" height="445" /></a><p class="wp-caption-text">The finished product</p></div>
<div id="attachment_84" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2751.jpg"><img class="wp-image-84 " title="DSCF2751" src="http://ejrob.files.wordpress.com/2011/12/dscf2751.jpg?w=300&#038;h=252" alt="" width="300" height="252" /></a><p class="wp-caption-text">My new Hakko FX-888 soldering station</p></div>
<p style="text-align:left;">This is not a project in which I spent much time designing or planning things myself, but I had a lot of fun with it, and it let me try out my brand new Hakko soldering station. It simply entails the assembly of the <a href="http://www.solarbotics.com/products/k_pp/" target="_blank">Photopopper Photovore robot kit</a> from <a href="http://www.solarbotics.com" target="_blank">Solarbotics.com</a> . What is a Photopopper Photovore? It&#8217;s basically a small solar powered robot, which uses Infrared and tactile sensors to simultaneously move towards sources of light and avoid obstacles. It also bears resemblance to an insect, especially a stinkbug. This kit really interests me, because the &#8220;behaviour&#8221; of the robot is caused through hardwired circuitry alone, and no microcontrollers or code are needed. The description included by Solarbotics says it is based on something called MillerEngine technology which (in all honesty) means nothing to me. Regardless, the circuit isn&#8217;t overly difficult to follow, and one need not know what a MillerEngine is to appreciate it.</p>
<div id="attachment_110" class="wp-caption aligncenter" style="width: 599px"><a href="http://ejrob.files.wordpress.com/2011/12/photopoppercircuit.png"><img class=" wp-image-110    " title="PhotopopperCircuit" src="http://ejrob.files.wordpress.com/2011/12/photopoppercircuit.png?w=589&#038;h=260" alt="" width="589" height="260" /></a><p class="wp-caption-text">The Photopopper Photovore circuit</p></div>
<p>Since I am only a hobbyist, my assessment may not be correct, but hopefully I&#8217;m not too far off the mark. Essentially what happens is that the solar cell charges the large 4.7mF capacitor (C1), and then when the voltage in the capacitor is high enough, the voltage trigger on one of the sides engages.The determination of which voltage trigger is engaged is determined by the IR and tactile sensors, where the tactile sensors take priority over the IR sensors to ensure obstacle avoidance in addition to the light seeking behaviour. The voltage trigger then trips the corresponding transistor which applies a current across the motor on that side until the voltage  drops enough to disengage the voltage trigger. The small capacitors (C2 and C3) are responsible for determining the length and frequency of the motor activity by affecting the voltage at the voltage triggers, and the diodes simply make sure the current moves in the correct direction. The trimpot makes it possible to tune the robot to favor one side over the other, or to balance it so that it moves directly towards sources of light.</p>
<p>Before going further, I feel like it would be a good idea to make it clear that this project was very enjoyable even though I encountered several issues while working on it. I wouldn&#8217;t want to discourage anyone from taking it on simply because I like to complain about things.</p>
<div id="attachment_83" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2749.jpg"><img class="size-medium wp-image-83  " title="DSCF2749" src="http://ejrob.files.wordpress.com/2011/12/dscf2749.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The components all laid out (I apologize for the blurriness)</p></div>
<p>The <a href="http://www.solarbotics.com/assets/documentation/solarbotics_photopopper_kit_may032007.pdf">assembly instructions</a> were good, and I really can&#8217;t complain too much in that regard. To start, you are shown a parts list, so you can be sure you have all the necessary components before proceeding. The most interesting part in this kit is probably the PCB, which is cut and formed to make this robot recognizable as an insect. In addition, there is  a large capacitor, trimpot, solar cell, and a pair each of diodes, voltage triggers, transistors, capacitors, motors, IR sensors, and the components to make each antenna (the tactile sensors).</p>
<div id="attachment_87" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2764.jpg"><img class="size-medium wp-image-87 " title="DSCF2764" src="http://ejrob.files.wordpress.com/2011/12/dscf2764.jpg?w=300&#038;h=219" alt="" width="300" height="219" /></a><p class="wp-caption-text">The underside with the voltage triggers, diodes, transistors, capacitors and trimpot installed</p></div>
<p><span style="color:#ffffff;">.</span></p>
<p>The first components to be installed are the voltage triggers, trimpot, and diodes, followed by the transistors and small capacitors. After this, the IR sensors are added. The installation of all these components was fairly straight forward, and was easily accomplished with the new soldering iron.</p>
<div id="attachment_88" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2771.jpg"><img class="size-medium wp-image-88" title="DSCF2771" src="http://ejrob.files.wordpress.com/2011/12/dscf2771.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">The motor mounts with motors soldered on</p></div>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p><span style="color:#ffffff;">.</span></p>
<p>The next component to go on was the large storage capacitor, which had to have its leads bent 90 degrees so that it could lie flat against the PCB. The motor mounts were also fairly easy to attach, using a combination of folding tabs and plenty of solder. Once attached, the motors themselves simply clipped into place.</p>
<div id="attachment_91" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2780.jpg"><img class="size-medium wp-image-91" title="DSCF2780" src="http://ejrob.files.wordpress.com/2011/12/dscf2780.jpg?w=300&#038;h=239" alt="" width="300" height="239" /></a><p class="wp-caption-text">The support wire: Murphy's Law finally shows up.</p></div>
<p>Next, it was necessary to install the support wire to ensure the photopopper&#8217;s legs would reach the ground. Unfortunately this is where my problems began, since I failed to make sure the wire was short enough before I began soldering it on. While it is technically possible to fix this by twisting it to increase tension, I found the spring of the PCB itself was stronger than the wire and I had to constantly re-tighten it. Eventually metal fatigue occurred, and the poor wire broke. Luckily I had a paperclip of a similar gauge (seen in the picture to the left) which seemed to be much stronger, and was capable of withstanding the flex of the PCB. After this, some of the heat-shrink tubing was applied to the motor shafts to make the tires/feet, and the paperclip was given a small twist to make sure they reached the ground.</p>
<div id="attachment_90" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2777.jpg"><img class="size-medium wp-image-90" title="DSCF2777" src="http://ejrob.files.wordpress.com/2011/12/dscf2777.jpg?w=300&#038;h=215" alt="" width="300" height="215" /></a><p class="wp-caption-text">The solar panel is now attached</p></div>
<p>Attaching the solar cell was fairly easy, though wire strippers were needed to prepare the twisted red and black wire before it could be soldered to the right places. A piece of double sided sticky tape was then used to hold it into place. This was the next source of problems, because I mounted the solar panel before making sure each of the motors was working, and ruined it when I removed the panel to resolder one of the wires to the board. Luckily I had a replacement available, and I tested the conductivity of the adhesive before use to make sure it would not short anything. To best way to test each motor is to place the robot in direct sunlight or under an incandescent lightbulb, and then use something to short the square and circle pads on each side of the robot&#8217;s head (where the antennae will later be installed). From experience I recommend this step is performed before the solar panel is mounted. It is now a good idea to tune to robot, before the antenna are installed. To achieve this, the robot should be put near a source of light, and then the trimpot should be adjusted to make sure it moves towards that source, and doesn&#8217;t veer to either side. after this is achieved it is best to not to fiddle with it, as troubleshooting antennae and IR sensor balance at the same time was unnecessarily difficult.</p>
<div id="attachment_148" class="wp-caption aligncenter" style="width: 604px"><a href="http://ejrob.files.wordpress.com/2011/12/antennae.png"><img class="size-full wp-image-148" title="Antennae" src="http://ejrob.files.wordpress.com/2011/12/antennae.png?w=594&#038;h=298" alt="" width="594" height="298" /></a><p class="wp-caption-text">The structure of the tactile sensors</p></div>
<div id="attachment_93" class="wp-caption alignright" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf27821.jpg"><img class=" wp-image-93" title="DSCF2782" src="http://ejrob.files.wordpress.com/2011/12/dscf27821.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a><p class="wp-caption-text">With the antennae installed</p></div>
<p>The idea behind the tactile sensors is that when they collide with something it causes the spring to bend and connect with the central pin. This shorts the circuit and bypasses the IR sensor to make sure the robot moves away from obstacles. This step was especially troublesome, since the heat shrink tubing didn&#8217;t contract enough, and the spring would not fit without significant forcing. Through a combination of slightly untwisting the spring to increase its diameter, forcing the tubing through with a screwdriver, and applying excessive force (enough to bend the pin), the spring was eventually moved into place. The antennae were then ready to be soldered on, with the wire from the spring connecting with one pad, and the base of the pin onto the other pad. Because the pins were bent from the previous step, a fair amount of adjustment had to be performed to ensure the short only occurred when the sensors were triggered. The antennae alone took at least as long as the rest of the assembly combined.</p>
<div id="attachment_149" class="wp-caption alignleft" style="width: 310px"><a href="http://ejrob.files.wordpress.com/2011/12/dscf2801.jpg"><img class="size-medium wp-image-149" title="DSCF2801" src="http://ejrob.files.wordpress.com/2011/12/dscf2801.jpg?w=300&#038;h=185" alt="" width="300" height="185" /></a><p class="wp-caption-text">The finished Photopopper with curled antennae</p></div>
<p>After a fair amount of testing, I found that the antennae worked best when curled around, otherwise they would often spring past an obstacle, and fail to provide continued avoidance behaviour.</p>
<p>The last issue with this kit is that the solar panel it uses works extremely well in direct sunlight, but for us Canadians direct sunlight is in short supply this time of year. The alternative is to use an incandescent light bulb (florescent and halogen bulbs wont work), but these days incandescent lightbulbs are not so common. Luckily I was able to find an old desk lamp and incandescent bulb to use for testing and tuning. The video below shows some of this testing, in which the robot turns around to face the light source, then moves forward a short distance. This process slowly repeats itself. Obstacle avoidance is harder to fine tune, as the antennae often get stuck in the shorted position if mishandled. The problem of antennae springing past obstacles and not providing persistent avoidance still exists after they have been curled, though it&#8217;s less common.</p>
<p>Despite the issues encountered, this kit was very fun, and it was a great way to test out a new soldering iron. That being said; from start to finish it took much longer than the 2 hours they estimate in the instruction manual, and I can only imagine how difficult it would be with a cheap &#8220;fire starter&#8221; stick iron.</p>
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='594' height='365' src='http://www.youtube.com/embed/xe-yosaL-i0?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span>
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='594' height='365' src='http://www.youtube.com/embed/nzbNN_y84R0?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0'></iframe></span>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ejrob.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ejrob.wordpress.com/74/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=everettsprojects.com&#038;blog=14753287&#038;post=74&#038;subd=ejrob&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://everettsprojects.com/2011/12/27/solar-powered-robot-bugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="http://ejrob.files.wordpress.com/2011/12/dscf27821.jpg?w=150" />
		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf27821.jpg?w=150" medium="image">
			<media:title type="html">DSCF2782</media:title>
		</media:content>

		<media:content url="http://0.gravatar.com/avatar/9d76d9c8bafdbea146a9623eaa5b73ec?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ejrob</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2781.jpg" medium="image">
			<media:title type="html">DSCF2781</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2751.jpg" medium="image">
			<media:title type="html">DSCF2751</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/photopoppercircuit.png" medium="image">
			<media:title type="html">PhotopopperCircuit</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2749.jpg?w=300" medium="image">
			<media:title type="html">DSCF2749</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2764.jpg?w=300" medium="image">
			<media:title type="html">DSCF2764</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2771.jpg?w=300" medium="image">
			<media:title type="html">DSCF2771</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2780.jpg?w=300" medium="image">
			<media:title type="html">DSCF2780</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2777.jpg?w=300" medium="image">
			<media:title type="html">DSCF2777</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/antennae.png" medium="image">
			<media:title type="html">Antennae</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf27821.jpg?w=300" medium="image">
			<media:title type="html">DSCF2782</media:title>
		</media:content>

		<media:content url="http://ejrob.files.wordpress.com/2011/12/dscf2801.jpg?w=300" medium="image">
			<media:title type="html">DSCF2801</media:title>
		</media:content>
	</item>
	</channel>
</rss>
