<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[alexba.in]]></title>
  <link href="http://alexba.in/atom.xml" rel="self"/>
  <link href="http://alexba.in/"/>
  <updated>2016-08-22T03:14:07+00:00</updated>
  <id>http://alexba.in/</id>
  <author>
    <name><![CDATA[Alex Bain]]></name>
    <email><![CDATA[alex@alexba.in]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[lirc_web v0.3.0]]></title>
    <link href="http://alexba.in/blog/2016/03/13/lirc-web-v0-3-0/"/>
    <updated>2016-03-13T11:50:00+00:00</updated>
    <id>http://alexba.in/blog/2016/03/13/lirc-web-v0-3-0</id>
    <content type="html"><![CDATA[<p><code>v0.3.0</code> of <code>lirc_web</code> has just been published to npm.</p>

<p>This release targets mobile optimizations and performance. <code>lirc_web</code> now behaves more like a native app when added to the home screen of a mobile device. A favicon is now shown on the home screen, the URL bar will be hidden from view, and <code>lirc_web</code> will be selectable from the device&#8217;s multitasking screen. Furthermore, CSS assets are bundled into a single request, small images are now base64 encoded, and an application cache has been introduced to cache all assets locally between requests.</p>

<p>In my testing, with a warm cache, <code>lirc_web</code> now fires a <code>load</code> event within 300ms.</p>

<p>Here&#8217;s the relevant piece of <code>CHANGELOG.md</code> that describes all updates since <code>v0.2.0</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>## [0.3.0] - 2016-03-13
</span><span class='line'>
</span><span class='line'>* Adds `grunt-contrib-cssmin` task to combine all CSS requests into one
</span><span class='line'>* Adds ability to set lirc socket in `config.json` (thanks @pmgration)
</span><span class='line'>* Base64 `left-arrow.png` image to reduce a request
</span><span class='line'>* Adds application cache manifest file for offline caching
</span><span class='line'>
</span><span class='line'>## [0.2.4] - 2016-01-13
</span><span class='line'>
</span><span class='line'>* Extracts macros into a standalone lib/macros.js file
</span><span class='line'>* Adds Favicon (thanks @flochtililoch)
</span><span class='line'>* Adds npm run test:watch action (thanks @OvisMaximus)
</span><span class='line'>* Travis build will now run linter
</span><span class='line'>* Updated dependencies
</span><span class='line'>* Uses local version of jQuery for testing now
</span><span class='line'>
</span><span class='line'>## [0.2.3] - 2016-01-03
</span><span class='line'>
</span><span class='line'>* Fixing bug where labels were loaded before config (thanks @flochtililoch)
</span><span class='line'>
</span><span class='line'>## [0.2.2] - 2016-01-01
</span><span class='line'>
</span><span class='line'>* Removing `Makefile` for running tests. Only need `package.json`.
</span><span class='line'>* Fixing .gitignore error for the global lirc_web build
</span><span class='line'>
</span><span class='line'>## [0.2.1] - 2015-12-31
</span><span class='line'>
</span><span class='line'>* `lirc_web` can now be installed globally and called by `lirc_web` from CLI
</span><span class='line'>* Adding ESLint to the mix and ensuring all JS conforms to Airbnb ES5 standards
</span></code></pre></td></tr></table></div></figure>


<p>New features are documented in the <a href="https://github.com/alexbain/lirc_web/blob/master/README.md">README</a> and the <a href="https://github.com/alexbain/lirc_web/blob/master/CHANGELOG.md">CHANGELOG</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[lirc_web v0.2.0]]></title>
    <link href="http://alexba.in/blog/2015/12/31/lirc-web-v0-2-0/"/>
    <updated>2015-12-31T04:56:00+00:00</updated>
    <id>http://alexba.in/blog/2015/12/31/lirc-web-v0-2-0</id>
    <content type="html"><![CDATA[<p>The <code>lirc_web</code> project (available at <a href="https://github.com/alexbain/lirc_web">https://github.com/alexbain/lirc_web</a>) has been updated to <code>v0.2.0</code>, which contains some new features and bugfixes. Here&#8217;s the summary of the new functionality now available in the project:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[0.2.0] - 2015-12-30
</span><span class='line'>
</span><span class='line'>Adding blacklist configuration option to hide unused keys from UI (thanks @OvisMaximus)
</span><span class='line'>Adding support for SSL (thanks @de-live-gdev)
</span><span class='line'>Fixing example config in the README (thanks @de-live-gdev)
</span><span class='line'>Fixes url escaping bug with macros and remotes (issue #23)
</span><span class='line'>
</span><span class='line'>[0.1.0] - 2015-12-30
</span><span class='line'>
</span><span class='line'>Locking npm versions to ensure future install work
</span><span class='line'>Adding CHANGELOG.md
</span><span class='line'>Adding /refresh link on bottom to reload UI after making changes to LIRC (thanks @f00f)
</span><span class='line'>Adding ability to set custom labels on command and remote names (thanks @elysion)
</span><span class='line'>Adding Apple mobile app capability, disabling zoom (thanks @elysion)
</span><span class='line'>Moving Lato fonts locally to remove external network dependency</span></code></pre></td></tr></table></div></figure>


<p>New features are documented in the <a href="https://github.com/alexbain/lirc_web/blob/master/README.md">README</a>.</p>

<p>On a related note, <code>lirc_node</code> (available at <a href="https://github.com/alexbain/lirc_node">https://github.com/alexbain/lirc_node</a>) has been updated to <code>v0.0.4</code>. There&#8217;s no new functionality in this release, simply locked NPM dependency versions and the addition of a change log.</p>

<p>If you run into any issues with either project, let me know in the comments or (ideally) via the <a href="https://github.com/alexbain/lirc_web/issues">issues page</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Automatically reconnecting WiFi on a RaspberryPi]]></title>
    <link href="http://alexba.in/blog/2015/01/14/automatically-reconnecting-wifi-on-a-raspberrypi/"/>
    <updated>2015-01-14T03:55:00+00:00</updated>
    <id>http://alexba.in/blog/2015/01/14/automatically-reconnecting-wifi-on-a-raspberrypi</id>
    <content type="html"><![CDATA[<p>In this post, I&#8217;m going to cover writing a short script that automatically reconnects a RaspberryPi to a WiFi network. The script will check to see if the Pi has network connectivity and, if it&#8217;s offline, will restart the wireless interface to bring it back online. We&#8217;ll use <code>cron</code> to schedule the execution of this script at a regular interval.</p>

<p>There are a few ways to determine if the RaspberryPi has network connectivity. For this script, we&#8217;ll be using <code>ping</code>.</p>

<h3>Writing the script</h3>

<p>To get started, we&#8217;ll need to determine if the RaspberryPi is connected to the network. To do this, we&#8217;ll attempt to ping a server and see if we get a response. If the command succeeds (RaspberryPi receives a response from the server), we have network connectivity. If the command fails, we&#8217;ll turn <code>wlan0</code> off and back on.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>#!/bin/bash
</span><span class='line'>
</span><span class='line'># The IP for the server you wish to ping (8.8.8.8 is a public Google DNS server)
</span><span class='line'>SERVER=8.8.8.8
</span><span class='line'>
</span><span class='line'># Only send two pings, sending output to /dev/null
</span><span class='line'>ping -c2 ${SERVER} &gt; /dev/null
</span><span class='line'>
</span><span class='line'># If the return code from ping ($?) is not 0 (meaning there was an error)
</span><span class='line'>if [ $? != 0 ]
</span><span class='line'>then
</span><span class='line'>    # Restart the wireless interface
</span><span class='line'>    ifdown --force wlan0
</span><span class='line'>    ifup wlan0
</span><span class='line'>fi</span></code></pre></td></tr></table></div></figure>


<p>Name the script something memorable (<code>wifi_rebooter.sh</code>), and place this script in <code>/usr/local/bin</code>. Make sure it&#8217;s executable by running:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>chmod +x /usr/local/bin/wifi_rebooter.sh</span></code></pre></td></tr></table></div></figure>


<h3>Scheduling regular execution</h3>

<p>To ensure the script runs automatically, we&#8217;ll use <code>cron</code>. The frequency that you run this script is a matter of personal preference - I chose to run the script every five minutes.</p>

<p>To schedule the script, open <code>/etc/crontab</code> for editing and add this line to the bottom:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>*/5 *   * * *   root    /usr/local/bin/wifi_rebooter.sh</span></code></pre></td></tr></table></div></figure>


<p>This will ensure that the script is run, as root, every 5 minutes. If you&#8217;re unfamiliar with <code>cron</code> syntax, take a look at the <a href="http://www.nncron.ru/help/EN/working/cron-format.htm">cron format</a>.</p>

<h3>Testing</h3>

<p>To test that the script works as expected, we are going to take down the <code>wlan0</code> interface and wait for the script to bring it back up. Before taking down <code>wlan0</code>, you may want to adjust the interval in <code>/etc/crontab</code> to 1 minute. Also, note that this will immediately disconnect you from your shell session.</p>

<p>To take down <code>wlan0</code> to confirm the script works, run:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ifdown --force wlan0</span></code></pre></td></tr></table></div></figure>


<p>After waiting patiently for ~1 minute, try SSHing back into your RaspberryPi. Assuming everything worked, your RaspberryPi should have automatically reconnected to WiFi. Don&#8217;t forget to adjust the interval in <code>/etc/crontab</code> back to a more appropriate value, if you set it to one minute for testing.</p>

<p>Hopefully this helps keep your RaspberryPi projects online! If you have any questions, or have an alternative method to suggest, feel free to leave a comment.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[lirc_web v0.0.8]]></title>
    <link href="http://alexba.in/blog/2014/08/10/lirc-web-v0-0-8/"/>
    <updated>2014-08-10T19:18:00+00:00</updated>
    <id>http://alexba.in/blog/2014/08/10/lirc-web-v0-0-8</id>
    <content type="html"><![CDATA[<p>In this post I&#8217;m going to talk about two features I&#8217;ve added to the <a href="https://github.com/alexbain/lirc_web">lirc_web</a> project. <a href="https://github.com/alexbain/lirc_web">lirc_web</a> is a NodeJS app I wrote that provides a web interface and JSON based API for controlling <a href="http://lirc.org/">LIRC</a>, an open source project that lets you control IR devices from the command line. I built <a href="https://github.com/alexbain/lirc_web">lirc_web</a> to run on a RaspberryPi along with an expansion board I designed so that anyone could build their own fully customizable universal remote that is controllable via a web interface from any web connected device (phone, tablet, laptop, smart watch, etc).</p>

<p><img src="http://alexba.in/images/posts/universal-remote/lirc_web_v0_0_8.png" height="640px" width="384px" class="center" /></p>

<p>If you&#8217;d like additional context about the project, you may be interested in:</p>

<ul>
<li><a href="http://opensourceuniversalremote.com/">Open Source Univeral Remote</a></li>
<li><a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Pictures</a></li>
<li><a href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/">RaspberryPi IR Schematic for LIRC</a></li>
<li><a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC From the Web</a></li>
</ul>


<p>In v0.0.8 I&#8217;ve added two new features - macros and repeaters.</p>

<h3>Macros</h3>

<p>Macros allowing you to execute multiple IR commands in rapid succession from a single button tap or HTTP request. The use case for this would be when you need multiple devices to be turned on and set to a certain mode to perform an activity (say, playing a video game or watching a movie). An example macro might be:</p>

<ul>
<li>Turn TV on</li>
<li>Set TV to input 3</li>
<li>Turn receiver on</li>
<li>Set receiver input HDMI2</li>
<li>Turn game console on</li>
</ul>


<p>Macros make performing common multi-step tasks simpler. In addition, Macros are exposed via the API, which means you can execute macros by sending an HTTP request from a growing number of internet of things or web connected devices. For example, you could adjust the volume of the TV from your <a href="https://getpebble.com/steel">Pebble watch</a> or change the TV channel by waving your arm while wearing a <a href="https://www.thalmic.com/en/myo/">Myo armband</a>.</p>

<p>Macros are defined in a <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> configuration file (<code>config.json</code>) that <code>lirc_web</code> expects to find in the root of the project. Here&#8217;s an example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "macros": {
</span><span class='line'>    "Play Xbox 360": [
</span><span class='line'>      [ "SonyTV", "Power" ],
</span><span class='line'>      [ "SonyTV", "Xbox360" ],
</span><span class='line'>      [ "Yamaha", "Power" ],
</span><span class='line'>      [ "Yamaha", "Xbox360" ],
</span><span class='line'>      [ "Xbox360", "Power" ]
</span><span class='line'>    ],
</span><span class='line'>    "Listen to Music": [
</span><span class='line'>      [ "Yamaha", "Power" ],
</span><span class='line'>      [ "Yamaha", "AirPlay" ]
</span><span class='line'>    ]
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The <code>macros</code> key is an object of keys (labels) that are set to arrays of <code>[remote, command]</code>  pairs. The <code>remote</code> and <code>command</code> strings should match what is defined in the LIRC configuration file. A small delay is introduced between each command to ensure they are all received.</p>

<p>After you create or change anything in <code>config.json</code>, you will have to restart <code>lirc_web</code>. Afterwards, you&#8217;ll see your macros listed at the bottom of the user interface.</p>

<p>Macros are also available via the API. You can execute them by creating a POST request to a url like so:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>http://ip-of-remote/macros/Play%20Xbox%20360</span></code></pre></td></tr></table></div></figure>


<h3>Repeaters</h3>

<p>Repeaters are a type of button that repeatedly send it&#8217;s command as long as it is held down. The use case for a repeater would be a volume button that should continue to change the volume as long as it&#8217;s pressed - rather than needing to tap it many times.</p>

<p>Repeaters are also specified in the configuration file. Here&#8217;s an example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "repeaters": {
</span><span class='line'>    "SonyTV": {
</span><span class='line'>      "VolumeUp": true,
</span><span class='line'>      "VolumeDown": true
</span><span class='line'>    }
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Similar to macros, the name of the <code>remote</code> and <code>command</code> must match the names you gave these commands in the LIRC configuration file. If you want to change the name of a button, update the LIRC configuration file and restart LIRC / lirc_web.</p>

<h3>Enjoy</h3>

<p>I&#8217;ve found these two features make the <a href="http://opensourceuniversalremote.com/">Open Source Universal Remote</a> significantly more useful for common tasks. If you have any suggestions for new features or ideas on how to improve the project, please share your ideas in the comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Receiving SMS notifications from your washer & dryer]]></title>
    <link href="http://alexba.in/blog/2014/01/06/receiving-sms-notifications-from-your-washer/"/>
    <updated>2014-01-06T03:05:00+00:00</updated>
    <id>http://alexba.in/blog/2014/01/06/receiving-sms-notifications-from-your-washer</id>
    <content type="html"><![CDATA[<p><img src="http://alexba.in/images/posts/lundry/thumb_pebble_notification.jpg" class="center" /></p>

<p>Previously, I discussed how I built an <a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">open source universal remote</a> using a RaspberryPi, an expansion board, and a <a href="http://github.com/alexbain/lirc_web">NodeJS web application</a>. This device allows me to control any infrared device in my home from my phone, smart watch, laptop, or other web connected device. I use the remote daily, and it&#8217;s sparked my curiosity to devise new ways of enhancing my environment with internet connected devices.</p>

<p>In this post, I&#8217;m going to cover a new project I recently finished - creating a device that monitors a washer or dryer and sends a text message when it detects that a load of laundry has finished. Beyond the novelty and simplicity of receiving a text message when the laundry is done, I built this device for two reasons. First, I wanted a project that introduced me to accelerometers - a sensor I&#8217;ve wanted to work with. Second, I wanted to take another stab at applying the principles of <a href="http://en.wikipedia.org/wiki/Progressive_enhancement">progressive enhancement</a>, a web software concept, to the physical world.</p>

<blockquote><p>&#8220;Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, [&#8230;] while also providing an enhanced version of the page to those with more advanced browser software [&#8230;].&#8221; (<a href="http://en.wikipedia.org/wiki/Progressive_enhancement">Wikipedia</a>)</p></blockquote>

<p>I wanted to see if I could apply the concept of progressive enhancement to the physical world by enhancing an existing appliance (in this case, a washer or dryer) with new digital functionality - without modifying it&#8217;s existing form or interface. I wanted the appliance to look and behave exactly as it did before the modification, and I wanted no visual evidence that my device had been installed. After some brainstorming, I came up with an approach that met my goals. Read on to learn how I build it, and how you can build one yourself.</p>

<p><img src="http://alexba.in/images/posts/lundry/thumb_circuit_macro.jpg" class="center" /></p>

<h3>Overview</h3>

<p>At a high level, the project works as follows: a 3D printed enclosure magnetically attaches to the outside of the washer or dryer. Inside the enclosure is an <a href="http://electricimp.com">Electric Imp</a> microcontroller and an <a href="http://www.adafruit.com/products/163">ADXL335 accelerometer</a>. The accelerometer measures the vibrations of the washer and dryer. The microcontroller has firmware on it that samples the accelerometer, processes the output, and periodically sends a computed result to a server in the cloud. The server receives the output and runs an algorithm that determines whether the washer or dryer is currently running. Once the server has confidently determined that the washer or dryer has finished running, it sends an SMS (using <a href="http://twilio.com">Twilio</a>) to one or more predefined phone numbers.</p>

<p>I&#8217;ll cover the implementation in more detail below. This post is broken down into three sections:</p>

<ul>
<li>The hardware</li>
<li>The 3D printable enclosure</li>
<li>The software</li>
</ul>


<p>I&#8217;ll end with a conclusion and some closing thoughts.</p>

<h2>Part 1: The Hardware</h2>

<p><img src="http://alexba.in/images/posts/lundry/thumb_hardware_device.jpg" class="center" /></p>

<p>For this project, I purchased most of my parts from <a href="http://adafruit.com">Adafruit</a>, an online retailer of electronic components. The rest of the parts I purchased from <a href="http://amazon.com">Amazon</a>. Here&#8217;s the bill of materials:</p>

<ul>
<li><a href="http://www.adafruit.com/products/1129">Electric Imp</a></li>
<li><a href="http://www.adafruit.com/products/1130">April dev board for Electric Imp</a></li>
<li><a href="http://www.adafruit.com/products/163">ADXL335 analog 3.3V +-3g accelerometer</a></li>
<li><a href="http://www.adafruit.com/products/589">Quarter size perma-proto breadboard</a></li>
<li><a href="http://www.adafruit.com/products/501">USB power supply</a></li>
<li><a href="http://www.amazon.com/AmazonBasics-A-Male-Mini-B-Cable-Meters/dp/B001TH7GUK/ref=sr_1_1?ie=UTF8&amp;qid=1388982594&amp;sr=8-1&amp;keywords=usb+mini">USB A to Mini B cable</a></li>
<li><a href="http://www.adafruit.com/products/289">Solid core wire</a></li>
<li>2 small rare earth magnets (available from any hardware store)</li>
</ul>


<h3>Electric Imp</h3>

<p><img src="http://alexba.in/images/posts/lundry/thumb_electric_imp.jpg" class="center" /></p>

<p>For this project, I chose to work with the <a href="http://electricimp.com/product/">Electric Imp</a> microcontroller. The Electric Imp is a microcontroller in the form factor of an SD card with a 32bit Cortex M3 processor. What I find most interesting about the Electric Imp is that it also includes an 802.11b/g/n chip, making it one of the smallest WiFi enabled microcontrollers I&#8217;ve found. I also used the <a href="http://www.adafruit.com/products/1130">April development board</a>, a breakout board from the Electric Imp team, which breaks out the pins on the imp and provides a mini USB connection for power. You can see that development board, a green circuit board, in the image beneath the &#8220;Hardware&#8221; header.</p>

<p>Configuring the Electric Imp with your WiFi credentials is done through a clever process called <a href="http://electricimp.com/product/blinkup/">BlinkUp</a>. The Imp itself contains a phototransistor, which enables you to program your WiFi credentials optically, via an app on your Android or iOS device. Once you install and configure the app, the display on your phone strobes in a pattern that the Imp recognizes, which programs the WiFi credentials into the Imp. The process only takes a few seconds, and it worked flawlessly for me the first time.</p>

<p>Once you&#8217;ve programmed your WiFi credentials onto the Imp, it will automatically connect to the Electric Imp cloud service. From there, you&#8217;re able to login to the web based IDE and program the imp via your web browser. The IDE handles deploying code updates to the device, as well. I&#8217;d like to see a GitHub integration, which would provide version control, so hopefully that&#8217;s on their roadmap.</p>

<h3>ADXL335 Analog Accelerometer</h3>

<p><img src="http://alexba.in/images/posts/lundry/thumb_adxl335.jpg" class="center" /></p>

<p>For the accelerometer (the component that measures the vibration of the washing machine / dryer), I chose the <a href="http://www.analog.com/static/imported-files/data_sheets/ADXL335.pdf">ADXL335</a>. The ADXL335 is a 3.3V analog accelerometer sensitive to +- 3g. The device itself is widely used, and I found plenty of documentation online. In addition, <a href="http://adafruit.com">Adafruit</a> sells a breakout board (listed above in the bill of materials) that made including the device in my project an easy decision. The breakout board that Adafruit sells also allows you to connect the accelerometer to a 5V microcontroller, such as an Arduino.</p>

<h3>Assembling the Hardware</h3>

<p><a href="http://alexba.in/images/posts/lundry/hardware_device_2.jpg"><img src="http://alexba.in/images/posts/lundry/thumb_hardware_device_2.jpg" class="center" /></a></p>

<p>The assembly of the device is relatively straightforward. First, you will need to assemble the April development board and the ADXL335 breakout board by soldering the header pins onto the breakout boards. Next, you&#8217;ll need to solder both breakout boards into the perma-proto board. Lastly, you&#8217;ll solder in the 5 wires to enable the two components to communicate. <strong>If you intend to use the 3D printable enclosure, please ensure that the two components are mounted identically to the image above.</strong></p>

<p>The picture above shows how the device looks when assembled, and here are the specifics:</p>

<ul>
<li>Pin 1 from Electric Imp is connected to the X-out pin on accelerometer.</li>
<li>Pin 2 from the Electric Imp is connected to the Y-out pin on accelerometer.</li>
<li>Pin 5 from the Electric Imp is connected to the Z-out pin on accelerometer.</li>
<li>3V3 pin from Electric Imp is connected to the Vin pin on accelerometer.</li>
<li>GND pin from Electric Imp is connected to GND pin on accelerometer.</li>
</ul>


<p>At this point you should be able to:</p>

<ul>
<li>Boot the device up with a USB power supply</li>
<li>Program the Electric Imp to connect to your WiFi</li>
<li>Log into the Electric Imp web based IDE to program the device</li>
</ul>


<h2>Part 2: The 3D Printable Enclosure</h2>

<p><a href="http://alexba.in/images/posts/lundry/empty_case.jpg"><img src="http://alexba.in/images/posts/lundry/thumb_empty_case.jpg" class="center" /></a></p>

<p>For this project, I wanted a custom enclosure that would enable the device to be sealed from dust and debris. I contacted a friend of mine, John Steenson, who agreed to help me design a 3D printable enclosure for the project. He has agreed to let me post the STL files for the case, which you can download and have 3D printed yourself. I had my case printed from a local printer that I found on the <a href="http://3dhubs.com">3D Hubs</a> service. I had a great experience with 3D Hubs, and highly suggest it if you&#8217;re trying to find a local 3D printer.</p>

<p><a href="http://alexba.in/images/posts/lundry/occupied_case.jpg"><img src="http://alexba.in/images/posts/lundry/thumb_occupied_case.jpg" class="center" /></a></p>

<p><a href="http://alexba.in/images/posts/lundry/case_with_lid.jpg"><img src="http://alexba.in/images/posts/lundry/thumb_case_with_lid.jpg" class="center" /></a></p>

<p>The above photos show the device mounted in the case (with and without the lid). Inside of the case, but beneath the device, I have attached (with two sided tape) the two rare earth magnets. I then placed a thin sheet of plastic between the magnets and the device to ensure there is no chance of electrical short. I have not found that the magnets interfere with the device in any way. The two magnets are what enables the device to attach to the washer or dryer.</p>

<p><strong>STL files for the 3D printable enclosure:</strong></p>

<ul>
<li><a href="http://alexba.in/stl/lundry/Enclosure_base.STL">Enclosure - Base</a></li>
<li><a href="http://alexba.in/stl/lundry/Enclosure_lid.STL">Enclosure - Lid</a></li>
</ul>


<p><strong>Screws / nuts for mounting device within enclosure and securing lid:</strong></p>

<p>All part numbers are from <a href="http://www.mcmaster.com/">McMaster-Carr</a>. Per my friend John, quantities noted are the quantities required for assembly, not package quantity. You&#8217;ll have some extra parts, but they&#8217;ll probably come in handy for future projects down the road.</p>

<ul>
<li>3x - 91420A008</li>
<li>2x - 92000A015</li>
<li>2x - 93475A195</li>
<li>5x - 90592A004</li>
<li>1x - 8461K12 - Trim to fit</li>
</ul>


<h2>Part 3: Writing the Software</h2>

<p>When writing software for the Electric Imp, you write two programs. The first program, called the &#8220;Device&#8221;, runs on the Electric Imp hardware. The second program, called the &#8220;Agent&#8221;, runs on the Electric Imp cloud. The Agent has the ability to send and receive HTTP traffic, making it a perfect candidate for the Twilio API, a RESTful API that allows you to send SMS messages.</p>

<p>For this project, the Device samples the accelerometer 50x a second. I found this to be frequent enough to get a clear picture for how much the washer or dryer is vibrating. For each sample, I determine the magnitude of the accelerometer vector and compute the percentage of change against the previous sample&#8217;s magnitude. I track the amount of change over 5 seconds (250 samples), and return that value to the Agent. In my testing, I found that the average reading when the machine was turned off to be between 100 and 250. When the washer or dryer are running, I find the samples vary between 275 and 6000 depending on what stage of the cycle the machine is in.</p>

<p>The Agent receives the total amount change over the past 250 samples, and compares that against a threshold to determine if the machine is ON or OFF. If the value is above the threshold, the device is experiencing enough vibration where it&#8217;s safe to call the machine ON. In my testing, I found 280 to be a good threshold to determine if the washer or dryer was running. Once the Agent receives N consecutive samples above the threshold, it enters the RUNNING state. Then, at some point in the future, once the Agent receives M consecutive samples below the ON threshold, it returns to the OFF state. These delays help take into account lulls in vibration during a typical laundry cycle (ex: filling the washer, rinse cycle, draining the washer). Depending on your appliances, you may need to adjust the thresholds in the Agent to reduce false positives. Finally, when returning to the OFF state, if the device was in the RUNNING state, an SMS notification is emitted (via <a href="http://twilio.com">Twilio</a>) to each phone number stored in the <code>phoneNumbers</code> array.</p>

<p>If you&#8217;d like to read more about how to process the data coming off an accelerometer, I found <a href="http://www.starlino.com/imu_guide.html">A Guide To using IMU (Accelerometer and Gyroscope Devices) in Embedded Applications</a> to be an extremely informative read.</p>

<p><strong> Note:</strong> The Agent code requires you to setup a Twilio account and enter your Twilio credentials before you can send any messages. Twilio, at the time of writing this article, charges $0.01 per text message. At the rate I do laundry, it should cost &lt; $2 a year to send these text messages.</p>

<p><strong>Note2:</strong> If you would like to log all of your data to a persistent data store (either to show on a web page, or just to analyze output), <a href="http://firebase.com">Firebase</a> is a great option, and they have a free tier. Just change <code>logToFirebase</code> to be <code>true</code> and enter your Firebase URL if you want to enable this feature.</p>

<p>You may also <a href="https://gist.github.com/alexbain/8392153">view this code</a> on GitHub.</p>

<p>Here is the code for the Device, which reads in and processes the accelerometer data:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>total &lt;- 0; // Sum of % change from all samples
</span><span class='line'>n &lt;- 0;     // Counter for number of samples read
</span><span class='line'>last &lt;- 1;  // Previous reading of magnitude
</span><span class='line'>
</span><span class='line'>function readSensor() {
</span><span class='line'>    // Time interval
</span><span class='line'>    local interval = 0.02;
</span><span class='line'>
</span><span class='line'>    // Get source voltage, should be 3.3V
</span><span class='line'>    local vRef = hardware.voltage();
</span><span class='line'>
</span><span class='line'>    // Read in ADC values from accelerometer
</span><span class='line'>    local adcRx = hardware.pin1.read();
</span><span class='line'>    local adcRy = hardware.pin2.read();
</span><span class='line'>    local adcRz = hardware.pin5.read();
</span><span class='line'>    // server.log(format("Raw ADC values: %f, %f, %f", adcRx, adcRy, adcRz));
</span><span class='line'>
</span><span class='line'>    // Convert 16bit ADC accelerometer values (0-65535) into voltage
</span><span class='line'>    local voltsRx = (adcRx * vRef) / 65535.0;
</span><span class='line'>    local voltsRy = (adcRy * vRef) / 65535.0;
</span><span class='line'>    local voltsRz = (adcRz * vRef) / 65535.0;
</span><span class='line'>    // server.log(format("Voltages: %f, %f %f", voltsRx, voltsRy, voltsRz));
</span><span class='line'>
</span><span class='line'>    // Subtract 0g (1.5V at 3V, 1.65V at 3.3V)
</span><span class='line'>    local deltaVoltsRx = voltsRx - (vRef / 2);
</span><span class='line'>    local deltaVoltsRy = voltsRy - (vRef / 2);
</span><span class='line'>    local deltaVoltsRz = voltsRz - (vRef / 2);
</span><span class='line'>    // server.log(format("Adjusted voltages %f, %f, %f", deltaVoltsRx, deltaVoltsRy, deltaVoltsRz));
</span><span class='line'>
</span><span class='line'>    // Convert from voltage to g, using sensitivity of 300mV
</span><span class='line'>    local rX = deltaVoltsRx / 0.3;
</span><span class='line'>    local rY = deltaVoltsRy / 0.3;
</span><span class='line'>    local rZ = deltaVoltsRz / 0.3;
</span><span class='line'>    // server.log(format("Gs: %f, %f, %f", rX, rY, rZ));
</span><span class='line'>
</span><span class='line'>    // Compute magnitude of force
</span><span class='line'>    local magnitude = math.sqrt(math.pow(rX,2) + math.pow(rY, 2) + math.pow(rZ, 2));
</span><span class='line'>
</span><span class='line'>    // Compute % change since last reading
</span><span class='line'>    local change = math.fabs((magnitude - last)/last) * 100.0;
</span><span class='line'>
</span><span class='line'>    // Store magnitude in last for next time
</span><span class='line'>    last = magnitude;
</span><span class='line'>
</span><span class='line'>    // Log magnitude and percent change
</span><span class='line'>    // server.log(format("magnitude: %f, change amount: %f", magnitude, change));
</span><span class='line'>
</span><span class='line'>    // Increment total with % change, increment N
</span><span class='line'>    total = total + change;
</span><span class='line'>    n = n + 1;
</span><span class='line'>
</span><span class='line'>    // Log data to server once ever 250 samples (5 seconds)
</span><span class='line'>    if (n &gt;= 250) {
</span><span class='line'>        agent.send("data", total);
</span><span class='line'>        n = 0;
</span><span class='line'>        total = 0;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    // Sleep until time to read sensor again
</span><span class='line'>    imp.wakeup(interval, readSensor);
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>// X input
</span><span class='line'>hardware.pin1.configure(ANALOG_IN);
</span><span class='line'>
</span><span class='line'>// Y input
</span><span class='line'>hardware.pin2.configure(ANALOG_IN);
</span><span class='line'>
</span><span class='line'>// Z input
</span><span class='line'>hardware.pin5.configure(ANALOG_IN);
</span><span class='line'>
</span><span class='line'>// Start reading the sensor
</span><span class='line'>readSensor();</span></code></pre></td></tr></table></div></figure>


<p>Here is the code for the Agent, which determines when to send an SMS</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>// Run on Agent
</span><span class='line'>
</span><span class='line'>// Thresholds to adjust for better accuracy
</span><span class='line'>dataThreshold &lt;- 280; // Minimum accelerometer value to count as ON
</span><span class='line'>onThreshold &lt;- 24;    // Number of ON samples before machine enters RUNNING state
</span><span class='line'>offThreshold &lt;- 60;   // Number of OFF samples before machine enters OFF state
</span><span class='line'>
</span><span class='line'>// State variable
</span><span class='line'>running &lt;- false;
</span><span class='line'>
</span><span class='line'>// Keep track of counts
</span><span class='line'>onCount &lt;- 0;
</span><span class='line'>offCount &lt;- 0;
</span><span class='line'>
</span><span class='line'>// Twilio
</span><span class='line'>twilioURL &lt;- "https://USER:PASS@api.twilio.com/2010-04-01/Accounts/ID/Messages.json";
</span><span class='line'>twilioHeaders &lt;- { "Content-Type": "application/x-www-form-urlencoded" };
</span><span class='line'>twilioNumber &lt;- "+14155551212";
</span><span class='line'>
</span><span class='line'>// Array of phone numbers to be contacted with the laundry is done
</span><span class='line'>phoneNumbers &lt;- ["+14155555555", "+14155555556"];
</span><span class='line'>
</span><span class='line'>// Firebase
</span><span class='line'>logToFirebase &lt;- false;
</span><span class='line'>firebaseURL &lt;- "https://FIREBASE_URL.firebaseIO.com/data.json";
</span><span class='line'>firebaseHeaders &lt;- { "Content-Type": "application/json" };
</span><span class='line'>
</span><span class='line'>// Called every time the imp emits data
</span><span class='line'>device.on("data", function(data) {
</span><span class='line'>
</span><span class='line'>    // Is there enough accelerometer activity for the device to be considered ON?
</span><span class='line'>    if (data &gt;= dataThreshold) {
</span><span class='line'>        onCount = onCount + 1;
</span><span class='line'>
</span><span class='line'>        // Prevent overflow errors by resetting onCount when it gets close to limit
</span><span class='line'>        if (onCount &gt;= 65500) {
</span><span class='line'>            onCount = onThreshold;
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        // If the device has been ON for long enough, set running state to be true
</span><span class='line'>        if (onCount &gt;= onThreshold) {
</span><span class='line'>            running = true;
</span><span class='line'>
</span><span class='line'>            // Running, so reset offCount
</span><span class='line'>            offCount = 0;
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        // debug / logs
</span><span class='line'>        if (running == true) {
</span><span class='line'>            server.log(format("ON - RUNNING (%f), onCount (%d), offCount (%d)", data, onCount, offCount));
</span><span class='line'>        } else {
</span><span class='line'>            server.log(format("ON (%f), onCount (%d), offCount (%d)", data, onCount, offCount));
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>    // Imp is not recording much accelerometer movement, so device seems to be OFF
</span><span class='line'>    } else {
</span><span class='line'>        offCount = offCount + 1;
</span><span class='line'>
</span><span class='line'>        // Prevent overflow errors by resetting offCount when it gets close to limit
</span><span class='line'>        if (offCount &gt;= 65500) {
</span><span class='line'>            offCount = offThreshold;
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        // Has the device been off for long enough to be "done"?
</span><span class='line'>        if (offCount &gt;= offThreshold) {
</span><span class='line'>
</span><span class='line'>            // Was the device previously running?
</span><span class='line'>            if (running == true) {
</span><span class='line'>
</span><span class='line'>                // This means that the laundry had been running, and is now done.
</span><span class='line'>
</span><span class='line'>                // Send an SMS to each phone number in the phoneNumbers array.
</span><span class='line'>                foreach (number in phoneNumbers) {
</span><span class='line'>                    local body = format("To=%s&From=%s&Body=The%%20laundry%%20is%%20done.", number, twilioNumber);
</span><span class='line'>                    local request = http.post(twilioURL, twilioHeaders, body);
</span><span class='line'>                    local response = request.sendasync(function(done) {});
</span><span class='line'>                }
</span><span class='line'>
</span><span class='line'>                // debug / logs
</span><span class='line'>                server.log("!!!! Emitting OFF event !!!!");
</span><span class='line'>            }
</span><span class='line'>
</span><span class='line'>            // Reset on count
</span><span class='line'>            onCount = 0;
</span><span class='line'>
</span><span class='line'>            // Machine is no longer running
</span><span class='line'>            running = false;
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>        // debug / logs
</span><span class='line'>        if (running == true) {
</span><span class='line'>            server.log(format("OFF - WAS RUNNING (%f), onCount (%d), offCount (%d)", data, onCount, offCount));
</span><span class='line'>        } else {
</span><span class='line'>            server.log(format("OFF (%f), onCount (%d), offCount (%d)", data, onCount, offCount));
</span><span class='line'>        }
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    if (logToFirebase == true) {
</span><span class='line'>        // Build a post request to Firebase to log the data
</span><span class='line'>        local body = format("{\"amount\": %f, \"running\": %s, \".priority\": %d}", data, running ? "true" : "false", time());
</span><span class='line'>        local request = http.post(firebaseURL, firebaseHeaders, body);
</span><span class='line'>
</span><span class='line'>        // Send the data to Firebase async
</span><span class='line'>        local response = request.sendasync(function(done) {});
</span><span class='line'>    }
</span><span class='line'>});</span></code></pre></td></tr></table></div></figure>


<p>After loading these two pieces of software onto the Electric Imp (via the web IDE), you should be ready to install the device in your home! Installation is simple - just magnetically attach the device to any metal service on the washer or dryer. Give it a whirl by doing a load of laundry and watching the log files (via the web IDE). If all goes well, you should receive a text message a few minutes after the load of laundry completes.</p>

<h3>Conclusion</h3>

<p>I set out to build a minimally invasive device that progressively enhanced an appliance into the digital age, which didn&#8217;t physically modify the appliance in any way. During the project I had the opportunity to work with a few new technologies - the Electric Imp, an accelerometer, and 3D printing. All in all, I&#8217;d say the project was a success. The device is currently hooked up to my washer, and it works well in it&#8217;s current state.</p>

<p>This project came out of a (relatively) trivial need - to know when a load of laundry is done when you aren&#8217;t in close proximity to the washer or dryer. I thought it would be clever to receive a text message when the laundry is done, since all phones support SMS and Twilio has made interacting with SMS easy. This also gets around the need to download or install a native app on your phone.</p>

<p>I do recognize there are other approaches to solving this problem - monitoring the power output of the appliance, listening for the buzzer with a microphone, or placing a photodiode over a &#8220;done&#8221; indicator - but I ultimately chose the accelerometer because I wanted to gain experience working with the sensor.</p>

<p>While I do not believe I&#8217;ll be spending much additional time on this project, there are a number of potential enhancements that I see:</p>

<ul>
<li>Adding a battery, to make the device portable.</li>
<li>Swapping out a WiFi chip for a GSM chip, allowing you to take the device to a laundromat.</li>
<li>Designing a custom circuit board, to dramatically reduce the size of the device.</li>
<li>Creating a waterproof (and heat tolerant) device/enclosure so you can place the device inside the washer/dryer. This would be more secure than leaving a device on top of a machine.</li>
</ul>


<p>Hopefully you found this post helpful if you&#8217;re trying to implement a similar device yourself. If you have any questions, feel free to ask in the comments. If you&#8217;re interested in having one of these devices for yourself, but don&#8217;t want to build one, send me an email at <a href="mailto:alex@alexba.in">alex@alexba.in</a> and we can work something out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Running lirc_web with nginx and upstart]]></title>
    <link href="http://alexba.in/blog/2013/11/02/lirc-web-nginx-and-upstart/"/>
    <updated>2013-11-02T09:50:00+00:00</updated>
    <id>http://alexba.in/blog/2013/11/02/lirc-web-nginx-and-upstart</id>
    <content type="html"><![CDATA[<p>In this post I will cover how to start a NodeJS app (<code>lirc_web</code>) when a RaspberryPi boots up. This ensures that if the RaspberryPi ever loses power, the <code>lirc_web</code> app will restart when the system comes online. <code>lirc_web</code> is an open source NodeJS app I wrote as part of the <a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a> project. If you&#8217;d like to learn more about the project, please check out <a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Pictures</a>.</p>

<p>To accomplish this will take three steps:</p>

<ol>
<li>Configure the hostname for the RaspberryPi</li>
<li>Install and configure Upstart</li>
<li>Install and configure NGINX</li>
</ol>


<p><strong>Note: Not all mobile devices support <code>.local</code> domains. You may still need to connect via IP.</strong></p>

<h3>Configure the hostname for the RaspberryPi</h3>

<p>If you want your RaspberryPi to be accessible on your local network via hostname, instead of always typing it&#8217;s IP address, you&#8217;ll want to install an mDNS daemon. If you&#8217;d like to learn why, I recommend reading <a href="http://www.howtogeek.com/167190/how-and-why-to-assign-the-.local-domain-to-your-raspberry-pi/">How (and Why) to Assign the .local Domain to Your Raspberry Pi</a>. The RaspberryPi supports Avahi, which can be installed with:</p>

<pre><code>sudo apt-get install avahi-daemon
</code></pre>

<p>When that finishes, try pinging <code>raspberrypi.local</code> from a different computer. Everything should just work. Next, we&#8217;ll update the hostname of the RaspberryPi to be <code>universalremote</code>. This requires three steps:</p>

<ol>
<li>Edit <code>/etc/hosts</code> and change the last line to <code>127.0.1.1 universalremote</code></li>
<li>Edit <code>/etc/hostname</code> and change the hostname to <code>universalremote</code></li>
<li>Reboot the RaspberryPi by running <code>sudo shutdown -r now</code></li>
</ol>


<p>After the RaspberryPi boots back up, you should be able to connect to the RaspberryPi via hostname (<code>http://universalremote.local</code>) or IP.</p>

<h3>Install and configure Upstart</h3>

<p>To ensure the <code>lirc_web</code> app starts when the RaspberryPi boots, we will use a tool called <a href="http://upstart.ubuntu.com">Upstart</a>. Upstart is a project from Ubuntu that simplifies writing init scripts. If you want to learn more about it, you can visit <a href="http://upstart.ubuntu.com/">http://upstart.ubuntu.com/</a> and read more. RaspbianOS does not include Upstart by default, but it can be installed to replace sysvinit with no negative consequences. Here are the commands:</p>

<pre><code>sudo apt-get install upstart
# You will be asked to type 'Yes, do as I say!'
# You may see an error about initctl being unable to connect, which will be fixed after a reboot

# Reboot the RaspberryPi
sudo shutdown -r now
</code></pre>

<p>Once the RaspberryPi reboots Upstart should be installed. Upstart configuration files are placed in <code>/etc/init</code>. You can either use the sample Upstart configuration that comes with the <code>lirc_web</code> Git repository, or you can use this example (place in <code>/etc/init/open-source-universal-remote.conf</code>):</p>

<pre><code># /etc/init/open-source-universal-remote.conf
description "universalremote.local"

start on runlevel [2345]
stop on runlevel [016]

# Restart when job dies
respawn

# Give up restart after 5 respawns in 60 seconds
respawn limit 5 60

script

  echo $$ &gt; /var/run/open-source-universal-remote.pid
  exec /usr/local/bin/node /home/pi/lirc_web/app.js 2&gt;&amp;1 &gt;&gt; /var/log/open-source-universal-remote.upstart.log

end script

pre-start script
    # Date format same as (new Date()).toISOString() for consistency
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" &gt;&gt; /var/log/open-source-universal-remote.upstart.log
end script

pre-stop script
    rm /var/run/open-source-universal-remote.pid
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" &gt;&gt; /var/log/open-source-universal-remote.upstart.log
end script
</code></pre>

<p>After creating the Upstart script, you should be able to start the <code>lirc_web</code> project by running:</p>

<pre><code>sudo initctl start open-source-universal-remote
</code></pre>

<p>You can verify everything works by opening <code>http://universalremote.local:3000</code> (or the RaspberryPi&#8217;s IP address) in your web browser. You should see the <code>lirc_web</code> web interface.</p>

<h3>Install and Configure NGINX</h3>

<p>If you run <code>lirc_web</code> by itself it creates a basic web server on port 3000. This is fine, but it&#8217;s more convenient when an web application runs on port 80, the default port for web traffic. We&#8217;ll use the free and open source NGINX web server to accomplish this.</p>

<p>To install nginx and ensure it starts on boot, run:</p>

<pre><code>sudo apt-get install nginx
update-rc.d nginx defaults
sudo service nginx start
</code></pre>

<p>When this completes, confirm everything installed correctly by trying to  access <code>http://universalremote.local</code> in your web browser. You should see a &#8220;Welcome to nginx!&#8221; web page.</p>

<p>Next, we have to configure nginx to serve the <code>lirc_web</code> app. You can use the sample config file included in the <code>lirc_web</code> Git repository (within the config directory), or use this example:</p>

<pre><code>server {
    listen            80;
    server_name       universalremote.local;

    # Change this to the location you installed lirc_web
    root              /home/pi/lirc_web;
    index             index.html index.htm;

    access_log        /var/log/open-source-universal-remote.nginx.log;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://127.0.0.1:3000/;
        proxy_redirect off;
    }
}
</code></pre>

<p><strong>Update November 11th, 2013:</strong> Save this configuration data in a file called <code>/etc/nginx/conf.d/open-source-universal-remote.conf</code>. Nginx will automatically detect this file once you restart it.</p>

<p>Restart nginx to pick up the new configuration file with <code>sudo service nginx restart</code>.</p>

<p>Now, if you visit <code>http://universalremote.local</code> in your web browser you should now see the project running. In the future, any time you reboot the RaspberryPi <code>lirc_web</code> will start automatically.</p>

<h3>Conclusion</h3>

<p>If everything went smoothly you should now have a daemonzized version of <code>lirc_web</code> running on your RaspberryPi, which is being served via nginx over port 80. In addition, any time you restart your RaspberryPi the <code>lirc_web</code> app will start up at boot.</p>

<p>Are you interested in reading more about the Open Source Universal Remote project? Check out:</p>

<ul>
<li><a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/">Setting up LIRC on the RaspberryPi</a></li>
<li><a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC from the web</a></li>
<li><a href="http://alexba.in/blog/2013/06/01/using-the-pebble-watch-to-control-your-home-theater/">Using a RaspberryPi and a Pebble Watch to control your home theater</a></li>
<li><a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Pictures</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[lirc_web v0.0.5]]></title>
    <link href="http://alexba.in/blog/2013/08/21/lirc-web-v0-0-5/"/>
    <updated>2013-08-21T10:25:00+00:00</updated>
    <id>http://alexba.in/blog/2013/08/21/lirc-web-v0-0-5</id>
    <content type="html"><![CDATA[<p><strong>August 10, 2014 Update:</strong> Latest version is now <a href="http://alexba.in/blog/2014/08/10/lirc-web-v0-0-8/">lirc_web v0.0.8</a></p>

<p>I&#8217;ve updated the <code>lirc_web</code> project (available at <a href="http://github.com/alexbain/lirc_web">http://github.com/alexbain/lirc_web</a>) to v0.0.5. This version fixes a bug related to the <a href="https://npmjs.org/package/swig">swig</a> npm module that was causing an error when trying to view the project in a browser.</p>

<p>If you were encountering a JavaScript error after trying to install <code>lirc_web</code> this should fix it. Thanks to the folks that reported this.</p>

<p>Please let me know if you encounter any other errors!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Open Source Universal Remote - Parts &amp; Pictures]]></title>
    <link href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/"/>
    <updated>2013-06-08T16:17:00+00:00</updated>
    <id>http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures</id>
    <content type="html"><![CDATA[<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_installed.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_installed.jpg" class="center" /></a></p>

<p>This past weekend I converted my <a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a> breadboard layout into a more permanent soldered circuit. I used the <a href="http://octopart.com/ada801-adafruit+industries-27056076">Adafruit Protoboard</a> as a base instead of having a custom circuit board printed, which worked out well. The protoboard is perfectly sized for the RaspberryPi and I highly recommend it for any RaspberryPi related hardware projects.</p>

<p>Below, I&#8217;ve attached some high resolution photographs of the finished protoboard (front and back). I&#8217;ve also created separate versions of the photographs which are fully annotated and explain how all of the components are laid out. Please note that I did make one miscalculation in my circuit which I have corrected with a yellow jumper wire. I&#8217;ve pointed out the miscalculation on both annotated photographs.</p>

<h3>Parts list:</h3>

<ul>
<li><a href="http://octopart.com/ada801-adafruit+industries-27056076">1 Adafruit RaspberryPi Protoboard</a></li>
<li><a href="http://octopart.com/ir333c-everlight-17677690">2 940nm 40deg IR LEDs</a></li>
<li><a href="http://octopart.com/hlmp-5029-avago-549484">2 right angle LED holders</a></li>
<li><a href="http://octopart.com/p2n2222ag-on+semiconductor-358561">1 P2N2222AGOD-ND transistor</a></li>
<li><a href="http://octopart.com/od103je-ohmite-133027">1 10k Ohm resistor</a></li>
<li><a href="http://octopart.com/tsop38238-vishay-11814552">1 TSOP38238 38KHz IR receiver</a></li>
<li><a href="http://www.adafruit.com/products/1311">Hook-up Wire Spool Set - 22AWG Solid Core - 6 x 25 ft</a></li>
<li>RaspberryPi running LIRC (See: <a href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart/">RaspberryPi Quickstart</a>, <a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/">Setting Up LIRC on the RaspberryPi</a>, <a href="http://alexba.in/blog/2013/01/15/installing-nodejs-on-your-raspberrypi/">Installing NodeJS on your RaspberryPi</a>, and <a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC from the Web</a>)</li>
</ul>


<h3>Schematic:</h3>

<p><a href="http://upverter.com/alexbain/f24516375cfae8b9/Open-Source-Universal-Remote/#/"><img src="http://upverter.com/alexbain/f24516375cfae8b9/Open-Source-Universal-Remote/embed_img/13715285520000/" alt="Open Source Universal Remote by alexbain f24516375cfae8b9 - Upverter" /></a></p>

<h3>Project pictures:</h3>

<p>All pictures link to a full resolution image (10+ megapixel) which provides plenty of additional resolution for examining the circuit. The annotated photographs should help fill in anything that is unclear. If you have any questions, please leave them in the comments.</p>

<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_top.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_top.jpg" class="center" /></a></p>

<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_top_annotated.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_top_annotated.jpg" class="center" /></a></p>

<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_bottom.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_bottom.jpg" class="center" /></a></p>

<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_bottom_annotated.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_bottom_annotated.jpg" class="center" /></a></p>

<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_installed_alt.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_installed_alt.jpg" class="center" /></a></p>

<p><a href="http://alexba.in/images/posts/protoboard_v1/protoboard_v1_installed_back.jpg"><img src="http://alexba.in/images/posts/protoboard_v1/thumb_protoboard_v1_installed_back.jpg" class="center" /></a></p>

<p>If you&#8217;d like to read more about this project, here is some further reading:</p>

<ul>
<li><a href="http://alexba.in/blog/2013/03/06/open-source-universal-remote/">Open Source Universal Remote intro</a> - Intro post to the project</li>
<li><a href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/">RaspberryPi IR Schematic for LIRC</a> - Electrical schematic for the hardware</li>
<li><a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/">Setting up LIRC on the RaspberryPi</a> - Installing and configuring IR software</li>
<li><a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC From the Web</a> - Installing (mobile/desktop) web interface</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Open terminal's working directory in Finder]]></title>
    <link href="http://alexba.in/blog/2013/06/06/open-terminals-working-directory-in-finder/"/>
    <updated>2013-06-06T09:51:00+00:00</updated>
    <id>http://alexba.in/blog/2013/06/06/open-terminals-working-directory-in-finder</id>
    <content type="html"><![CDATA[<p>I frequently need to jump from the terminal to Finder in OSX. Turns out there is a very easy way to do that, which I thought I&#8217;d log here in case anyone else is searching for how to do this.</p>

<p>To open the current working directory in Finder, just run:</p>

<pre><code>open .
</code></pre>

<p>Simple, right? The more you know.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using a RaspberryPi and Pebble Watch to control your home theater]]></title>
    <link href="http://alexba.in/blog/2013/06/01/using-the-pebble-watch-to-control-your-home-theater/"/>
    <updated>2013-06-01T13:23:00+00:00</updated>
    <id>http://alexba.in/blog/2013/06/01/using-the-pebble-watch-to-control-your-home-theater</id>
    <content type="html"><![CDATA[<p>This post will serve as a guide to using a <a href="http://www.raspberrypi.org/">RaspberryPi</a>, a <a href="http://getpebble.com/">Pebble Watch</a>, and an Android phone (<a href="http://www.google.com/nexus/4/">Google Nexus 4</a>) to control your home theater from your wrist. The result is something like this:</p>

<p><img src="http://alexba.in/images/posts/open-source-universal-remote-pebble-watch.jpg" height="450px" width="600px" class="center" /></p>

<h3>Introduction</h3>

<p>For a bit of backstory, around eighteen months ago I decided to start experimenting with and teaching myself electronics. I started working with an <a href="http://arduino.cc/en/Main/arduinoBoardUno">Arduino Uno</a> and eventually moved to a <a href="http://www.raspberrypi.org">RasperryPi</a>. I wanted to build open hardware, open source, web connected devices and these seemed like the right tools for the job. I wanted to ensure that every device I built could, down the road, be controlled in entirely new ways with novel human computer interfaces like the <a href="http://getpebble.com">Pebble Watch</a>, <a href="https://www.thalmic.com/myo/?autoplay=true">Thalmic Labs Myo</a>, <a href="http://www.emotiv.com/">Emotiv EPOC EEG Headset</a>, <a href="https://www.leapmotion.com/">Leap Motion</a>, <a href="http://www.google.com/glass/start/">Google Glass</a>, and others.</p>

<p>So, after some consideration, I chose to build a RaspberryPi powered device that controls all of the infrared devices in my home. This project has turned into the <a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a>, an open hardware/open source device you can make yourself with a RaspberryPi and $10 of electronic parts. This post will discuss how I wired up my Pebble Watch to control my Open Source Universal remote using my Android phone.</p>

<p>Let&#8217;s get started!</p>

<h3>Outline</h3>

<ul>
<li>Part 0: How it Works</li>
<li>Part 1: Open Source Universal Remote</li>
<li>Part 2: The Android Phone</li>
<li>Part 3: The Pebble Watch</li>
<li>Part 4: Conclusion / What&#8217;s next</li>
</ul>


<h3>Part 0: How it Works</h3>

<p>At a high level, the project works like this:</p>

<ol>
<li>User taps button on Pebble Watch.</li>
<li>Pebble Watch tells Android phone that a button has been tapped.</li>
<li>Android phone makes web request to Open Source Universal Remote API.</li>
<li>Open Source Universal Remote receives web request and sends out infrared pulses.</li>
<li>Home theater device detects infrared pulses and responds accordingly.</li>
</ol>


<p>I&#8217;ll work backwards from the Open Source Universal Remote to the Pebble Watch.</p>

<h3>Part 1: Open Source Universal Remote</h3>

<p><img src="http://alexba.in/images/posts/open-source-universal-remote.jpg" height="320px" width="640px" class="center" /></p>

<p>The foundation of this project is the <a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a>. I won&#8217;t be going into detail about how to make one here, but if you&#8217;re interested in learning more or making your own, here is all the information you need:</p>

<ol>
<li><a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a> - The open source universal remote home page. This is an overview of the project and how it works.</li>
<li><a href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart/">RaspberryPi QuickStart</a> - A guide I wrote to purchasing and doing the initial configuration on a RaspberryPi.</li>
<li><a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/">Setting up LIRC on the RaspberryPi</a> - How to setup and install the <a href="http://lirc.org">Linux Infrared Remote Control (LIRC)</a> software on the RaspberryPi</li>
<li><a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC from the Web</a> - How to install and configure two open source projects I wrote (<a href="https://github.com/alexbain/lirc_node">lirc_node</a> and <a href="https://github.com/alexbain/lirc_web">lirc_web</a>) to enable you to control LIRC from the web.</li>
<li><a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Picturse</a> - Finalized parts list and build pictures from a protoboard I soldered together.</li>
</ol>


<p>For this project, I&#8217;ll be using the HTTP based API that the Open Source Universal Remote generates based on the remotes and commands you teach it. Here are the three URLs I used for this project:</p>

<pre><code>http://192.168.1.115:3000/remotes/Yamaha/power
http://192.168.1.115:3000/remotes/Microsoft_xbox360/onoff
http://192.168.1.115:3000/remotes/sonytv/power
</code></pre>

<p>You could get clever and use the hostname of the open source remote, I&#8217;m just using the static IP address here.</p>

<h3>Part 2: The Android Phone</h3>

<p>The second component of this project is an Android phone with the <a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm">Tasker</a> app installed on it. <a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm">Tasker</a> is a great app that provides a rich way to control your Android phone. One of the functions is the ability to send HTTP POST requests to specific URLs, which is the feature we&#8217;ll be using for this project.</p>

<p>Within the Tasker app you&#8217;ll need to create three new tasks, one for each button on the Pebble watch. Each task should be created with a descriptive name (like &#8220;Yamaha Power&#8221;) and will contain a single <code>HTTP POST</code> action (found in the <code>Net</code> menu), which will be sent to the open source remote. Here&#8217;s where the <code>HTTP POST</code> action can be found:</p>

<p><img src="http://alexba.in/images/posts/tasker-http-post.jpg" height="640px" width="384px" class="center" /></p>

<p>The <code>HTTP POST</code> action should be setup like this:</p>

<p><img src="http://alexba.in/images/posts/tasker-action-example.jpg" height="640px" width="384px" class="center" /></p>

<pre><code># IP / Port of the Open Source Universal Remote
Server:Port   http://192.168.1.115:3000

# Path to the remote/command combo you want to call
Path          /remotes/Yamaha/power
</code></pre>

<p>Once you&#8217;ve created those three Tasks, you&#8217;re ready to setup the Pebble Watch.</p>

<h3>Part 3: Pebble Watch</h3>

<p>The <a href="http://getpebble.com">Pebble Watch</a> was a successful Kickstarter project that launched in 2012. It&#8217;s a smart watch which connects to your cell phone via Bluetooth. It has a software development kit enabling anyone to write apps for the watch. I participated in the Kickstarter project, and have been very excited to start using my watch as a &#8220;remote control for reality.&#8221;</p>

<p>For this project we&#8217;ll be using the Android/Pebble combo app called <a href="https://play.google.com/store/apps/details?id=com.kodek.pebbletasker">PebbleTasker</a>. This is a very straightforward app. You install the app on your phone, which gives you the option to install the PebbleTasker app on the watch.</p>

<p>Once the watch app has been installed, you use the Android app to define which Tasker actions should be assigned to which button. Select the three Tasker actions that you created above and you should be set!</p>

<p><img src="http://alexba.in/images/posts/pebble-tasker.jpg" height="640px" width="384px" class="center" /></p>

<p>Here&#8217;s a photograph of my Pebble Watch with the above Tasker actions programmed into the watch:</p>

<p><img src="http://alexba.in/images/posts/open-source-universal-remote-pebble-watch-2.jpg" height="450px" width="600px" class="center" /></p>

<h3>Part 4: Conclusion / What&#8217;s Next</h3>

<p>Not to wax too philosophical, but I believe that next generation user interface devices like the Pebble Watch have the potential to transform how humans interact with the digital world. The cell phone was revolutionary - it enabled humans to interact with their data while away from a desktop or laptop computer. Now, devices like the Pebble Watch and the RaspberryPi allow you to move beyond the phone and begin interacting with the digital world in an entirely new way.</p>

<p>As additional web connected devices are made that control lights, garage doors, cars, appliances, and beyond, the interplay between those devices and user interface devices like the Pebble Watch, Myo, Emotiv EPOC, Google Glass, and others are going to give us new and powerful interactions to control the digital and physical world. These interactions were, until now, the stuff of science fiction. These are exciting times we live in.</p>

<p>If you found this post interesting, please subscribe to the <a href="http://feeds.feedburner.com/alexbain">RSS feed</a> to receive future updates or share this post with your social network. If you have any questions, feel free to leave a comment or send me an email (alex[at]thisdomain).</p>

<p>Tune in next time where I&#8217;ll be writing up how to control the Open Source Universal Remote with your mind using an Emotiv EPOC EEG headset.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[lirc_web v0.0.3]]></title>
    <link href="http://alexba.in/blog/2013/04/14/lirc-web-v0-dot-0-3/"/>
    <updated>2013-04-14T13:00:00+00:00</updated>
    <id>http://alexba.in/blog/2013/04/14/lirc-web-v0-dot-0-3</id>
    <content type="html"><![CDATA[<p><strong>August 10, 2014 Update:</strong> Latest version is now <a href="http://alexba.in/blog/2014/08/10/lirc-web-v0-0-8/">lirc_web v0.0.8</a></p>

<p>As part of the <a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a> project I&#8217;ve been creating a simple and touch friendly user interface for LIRC. In a previous post I covered <a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC From the Web</a>, where I introduced version 0.0.1 of <a href="http://github.com/alexbain/lirc_web">lirc_web</a>. Lirc_web is a simple NodeJS app I created for controlling LIRC from the web.</p>

<p>Since then, I&#8217;ve created a set of UI styles and fixed a number of touch related bugs with the project. I&#8217;m excited to announce <a href="http://github.com/alexbain/lirc_web">v0.0.3 of lirc_web</a> which is now on GitHub.</p>

<p>Here is a screen shot of the remote listing page:</p>

<p><img src="http://alexba.in/images/posts/universal-remote/lirc_web_v003_remotes.png" class="center" /></p>

<p>Upon tapping on any remote, you&#8217;ll be taken to a page that shows all known commands for that remote:</p>

<p><img src="http://alexba.in/images/posts/universal-remote/lirc_web_v003_commands.png" class="center" /></p>

<p>I have a long list of intended improvements, so if you&#8217;re interested in contributing to the project please let me know. As always, if you discover any bugs or have any feedback, please let me know in the comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RaspberryPi IR Schematic for LIRC]]></title>
    <link href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/"/>
    <updated>2013-03-09T09:19:00+00:00</updated>
    <id>http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc</id>
    <content type="html"><![CDATA[<p>Here is a <a href="http://upverter.com/alexbain/f24516375cfae8b9/Open-Source-Universal-Remote/">schematic</a> I designed that demonstrates you how you could create an IR transceiver for your RaspberryPi. You can use this schematic with the <a href="http://lirc.org">LIRC</a> software package to create your own universal remote. It&#8217;s hosted on <a href="http://upverter.com">Upverter</a> and contains a parts list for where to purchase the parts I used.</p>

<p><strong>June 1st, 2013: Thanks to some feedback and experimentation I&#8217;ve updated the schematic. This latest version reflects the best combination of parts I&#8217;ve found so far.</strong></p>

<p><strong>June 3rd, 2013: Two more schematic bugfixes.</strong></p>

<p><strong>June 8th, 2013:</strong> Read about the finished protoboard build in my <a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Picturse</a> blog post.</p>

<p><a href="http://upverter.com/alexbain/f24516375cfae8b9/Open-Source-Universal-Remote/#/"><img src="http://upverter.com/alexbain/f24516375cfae8b9/Open-Source-Universal-Remote/embed_img/13702922880000/" alt="Open Source Universal Remote by alexbain f24516375cfae8b9 - Upverter" /></a></p>

<p><a href="http://upverter.com/alexbain/f24516375cfae8b9/Open-Source-Universal-Remote/#">View the schematic and parts list</a></p>

<p>If you have any suggestions for improvements feel free to tinker on it and submit them.</p>

<p>Interested in installing LIRC on your RaspberryPi? You may be interested in reading <a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/">Setting up LIRC on the RaspberryPi</a> and <a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC From the Web</a>.</p>

<p><strong>Update:</strong> Thanks to Steve in the comments for pointing out a few errors I had in the schematic.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Open Source Universal Remote]]></title>
    <link href="http://alexba.in/blog/2013/03/06/open-source-universal-remote/"/>
    <updated>2013-03-06T11:55:00+00:00</updated>
    <id>http://alexba.in/blog/2013/03/06/open-source-universal-remote</id>
    <content type="html"><![CDATA[<p><img src="http://alexba.in/images/posts/universal-remote/transistor.jpg" /></p>

<p>Almost a year ago I decided to teach myself electronics by creating my own WiFi enabled universal remote. Initially I tried to build the project with an Arduino, but later switched to a RaspberryPi. As I&#8217;ve made progress on my project I&#8217;ve open sourced the software I&#8217;ve written and blogged about every step of the process.</p>

<p>To date, I&#8217;ve had over nine thousand unique visitors check out the posts related to this project. Based on the positive feedback I&#8217;ve received and the questions asked, I believe it makes sense to aggregate all of the data I&#8217;ve spread out across numerous blog posts into one guide. Over the coming weeks I&#8217;ll be creating a step by step guide for building your own RaspberryPi powered universal remote. In addition, I&#8217;ll be creating and open sourcing additional components of the project such as a printed circuit board and a 3D printable case to enclose the project.</p>

<p>Check out the <a href="http://opensourceuniversalremote.com">Open Source Universal Remote</a> landing page I created for the project. In the coming weeks I&#8217;ll be adding additional content to that page.</p>

<p>If you have any requests or ideas for this project please don&#8217;t hesitate to ask in the comments. In addition, if you have hardware engineering experience or industrial design experience and would like to contribute please get in touch.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Controlling LIRC from the web]]></title>
    <link href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/"/>
    <updated>2013-02-23T13:06:00+00:00</updated>
    <id>http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web</id>
    <content type="html"><![CDATA[<p>In this post I will cover how to create a web interface + API for <a href="http://lirc.org">LIRC</a>, the Linux Infrared Remote Control project. I will be using NodeJS and a RaspberryPi in this post, but the ideas generalize to other languages and hardware. This post will serve as Part 3 of my open source universal remote project posts. If you haven&#8217;t had an opportunity to read the first two posts, I suggest checking out <a href="http://alexba.in/blog/2012/07/08/universal-remote-experiments/">Universal remote experiments</a> (Part 1) and <a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi">Setting up LIRC on the RaspberryPi</a> (Part 2) before proceeding. You may also want to read <a href="http://alexba.in/blog/2013/01/15/installing-nodejs-on-your-raspberrypi">Installing NodeJS on your RaspberryPi</a>, where I cover installing NodeJS.</p>

<p>If you&#8217;re completely new to the RaspberryPi and want to learn more I wrote a <a href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart">RaspberryPi Quickstart</a> post which covers everything from purchasing the parts to configuring the WiFi. Check that out if you&#8217;re new to the RaspberryPi ecosystem.</p>

<p>With that out of the way, let&#8217;s get started!</p>

<p><img src="http://alexba.in/images/posts/universal-remote/ir-leds.jpg" class="center" /></p>

<h3>Why a web interface + API?</h3>

<p>LIRC is an awesome open source project that handles all of the low level requirements of sending and receiving Infrared commands from a Linux computer. It&#8217;s well documented, well supported, and thanks to the work of the open source community there is now a <code>lirc_rpi</code> driver included in the latest version of RaspbianOS. This means that, as long as you&#8217;re running a RaspberryPi with the latest OS and firmware, LIRC can interface with the RaspberryPi GPIO pins. Fantastic.</p>

<p>Once you have LIRC installed and configured (which I cover in my <a href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi">Setting up LIRC on the RaspberryPi</a> post), you can use LIRC executables like <a href="http://www.lirc.org/html/irsend.html">irsend</a> and <a href="http://www.lirc.org/html/irrecord.html">irrecord</a> to send and record IR commands for all your IR devices - right from the command line! This is great fun, but not very user friendly.</p>

<p>I wanted a way to control LIRC from the web. I wanted a web application that enabled me to interact with LIRC from any web connected device. If I had that, I could create a mobile web app for my phone, a regular web app for a desktop, and a RESTful API for web services. The API would give me a way to connect LIRC with any external web service - opening the door for future integrations. All I needed to do was find a way to call LIRC commands from within a web application.</p>

<p>Which brings us to the meat of this post. Getting NodeJS and LIRC to talk.</p>

<p><img src="http://alexba.in/images/posts/universal-remote/breadboard-wires.jpg" class="center" /></p>

<h3>Getting LIRC and NodeJS to talk</h3>

<p>To make LIRC usable from the web I needed a client library in a language I could build a web application in. The client library would provide some way to make calls from the web application to LIRC. This would give me the building blocks I needed to build a web application. The usual web languages include PHP, Python, Ruby, and NodeJS.</p>

<p>For this project I chose to work in NodeJS. If you would prefer to implement a web application in a different language, I found two existing LIRC client libraries. Sadly, neither seem maintained. I found <a href="https://github.com/fugalh/lircr">lircr</a> for Ruby and <a href="http://sourceforge.net/projects/pylirc/">pyLirc</a> for Python.</p>

<p>Since I could not find an existing NodeJS LIRC client library, and the existing libraries I did find were not up to date, I built my own. I created <a href="https://github.com/alexbain/lirc_node">lirc_node</a>, a lightweight NodeJS client library that interfaces with LIRC. v0.0.1 of <code>lirc_node</code> only supports <code>irsend</code>. This allows you to send IR commands to devices that LIRC knows about.</p>

<p>Before trying to install and use <code>lirc_node</code> make sure you have completed these steps:</p>

<ul>
<li>Purchased, setup, and configured a RaspberryPi to join a network</li>
<li>Wired up an IR LED and an IR Receiver to your RaspberryPi</li>
<li>Installed and configured LIRC to interface with your IR LED and IR Receiver</li>
<li>Programmed LIRC to understand your remote controls</li>
<li>Installed NodeJS on your RaspberryPi</li>
</ul>


<p>If you have not completed all of those steps scroll back to the top of this post and check out my earlier posts. I have written detailed step by step guides to get you through each of those steps.</p>

<p>All caught up? Great! We&#8217;re ready to install a basic web application for LIRC.</p>

<p><img src="http://alexba.in/images/posts/universal-remote/ir-receiver.jpg" class="center" /></p>

<h3>Creating a NodeJS web application using <code>lirc_node</code> and <code>lirc_web</code></h3>

<p>The easiest way to setup a NodeJS web application using <code>lirc_node</code> is to use v0.0.1 of <a href="https://github.com/alexbain/lirc_web">lirc_web</a>, a sample NodeJS application I wrote as a proof of concept for <code>lirc_node</code>. This web application is extremely basic, and only proves that <code>lirc_node</code> works. I have plans to grow this application with additional functionality and an improved interface. You may also use the basic API included in this web application to connect your universal remote with services like <a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&amp;hl=en">Tasker</a> or <a href="https://ifttt.com/">IFTTT</a>.</p>

<p><strong>January 17th 2015 Update:</strong> <a href="https://github.com/alexbain/lirc_web">lirc_web</a> is now at v0.0.8 and contains bugfixes and additional functionality. The user interface has been improved since v0.0.1, as well.</p>

<p>To download and install <a href="https://github.com/alexbain/lirc_web">lirc_web</a>:</p>

<pre><code>wget https://github.com/alexbain/lirc_web/archive/master.zip
unzip master.zip
mv lirc_web-master lirc_web
rm master.zip
cd lirc_web
npm install
node app.js
</code></pre>

<p>That should do it. Now, visit <code>http://raspberrypi:3000/</code> (or the IP address of your RaspberryPi) to confirm the sample web application shows all of the remotes and commands LIRC knows about. Clicking any of the links will tell LIRC to send that IR command via the API endpoint.</p>

<p><img src="http://alexba.in/images/posts/universal-remote/lirc_web.jpg" class="center" /></p>

<p><strong>November 2nd 2013 Update:</strong> I have posted a follow up post that discusses how to ensure the <code>lirc_web</code> project automatically starts on boot and is accessible via port 80. Check out <a href="http://alexba.in/blog/2013/11/02/lirc-web-nginx-and-upstart/">Running lirc_web with Nginx and Upstart</a> to learn more.</p>

<h3>Success!</h3>

<p>At this point, assuming you&#8217;ve been able to get each step working, you should have a web application you can use to control any IR device that LIRC knows about.</p>

<h3>What&#8217;s next?</h3>

<p>In the coming months I hope to:</p>

<ul>
<li>Create an open hardware schematic and PCB board that anyone can use for the hardware.</li>
<li>3D print an enclosure for the RaspberryPi + expansion board.</li>
<li>Improve the web application and give it a proper mobile web interface.</li>
<li>Write about how to connect <a href="https://github.com/alexbain/lirc_web">lirc_web</a> to Tasker or IFTTT.</li>
</ul>


<p>If you have any questions, suggestions, or run into any issues - please let me know.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Installing NodeJS on your RaspberryPi]]></title>
    <link href="http://alexba.in/blog/2013/01/15/installing-nodejs-on-your-raspberrypi/"/>
    <updated>2013-01-15T12:04:00+00:00</updated>
    <id>http://alexba.in/blog/2013/01/15/installing-nodejs-on-your-raspberrypi</id>
    <content type="html"><![CDATA[<p>Here&#8217;s how I installed <a href="http://nodejs.org/">NodeJS</a> on my RaspberryPi:</p>

<h3>Upgrade to the latest OS / Firmware</h3>

<p>If you have not already upgraded to the latest version of Raspbian OS and the
latest RaspberryPi firmware, I recommend following my <a href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart/">RaspberryPi Quickstart</a>.</p>

<h3>Getting and Compiling NodeJS</h3>

<p>Once your RaspberryPi is up to date, here&#8217;s how to download and compile NodeJS:</p>

<pre><code># Install some prerequisites
sudo apt-get install python g++ make

# Grab the latest version of NodeJS
mkdir ~/nodejs &amp;&amp; cd $_
wget -N http://nodejs.org/dist/node-latest.tar.gz
tar xzvf node-latest.tar.gz &amp;&amp; cd `ls -rd node-v*`

# Compile and install to your RaspberryPi
./configure
make
sudo make install
</code></pre>

<p>Please note that it takes about two hours to compile NodeJS.</p>

<h3>Confirming Installation</h3>

<p>You can confirm that NodeJS was installed correctly by running:</p>

<pre><code>node -v
npm --help
</code></pre>

<p>That&#8217;s it! You&#8217;re ready to begin development.</p>

<h3>Additional Reading:</h3>

<p>If you&#8217;d like to do some additional reading about NodeJS or ways to access the
GPIO pins on the RaspberryPi, check out:</p>

<ul>
<li><a href="http://nodejs.org/">NodeJS</a> - NodeJS home page</li>
<li><a href="https://github.com/rakeshpai/pi-gpio">pi-gpio</a> - &#8220;node.js based library to help access the GPIO of the Raspberry Pi&#8221;</li>
<li><a href="https://github.com/EnotionZ/GpiO">GpiO</a> - &#8220;Talk to your Raspberry Pi&#8217;s GPIO&#8221;</li>
</ul>


<p>If you have any other recommended resources please let me know!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Use your RaspberryPi to power a company dashboard]]></title>
    <link href="http://alexba.in/blog/2013/01/07/use-your-raspberrypi-to-power-a-company-dashboard/"/>
    <updated>2013-01-07T15:51:00+00:00</updated>
    <id>http://alexba.in/blog/2013/01/07/use-your-raspberrypi-to-power-a-company-dashboard</id>
    <content type="html"><![CDATA[<p>Here are five steps to follow if you want to start using a RaspberryPi to power a company dashboard. I&#8217;ve just finished putting this together at my office. We&#8217;re using <a href="http://www.geckoboard.com">Geckoboard</a> for the web interface:</p>

<p><img class="center" src="http://alexba.in/images/posts/raspberrypi-dashboard.jpg" /></p>

<p><img class="center" src="http://alexba.in/images/posts/raspberrypi-dashboard-2.jpg" /></p>

<h3>0: Make sure your RaspberryPi is fully updated</h3>

<p>Before you get started I highly recommend you follow my <a href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart/">RaspberryPi Quickstart</a> guide to get your RaspberryPi updated to the latest OS and Firmware. That post also includes links to the case and peripherals I purchased for this project.</p>

<h3>1: Install Chromium</h3>

<p>First, you&#8217;ll want to install Chromium on your RaspberryPi. We&#8217;ll be using Chromium to load the dashboard. I&#8217;ve also included the <code>ttf-mscorefonts-installer</code> package so things render nicely.</p>

<pre><code>sudo apt-get install chromium ttf-mscorefonts-installer
</code></pre>

<h3>2: Boot into X11 automatically</h3>

<p>You&#8217;ll want to make sure your RaspberryPi immediately boots into X11.</p>

<pre><code>sudo raspi-config
</code></pre>

<p>Scroll down to <code>boot_behavior</code> and hit enter. Make sure &#8220;Yes&#8221; is marked and hit enter again.</p>

<p>You&#8217;re done here, so scroll to Finish (right arrow key) and hit enter.</p>

<h3>3: Start Chromium on boot</h3>

<p>Third, you&#8217;ll want to make sure Chromium starts in kiosk (full screen, no user interface) as soon as your RaspberryPi boots up.</p>

<p>Create (or modify) <code>~/.config/lxsession/LXDE/autostart</code> and add the line:</p>

<pre><code>chromium --kiosk http://url_to_your_dashboard.com --incognito
</code></pre>

<p>Kiosk mode boots Chromium into full screen mode, by default. Incognito mode prevents a &#8220;Chrome did not shutdown cleanly&#8221; message from appearing on the top if the RaspberryPi loses power.</p>

<h3>4: Make sure the screen does not go to sleep</h3>

<p>Dashboards aren&#8217;t very useful if the screen goes into standy after ten minutes.</p>

<p>Edit <code>/etc/xdg/lxsession/LXDE/autostart</code> and make sure the <code>@xscreensaver</code> line is commented out. In addition, we&#8217;ll be adding three options that prevent the screen from going blank:</p>

<pre><code>#@xscreensaver -no-splash
@xset s off
@xset -dpms
@xset s noblank
</code></pre>

<p>I also needed to modify <code>/etc/lightdm/lightdm.conf</code>. Add this line to the <code>[SeatDefaults]</code> section:</p>

<pre><code>xserver-command=X -s 0 dpms
</code></pre>

<h3>5: Hide the mouse cursor</h3>

<p>There&#8217;s no reason to keep the mouse cursor stuck in the middle of the screen.  We&#8217;ll use the unclutter utility to hide it after boot.</p>

<pre><code>sudo apt-get install unclutter
</code></pre>

<p>You&#8217;ll need to add this to your <code>~/.config/lxsession/LXDE/autostart</code> file:</p>

<pre><code>unclutter -idle 0
</code></pre>

<h3>Enjoy!</h3>

<p>Reboot your RaspberryPi and it should:</p>

<ul>
<li>Boot directly into X11</li>
<li>Start Chromium in kiosk mode and load up your dashboard</li>
<li>Prevent the screen from going to sleep after 10 minutes</li>
<li>Hide the mouse cursor</li>
</ul>


<p>Please let me know if you have any questions or comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting up LIRC on the RaspberryPi]]></title>
    <link href="http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi/"/>
    <updated>2013-01-06T08:38:00+00:00</updated>
    <id>http://alexba.in/blog/2013/01/06/setting-up-lirc-on-the-raspberrypi</id>
    <content type="html"><![CDATA[<p><strong>June 8th 2013 Update:</strong> I have completed a soldered circuit prototype, complete with a full parts list and high resolution build pictures. Please read <a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Picturse</a> to learn more.</p>

<p><strong>March 9th 2013 Update:</strong> I have formalized the schematic and parts list that I&#8217;m using and have made it available on <a href="http://upverter.com">Upverter</a>. Please read <a href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/">RaspberryPi IR Schematic for LIRC</a> for more details.</p>

<p><strong>March 4th Update:</strong> I&#8217;ve written a follow up post that describes how to control your RaspberryPi universal remote from the web. Please check out <a href="http://alexba.in/blog/2013/02/23/controlling-lirc-from-the-web/">Controlling LIRC from the web</a> for instructions on how to install and configure the software.</p>

<h3>Preface</h3>

<p>In July 2012 I wrote a post called <a href="http://alexba.in/blog/2012/07/08/universal-remote-experiments/">Universal remote experiments</a> about creating a web controlled universal remote from the electronics up. The first platform I started with was an Arduino Uno. After much experimentation I learned that asking an Arduino to maintain a WiFi connection, maintain a TCP socket with a host computer, and send/receive IR signals was a bit much. With the limited memory and storage I had a hard time managing memory and keeping the system stable. I was, however, able to build a functional prototype:</p>

<p><img src="http://alexba.in/images/posts/arduino-ir.jpg" class="center" /></p>

<p>At the end of that post I had decided to rebuild the project on a RaspberryPi. I chose the RaspberryPi because I wanted a single device to host a web server in addition to being able to handle the IR transmitting and receiving. Given that the RaspberryPi runs Linux I could rely on it&#8217;s stable TCP/IP implementation and use open source software packages like nginx and NodeJS to build a web application.</p>

<p>This post will serve as &#8216;part two&#8217; of that project and cover how to install and configure LIRC on a RaspberryPi.</p>

<h3>LIRC - Linux Infrared Remote Control</h3>

<p><a href="http://www.lirc.org/">LIRC</a> is a mature and stable open source library that provides the ability to send and receive IR commands. Thanks to the contributions of <a href="http://aron.ws/">ar0n</a>, LIRC support is now included by default in the latest version of Raspbian OS. If you&#8217;d like to see the details of the RaspberryPi GPIO integration check out the <a href="https://github.com/raspberrypi/linux/pull/152">pull request</a> he opened for it a while back.</p>

<h3>Setting up LIRC on the RaspberryPi</h3>

<p>Getting LIRC setup on the RaspberryPi is significantly easier now than it was six months ago.</p>

<p>You must be running on the latest firmware and OS for this guide to work. If you&#8217;re new to the RaspberryPi, or you haven&#8217;t upgraded to the latest firmware and OS, I recommend following my <a href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart/">RaspberryPi Quickstart</a> guide to get your RaspberryPi up and running on the latest OS and firmware.</p>

<p>First, we&#8217;ll need to install and configure LIRC to run on the RaspberryPi:</p>

<pre><code>sudo apt-get install lirc
</code></pre>

<p>You have to modify two files before you can start testing the receiver and IR LED. I modified these files based on a thread I found on the RaspberryPi forums. If you would like to read more about these changes please check out the <a href="http://www.raspberrypi.org/phpBB3/viewtopic.php?f=45&amp;t=7798&amp;start=100">LIRC GPIO driver for homebrew adapter</a> thread. In particular, read through the posts by <a href="http://www.raspberrypi.org/phpBB3/memberlist.php?mode=viewprofile&amp;u=16815">rudiratlos</a> on page five, as he posts his configuration files.</p>

<p>Add this to your <code>/etc/modules</code> file:</p>

<pre><code>lirc_dev
lirc_rpi gpio_in_pin=23 gpio_out_pin=22
</code></pre>

<p>Change your <code>/etc/lirc/hardware.conf</code> file to:</p>

<pre><code>########################################################
# /etc/lirc/hardware.conf
#
# Arguments which will be used when launching lircd
LIRCD_ARGS="--uinput"

# Don't start lircmd even if there seems to be a good config file
# START_LIRCMD=false

# Don't start irexec, even if a good config file seems to exist.
# START_IREXEC=false

# Try to load appropriate kernel modules
LOAD_MODULES=true

# Run "lircd --driver=help" for a list of supported drivers.
DRIVER="default"
# usually /dev/lirc0 is the correct setting for systems using udev
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"

# Default configuration files for your hardware if any
LIRCD_CONF=""
LIRCMD_CONF=""
########################################################
</code></pre>

<p>Now restart <code>lircd</code> so it picks up these changes:</p>

<pre><code>sudo /etc/init.d/lirc stop
sudo /etc/init.d/lirc start
</code></pre>

<p><strong>January 25th 2015:</strong> Marc W. in the comments pointed out that in the 3.18.x RaspberryPi firmware you must modify one additional file for the <code>lirc-rpi</code> kernel extension to be loaded:</p>

<p>Edit your <code>/boot/config.txt</code> file and add:</p>

<pre><code>dtoverlay=lirc-rpi,gpio_in_pin=23,gpio_out_pin=22
</code></pre>

<p>Reboot your RaspberryPi after making this change.</p>

<h3>Wiring up the IR transceiver</h3>

<p><strong>June 8th 2013 Update:</strong> I&#8217;ve finished a more permanent build and documented the process in my <a href="http://alexba.in/blog/2013/06/08/open-source-universal-remote-parts-and-pictures/">Open Source Universal Remote - Parts &amp; Picturse</a> blog post.</p>

<p><strong>March 9th 2013 Update:</strong> I have formalized the schematic and parts list that I&#8217;m using and have made it available on <a href="http://upverter.com">Upverter</a>. Please read <a href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/">RaspberryPi IR Schematic for LIRC</a> for more details.</p>

<p>To send and receive IR signals from your RaspberryPi you&#8217;ll need to wire up an IR LED and an IR receiver and tell LIRC where to find them. Here are the parts I purchased for my own project:</p>

<ul>
<li><a href="https://www.adafruit.com/products/387">940nm IR LED 20deg</a> - 20 degree viewing angle. Bright and tuned to 940nm wavelength</li>
<li><a href="http://www.digikey.com/product-detail/en/IR333C/1080-1081-ND/2675572?WT.z_cid=ref_octopart_dkc_buynow">940nm IR LED 40deg</a> - 40 degree viewing angle. Bright and tuned to 940nm wavelength.</li>
<li><a href="https://www.adafruit.com/products/157">38khz IR Receiver</a> - Receives IR signals at remote control frequencies</li>
<li><a href="https://www.adafruit.com/products/756">PN2222 Transistor</a> - Transistor to help drive IR LED</li>
<li><a href="https://www.sparkfun.com/products/8374">10k Ohm resistor</a> - Resistor that goes between rPi GPIO and the PN2222 transistor</li>
</ul>


<p>If you don&#8217;t already have wires and a breadboard to prototype with, you may be interested in:</p>

<ul>
<li><a href="http://adafruit.com/products/942">Mounting plate + breadboard</a> - A mounting plate + breadboard for your RaspberryPi</li>
<li><a href="http://adafruit.com/products/914">Adafruit Pi Cobbler Breakout Kit</a> - Breakout kit for getting the GPIO pins onto the breadboard</li>
<li><a href="https://www.adafruit.com/products/153">Breadboard wire bundle</a> - Bundle of wires to use in the breadboard</li>
</ul>


<p>For this project I wired up the IR LED to GPIO pin 22 and the IR Receiver to GPIO pin 23. You&#8217;ll see that mentioned in the <code>/etc/modules</code> file above.</p>

<p>Please check out these diagrams for information and schematics about how to wire everything up:</p>

<ul>
<li><a href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/">RasperryPi IR Schematic for LIRC</a> - My own schematic, which I&#8217;ve been using myself.</li>
<li><a href="http://aron.ws/projects/lirc_rpi/">RaspberryPi lirc_rpi</a> - Contains hardware and schematics for the raspberryPi</li>
<li><a href="http://www.ladyada.net/make/tvbgone/design.html">TV-B-Gone Schematic</a> - Info on wiring up IR leds / receivers</li>
<li><a href="http://www.instructables.com/files/deriv/FJA/5B1M/H2WERJ0U/FJA5B1MH2WERJ0U.LARGE.jpg">GPIO pinout for RaspberryPi</a> - GPIO pinout diagram</li>
</ul>


<p>Here&#8217;s a picture of my initial schematic (<a href="http://alexba.in/blog/2013/03/09/raspberrypi-ir-schematic-for-lirc/">view the updated one here</a>) wired up to my RaspberryPi with all of the components tested and working:</p>

<p><img src="http://alexba.in/images/posts/raspberrypi-ir.jpg" class="center" /></p>

<h3>Testing the IR receiver</h3>

<p>Testing the IR receiver is relatively straightforward.</p>

<p>Run these two commands to stop <code>lircd</code> and start outputting raw data from the IR receiver:</p>

<pre><code>sudo /etc/init.d/lirc stop
mode2 -d /dev/lirc0
</code></pre>

<p>Point a remote control at your IR receiver and press some buttons. You should see something like this:</p>

<pre><code>space 16300
pulse 95
space 28794
pulse 80
space 19395
pulse 83
space 402351
pulse 135
space 7085
pulse 85
space 2903
</code></pre>

<p>If you don&#8217;t, something is probably incorrectly configured. Triple check that you&#8217;ve connected everything properly and haven&#8217;t crossed any wires. I highly recommend referring to the schematics I linked to above. There is also some trouble shooting advice in the RaspberryPi Forum thread I linked to above. Finally - you may want to do this in a dark room. I found that my desk lamp and overhead light would cause the IR receiver to think it was receiving valid signals.</p>

<h3>Testing the IR LED</h3>

<p>You&#8217;re going to need to either find an existing LIRC config file for your remote control or use your IR receiver to generate a new LIRC config file. In my case I created a new LIRC config file. To do this, read the documentation on the <a href="http://www.lirc.org/html/irrecord.html">irrecord</a> application that comes with LIRC.</p>

<p>When using irrecord it will ask you to name the buttons you&#8217;re programming as you program them. Be sure to run <code>irrecord --list-namespace</code> to see the valid names before you begin.</p>

<p>Here were the commands that I ran to generate a remote configuration file:</p>

<pre><code># Stop lirc to free up /dev/lirc0
sudo /etc/init.d/lirc stop

# Create a new remote control configuration file (using /dev/lirc0) and save the output to ~/lircd.conf
irrecord -d /dev/lirc0 ~/lircd.conf

# Make a backup of the original lircd.conf file
sudo mv /etc/lirc/lircd.conf /etc/lirc/lircd_original.conf

# Copy over your new configuration file
sudo cp ~/lircd.conf /etc/lirc/lircd.conf

# Start up lirc again
sudo /etc/init.d/lirc start
</code></pre>

<p>Once you&#8217;ve completed a remote configuration file and saved/added it to <code>/etc/lirc/lircd.conf</code> you can try testing the IR LED. We&#8217;ll be using the <a href="http://www.lirc.org/html/irsend.html">irsend</a> application that comes with LIRC to facilitate sending commands. You&#8217;ll definitely want to check out the documentation to learn more about the options <code>irsend</code> has.</p>

<p>Here are the commands I ran to test my IR LED (using the &#8220;yamaha&#8221; remote configuration file I created):</p>

<pre><code># List all of the commands that LIRC knows for 'yamaha'
irsend LIST yamaha ""

# Send the KEY_POWER command once
irsend SEND_ONCE yamaha KEY_POWER

# Send the KEY_VOLUMEDOWN command once
irsend SEND_ONCE yamaha KEY_VOLUMEDOWN
</code></pre>

<p>I tested that this was working by pointing the IR led at my Yamaha receiver and testing whether I could turn it on and adjust the volume.</p>

<h3>Success!</h3>

<p>That&#8217;s it! You&#8217;ve now successfully installed and configured LIRC on your RaspberryPi. You can add additional remote control configuration files to your <code>/etc/lirc/lircd.conf</code> file to control multiple remotes.</p>

<h3>Resources</h3>

<p>Here&#8217;s a few resources to explore if you&#8217;d like to learn more:</p>

<ul>
<li><a href="http://www.lirc.org">lirc</a> - LIRC home page</li>
<li><a href="http://aron.ws/projects/lirc_rpi/">RaspberryPi lirc_rpi GPIO driver</a> - ar0n&#8217;s lirc_rpi page</li>
<li><a href="http://www.raspberrypi.org/phpBB3/viewtopic.php?f=45&amp;t=7798&amp;start=100">LIRC GPIO driver for homebrew adapter</a></li>
<li><a href="http://www.ladyada.net/make/tvbgone/design.html">TV-B-Gone Schematic</a></li>
</ul>


<h3>My next steps</h3>

<p>The next step for my web controlled universal remote project is going to be finding or creating remote files for all of the IR devices in my house. Once I&#8217;ve gathered all of those files together and placed them in the <code>lircd.conf</code> file I&#8217;ll begin work on the web application server.</p>

<p>I&#8217;ll cover all of that in a future post.</p>

<h3>Questions? Comments?</h3>

<p>Please let me know if you have any questions or run into any trouble while running through these steps. All of these steps were tested and working on the date this post was published.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RaspberryPi Quickstart]]></title>
    <link href="http://alexba.in/blog/2013/01/04/raspberrypi-quickstart/"/>
    <updated>2013-01-04T20:08:00+00:00</updated>
    <id>http://alexba.in/blog/2013/01/04/raspberrypi-quickstart</id>
    <content type="html"><![CDATA[<p>I recently had the opportunity to purchase and setup a second RaspberryPi system. Here&#8217;s a very brief shopping list and collection of links to get your own RaspberryPi system setup.</p>

<h3>Parts List</h3>

<ul>
<li><a href="http://www.amazon.com/gp/product/B009SQQF9C/ref=oh_details_o01_s00_i01">RaspberryPi</a> - 512MB version</li>
<li><a href="http://www.amazon.com/gp/product/B008TCUXLW/ref=oh_details_o01_s01_i01">Enclosure for the RaspberryPi</a> - Clear and contains cutous for all of the ports + GPIO pins.</li>
<li><a href="http://www.amazon.com/gp/product/B003X26PMO/ref=oh_details_o01_s01_i02">WiFi Card</a> - Drivers are included in the latest Raspbian distribution.</li>
<li><a href="http://www.amazon.com/gp/product/B003VNKNEG/ref=oh_details_o01_s01_i03">8GB Class 10 SD card</a> - Class 10 cards have a fast read / write speed.</li>
<li><a href="http://www.amazon.com/gp/product/B003ES5ZSW/ref=oh_details_o01_s00_i00">USB A to USB MicroB cable</a> - The &#8216;power cable&#8217; for the RaspberryPi</li>
<li><a href="http://www.amazon.com/gp/product/B005CG2ATQ/ref=oh_details_o01_s01_i00">USB power supply</a> - High powered USB power supply to drive the RaspberryPi + WiFi card.</li>
<li><a href="http://www.amazon.com/AmazonBasics-High-Speed-HDMI-Cable-Meters/dp/B003L1ZYYM">HDMI cable</a> - HDMI cable to connect to HDTV / monitor.</li>
</ul>


<h3>Setting up the SD card</h3>

<ol>
<li>Download the latest <a href="http://www.raspberrypi.org/downloads">Rasbian linux image</a>.</li>
<li>Setup the SD card by following the <a href="http://elinux.org/RPi_Easy_SD_Card_Setup">RPi Easy SD Card Setup</a> guide.</li>
</ol>


<h3>Booting it all up</h3>

<p>Plug everything in, boot up the system. If you&#8217;re planning to SSH into the RaspberryPi via Ethernet (instead of using a keyboard/mouse/monitor) you&#8217;ll have to log into your router and determine what it&#8217;s IP address is.</p>

<p>The default RaspberryPi login is username <code>pi</code> with password <code>raspberry</code>. You&#8217;ll probably want to change this.</p>

<h3>Expanding the root partition</h3>

<p><strong>Update: April 12th 2013</strong>: Thanks to Conky (and Kevin) for suggesting this.</p>

<p>Once your RaspberryPi boots up, you&#8217;ll want to adjust the root partition to take up the entire SD card. This will help prevent errors about the file system being full once you start updating packages and installing new packages:</p>

<pre><code># Open the RaspiConfig tool:
sudo raspi-config

# Navigate to the "expand_rootfs" option and select it
# Quit out of the raspi-config screen

# Reboot the system:
sudo shutdown -r now
</code></pre>

<h3>Setting up the WiFi</h3>

<p>Assuming everything booted up okay, you&#8217;re ready to setup the wireless. To setup the wireless card to connect to your WPA/WPA2 secured wireless network, edit <code>/etc/network/interfaces</code> and add this to the bottom of the file. You may need to remove some existing configuration for <code>wlan0</code>.</p>

<pre><code>allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
    wpa-ssid YOUR_SSID
    wpa-psk YOUR_PASSWORD
</code></pre>

<p>Save this file, and run:</p>

<pre><code>sudo ifdown wlan0
sudo ifup wlan0
</code></pre>

<p>Run <code>ifconfig</code> and you should see that <code>wlan0</code> has an IP address.</p>

<h3>Setting up NTP</h3>

<p>Accurate time is useful.</p>

<pre><code>sudo apt-get install ntpdate
sudo ntpdate -u ntp.ubuntu.com
</code></pre>

<h3>Updating Raspbian OS</h3>

<p>After everything is setup you&#8217;ll probably want to update Raspbian to the latest packages and version.</p>

<pre><code>sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
</code></pre>

<h3>Updating the RaspberryPi&#8217;s firmware</h3>

<p>To update the firmware to the latest version, we&#8217;ll use <a href="https://www.github.com/Hexxeh/rpi-update">Hexxeh&#8217;s rpi-update script</a>.</p>

<pre><code>sudo apt-get install git-core
sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update &amp;&amp; sudo chmod +x /usr/bin/rpi-update
sudo rpi-update
</code></pre>

<h3>You&#8217;re done!</h3>

<p>At this point you should be completely setup and operational.</p>

<p>If you had any troubles with this please let me know in the comments.</p>

<h3>More reading</h3>

<p>Here are some resources to do further reading:</p>

<ul>
<li><a href="http://elinux.org/RPi_Community">http://elinux.org/RPi_Community</a></li>
<li><a href="http://www.raspberrypi.org/phpBB3/">http://www.raspberrypi.org/phpBB3/</a></li>
<li>Should I add a link here? Let me know.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Spreadsheets to Websites]]></title>
    <link href="http://alexba.in/blog/2012/12/07/spreadsheets-to-websites/"/>
    <updated>2012-12-07T10:29:00+00:00</updated>
    <id>http://alexba.in/blog/2012/12/07/spreadsheets-to-websites</id>
    <content type="html"><![CDATA[<p>This morning I came across a two interesting JavaScript libraries designed to help
make Google Spreadsheets a data source for websites. Given how simple it is to
get started creating a spreadsheet it seems like a great way to make that data
available for public viewing.</p>

<p>I can imagine this being extremely useful for someone who already maintains a
spreadsheet with carefully tabulated and calculated data who isn&#8217;t interested
in repeatedly exporting / importing it into a database for web viewing.</p>

<h3>Tabletop</h3>

<blockquote><p>Tabletop takes a Google Spreadsheet and makes it easily accessible through Javascript.</p></blockquote>

<p><a href="http://builtbybalance.com/Tabletop/">http://builtbybalance.com/Tabletop/</a></p>

<h3>Sheetsee</h3>

<blockquote><p>Sheetsee.js is a javascript library mashup that allows you to fill a website with content
from a Google Spreadsheet. The web content and visualizations will update with every
auto save by Google.</p></blockquote>

<p><a href="https://github.com/jllord/sheetsee.js">https://github.com/jllord/sheetsee.js</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[User agent stylesheets and border-box]]></title>
    <link href="http://alexba.in/blog/2012/10/16/user-agent-stylesheets-and-border-box/"/>
    <updated>2012-10-16T12:38:00+00:00</updated>
    <id>http://alexba.in/blog/2012/10/16/user-agent-stylesheets-and-border-box</id>
    <content type="html"><![CDATA[<p>Recently I was trying to troubleshoot why all of the inputs on a project had
<code>box-sizing: border-box</code> applied to them. It turns out that a user agent
stylesheet rule that I don&#8217;t normally see was being applied to all input elements.
This user agent stylesheet rule was being applied in Chrome, Firefox, and Safari.</p>

<p>Here is the <code>user agent stylesheet</code> rule that was being applied:</p>

<pre><code>input:not([type="image"]), textarea {
  box-sizing: border-box;
}
</code></pre>

<p>After some troubleshooting it turns out this rule was being applied due
to a typo in the DOCTYPE for the project. After changing the DOCTYPE back
to the correct HTML5 doctype (<code>&lt;!doctype html&gt;</code>) everything loaded correctly.</p>
]]></content>
  </entry>
  
</feed>
