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

  <title><![CDATA[isquared.nl]]></title>
  <link href="http://isquared.nl//atom.xml" rel="self"/>
  <link href="http://isquared.nl//"/>
  <updated>2017-03-05T10:44:59+01:00</updated>
  <id>http://isquared.nl//</id>
  <author>
    <name><![CDATA[Hessel Schut]]></name>
    <email><![CDATA[hessel@isquared.nl]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Macintosh Plus/10]]></title>
    <link href="http://isquared.nl//blog/2016/09/25/macintosh-plus-slash-10/"/>
    <updated>2016-09-25T21:32:00+02:00</updated>
    <id>http://isquared.nl//blog/2016/09/25/macintosh-plus-slash-10</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://isquared.nl/images/plus10-installed.jpg">
The <em>Macintosh Plus</em> is one of the first Apple Macintosh computers and the first Macintosh I ever owned.
The Macintosh Plus is normally powered by a Motorola 68000 microprocessor.</p>

<p>To the right is a picture of the motherboard of one of my Macintosh Plusses upgraded to a 68010 microprocessor. After the 68030 powered <em>Macintosh SE/30</em>, I think <em>Macintosh Plus/10</em> is an appropriate name.</p>

<p>The 68010 does not bring much improvement, multiply/ divide is supposed to
be somewhat faster.</p>

<p>The cpu upgrade is interesting, but <em>Plus/10</em> is mostly meant as a start to do some hardware experiments with this classic Macintosh.</p>

<p>The bottom side of the upgrade board with plenty of empty space for more hardware is pictured below.</p>

<p><img class="right" src="http://isquared.nl/images/plus10-brd.jpg"></p>

<p><em>More to follow&#8230;</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[LM75 Temperature Sensor Library for NodeMCU]]></title>
    <link href="http://isquared.nl//blog/2015/01/03/lm75-temperature-sensor-library-for-nodemcu/"/>
    <updated>2015-01-03T15:11:00+01:00</updated>
    <id>http://isquared.nl//blog/2015/01/03/lm75-temperature-sensor-library-for-nodemcu</id>
    <content type="html"><![CDATA[<p>In all my excitement about the ESP8266 modules, I almost forgot that
I had some boards made to create nice standalone temperature sensors
with the ESP8266 using LM75 i2c temperature sensors.</p>

<p><img class="right" src="http://isquared.nl/images/lm75-board.png" width="320"></p>

<p>Before my boards arrived, I had already made the <a href="http://isquared.nl/blog/2015/01/02/more-esp8266-lua-projects/">central heating temperature
logger</a> and
forgot about them.
Today I soldered one of these boards as a test, the result is in the picture to the right. The board is mounted on a simple breakout that I made for my ESP8266
experiments. The sensor itself is not visible, as it is on the bottom side of
the black PCB, so that it can easily be mounted to a surface and make proper
thermal contact.</p>

<p>Compared to the DS1820 one-wire sensors, the temperature resolution is not
that great, only 0.5 &deg;C resolution, but interfacing these is a lot easier.
To make interfacing even easier, I created a small Lua library to read an LM75
sensor from NodeMCU, it&#8217;s available in the public domain on <a href="https://github.com/hessch/lm75lib">Github</a>.</p>

<p>Usage is easy:</p>

<figure class='code'><figcaption><span></span></figcaption><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>
</pre></td><td class='code'><pre><code class='lua'><span class='line'><span class="nb">require</span><span class="p">(</span><span class="s1">&#39;</span><span class="s">lm75&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">-- GPIO indexes of i2c signals</span>
</span><span class='line'><span class="n">sda</span><span class="p">,</span> <span class="n">scl</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span>
</span><span class='line'><span class="n">lm75</span><span class="p">:</span><span class="n">init</span><span class="p">(</span><span class="n">sda</span><span class="p">,</span> <span class="n">scl</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>The temperatures can then be read as either a sting repreenting a floating
point value or scaled to an integer (temperature in &deg;C is value/10.)</p>

<p>For example:</p>

<figure class='code'><figcaption><span></span></figcaption><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>
</pre></td><td class='code'><pre><code class='lua'><span class='line'><span class="o">&gt;</span> <span class="o">=</span><span class="n">lm75</span><span class="p">:</span><span class="n">strTemp</span><span class="p">()</span>
</span><span class='line'><span class="mf">22.5</span>
</span><span class='line'><span class="o">&gt;</span> <span class="o">=</span><span class="n">lm75</span><span class="p">:</span><span class="n">intTemp</span><span class="p">()</span>
</span><span class='line'><span class="mi">225</span>
</span></code></pre></td></tr></table></div></figure>


<p>Using this library, a sensor node that emits temperatures in mrtg external
script format to a TCP client can fit in this tiny snippet of code:</p>

<figure class='code'><figcaption><span></span></figcaption><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>
</pre></td><td class='code'><pre><code class='lua'><span class='line'><span class="nb">require</span><span class="p">(</span><span class="s1">&#39;</span><span class="s">lm75&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">sda</span><span class="p">,</span> <span class="n">scl</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span>
</span><span class='line'><span class="n">port</span> <span class="o">=</span> <span class="mi">27315</span>
</span><span class='line'>
</span><span class='line'><span class="n">lm75</span><span class="p">:</span><span class="n">init</span><span class="p">(</span><span class="n">sda</span><span class="p">,</span> <span class="n">scl</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">srv</span><span class="o">=</span><span class="n">net</span><span class="p">.</span><span class="n">createServer</span><span class="p">(</span><span class="n">net</span><span class="p">.</span><span class="n">TCP</span><span class="p">)</span>
</span><span class='line'><span class="n">srv</span><span class="p">:</span><span class="n">listen</span><span class="p">(</span><span class="n">port</span><span class="p">,</span>
</span><span class='line'>        <span class="k">function</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
</span><span class='line'>                <span class="kd">local</span> <span class="n">temp</span>
</span><span class='line'>                <span class="n">temp</span> <span class="o">=</span> <span class="n">lm75</span><span class="p">:</span><span class="n">intTemp</span><span class="p">()</span>
</span><span class='line'>                <span class="n">conn</span><span class="p">:</span><span class="n">send</span><span class="p">(</span>
</span><span class='line'>                        <span class="n">temp</span><span class="o">..</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s">&quot;</span>
</span><span class='line'>                        <span class="o">..</span><span class="n">temp</span><span class="o">..</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s">&quot;</span>
</span><span class='line'>                        <span class="o">..</span><span class="n">tmr</span><span class="p">.</span><span class="n">now</span><span class="p">()</span><span class="o">..</span><span class="s2">&quot;</span><span class="s"> ticks</span><span class="se">\n</span><span class="s">&quot;</span>
</span><span class='line'>                        <span class="o">..</span><span class="s2">&quot;</span><span class="s">node-&quot;</span><span class="o">..</span><span class="n">node</span><span class="p">.</span><span class="n">chipid</span><span class="p">())</span>
</span><span class='line'>                <span class="n">conn</span><span class="p">:</span><span class="n">on</span><span class="p">(</span><span class="s2">&quot;</span><span class="s">sent&quot;</span><span class="p">,</span>
</span><span class='line'>                        <span class="k">function</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span> <span class="n">conn</span><span class="p">:</span><span class="n">close</span><span class="p">()</span> <span class="k">end</span>
</span><span class='line'>                <span class="p">)</span>
</span><span class='line'>        <span class="k">end</span>
</span><span class='line'><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>See my <a href="http://isquared.nl/blog/2015/01/02/more-esp8266-lua-projects/">previous post</a> about how to easily integrate this into mrtg using netcat.</p>

<p>Enjoy!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[More ESP8266 Lua Projects]]></title>
    <link href="http://isquared.nl//blog/2015/01/02/more-esp8266-lua-projects/"/>
    <updated>2015-01-02T20:04:00+01:00</updated>
    <id>http://isquared.nl//blog/2015/01/02/more-esp8266-lua-projects</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://isquared.nl/images/cv-logger.png" width="200" height="300"></p>

<p>I had some more fun with Lua on the ESP8266 wifi modules. These things are
so cheap and so versatile that I have already reserved a dedicated subnet
for sensor nodes in the house.</p>

<p>The latest ESP8266 projects are a temperature logger for the water temperature
of the central heating and a meter reader for water consumption.</p>

<p>The <a href="http://nodemcu.com/index_en.html">NodeMCU Lua firmware</a> has native
support for onewire, making it trivial to add some DS18B20 temperature
sensors. A bit of Lua glues these to a TCP socket and outputs the sensor
values when a TCP connection is made.
This way it is very easy to grab the sensor values from <a href="http://oss.oetiker.ch/mrtg/index.en.html">MRTG</a>.</p>

<p>MRTG Then generates pretty graphs like the one below. In this graph the red
line shows the hot water from the central heating boiler, the blue area is the
return water temperature.</p>

<p><img src="http://isquared.nl/images/cv-temperature-day.png"></p>

<p>The code behind this is too dirty to publish, some cleaning up needs to be done
first. The water usage logger is a better example.</p>

<!-- MORE -->


<p>The water usage logger uses a reflective infrared sensor mounted on the water
meter. The  water meter has a disc with a reflective part that the sensor can
detect, giving an impulse per liter of water used.</p>

<p>The impulse output of the sensor is connected to a GPIO on the ESP8266, the
ESP8266 increments a global counter on every impulse received. It also listens
for TCP connections, when a connection is received it emits the measured values
in the format that MRTG expects for external scripts. Thus making it easy to
gather the values from MRTG using nothing more than netcat.</p>

<figure class='code'><figcaption><span>main.lua </span></figcaption>
 <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>
</pre></td><td class='code'><pre><code class='lua'><span class='line'><span class="n">gpio0</span> <span class="o">=</span> <span class="mi">3</span>
</span><span class='line'><span class="n">gpio2</span> <span class="o">=</span> <span class="mi">4</span>
</span><span class='line'>
</span><span class='line'><span class="n">count</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">gpio</span><span class="p">.</span><span class="n">mode</span><span class="p">(</span><span class="n">gpio0</span><span class="p">,</span> <span class="n">gpio</span><span class="p">.</span><span class="n">INT</span><span class="p">)</span>
</span><span class='line'><span class="n">gpio</span><span class="p">.</span><span class="n">mode</span><span class="p">(</span><span class="n">gpio2</span><span class="p">,</span> <span class="n">gpio</span><span class="p">.</span><span class="n">INT</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">function</span> <span class="nf">increment</span><span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span>
</span><span class='line'>  <span class="n">count</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">count</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">gpio</span><span class="p">.</span><span class="n">trig</span><span class="p">(</span><span class="n">gpio0</span><span class="p">,</span> <span class="s2">&quot;</span><span class="s">up&quot;</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="n">increment</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="k">end</span><span class="p">)</span>
</span><span class='line'><span class="n">gpio</span><span class="p">.</span><span class="n">trig</span><span class="p">(</span><span class="n">gpio2</span><span class="p">,</span> <span class="s2">&quot;</span><span class="s">up&quot;</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="n">increment</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">state</span><span class="p">)</span> <span class="k">end</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">srv</span><span class="o">=</span><span class="n">net</span><span class="p">.</span><span class="n">createServer</span><span class="p">(</span><span class="n">net</span><span class="p">.</span><span class="n">TCP</span><span class="p">)</span>
</span><span class='line'><span class="n">srv</span><span class="p">:</span><span class="n">listen</span><span class="p">(</span><span class="mi">5555</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
</span><span class='line'>        <span class="n">str</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="s">&quot;</span>
</span><span class='line'>        <span class="k">for</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span> <span class="k">do</span>
</span><span class='line'>                <span class="n">str</span> <span class="o">=</span> <span class="n">str</span> <span class="o">..</span> <span class="nb">tostring</span><span class="p">(</span><span class="n">count</span><span class="p">[</span><span class="n">i</span><span class="p">])</span><span class="o">..</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s">&quot;</span>
</span><span class='line'>        <span class="k">end</span>
</span><span class='line'>        <span class="n">str</span> <span class="o">=</span> <span class="n">str</span> <span class="o">..</span> <span class="nb">tostring</span><span class="p">(</span><span class="n">tmr</span><span class="p">.</span><span class="n">now</span><span class="p">())</span><span class="o">..</span><span class="s2">&quot;</span><span class="s"> ticks</span><span class="se">\n</span><span class="s">&quot;</span>
</span><span class='line'>        <span class="n">str</span> <span class="o">=</span> <span class="n">str</span> <span class="o">..</span> <span class="s2">&quot;</span><span class="s">node-&quot;</span><span class="o">..</span><span class="nb">tostring</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">chipid</span><span class="p">())</span><span class="o">..</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s">&quot;</span>
</span><span class='line'>        <span class="n">c</span><span class="p">:</span><span class="n">send</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
</span><span class='line'>        <span class="n">c</span><span class="p">:</span><span class="n">on</span><span class="p">(</span><span class="s2">&quot;</span><span class="s">sent&quot;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="n">c</span><span class="p">:</span><span class="n">close</span><span class="p">()</span> <span class="k">end</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>On a TCP connect the ESP8266 emits something similar to this:</p>

<pre><code>402
0
1915768749 ticks
node-12341234
</code></pre>

<p>This is exactly the format that MRTG uses, making MRTG side of things very
simple:</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>
</pre></td><td class='code'><pre><code class=''><span class='line'>Title[water]: Water Flow
</span><span class='line'>Target[water]: `/bin/nc water.metering.iot.intra.isquared.nl 5555`
</span><span class='line'>PageTop[water]: &lt;H1>Water Flow&lt;/H1>
</span><span class='line'>Options[water]: nopercent, noo, perminute
</span><span class='line'>MaxBytes[water]: 10000
</span><span class='line'>Factor[water]: 1
</span><span class='line'>YTicsFactor[water]: 1
</span><span class='line'>WithPeak[water]: wmy
</span><span class='line'>YLegend[water]: Liter/min
</span><span class='line'>ShortLegend[water]: l/min
</span><span class='line'>LegendI[water]: flow
</span><span class='line'>Colours[water]: BLUE#2222aa, BLUE#2222aa, LIGHTBLUE#3399ff, LIGHTBLUE#3399ff</span></code></pre></td></tr></table></div></figure>


<p>The gas and electricity meters still pose a bit of a problem, the infrared
sensors have a had time picking up a signal from those. For electricity</p>

<p>I&#8217;ll probably add one or two kWh meters with an S0 output behind the meter
provided by the utility company. This is easier and probably more reliable than
trying to read the meter optically.</p>

<p>Graphing many more values using MRTG will probably also demand too much from
the Raspberry Pi that now does all the graphing. A cusom solution using RRDTool
will probably be a better solution.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ESP8266 Lua Adventures]]></title>
    <link href="http://isquared.nl//blog/2014/12/15/esp8266-lua-adventures/"/>
    <updated>2014-12-15T23:11:00+01:00</updated>
    <id>http://isquared.nl//blog/2014/12/15/esp8266-lua-adventures</id>
    <content type="html"><![CDATA[<p>After appearing on <a href="http://hackaday.com/2014/08/26/new-chip-alert-the-esp8266-wifi-module-its-5/">Hackaday</a> the ESP8266 wifi modules took the world by storm.
No wonder; for a few Euro a piece, these modules are already cheap as embedded
wifi adapters. But with an SDK available, the ESP8266 is absolutely amazing.</p>

<p><img class="right" src="http://isquared.nl/images/esp8266.png"></p>

<p>Development for these modules has recently gotten even better with the
release of <a href="http://nodemcu.com/index_en.html">Lua firmware</a> for these modules.
Not that I&#8217;m particularly fond of Lua as a language, but it is lightweight
and its not too hard to whip up some code in it without much experience.
And that is what I&#8217;ve been doing today, I wrote some Lua code that runs
unattended op the module, scanning for nearby wifi access points and sending
these, along with the signal strength (RSSI) value to a server in my home
network.</p>

<p>I hope to build a rudimentary location based service with this, tracking
the location of the ESP8266 module through the house.</p>

<!-- MORE -->


<p>The code for the <em>location tag</em> is pretty straightforward:</p>

<figure class='code'><figcaption><span>main.lua </span></figcaption>
 <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>
</pre></td><td class='code'><pre><code class='lua'><span class='line'><span class="n">wifi</span><span class="p">.</span><span class="n">setmode</span><span class="p">(</span><span class="n">wifi</span><span class="p">.</span><span class="n">STATION</span><span class="p">)</span>
</span><span class='line'><span class="n">wifi</span><span class="p">.</span><span class="n">sta</span><span class="p">.</span><span class="n">config</span><span class="p">(</span><span class="s2">&quot;</span><span class="s">essid&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="s">wpakey&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">function</span> <span class="nf">listap</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
</span><span class='line'>        <span class="n">myid</span> <span class="o">=</span> <span class="nb">string.lower</span><span class="p">(</span><span class="nb">string.gsub</span><span class="p">(</span><span class="n">wifi</span><span class="p">.</span><span class="n">sta</span><span class="p">.</span><span class="n">getmac</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="s">-&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="s">:&quot;</span><span class="p">))</span>
</span><span class='line'>        <span class="n">conn</span><span class="o">=</span><span class="n">net</span><span class="p">.</span><span class="n">createConnection</span><span class="p">(</span><span class="n">net</span><span class="p">.</span><span class="n">UDP</span><span class="p">,</span> <span class="kc">false</span><span class="p">)</span>
</span><span class='line'>        <span class="n">conn</span><span class="p">:</span><span class="n">connect</span><span class="p">(</span><span class="mi">8021</span><span class="p">,</span> <span class="s2">&quot;</span><span class="s">192.168.1.1&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="n">conn</span><span class="p">:</span><span class="n">send</span><span class="p">(</span><span class="n">myid</span><span class="o">..</span><span class="s2">&quot;</span><span class="s">: begin scan</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="k">for</span> <span class="n">key</span><span class="p">,</span><span class="n">value</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">do</span>
</span><span class='line'>                <span class="n">enc</span><span class="p">,</span> <span class="n">rssi</span><span class="p">,</span> <span class="n">bssid</span><span class="p">,</span> <span class="n">chan</span> <span class="o">=</span> <span class="nb">string.match</span><span class="p">(</span><span class="n">value</span><span class="p">,</span>
</span><span class='line'>                        <span class="s2">&quot;</span><span class="s">(%d),(-?%d+),(%x%x:%x%x:%x%x:%x%x:%x%x:%x%x),(%d+)&quot;</span><span class="p">)</span>
</span><span class='line'>                <span class="n">conn</span><span class="p">:</span><span class="n">send</span><span class="p">(</span><span class="n">myid</span><span class="o">..</span><span class="s2">&quot;</span><span class="s">: &quot;</span><span class="o">..</span><span class="n">bssid</span><span class="o">..</span><span class="s2">&quot;</span><span class="s">,&quot;</span><span class="o">..</span><span class="n">rssi</span><span class="o">..</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
</span><span class='line'>        <span class="k">end</span>
</span><span class='line'>        <span class="n">conn</span><span class="p">:</span><span class="n">close</span><span class="p">()</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="n">tmr</span><span class="p">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30000</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="k">function</span><span class="p">()</span> <span class="n">wifi</span><span class="p">.</span><span class="n">sta</span><span class="p">.</span><span class="n">getap</span><span class="p">(</span><span class="n">listap</span><span class="p">)</span> <span class="k">end</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Every 30 seconds the <code>tmr.alarm()</code> call fires <code>wifi.sta.getap()</code>. This function
scans for wifi networks and makes a callback to <code>listap()</code> on completion of the
scan.
The <code>listap()</code> function munges the data from <code>wifi.sta.getap()</code> and pushes it
through some UDP packets to a remote host for further processing.</p>

<p>Right now on the remote host there is just a <code>netcat</code> listening:</p>

<pre><code>hessch@leibniz ~ $ nc -ul 8021
18:fe:34:yy:yy:yy: begin scan
18:fe:34:yy:yy:yy: 84:9c:a6:xx:xx:xx,-76
18:fe:34:yy:yy:yy: 00:20:91:xx:xx:xx,-47
18:fe:34:yy:yy:yy: d4:ca:6d:xx:xx:xx,-46
18:fe:34:yy:yy:yy: d8:bx:4c:xx:xx:xx,-85
18:fe:34:yy:yy:yy: begin scan
18:fe:34:yy:yy:yy: 84:9c:a6:xx:xx:xx,-74
18:fe:34:yy:yy:yy: 00:20:91:xx:xx:xx,-49
18:fe:34:yy:yy:yy: d4:ca:6d:xx:xx:xx,-48
18:fe:34:yy:yy:yy: d8:bx:4c:xx:xx:xx,-85
</code></pre>

<p>Eventually a script should be listening here that computes a likely position
based on these values. Not sure yet how I&#8217;m hoing to implement this, maybe more
about this in a later post.</p>

<p>Playing with Lua on the ESP8266 today, though, makes me believe that its not
very likely that I&#8217;ll come anything near to an Arduino for anything wifi related.<br/>
The combination of a interpreted language like Lua and Wifi for this price is
unbeatable, the only things that I&#8217;d really like to see still are IPv6 support
and access to raw wifi packets, preferably in monitor mode.</p>

<p>I&#8217;m already planning a few more projects with these modules: a physical switch
for my Lifx lightbulbs in the house and various sensors for energy measuring.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RS-422 Transputer Link, First Packets]]></title>
    <link href="http://isquared.nl//blog/2014/11/15/rs-422-link-first-packets/"/>
    <updated>2014-11-15T15:37:00+01:00</updated>
    <id>http://isquared.nl//blog/2014/11/15/rs-422-link-first-packets</id>
    <content type="html"><![CDATA[<p>This week another of the familiar yellow bubblewrap envelopes from China
dropped on my doormat, delivering some ds89c21 rs-422 line driver chips.</p>

<p><img class="right" src="http://isquared.nl/images/rs422bias.jpg" width="450" height="200"></p>

<p>The ds89c21 chips fit the board designed in the previous post and led to
some first tests with a rs-422 differential link.
First of all, I found that I had omitted the bias resistors necessary
for the rs-422 link on the link input in my design. These were easily
bodged to the board for a quick test, the ugly results of impatient
soldering shown to the right.
But no success, the link input remained pinned to a logic high signal.</p>

<p>A few days of debugging later, it suddenly dawned to me to cross the
wires of the link and the link immediately sprang to life. <em>Doh</em>.
For now the link seems to be reliable even at 20 Mbit/s, great.</p>

<p><img class="right" src="http://isquared.nl/images/rs422.png" width="450" height="200"></p>

<p>I rechecked the schematic and the board silkscreen, seems that even
though the ds89c21 seems to match the board, these plus/minus lines on
either the receive or transmit lines are swapped in respect to the
board layout.</p>

<p>The oscilloscope picture to the right shows that the negative signal has
some nasty degradation, while the positive is pretty decent, strange.
It may just as well be the terrible bodged-on bias resistors, but I can&#8217;t
really explain why this would affect only one of the signal lines.</p>

<p>Oh well, time for more interesting tests than a simple loopback.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Raspberry Pi Inmos Link Progress]]></title>
    <link href="http://isquared.nl//blog/2014/10/30/raspberry-pi-inmos-link-progress/"/>
    <updated>2014-10-30T23:45:00+01:00</updated>
    <id>http://isquared.nl//blog/2014/10/30/raspberry-pi-inmos-link-progress</id>
    <content type="html"><![CDATA[<p>I finally found the time to work on the <a href="http://isquared.nl/blog/2014/06/18/raspberry-pi-inmos-link/">Raspberry Pi Inmos Link
Adapter</a>
again.
After spending many hours debugging the previous version without
any results, I abandoned that design.</p>

<p>This time I managed to bring up  the patience to do some quick tests
on a breadboard before committing it straight to a PCB. The tests
on breadboard looked promising, although I used a C012 link adaptor
chip for the breadboard tests instead of the C011 used in the PCB
version.</p>

<p><img class="right" src="http://isquared.nl/images/rpilink222pcb.png" width="450" height="296"></p>

<p>This new version is based on the Microchip MCP23017 16-bit i<sup>2</sup>c
GPIO interface instead of the two PCF8574&#8217;s in the previous version.</p>

<p>Using only one chip makes the software side a bit easier, but
the main reason I chose the MCP23017 over the PCF8574 was that I did
not really trust the quasi-bidirectional IO of the latter in my previous
design.
The MCP23017 feels more deterministic in that respect, giving the user
control over each GPIO&#8217;s direction, its default value, etc. A pretty
nice chip.</p>

<p>All IO is now running on 5 volt, as the i<sup>2</sup>c
bus is active low and pulled up to 3.3 volt by the Raspberry Pi, the
MCP23017 can safely run on 5 volt without damaging the Raspberry Pi&#8217;s
GPIOs.</p>

<p>The Inmos link, a reset line and a 5 MHz clock are available as
buffered TTL signals, the link speed is selectable in software, of
course with the obligatory associated blinkenlights.
The IMS-C011 <code>InputInterrupt</code> and <code>OutputInterrupt</code> signals are OR-ed
trough to open-collector outputs to one of the Raspberry&#8217;s GPIO&#8217;s.</p>

<p>I planned these signals to be available through rs-422 line drivers
as well. The rs-422 transceivers I picked from Eagle&#8217;s component
library seem to be either made from unobtainium or from unaffordium,
though. These need to be replace with something more commonly available.
As the board outline interferes with the Raspberry Pi&#8217;s ugly USB
connectors as well, a third version of the board may hopefully
straighten out these last few glitches.</p>

<p>But&#8230;does it work this time? Well, yes, it seems so, although more
testing still needs to be done.</p>

<p><img class="right" src="http://isquared.nl/images/rpilink222.jpg" width="450" height="200"></p>

<p>To the right is the new link interface in all its glory booting a
lowly T222 Transputer.</p>

<p>The Raspberry&#8217;s side of things is using a little Python module to
abstract the MCP23017 and C011 link adaptor from programs.</p>

<p>With default i<sup>2</sup>c addresses and a 10 Mbit/s link, writing
a byte to the link is a simple as:</p>

<pre><code>import Inmos2
link = Inmos2.Link()
link.write(0x42)
</code></pre>

<p>The T222 booting using the new link adaptor is shown below:</p>

<pre><code>hessch@archimedes ~/src/rpilink $ ./tdetect.py
Writing 23 bytes of boot code to Transputer:

    b1 d1 24 f2 21 fc 24 f2 
    21 f8 f0 60 5c 2a 2a 2a 
    4a ff 21 2f ff 02 00 

Read result from Transputer:

    aa aa


16-bit Transputer found
</code></pre>

<p>It&#8217;s alive!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Airbus MTP EPROM Repair]]></title>
    <link href="http://isquared.nl//blog/2014/08/10/airbus-mtp-eprom-repair/"/>
    <updated>2014-08-10T14:49:00+02:00</updated>
    <id>http://isquared.nl//blog/2014/08/10/airbus-mtp-eprom-repair</id>
    <content type="html"><![CDATA[<p>Last week I spent some time with an Ebay find, pictured to the right. This is
a <em>Maintenance Test Panel</em> (MTP), presumably from an Airbus A300-600.
First of all, I&#8217;m curious from which airline this unit came, as the buttons
seem to have distict nicotine residue on them.</p>

<p><img class="right" src="http://isquared.nl/images/airbus-mtp.jpg" width="320" height="320" title="Airbus MTP" ></p>

<p>The Maintenance Test Panel is located in the cockpit of the aircraft, behind
the first officer. It stores fault information from all computers that make
up the automated flight system and can run tests initiated by maintenance
engineers. In essence it is the <em>debug port</em>, or for car people, the <em>OBD-II</em>
port of the airplanes computers.</p>

<p>I have close to no documentation about this unit, or its use, but it is a
fun toy to play with, built with price being no issue. It is a self-contained
computer system around an Intel 8085 microprocessor, a couple of Harris,
now Intersil, HS-3282 ARINC-429 interfaces for communication and a two-line
liquid crystal display (LCD), that is very low in contrast and lit by two
good old incandescent light bulbs.</p>

<p>The LCD is interesting as it has no built-in character ROM, something that
is rare for character LCD modules, at least nowadays where most LCD&#8217;s use
a Hitachi HD44780 (or compatible) controller.</p>

<p>The character set for the display is stored in an EPROM on the first printed
circuit board module in the unit.
In the process of reverse-engineering the MTP, I made a dump of this EPROM,
an Intel 2716 from the 20th week of 1981. <br/>
Why do I care so much about this date, you probaby ask? <br/>
Well, I extracted the character definitions from the ROM dump and was amazed
by the amount of bitrot. Dozens of bits had clearly lost their value in this
ROM.
Which made for an interesting hour or so in a hex-editor, fixing the glyph
definitions in the ROM dump.</p>

<p><img class="right" src="http://isquared.nl/images/airbus-eprom.jpg" width="320" height="320" title="Old and New EPROM" ></p>

<p>After that, I tried to write the fixed ROM dump back to an EPROM. Not wanting
to erase the original EPROM in the unit, I rummaged through my junk drawers
and found a couple of old Soviet КР537РФ2 ROM&#8217;s. These chips should be 2716
compatibles, which was good news.
Just to find that my, otherwise pretty good, TL866 programmer was not able to
supply either the voltage or the current necessary to program these chips.</p>

<p>Already in the later hours of the evening I dug out an
<a href="http://www.artbv.nl/support/programmers/epp1f/">EPROM programmer</a> of a
vintage closer to the EPROMs to be programmed.
I had bought the programmer already some years ago, but never took the time
to try it. The great thing of this programmer is that it has a serial command
based interface. No software on the host pc is really necessary, if you are
willing to compile many arcane hex-values from bit-fields defined in the
documentation and type these into a terminal, what is exactly what I did. <br/>
This is also how I <em>had</em> to do it, as the (although still available) software
is written for long gone versions of MS Windows and I mostly use Mac OS and
various other Unix flavors for my hobbies. A Windows XP virtual machine that
I keep for moments like this, was certainly too recent for the programmers
software, already.</p>

<p>Hours of fumbling with conversion to Motorola S-record formats that the
programmer requires and serial line voodoo later, (my EPROM eraser running
overtime in the process too) I managed to burn the fixed ROM image to the
replacement EPROM chip. <br/>
If you can make out the faint text in the display in the first picture of
this article, the result is just about visible.</p>

<p>Useful? No, certainly not, as I don&#8217;t own an Airbus A300. ;) But it made
for some fun adventures with obsolete electronics, again.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Poor Man's PLCC Probe]]></title>
    <link href="http://isquared.nl//blog/2014/07/13/poor-mans-plcc-probe/"/>
    <updated>2014-07-13T14:10:00+02:00</updated>
    <id>http://isquared.nl//blog/2014/07/13/poor-mans-plcc-probe</id>
    <content type="html"><![CDATA[<p>Experimenting with an old <a href="http://en.wikipedia.org/wiki/Macintosh_Classic">Macintosh Classic</a>, I searched for a way to easily connect my logic analyzer to
its 68000 processor.</p>

<p>The MC68000 in the Macintosh Classic is a surface mounted 68-pin PLCC package,
of course it&#8217;s possible to attach many SMD grabbers to the pins of this package,
but that is far from practical.</p>

<p>True PLCC test adapters are far too expensive for hobbyist purposes, so I tried
something else, with good results.
On Ebay, I ordered a few PLCC86 sockets, and tried to placed one on top of the
MC68000.
This works, but not reliably, as the contact springs of the socket
force the socket off the IC package.<br/>
By sanding down the PLCC socket and removing four internal notches, the socket
can be pushed farther over the IC and you get a pretty snug fit.</p>

<p>Spot the differences in the pictures below, left the original socket, right the
modified one.</p>

<p><img src="http://isquared.nl/images/socket.jpg" width="240" height="240" title="PLCC socket" >
<img src="http://isquared.nl/images/socket_trim.jpg" width="240" height="240" title="PLCC socket, trimmed down" ></p>

<p>The modified socket attaches tightly around the PLCC IC to be probed, tight
enough that it takes some force to remove it again.
Certainly good enough for probing, but it may even suffice for adding hardware
permanently to the machine.</p>

<p>Below you can see the socket mounted on top of the MC68000 on a Macintosh Classic logic board.</p>

<p><img src="http://isquared.nl/images/classic_brd.jpg" width="320" height="240" title="Macintosh Classic logic board" >
<img src="http://isquared.nl/images/classic_brd_probe.jpg" width="320" height="240" title="Macintosh Classic logic board, socket fitted" ></p>

<p>Once mounted on the board, it&#8217;s easy to attach logic analyzer pods to the
socket pins.
But as you can see in the last picture, this becomes a ratsnest pretty fast.
It suffices for now, but terminating the logic analyzer to an adapter PCB
with proper header connectors for this purpose will be the next step.</p>

<p><img src="http://isquared.nl/images/68000_probed_in_mac.jpg" width="480" height="240" title="Macintosh Classic, 68000 probe" >
<img src="http://isquared.nl/images/68000_probed.jpg" width="240" height="240" title="Macintosh Classic, 68000 probe" ></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Raspberry Pi Inmos Link]]></title>
    <link href="http://isquared.nl//blog/2014/06/18/raspberry-pi-inmos-link/"/>
    <updated>2014-06-18T23:07:00+02:00</updated>
    <id>http://isquared.nl//blog/2014/06/18/raspberry-pi-inmos-link</id>
    <content type="html"><![CDATA[<p>While I haven&#8217;t progressed much with the AVM M1 as an Inmos link
adapter, I have also been designing an Inmos IMS-C011 based link
adapter for the Raspberry Pi.</p>

<p><img class="right" src="http://isquared.nl/images/rpi-link.jpg" width="512" height="384"></p>

<p>The Raspberry Pi link interface uses two PCF8574 I2C I/O expanders
to interface to the Raspberry Pi. I2C makes development easier,
as all can be done in user-mode using Python.</p>

<p>The software that I wrote for the AVM M1 before was not reliable,
first I thought this was due to my own programming, but on more
investigation it turs out that the AVM driver is interfering, but
without a driver the Linux PCMCIA subsystem doesn&#8217;t allocate
resources for the card.</p>

<p>For my purpose and because I was getting on a roll designing some
other printed circuit boards in Eagle, I deciced to postpone the M1
for a while to experiment with this new link board for the Raspberry
Pi.</p>

<p>The PCF8574 I/O expanders divide the work, one (on i2c address <code>0x20</code>)
handles the databus to the IMS-C011 link adapter, the other (on
address <code>0x21</code>) the control signals.</p>

<p>The circuit board shown above still has some issues, it could use
a better shape to clear the composite video connector on the
Raspberry Pi. I had wired the Input and Output interrupts of the
IMS-C001 directly to some Raspberry GPIO&#8217;s without thinking of the
5 volt levels the IMS-C011 uses, to prevent damage to the Raspberry
Pi&#8217;s GPIO&#8217;s I&#8217;ve cut the races to these GPIO&#8217;s on this board.</p>

<p>No software has been written yet, but the first hardware tests seem
to be ok, the 5 MHz oscillator is running and both PCF8574&#8217;s can be
seen from the Raspberry Pi side of things:</p>

<pre><code>hessch@leibniz ~ $ sudo i2cdetect -y -a 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 21 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
</code></pre>

<p>The status LED&#8217;s can be made to blink with a quick and dirty shell
script:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">while</span> <span class="o">[</span> <span class="o">==</span> <span class="o">]</span>
</span><span class='line'><span class="k">do </span>
</span><span class='line'><span class="k">  </span>sudo i2cset -y 0 0x21 0x40 0xff; sleep 1
</span><span class='line'>  sudo i2cset -y 0 0x21 0x40 0x00; sleep 1
</span><span class='line'><span class="k">done</span>
</span></code></pre></td></tr></table></div></figure>


<p>So far so good, to be continued&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[AVM M1 as Transputer link]]></title>
    <link href="http://isquared.nl//blog/2013/12/25/avm-m1-as-transputer-link/"/>
    <updated>2013-12-25T22:26:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/12/25/avm-m1-as-transputer-link</id>
    <content type="html"><![CDATA[<p>From my early highschool years on, I&#8217;ve been fascinated by the <a href="http://en.wikipedia.org/wiki/Transputer">Inmos Transputer</a> and have recently acquired some <a href="http://www.transputer.net/tn/11/tn11.html">Inmos B004 cards</a> and other hardware with the idea to start experimenting with Transputers.<br/>
One problem though, these B004 cards are old 8-bit ISA hardware.</p>

<p>Since IBM compatible PC&#8217;s are almost the complete opposite of Transputers in
<em>interestingness</em>, I didn&#8217;t really like to invest scarce space in my house for
a boring grey PC box just to fit the B004 cards.
I had already been toying with the idea of making a custom interface from ISA
to something more modern, but luckily I found a better option:</p>

<p>Axel Muhr describes on <a href="http://www.geekdot.com/avm-b1.html">this page</a> (geekdot.com) onwards his hacks using AVM B1 active ISDN controllers as B004 sustitutes.
There is a PCI version of the B1, but I wasn&#8217;t sure about compatibility and
the price of these cards is still higher than what I paid for my original B004&#8217;s.</p>

<p><em>Enter the AVM M1 PCMCIA card&#8230;</em></p>

<p><img class="right" src="http://isquared.nl/images/m1card.jpg"></p>

<p>This card seems to be a PCMCIA variant of the B1 hardware, has 1 MB of RAM and
a IMST400 Transputer on board. Making Transputers compatible with reasonably
modern laptops! Oh, and these cards can be had for a few Euro a piece on Ebay.</p>

<p>I did some quick reverse engineering of this card. The link adapter is
implemented in a Xilinx XC3164A FPGA and the T400 seems to boot from link 0.
The link adapter in the FPGA looks to be IMSC012 compatible.
The config of the FPGA is fixed and stored in a serial configuration ROM.
Then there is a parallel EEPROM that holds all PCMCIA parameter info and a
second serial EEPROM, presumably for settings storage.</p>

<p>The M1 was meant to interface with Siemens GSM mobile phones and as such has
no ISDN controller inside, just an UART. In our case, this is actually good
news, as there is no other crap attached to our precious Transputer.
A similar card, called M2, exists and has exactly the same hardware but also
a Siemens ISDN chipset fitted on the board.</p>

<p>The UART can easily be removed from the PCB, and there is probably enough space
to fit some buffers or even a RS-422 driver to feed the remaining free link
(link 1) to the outside, as I plan to do when I get the software side up to
scratch. From there on it would be easy to bootstrap larger Transputer networks
from this PCMCIA card.</p>

<p>A quick test with the original CAPI drivers for Linux confirms that this card
appears to the host just like a B1 (and so like a B004!):</p>

<pre><code>hessch@bt:~$ dmesg
...
[ 9888.081914] b1pcmcia: AVM M1 at i/o 0x150, irq 3, revision 3
...
</code></pre>

<p>The only problem, as could be expected with ancient hardware, is that all Linux
Transputer link drivers that I could find are equally ancient.
<em>Ancient and crufty.</em></p>

<p>As a quick test, I modified <a href="http://www.geekdot.com/1st-sample-code.html">Apple II interface code</a>, also from Axel Muhr&#8217;s <a href="http://www.geekdot.com/">geekdot.com</a>.
I translated this to a bit of Python code that uses <code>portio</code> to do I/O with
the M1 to test loading code to the T400 Transputer.
My code is far from reliable, in its current state. Actually it seems more like it worked by accident, shown here:</p>

<pre><code>hessch@bt:~$ sudo ./tdetect.py 
ioperm() was successful for all C012 registers from 0x150 onwards

resetting Transputer...

ISR value: 0x0
OSR value: 0x1

writing data to Transputer:

    17 b1 d1 24 f2 21 fc 24 f2 21 f8 f0 60 5c 2a 2a 
    2a 4a ff 21 2f ff 2 0 

read result from Transputer:

    aa aa 0 0 
</code></pre>

<p>Yay, we have a 32-bit Transputer answering!</p>

<p>I&#8217;m not really bothered by the reliability of my code yet, as it would
be still a lot of work to make this in something useful. Having the common
Transputer link infrastructure in place should make all old userspace stuff
that is still available come alive again.
Probably, I will strip all CAPI/ ISDN related stuff out of the working AVM
M1 driver that is in the current Linux source tree and implement Transputer
link driver compatible ioctl&#8217;s in that driver, as all needed functionality is
already in the existing M1 driver in Linux.
While writing the Python code mentioned above I had a good few reads of the
source of this module already and it is quite readable, which gives me better
hopes of getting something working than trying to bring the old Linux link
drivers back to the 21st century.</p>

<p>I&#8217;ll probably create a new page somewhere on this site to document my progress.
When that happens, it will be linked from here.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Online hexdump tool]]></title>
    <link href="http://isquared.nl//blog/2013/11/02/online-hexdump-tool/"/>
    <updated>2013-11-02T16:34:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/11/02/online-hexdump-tool</id>
    <content type="html"><![CDATA[<p>I have just published a testing version of an online hexdump
utility, which can be found <a href="http://isquared.nl/tools/hexdump.html">here</a>.</p>

<p>There exist a few online hexdump tools already, but these all require
you to upload a file to a remote server, which may be inappropriate.
Also, in most cases these tools produce an output quite unlike what we
are used to with <code>od</code>, <code>xxd</code> and the like. I wanted something closer to
what my favorite shell utilities produce.</p>

<p>My (still experimental) tool processes files locally in JavaScript, using HTML5
local file access and produces something similar to <code>hexdump -C</code>&#8217;s output, without
byte grouping.</p>

<p>A screenshot of the tool in action is shown below:</p>

<p><img src="http://isquared.nl/images/hexdump.png"></p>

<p>This tool may be useful in circumstances where you don&#8217;t have a machine with a
proper operating system at hand and quickly want to inspect some file.</p>

<!-- MORE -->


<p>It still has some rough edges and especially large files may hang the browser.
I learned the rough way that <code>document.createTextNode()</code> is very expensive, and
had to replace many instances of it with simple string concatenation and a
single call to <code>createTextNode()</code>. That speeded things up a lot.</p>

<p>The most interesting part of the code is the formatting of the hex dump output,
this is shown below:</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>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">image</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// write address</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mi">16</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">i</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="mi">16</span><span class="p">);</span>
</span><span class='line'>      <span class="k">while</span> <span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">)</span> <span class="nx">a</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="o">+</span> <span class="nx">a</span><span class="p">;</span> <span class="c1">// FIXME: hardcoded format </span>
</span><span class='line'>      <span class="nx">frag</span> <span class="o">+=</span> <span class="nx">a</span> <span class="o">+</span> <span class="s2">&quot;: &quot;</span><span class="p">;</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">image</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>       <span class="c1">// raw byte (char)</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">cc</span> <span class="o">=</span> <span class="nx">c</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>   <span class="c1">// charcode</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// format byte</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">h</span> <span class="o">=</span> <span class="nx">cc</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="mi">16</span><span class="p">);</span>
</span><span class='line'>  <span class="k">while</span> <span class="p">(</span><span class="nx">h</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="nx">h</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="o">+</span> <span class="nx">h</span><span class="p">;</span>
</span><span class='line'>  <span class="nx">frag</span> <span class="o">+=</span> <span class="nx">h</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// append char to ascii representation, print non-printable as &quot;.&quot;</span>
</span><span class='line'>  <span class="nx">ascii</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">cc</span> <span class="o">&gt;</span> <span class="mi">31</span> <span class="o">&amp;&amp;</span> <span class="nx">cc</span> <span class="o">&lt;</span> <span class="mi">127</span><span class="p">)</span><span class="o">?</span><span class="nx">c</span><span class="o">:</span><span class="s1">&#39;.&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// format columns</span>
</span><span class='line'>  <span class="nx">frag</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mi">16</span> <span class="o">==</span> <span class="mi">15</span><span class="p">)</span><span class="o">?</span><span class="nx">ascii</span> <span class="o">+</span> <span class="s2">&quot;\n&quot;</span><span class="o">:</span><span class="s2">&quot; &quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mi">16</span> <span class="o">==</span> <span class="mi">15</span><span class="p">)</span> <span class="nx">ascii</span> <span class="o">=</span> <span class="s2">&quot;    &quot;</span><span class="p">;</span> <span class="c1">// clear ascii rep. on newline</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// handle last line, pad empty bytes</span>
</span><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">s</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">s</span> <span class="o">&lt;</span> <span class="p">(</span><span class="mi">16</span> <span class="o">-</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mi">16</span><span class="p">))</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">s</span><span class="o">++</span><span class="p">)</span> <span class="nx">frag</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span><span class="p">;</span>
</span><span class='line'><span class="nx">frag</span> <span class="o">+=</span> <span class="nx">ascii</span> <span class="o">+</span> <span class="s2">&quot;\n&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// commit fragment to DOM</span>
</span><span class='line'><span class="k">this</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">createTextNode</span><span class="p">(</span><span class="nx">frag</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>This code was originally written for another purpose and it does not
format addresses over <code>0xffff</code> properly, but I will fix that sooner or
later.</p>

<p>More output format options (byte grouping, columns, etc.) would also be useful,
but implementing that requires some cleaning up of the code above, as it is
already turning crufty after a few iterations. :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CA board]]></title>
    <link href="http://isquared.nl//blog/2013/10/27/ca-board/"/>
    <updated>2013-10-27T14:45:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/10/27/ca-board</id>
    <content type="html"><![CDATA[<p>Some time ago I had these boards made by <a href="http://oshpark.com">OSH Park</a>,
and I&#8217;m pretty pleased how they turned out. It&#8217;s great to see your own
designs professionally manufactured, now just hope I didn&#8217;t screw anything
up in my design. :)</p>

<p><img class="right" src="http://isquared.nl/images/cam_board_front_400.jpg" title="CAM board (front)" ></p>

<p><img class="right" src="http://isquared.nl/images/cam_board_back_400.jpg" title="CAM board (back)" ></p>

<p>This board is part of an experiment with cellular automata that I&#8217;m sometimes
spending my thoughts on. Like almost all the stuff I do, this project as to compete for my attention with many other unfinished stuff.</p>

<p>The board will be populated with 16 Atmel ATTiny13 microcontroller, of which
I had already ordered a lot of 50 pieces from <a href="http://ebay.com">Ebay</a>.</p>

<p>All components will hot air soldered using stencilled on solder paste.</p>

<p>This weekend I experimented with programming the SO-8 packaged microcontrollers.
To do so I also ordered a programming adapter from <a href="http://www.wvshare.com/">WaveShare</a> as pictured below.</p>

<p><img class="right" src="http://isquared.nl/images/t13_pgm_400.jpg" title="programming adapter" ></p>

<p>This adapter allows programming of the comtroller before soldering it to the
board. I&#8217;ll probably prototype on breadboard anyway. I want to be able to
dynamically load code to the controllers which will be executed in a simple virtual machine.</p>

<p>To test code running on the Tiny13, I&#8217;ve made a small plug with 3 LEDs that can be attached to one of the headers of the programming adapter. The LEDs show
the state of PB0 - PB2, actually the inverse state, as the GPIOs sink Vcc in this case.</p>

<p>It didn&#8217;t take long to get the first code running on the Tiny13, blinky LEDs
this weekend!</p>

<p>Time to think of implementing a protocol for the controllers to exchange
state information, updating code on a remote controller as well as
synchronizing the controllers as they will all run asynchronously by default.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Categories as keywords in Octopress]]></title>
    <link href="http://isquared.nl//blog/2013/10/20/categories-as-keywords-in-octopress/"/>
    <updated>2013-10-20T15:57:00+02:00</updated>
    <id>http://isquared.nl//blog/2013/10/20/categories-as-keywords-in-octopress</id>
    <content type="html"><![CDATA[<p>The version of Octopress that I use for this blog requires you to give both
categories as well as keywords for a page / post to have these appear in the
meta tags of the generated HTML. I didn&#8217;t check what the current Octopress
does in this respect, as I don&#8217;t feel like upgrading at the moment.</p>

<p>Since I&#8217;m lazy, I&#8217;ve updated <code>source/_includes/head.html</code> to fall back to
using categories as keywords for a page if no keywords are given.</p>

<p>As this may be useful to other Octopress users, this is what I&#8217;ve changed:
In <code>source/_includes/head.html</code>, change:</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'>{% if page.keywords %}&lt;meta name="keywords" content="{{ page.keywords }}">{% endif %}</span></code></pre></td></tr></table></div></figure>


<p>to:</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'>{% capture keywords %}{% if page.keywords %}
</span><span class='line'>  {{ page.keywords }}
</span><span class='line'>{% elsif page.categories %}
</span><span class='line'>  {{ page.categories | join: ', ' }}
</span><span class='line'>{% else %}
</span><span class='line'>  {{ site.keywords }}
</span><span class='line'>{% endif %}{% endcapture %}
</span><span class='line'>&lt;meta name="keywords" content="{{ keywords }}"></span></code></pre></td></tr></table></div></figure>


<p>and Octopress will default to the categories of a post to use as <code>meta</code> keywords.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Psion Organiser II UDG Framebuffer, Part 1.75]]></title>
    <link href="http://isquared.nl//blog/2013/09/16/psion-organiser-ii-udg-framebuffer/"/>
    <updated>2013-09-16T22:30:00+02:00</updated>
    <id>http://isquared.nl//blog/2013/09/16/psion-organiser-ii-udg-framebuffer</id>
    <content type="html"><![CDATA[<p>In 2009 I wrote about using the user defined characters of the
Hitachi <code>HD44780</code> LCD controller as a poor man&#8217;s framebuffer.
See <a href="http://isquared.nl//blog/2009/06/16/UDGBUF-Part-1.5-%3A-Adventures-with-the-HD44780/">this</a>
post for details about my experiments on a Psion Organiser II back then.</p>

<p>Well, somewhere this year I revisited that project and wrote a set of Psion OPL
programs to create and manipulate a small framebuffer implemented in eight
characters of the Psion&#8217;s little LCD.
Actually, since I&#8217;m nowadays the proud owner of a Psion Organiser II model LZ64 , the LCD is larger than it was in 2009. ;)</p>

<p>The library of OPL programs is called <code>UDGFB</code> and is available on <a href="https://github.com/hessch/udgbuf">Github</a>. Should I ever update it, expect it to appear there.</p>

<p>More technical details about UDGFB after the break&#8230;</p>

<!-- more -->


<p>The framebuffer uses the user-defined characters printed in the following configuration:</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>
</pre></td><td class='code'><pre><code class=''><span class='line'>udg0 udg1 udg2 udg3
</span><span class='line'>udg4 udg5 udg6 udg7</span></code></pre></td></tr></table></div></figure>


<p>The following functions are defined:</p>

<ul>
<li><h2>clearfb:</h2>

<p>clears the framebuffer</p></li>
<li><h2>printfb:(xpos, ypos) </h2>

<p>print framebuffer UDGs at location (xpos, ypos)</p></li>
<li><h2>pset:(x, y, s)</h2>

<p>set pixel at (x, y) to state s, where &#8220;s&#8221; is 0 or 1</p></li>
<li><h2>pixel%:(x, y)</h2>

<p>get value of pixel at (x, y)</p></li>
<li><h2>blitup:</h2>

<p>scroll all pixels one row up, duplicates row 15</p></li>
</ul>


<p>The following functions are for internal use:</p>

<ul>
<li><h2>pokeudg:(char, row, value)</h2>

<p>write value to udg row of udg character</p></li>
<li><h2>peekudg%:(char, row)</h2>

<p>read byte defining row of udg character</p></li>
</ul>


<p>An example of how to use UDGFB follows below:</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'>fbtest:
</span><span class='line'>  local x%, y%
</span><span class='line'>
</span><span class='line'>  clearfb:
</span><span class='line'>  printfb:(8, 2)
</span><span class='line'>
</span><span class='line'>  at 3,1
</span><span class='line'>  print "Framebuffer Test";
</span><span class='line'>
</span><span class='line'>  y%  = 0
</span><span class='line'>  while y% &lt;= 15
</span><span class='line'>    x% = 0
</span><span class='line'>    while x% &lt;= 19
</span><span class='line'>      pset:(x%, y%, 1)
</span><span class='line'>      x% = x% + 1
</span><span class='line'>    endwh
</span><span class='line'>    y% = y% + 1
</span><span class='line'>  endwh
</span><span class='line'>
</span><span class='line'>  while y% >= 0
</span><span class='line'>    x% = 19
</span><span class='line'>    while x% >= 0
</span><span class='line'>      pset:(x%, y%, 0)
</span><span class='line'>      x% = x% - 2
</span><span class='line'>    endwh
</span><span class='line'>    y% = y% - 2
</span><span class='line'>  endwh
</span><span class='line'>
</span><span class='line'>  at 8,4 : print "done";</span></code></pre></td></tr></table></div></figure>


<p>The techniques used should be easily adaptable to all <code>HD44780</code> based LCD
modules.
I may have a go trying this on an Arduino and a bare character LCD module. But
first I&#8217;d like to port UDGFB, or at least the most frequently called functions,
to machine code for the Organiser II.</p>

<p>More in about a year or four. In this pace, that is&#8230; :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Squeezebox Radio Ambient Light Sensor]]></title>
    <link href="http://isquared.nl//blog/2013/09/15/squeezebox-radio-ambient-light-sensor/"/>
    <updated>2013-09-15T21:20:00+02:00</updated>
    <id>http://isquared.nl//blog/2013/09/15/squeezebox-radio-ambient-light-sensor</id>
    <content type="html"><![CDATA[<p>Almost half a year has passed since I last wrote anything here, terrible.
Anyways, here is a description of a little hack I did some time ago:</p>

<p>Our bedroom has this Squeezebox radio, that I mostly use as a clock and to
play from Spotify.</p>

<p><img class="center" src="http://isquared.nl//images/squeezebox.jpg"></p>

<p>The Squeezebox has an ambient light sensor that dims the screen when the
lights go out. Which works fine, the screen is dim enough at night not to
interfere with my sleep.</p>

<p>Anyways, of course I had enabled SSH access to the Squeezebox just after
installing it.
Last year I was poking around in its filesystem to discover the ambient
light sensor hanging around in /sys:</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>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ cat /sys/bus/i2c/drivers/msp430/1-0010/ambient
</span><span class='line'>345</span></code></pre></td></tr></table></div></figure>


<p>Every variable in the <em>hessch</em> residence needs to be graphed, this data
could not be left aside.
Also, as the ambient light sensor faces the window in the bedroom, I thought
this might give some interesting data on the length of the days.</p>

<!-- more -->


<p>I hadn&#8217;t played with Cosm before, and thought this was a good occasion to give
it a try. (Cosm was called Patchube before, and is now renamed to Xively, probably as I write this they&#8217;re planning on another name.)
It turned out Cosm was pretty easy to use, and I quickly whipped up a piece of
shell script to send values from the Squeezebox to Cosm:</p>

<figure class='code'><figcaption><span>cosm-update-brightness </span></figcaption>
 <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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/sh</span>
</span><span class='line'><span class="nv">APIKEY</span><span class="o">=</span><span class="s1">&#39;MYAPIKEY&#39;</span>
</span><span class='line'><span class="nv">HOST</span><span class="o">=</span>insomnia.intra.isquared.nl
</span><span class='line'>curl  --header <span class="s2">&quot;X-ApiKey: ${APIKEY}&quot;</span> <span class="se">\</span>
</span><span class='line'>  --request PUT <span class="se">\</span>
</span><span class='line'>  --data <span class="s1">&#39;{&quot;datastreams&quot;:[{&quot;id&quot;:&quot;bedroom&quot;, &quot;current_value&quot;:&quot;&#39;</span><span class="se">\</span>
</span><span class='line'>      <span class="k">$(</span>ssh <span class="k">${</span><span class="nv">HOST</span><span class="k">}</span> <span class="s1">&#39;cat /sys/bus/i2c/drivers/msp430/1-0010/ambient&#39;</span> |<span class="se">\</span>
</span><span class='line'>          awk <span class="s1">&#39;{</span>
</span><span class='line'><span class="s1">             printf &quot;%4.4f\n&quot;,(11.51293 - log($1 + 1))</span>
</span><span class='line'><span class="s1">         }&#39;</span> <span class="k">)</span><span class="s1">&#39;&quot; \</span>
</span><span class='line'><span class="s1">     }], &quot;version&quot;:&quot;1.0.0&quot;}&#39;</span> <span class="se">\</span>
</span><span class='line'>  --silent http://api.cosm.com/v2/feeds/83451
</span></code></pre></td></tr></table></div></figure>


<p>Actually this is a very ugly oneliner that I&#8217;ve cleaned up a bit, it&#8217;s still ugly code, though.
It fetches the current sensor value over ssh from the Squeezebox, and spits it as JSON to Cosm.
It also tries to munch the raw values a bit as the output of the sensor is far from linear.</p>

<p><img class="center" src="http://isquared.nl//images/ambient.png"></p>

<p>The graph above is the last 3 month of data as displayed in Cosm / Xively / whatever, one can see the days already getting shorter and darker, going towards the
inevitable winter.</p>

<p>Zooming to a days worth of data one can nicely see the sunrise around 5:00 UTC and the sunset around 18:00 UTC, and the lamp in the room switching on around 19:00 UTC:</p>

<p><img class="center" src="http://isquared.nl//images/ambient-day.png"></p>

<p>It might be interesting to filter out the characteristic level of the lamps in the room as the lamps mess with measuring the length of the day.
In the graph above the first peak in the graph (around 22:00 UTC) is the ceiling
light, which is switched off and being replaced with a bedside lamp that has three dimmer levels, of which two can be seen in the graph. When I&#8217;m writing this,
as you can see the ceiling lamp is switched on again. :)</p>

<p>It could be fun to analyze the data to get an insight in our sleeping patterns and maybe even if (and how) the daylight affects these.</p>

<p><em>Maybe to be coninued&#8230;</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[MSP430 Boids]]></title>
    <link href="http://isquared.nl//blog/2013/04/09/msp430-boids/"/>
    <updated>2013-04-09T23:26:00+02:00</updated>
    <id>http://isquared.nl//blog/2013/04/09/msp430-boids</id>
    <content type="html"><![CDATA[<p>As posted before on <a href="https://twitter.com/hessch/status/319886932920397825">Twitter</a> I&#8217;ve
been playing with <a href="https://www.olimex.com/">Olimex</a>&#8217;s <a href="https://www.olimex.com/Products/MSP430/Booster/MSP430-LED8x8-B00STERPACK/">MSP430-LED boosterpack</a>.
I&#8217;ve bought some ARM Cortex M3 modules from Olimex before that I liked. This modle is really nice
hardware, again. Well engineered and very good value for money.
I think I&#8217;ll try one of their OLinuXino boards later on too.</p>

<p>After trying a simple rule 110 cellular automaton as a first test for the display. I&#8217;ve now ported
my <a href="http://isquared.nl//blog/2010/02/22/fi.sh-a-Boids-clone-in-Bash/">Bash implementation</a> of Craig Reynolds Boids to
the MSP430 microcontroller.</p>

<p>A video follows after the break:</p>

<!-- MORE -->


<p><video width='640' height='360' preload='none' controls poster=' http://isquared.nl/images/msp430boids.png'><source src='http://isquared.nl/images/boids.m4v' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'/></video></p>

<p>The bad compact camera video doesn&#8217;t really do justice to the effect, which looks a lot better and more
fluidic in real life.</p>

<p>The code for this is written in the great <a href="https://github.com/energia/Energia/wiki">Energia IDE</a>, a
fork of Arduino for the MSP430 Launchpad.</p>

<p>The code is pretty ugly, as this was a quick two hour hack on the couch last evening.
Also like fi.sh, the Bash version, this doesn&#8217;t do real vector arithmetic, it just does
calculations on the x- and y-components on vectors.
Since C is more capable than Bash in this respect, I might update that later, although
it isn&#8217;t really necessary to achieve the right behaviour.</p>

<p>The full code is included below, put on your peril sensitive sunglasses:</p>

<figure class='code'><figcaption><span>mspboids.c  </span></figcaption>
 <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>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
<span class='line-number'>143</span>
<span class='line-number'>144</span>
<span class='line-number'>145</span>
<span class='line-number'>146</span>
<span class='line-number'>147</span>
<span class='line-number'>148</span>
<span class='line-number'>149</span>
<span class='line-number'>150</span>
<span class='line-number'>151</span>
<span class='line-number'>152</span>
<span class='line-number'>153</span>
<span class='line-number'>154</span>
<span class='line-number'>155</span>
<span class='line-number'>156</span>
<span class='line-number'>157</span>
<span class='line-number'>158</span>
<span class='line-number'>159</span>
<span class='line-number'>160</span>
<span class='line-number'>161</span>
<span class='line-number'>162</span>
<span class='line-number'>163</span>
<span class='line-number'>164</span>
<span class='line-number'>165</span>
<span class='line-number'>166</span>
<span class='line-number'>167</span>
<span class='line-number'>168</span>
<span class='line-number'>169</span>
<span class='line-number'>170</span>
<span class='line-number'>171</span>
<span class='line-number'>172</span>
<span class='line-number'>173</span>
<span class='line-number'>174</span>
<span class='line-number'>175</span>
<span class='line-number'>176</span>
<span class='line-number'>177</span>
<span class='line-number'>178</span>
<span class='line-number'>179</span>
<span class='line-number'>180</span>
<span class='line-number'>181</span>
<span class='line-number'>182</span>
<span class='line-number'>183</span>
<span class='line-number'>184</span>
<span class='line-number'>185</span>
<span class='line-number'>186</span>
<span class='line-number'>187</span>
<span class='line-number'>188</span>
<span class='line-number'>189</span>
<span class='line-number'>190</span>
<span class='line-number'>191</span>
<span class='line-number'>192</span>
<span class='line-number'>193</span>
<span class='line-number'>194</span>
<span class='line-number'>195</span>
<span class='line-number'>196</span>
<span class='line-number'>197</span>
<span class='line-number'>198</span>
<span class='line-number'>199</span>
<span class='line-number'>200</span>
<span class='line-number'>201</span>
<span class='line-number'>202</span>
<span class='line-number'>203</span>
<span class='line-number'>204</span>
<span class='line-number'>205</span>
<span class='line-number'>206</span>
<span class='line-number'>207</span>
<span class='line-number'>208</span>
<span class='line-number'>209</span>
<span class='line-number'>210</span>
<span class='line-number'>211</span>
<span class='line-number'>212</span>
<span class='line-number'>213</span>
<span class='line-number'>214</span>
<span class='line-number'>215</span>
<span class='line-number'>216</span>
<span class='line-number'>217</span>
<span class='line-number'>218</span>
<span class='line-number'>219</span>
<span class='line-number'>220</span>
<span class='line-number'>221</span>
<span class='line-number'>222</span>
<span class='line-number'>223</span>
<span class='line-number'>224</span>
<span class='line-number'>225</span>
<span class='line-number'>226</span>
<span class='line-number'>227</span>
<span class='line-number'>228</span>
<span class='line-number'>229</span>
<span class='line-number'>230</span>
<span class='line-number'>231</span>
<span class='line-number'>232</span>
<span class='line-number'>233</span>
<span class='line-number'>234</span>
<span class='line-number'>235</span>
<span class='line-number'>236</span>
<span class='line-number'>237</span>
<span class='line-number'>238</span>
<span class='line-number'>239</span>
<span class='line-number'>240</span>
<span class='line-number'>241</span>
<span class='line-number'>242</span>
<span class='line-number'>243</span>
<span class='line-number'>244</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="cm">/* </span>
</span><span class='line'><span class="cm"> * Boids for Olimex MSP430-LED boosterpack and Energia</span>
</span><span class='line'><span class="cm"> * mostly ported from fi.sh </span>
</span><span class='line'><span class="cm"> * (http://isquared.nl/blog/2010/02/22/fi.sh-a-Boids-clone-in-Bash/)</span>
</span><span class='line'><span class="cm"> *</span>
</span><span class='line'><span class="cm"> * Hessel Schut, hessel@isquared.nl, 2013-04-07</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// The 8x8 led matrix</span>
</span><span class='line'><span class="cp">#define LATCH 6</span>
</span><span class='line'><span class="cp">#define CLOCK 7</span>
</span><span class='line'><span class="cp">#define DATA 14</span>
</span><span class='line'><span class="cp">#define DELAYTIME 1 </span><span class="c1">// microseconds to wait after setting pin</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// MIC seeds random()</span>
</span><span class='line'><span class="cp">#define AIN 0 </span><span class="c1">// Note: AIN0 == pin2</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// number of boids</span>
</span><span class='line'><span class="cp">#define NBOIDS 4</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// minimum separation for avoid()</span>
</span><span class='line'><span class="cp">#define SEP 3</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// frame buffer </span>
</span><span class='line'><span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">image</span><span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span>
</span><span class='line'>  <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// coordinates</span>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span> <span class="n">point</span> <span class="p">{</span>
</span><span class='line'>  <span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">x</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">y</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// vectors</span>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span> <span class="n">vector</span> <span class="p">{</span>
</span><span class='line'>  <span class="kt">signed</span> <span class="kt">short</span> <span class="n">x</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">signed</span> <span class="kt">short</span> <span class="n">y</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// boids </span>
</span><span class='line'><span class="k">typedef</span> <span class="k">struct</span> <span class="n">boid</span>  <span class="p">{</span>
</span><span class='line'>  <span class="n">point</span> <span class="n">position</span><span class="p">;</span>
</span><span class='line'>  <span class="n">vector</span> <span class="n">heading</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// boid instances</span>
</span><span class='line'><span class="n">boid</span> <span class="n">boids</span><span class="p">[</span><span class="n">NBOIDS</span><span class="p">]</span> <span class="o">=</span> <span class="p">{};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// clear framebuffer</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">clearScreen</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">image</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mh">0x00</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="c1">// set pin modes</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">CLOCK</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">DATA</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">LATCH</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">RED_LED</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">analogReference</span><span class="p">(</span><span class="n">INTERNAL1V5</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// initialize boids</span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">position</span> <span class="o">=</span> <span class="p">(</span><span class="n">point</span><span class="p">){</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">};</span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">heading</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span><span class='line'>  <span class="c1">//</span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">position</span> <span class="o">=</span> <span class="p">(</span><span class="n">point</span><span class="p">){</span><span class="mi">7</span><span class="p">,</span> <span class="mi">1</span><span class="p">};</span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">heading</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">};</span>
</span><span class='line'>  <span class="c1">// </span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">position</span> <span class="o">=</span> <span class="p">(</span><span class="n">point</span><span class="p">){</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">};</span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">heading</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">};</span>
</span><span class='line'>  <span class="c1">// </span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="n">position</span> <span class="o">=</span> <span class="p">(</span><span class="n">point</span><span class="p">){</span><span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">};</span>
</span><span class='line'>  <span class="n">boids</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="n">heading</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// initial display</span>
</span><span class='line'>  <span class="n">plotBoids</span><span class="p">();</span>
</span><span class='line'>  <span class="n">sendImage</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// send 16 bits to LED tile (bits 0..7 are column, 8..15 are row) </span>
</span><span class='line'><span class="kt">void</span> <span class="nf">sendData</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">16</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">digitalWrite</span><span class="p">(</span><span class="n">DATA</span><span class="p">,</span> <span class="p">(</span><span class="n">data</span> <span class="o">&amp;</span> <span class="p">((</span><span class="kt">unsigned</span> <span class="kt">short</span><span class="p">)</span><span class="mi">1</span><span class="o">&lt;&lt;</span><span class="n">i</span><span class="p">))</span><span class="o">?</span><span class="n">HIGH</span><span class="o">:</span><span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>      <span class="n">delayMicroseconds</span><span class="p">(</span><span class="n">DELAYTIME</span><span class="p">);</span>
</span><span class='line'>      <span class="n">digitalWrite</span><span class="p">(</span><span class="n">CLOCK</span><span class="p">,</span><span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>      <span class="n">delayMicroseconds</span><span class="p">(</span><span class="n">DELAYTIME</span><span class="p">);</span>
</span><span class='line'>      <span class="n">digitalWrite</span><span class="p">(</span><span class="n">CLOCK</span><span class="p">,</span><span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>  <span class="n">delayMicroseconds</span><span class="p">(</span><span class="n">DELAYTIME</span><span class="p">);</span>
</span><span class='line'>  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LATCH</span><span class="p">,</span><span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>  <span class="n">delayMicroseconds</span><span class="p">(</span><span class="n">DELAYTIME</span><span class="p">);</span>
</span><span class='line'>  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LATCH</span><span class="p">,</span><span class="n">LOW</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="nf">setPixel</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">x</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">y</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">image</span><span class="p">[</span><span class="n">y</span><span class="p">]</span> <span class="o">|=</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span><span class='line'>      <span class="n">sendImage</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
</span><span class='line'>      <span class="n">delay</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span><span class='line'>  <span class="p">};</span> <span class="c1">// try to compensate for bright col 0</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// scan an image on the LED tile</span>
</span><span class='line'><span class="c1">// 8x8 bitmap img is the input</span>
</span><span class='line'><span class="kt">void</span> <span class="n">sendImage</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">img</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">data</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">8</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">data</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o">&lt;&lt;</span><span class="mi">8</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">i</span><span class="p">;</span>
</span><span class='line'>      <span class="n">data</span> <span class="o">|=</span> <span class="o">*</span><span class="n">img</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>      <span class="n">sendData</span><span class="p">(</span><span class="n">data</span><span class="p">);</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">plotBoids</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">clearScreen</span><span class="p">();</span>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">NBOIDS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>      <span class="n">setPixel</span><span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">boids</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>  <span class="n">sendImage</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">point</span> <span class="n">handleEdge</span><span class="p">(</span><span class="k">struct</span> <span class="n">point</span> <span class="n">p</span><span class="p">,</span> <span class="k">struct</span> <span class="n">vector</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">{(</span><span class="n">p</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">d</span><span class="p">.</span><span class="n">x</span><span class="p">)</span><span class="o">%</span><span class="mi">8</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">d</span><span class="p">.</span><span class="n">y</span><span class="p">)</span><span class="o">%</span><span class="mi">8</span><span class="p">};</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">vector</span> <span class="n">flock</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">me</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">vector</span> <span class="n">flocking_vector</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">peer</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">peer</span> <span class="o">&lt;</span> <span class="n">NBOIDS</span><span class="p">;</span> <span class="n">peer</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">// skip myself  </span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">peer</span> <span class="o">==</span> <span class="n">me</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// calculate peer x/y distances</span>
</span><span class='line'>      <span class="n">vector</span> <span class="n">peer_vec</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span>
</span><span class='line'>          <span class="n">boids</span><span class="p">[</span><span class="n">peer</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span><span class="p">,</span>
</span><span class='line'>          <span class="n">boids</span><span class="p">[</span><span class="n">peer</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span>
</span><span class='line'>      <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// look only in flight direction</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// handle screen wrap-around, wrap for peers on opposite screen half</span>
</span><span class='line'>      <span class="n">point</span> <span class="n">peer_pos</span> <span class="o">=</span> <span class="n">boids</span><span class="p">[</span><span class="n">peer</span><span class="p">].</span><span class="n">position</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">-</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">y</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">-</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// sum flocking_vector, attraction fades with distance</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">peer_pos</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span><span class="p">)</span>
</span><span class='line'>          <span class="n">flocking_vector</span><span class="p">.</span><span class="n">x</span> <span class="o">-=</span> <span class="mi">8</span><span class="o">/</span><span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">peer_pos</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span><span class="p">)</span>
</span><span class='line'>          <span class="n">flocking_vector</span><span class="p">.</span><span class="n">x</span> <span class="o">+=</span> <span class="mi">8</span><span class="o">/</span><span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">peer_pos</span><span class="p">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
</span><span class='line'>          <span class="n">flocking_vector</span><span class="p">.</span><span class="n">y</span> <span class="o">-=</span> <span class="mi">8</span><span class="o">/</span><span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">peer_pos</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">peer_pos</span><span class="p">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span><span class="p">)</span>
</span><span class='line'>          <span class="n">flocking_vector</span><span class="p">.</span><span class="n">y</span> <span class="o">+=</span> <span class="mi">8</span><span class="o">/</span><span class="n">peer_vec</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>   
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">flocking_vector</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">struct</span> <span class="n">vector</span> <span class="n">avoid</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">me</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">vector</span> <span class="n">avoidance_vector</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">peer</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">peer</span> <span class="o">&lt;</span> <span class="n">NBOIDS</span><span class="p">;</span> <span class="n">peer</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">// skip myself  </span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">peer</span> <span class="o">==</span> <span class="n">me</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// calculate peer x/y distances</span>
</span><span class='line'>      <span class="n">vector</span> <span class="n">peer_vec</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span>
</span><span class='line'>          <span class="n">boids</span><span class="p">[</span><span class="n">peer</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">x</span><span class="p">,</span>
</span><span class='line'>          <span class="n">boids</span><span class="p">[</span><span class="n">peer</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">position</span><span class="p">.</span><span class="n">y</span>
</span><span class='line'>      <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// look only in flight direction</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">me</span><span class="p">].</span><span class="n">heading</span><span class="p">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// avoid() only acts above threshold</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span> <span class="n">abs</span><span class="p">(</span><span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">SEP</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="c1">// safeguard against division by zero</span>
</span><span class='line'>          <span class="k">if</span> <span class="p">(</span><span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>          <span class="c1">// if (peer_vec.x == 0) continue;</span>
</span><span class='line'>          <span class="c1">// subtract from avoidance vector, move away from peer</span>
</span><span class='line'>          <span class="n">avoidance_vector</span><span class="p">.</span><span class="n">x</span> <span class="o">-=</span> <span class="mi">8</span> <span class="o">/</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>      <span class="p">};</span>
</span><span class='line'>      <span class="c1">// avoid() only acts above threshold</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span> <span class="n">abs</span><span class="p">(</span><span class="n">peer_vec</span><span class="p">.</span><span class="n">y</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">SEP</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="c1">// safeguard against division by zero  </span>
</span><span class='line'>          <span class="k">if</span> <span class="p">(</span><span class="n">peer_vec</span><span class="p">.</span><span class="n">y</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">y</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>          <span class="c1">// if (peer_vec.y == 0) continue;</span>
</span><span class='line'>          <span class="c1">// subtract from avoidance vector, move away from peer</span>
</span><span class='line'>          <span class="n">avoidance_vector</span><span class="p">.</span><span class="n">y</span> <span class="o">-=</span> <span class="mi">8</span> <span class="o">/</span> <span class="n">peer_vec</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>      <span class="p">};</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">avoidance_vector</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">calculateBoids</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">vector</span> <span class="n">avoid_vec</span><span class="p">,</span> <span class="n">flock_vec</span><span class="p">;</span>
</span><span class='line'>  <span class="n">vector</span> <span class="n">sum</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">b</span> <span class="o">&lt;</span> <span class="n">NBOIDS</span><span class="p">;</span> <span class="n">b</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>       <span class="c1">// calculate behaviors</span>
</span><span class='line'>       <span class="n">avoid_vec</span> <span class="o">=</span> <span class="n">avoid</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>
</span><span class='line'>       <span class="n">flock_vec</span> <span class="o">=</span> <span class="n">flock</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>
</span><span class='line'>      
</span><span class='line'>       <span class="c1">// weighted sum of behaviors, plus random default direction</span>
</span><span class='line'>       <span class="n">sum</span><span class="p">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">random</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">flock_vec</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">avoid_vec</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
</span><span class='line'>       <span class="n">sum</span><span class="p">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">random</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">flock_vec</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">avoid_vec</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="cm">/* sum = { </span>
</span><span class='line'><span class="cm">         random(3) + 3 * flock(b).x + 2 * avoid(b).x,</span>
</span><span class='line'><span class="cm">         random(2) + 3 * flock(b).y + 2 * avoid(b).y </span>
</span><span class='line'><span class="cm">     }; */</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// make discrete heading</span>
</span><span class='line'>      <span class="n">boids</span><span class="p">[</span><span class="n">b</span><span class="p">].</span><span class="n">heading</span> <span class="o">=</span> <span class="p">(</span><span class="n">vector</span><span class="p">){</span>
</span><span class='line'>          <span class="p">(</span><span class="n">sum</span><span class="p">.</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span><span class="o">?</span><span class="mi">0</span><span class="o">:</span><span class="p">(</span><span class="n">sum</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span><span class="o">?-</span><span class="mi">1</span><span class="o">:</span><span class="mi">1</span><span class="p">,</span>
</span><span class='line'>          <span class="p">(</span><span class="n">sum</span><span class="p">.</span><span class="n">y</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span><span class="o">?</span><span class="mi">0</span><span class="o">:</span><span class="p">(</span><span class="n">sum</span><span class="p">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span><span class="o">?-</span><span class="mi">1</span><span class="o">:</span><span class="mi">1</span>      
</span><span class='line'>      <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">// update position</span>
</span><span class='line'>      <span class="n">boids</span><span class="p">[</span><span class="n">b</span><span class="p">].</span><span class="n">position</span> <span class="o">=</span> <span class="n">handleEdge</span><span class="p">(</span><span class="n">boids</span><span class="p">[</span><span class="n">b</span><span class="p">].</span><span class="n">position</span><span class="p">,</span> <span class="n">boids</span><span class="p">[</span><span class="n">b</span><span class="p">].</span><span class="n">heading</span><span class="p">);</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">loop</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// toggle red LED on each iteration</span>
</span><span class='line'>  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">RED_LED</span><span class="p">,</span> <span class="o">!</span><span class="n">digitalRead</span><span class="p">(</span><span class="n">RED_LED</span><span class="p">));</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">random</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="n">randomSeed</span><span class="p">(</span><span class="n">analogRead</span><span class="p">(</span><span class="n">AIN</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">calculateBoids</span><span class="p">();</span>
</span><span class='line'>  <span class="n">plotBoids</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">delay</span><span class="p">(</span><span class="mi">15</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Adding LEDs to a Ruckus VF2111]]></title>
    <link href="http://isquared.nl//blog/2013/03/16/adding-leds-to-a-ruckus-vf2111/"/>
    <updated>2013-03-16T21:06:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/03/16/adding-leds-to-a-ruckus-vf2111</id>
    <content type="html"><![CDATA[<p>Last week I bought a <a href="http://www.ruckuswireless.com/">Ruckus Wireless</a> bundle
consisting of a VF2825 WiFi accesspoint and a VF2111 media (client) adapter.
They were new in box and cheap, 15 euro for both.
Snooping around in the configuration makes me believe these bundles were once
offered by the Portuguese provider <a href="http://www.clix.pt">Clix</a>.</p>

<p>These Ruckus boxes have an amazing beamforming antenna array inside and the
VF2825 actually has LEDs on the antenna PCB that shine through a translucent
window on top of the unit so that you can see which of the antennas are
switched on at any given moment.
The LEDs are pointing like a compass needle to the client that it talks to, in many cases, but reflections from the concrete walls in my house seem to spoil that effect a bit.</p>

<p>The VF2111 hasn&#8217;t got these LEDs, this had to be fixed of course.
It was time to heat up the soldering iron!</p>

<p><img src="http://isquared.nl//images/ruckus_leds.jpg"></p>

<p>On Ebay I ordered a couple of 0402 green SMD LEDs. Well, I quickly realized two things:</p>

<ul>
<li>0402 surface mount packages are way too small for comfort.</li>
<li>The SMT technology used in the Ruckus seem to be the larger  0603, not 0402. Which would, of course, have been less of a pain to solder.</li>
</ul>


<p>Breathing carefully, I did manage to mount the six leds to the board, as you can see in the picture above.
I only dropped three LEDs in the process, of course making them disappear forever.
One PCB pad was lifted when removing the resistors that were populated on the PCB in place of the LEDs.
After some micro-surgery with an Xacto knife I did manage to save the pad, though.</p>

<p><strong>More Blinkenlights in the house!</strong></p>

<p>I have located the console port of the VF2111 already, maybe I find the time
this weekend to get a shell on the box and poke around some more. I hope the
beamforming that these boxes do can make for an interesting WiFi radarscope
after some hacking.</p>

<p><em>To be continued&#8230;</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Some handy Bash functions]]></title>
    <link href="http://isquared.nl//blog/2013/03/07/some-handy-bash-functions/"/>
    <updated>2013-03-07T19:24:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/03/07/some-handy-bash-functions</id>
    <content type="html"><![CDATA[<p>Probably a couple of times a day I use pipelines like <code>foo | cut -d\  -f3 | sort -u</code> or <code>awk '$5 ~ /foo/ { print $3, $5 }'</code>.
Well, while working on an assignment for my study I decided that I had to put
an end to this terrible neglect of using Bash&#8217;s expressiveness. :)</p>

<p>So, I made two additions to my stable of practical Bash functions:</p>

<p><code>match_field()</code> Returns a boolean value when a field in a line matches a pattern:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># match_field &lt;fieldnum&gt; &lt;RE&gt; &lt;line&gt; ; match field in line</span>
</span><span class='line'><span class="k">function </span>match_field<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="nv">nf</span><span class="o">=</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span>; <span class="nv">re</span><span class="o">=</span><span class="k">${</span><span class="nv">2</span><span class="k">}</span>; <span class="nb">shift </span>2;
</span><span class='line'>  <span class="o">[[</span> <span class="k">${</span><span class="p">!nf</span><span class="k">}</span> <span class="o">=</span>~ <span class="k">${</span><span class="nv">re</span><span class="k">}</span> <span class="o">]]</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>extract_field()</code> Is a bit like <code>cut</code>, it prints the content of a field in a line:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># extract_field &lt;fieldnum&gt; &lt;line&gt; ; extract field from line</span>
</span><span class='line'><span class="k">function </span>extract_field<span class="o">()</span> <span class="o">{</span> <span class="nv">nf</span><span class="o">=</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span>; <span class="nb">shift</span>; <span class="nb">echo</span> <span class="k">${</span><span class="p">!nf</span><span class="k">}</span>; <span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Both abuse positional parameters to select fields, expect this to break
horribly when using other field separators than default $IFS.</p>

<p>These can be used to make many of the common <code>cut</code> and <code>awk</code> constructs that probably many of us use over and over again:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">while </span><span class="nb">read </span>line
</span><span class='line'><span class="k">do</span>
</span><span class='line'><span class="k">  if </span>match_field 2 <span class="s2">&quot;foo&quot;</span> <span class="k">${</span><span class="nv">line</span><span class="k">}</span>
</span><span class='line'>  <span class="k">then</span>
</span><span class='line'><span class="k">      </span><span class="nv">foo</span><span class="o">=</span><span class="k">$(</span>extract_field 1 <span class="k">${</span><span class="nv">line</span><span class="k">})</span>
</span><span class='line'>      <span class="nv">bar</span><span class="o">=</span><span class="k">$(</span>extract_field 3 <span class="k">${</span><span class="nv">line</span><span class="k">})</span>
</span><span class='line'>      <span class="nb">echo</span> <span class="k">${</span><span class="nv">bar</span><span class="k">}</span> <span class="k">${</span><span class="nv">foo</span><span class="k">}</span>
</span><span class='line'>  <span class="k">fi</span>
</span><span class='line'><span class="k">done</span> &lt; <span class="k">${</span><span class="nv">somefile</span><span class="k">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is equivalent to the awk script:</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>
</pre></td><td class='code'><pre><code class='awk'><span class='line'>  <span class="p">(</span><span class="o">$</span><span class="mi">2</span> <span class="o">~</span> <span class="sr">/foo/</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="kr">print</span> <span class="o">$</span><span class="mi">1</span><span class="p">,</span> <span class="o">$</span><span class="mi">3</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Not really more efficient in lines of code, indeed.
It doesn&#8217;t require forking <code>awk</code>, though. So in tight loops, this might be a
bit more easy on system resources.
That is all moot because this was just another exercise in going Bash all the
way. :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cellular Automata in Bash]]></title>
    <link href="http://isquared.nl//blog/2013/02/16/cellular-automata-in-bash/"/>
    <updated>2013-02-16T23:01:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/02/16/cellular-automata-in-bash</id>
    <content type="html"><![CDATA[<p>Stephen Wolfram eat your heart out. We don&#8217;t need no stinking Mathematica when we have Bash. I wish I could afford Mathematica, though. ;)</p>

<p><img src="http://isquared.nl//images/ca.sh.png"></p>

<p><em>ca.sh</em> Is a <a href="http://mathworld.wolfram.com/ElementaryCellularAutomaton.html">one-dimensional elementary cellular automaton</a> written in Bash.
This implementation uses a string of binary digits to store its world in a
variable called <code>states</code>.</p>

<p>The following function reads this variable to lookup the states of a cell and
its immediate neighbours:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># neigh &lt;cell index&gt; : returns neighbourhood state as integer</span>
</span><span class='line'><span class="k">function </span>neigh<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>        <span class="c"># cell(n - 1), wrap on edge</span>
</span><span class='line'>        <span class="nv">state</span><span class="o">=</span><span class="k">$((</span><span class="m">4</span> <span class="o">*</span> <span class="k">${</span><span class="nv">states</span><span class="p">:(</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> == 0)?</span><span class="k">${#</span><span class="nv">states</span><span class="k">}</span><span class="p"> - 1:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> - 1:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>        <span class="c"># self</span>
</span><span class='line'>        <span class="nv">state</span><span class="o">=</span><span class="k">$((</span>state <span class="o">+</span> <span class="m">2</span> <span class="o">*</span> <span class="k">${</span><span class="nv">states</span><span class="p">:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p">:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>        <span class="c"># cell(n + 1), wrap on edge</span>
</span><span class='line'>        <span class="nb">echo</span> <span class="k">$((</span>state <span class="o">+</span> <span class="k">${</span><span class="nv">states</span><span class="p">:(</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> == (</span><span class="k">${#</span><span class="nv">states</span><span class="k">}</span><span class="p"> - 1))?0:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> + 1:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Even with the comments this makes for some nice Bash code golf. I think
the if-statements of the shell are plain ugly, so in this case I used the
conditional operator to wrap around the begin and end of the string in <code>states</code>
when looking up the states of the cells on the far left and right.</p>

<p>The value of the neighbourhood can then be fed to <code>ca()</code> which does return
the next state for a cell based on the current rule number:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># ca &lt;state&gt; &lt;rule&gt; : returns new binary state for cell</span>
</span><span class='line'><span class="k">function </span>ca<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>        <span class="nb">echo</span> <span class="k">$((</span><span class="o">(</span><span class="k">${</span><span class="nv">2</span><span class="k">}</span>&gt;&gt;<span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="o">)&amp;</span><span class="m">1</span><span class="k">))</span>;
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Yup, that&#8217;s right, Bash has bitwise operators. :)</p>

<p>These two functions can then be combined like so to display succesive generations op the automaton:</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='bash'><span class='line'><span class="c"># run ca algorithm</span>
</span><span class='line'><span class="k">for</span> <span class="o">((</span>;;<span class="o">))</span> <span class="o">{</span>
</span><span class='line'>        <span class="c"># display current state using ANSI colors</span>
</span><span class='line'>        <span class="nv">display</span><span class="o">=</span><span class="k">${</span><span class="nv">states</span><span class="p">//0/</span><span class="s1">$&#39;\e[0;30;44m &#39;</span><span class="k">}</span>
</span><span class='line'>        <span class="nb">echo</span> <span class="k">${</span><span class="nv">display</span><span class="p">//1/</span><span class="s1">$&#39;\e[0;30;45m &#39;</span><span class="k">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">next_states</span><span class="o">=</span><span class="s2">&quot;&quot;</span>
</span><span class='line'>
</span><span class='line'>        <span class="c"># update cells</span>
</span><span class='line'>        <span class="k">for</span><span class="o">((</span><span class="nv">c</span><span class="o">=</span>0;c &lt; <span class="k">${#</span><span class="nv">states</span><span class="k">}</span>;c++<span class="o">))</span> <span class="o">{</span>
</span><span class='line'>                <span class="nv">next_states</span><span class="o">=</span><span class="k">${</span><span class="nv">next_states</span><span class="k">}$(</span>ca <span class="k">$(</span>neigh <span class="k">${</span><span class="nv">c</span><span class="k">})</span> <span class="k">${</span><span class="nv">rule</span><span class="k">})</span>
</span><span class='line'>        <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">states</span><span class="o">=</span><span class="k">${</span><span class="nv">next_states</span><span class="k">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>As you can see, I used a regular-expression replace to change the values in
<code>states</code> to spaces with an ANSI escape sequence defined background color.
Pretty elegant, I think. Although I don&#8217;t like the temporary variable <code>display</code>
too much.</p>

<p>The full code of <code>ca.sh</code> is included below the break:</p>

<!-- more -->




<figure class='code'><figcaption><span>ca.sh  (ca.sh)</span> <a href='http://isquared.nl//downloads/code/ca.sh'>download</a></figcaption>
 <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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'><span class="c"># ca.sh - 1D elementary cellular automaton</span>
</span><span class='line'><span class="c"># Hessel Schut, hessel@isquared.nl, 2013-02-16</span>
</span><span class='line'>
</span><span class='line'><span class="c"># defaults to rule 30 when no argument given</span>
</span><span class='line'><span class="nv">rule</span><span class="o">=</span><span class="k">${</span><span class="nv">1</span><span class="k">:-</span><span class="nv">30</span><span class="k">}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># cleanup terminal after the mess we&#39;ve made</span>
</span><span class='line'><span class="nb">trap </span>cleanup TERM EXIT INT;
</span><span class='line'><span class="k">function </span>cleanup<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="c"># simple reset should be enough</span>
</span><span class='line'>  <span class="nb">echo</span> -n <span class="s1">$&#39;\ec&#39;</span>
</span><span class='line'>  <span class="nb">exit</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># cellular automaton: ca &lt;state&gt; &lt;rule&gt; returns new state for cell</span>
</span><span class='line'><span class="k">function </span>ca<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="nb">echo</span> <span class="k">$((</span><span class="o">(</span><span class="k">${</span><span class="nv">2</span><span class="k">}</span>&gt;&gt;<span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="o">)&amp;</span><span class="m">1</span><span class="k">))</span>;
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># neigh &lt;cell&gt; : returns integer neighbourhood state</span>
</span><span class='line'><span class="k">function </span>neigh<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="c"># cell(n - 1), wrap on edge</span>
</span><span class='line'>  <span class="nv">state</span><span class="o">=</span><span class="k">$((</span><span class="m">4</span> <span class="o">*</span> <span class="k">${</span><span class="nv">states</span><span class="p">:(</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> == 0)?</span><span class="k">${#</span><span class="nv">states</span><span class="k">}</span><span class="p"> - 1:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> - 1:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>  <span class="c"># self</span>
</span><span class='line'>  <span class="nv">state</span><span class="o">=</span><span class="k">$((</span>state <span class="o">+</span> <span class="m">2</span> <span class="o">*</span> <span class="k">${</span><span class="nv">states</span><span class="p">:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p">:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>  <span class="c"># cell(n + 1), wrap on edge</span>
</span><span class='line'>  <span class="nb">echo</span> <span class="k">$((</span>state <span class="o">+</span> <span class="k">${</span><span class="nv">states</span><span class="p">:(</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> == (</span><span class="k">${#</span><span class="nv">states</span><span class="k">}</span><span class="p"> - 1))?0:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> + 1:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'><span class="o">}</span>  
</span><span class='line'>
</span><span class='line'><span class="c"># combined ca() and neigh(), saves expensive function call</span>
</span><span class='line'><span class="k">function </span>ca<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="c"># cell(n - 1), wrap on edge</span>
</span><span class='line'>  <span class="nv">state</span><span class="o">=</span><span class="k">$((</span><span class="m">4</span> <span class="o">*</span> <span class="k">${</span><span class="nv">states</span><span class="p">:(</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> == 0)?</span><span class="k">${#</span><span class="nv">states</span><span class="k">}</span><span class="p"> - 1:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> - 1:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>  <span class="c"># self</span>
</span><span class='line'>  <span class="nv">state</span><span class="o">=</span><span class="k">$((</span>state <span class="o">+</span> <span class="m">2</span> <span class="o">*</span> <span class="k">${</span><span class="nv">states</span><span class="p">:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p">:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>  <span class="c"># cell(n + 1), wrap on edge</span>
</span><span class='line'>  <span class="nv">state</span><span class="o">=</span><span class="k">$((</span>state <span class="o">+</span> <span class="k">${</span><span class="nv">states</span><span class="p">:(</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> == (</span><span class="k">${#</span><span class="nv">states</span><span class="k">}</span><span class="p"> - 1))?0:</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="p"> + 1:</span><span class="nv">1</span><span class="k">}))</span>
</span><span class='line'>  <span class="c"># return new state based on rule in ${2}</span>
</span><span class='line'>  <span class="nb">echo</span> <span class="k">$((</span><span class="o">(</span><span class="k">${</span><span class="nv">2</span><span class="k">}</span>&gt;&gt;state<span class="o">)&amp;</span><span class="m">1</span><span class="k">))</span>
</span><span class='line'><span class="o">}</span>  
</span><span class='line'>
</span><span class='line'><span class="c"># tput is for weenies, query terminal for its size</span>
</span><span class='line'><span class="k">function </span>term_size<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="nb">read</span> -p <span class="s1">$&#39;\e[18t&#39;</span> -s -r -d t s;
</span><span class='line'>  <span class="o">}</span> &lt;&gt; /dev/tty
</span><span class='line'>  <span class="nb">echo</span> <span class="k">${</span><span class="nv">s</span><span class="p">#*;</span><span class="k">}</span>;
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># extract columns from terminal size</span>
</span><span class='line'><span class="nv">cols</span><span class="o">=</span><span class="k">${</span><span class="nv">COLUMNS</span><span class="k">:-$(</span><span class="nv">s</span><span class="o">=</span><span class="k">$(</span>term_size<span class="k">)</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="k">${</span><span class="nv">s</span><span class="p">/*;</span><span class="k">})}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># initialize states with single cell</span>
</span><span class='line'><span class="nv">states</span><span class="o">=</span><span class="s2">&quot;&quot;</span>
</span><span class='line'><span class="k">for</span> <span class="o">((</span><span class="nv">i</span> <span class="o">=</span> 0; i &lt;<span class="o">=</span> cols; i++<span class="o">))</span> <span class="o">{</span>
</span><span class='line'>  <span class="c"># only set one cell in the middle of the screen</span>
</span><span class='line'>  <span class="c"># all others will be dead initially</span>
</span><span class='line'>  <span class="nv">states</span><span class="o">=</span><span class="k">${</span><span class="nv">states</span><span class="k">}$((</span><span class="o">(</span><span class="nv">i</span> <span class="o">==</span> cols/2<span class="o">)</span>?1:0<span class="k">))</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># run ca algorithm</span>
</span><span class='line'><span class="k">for</span> <span class="o">((</span>;;<span class="o">))</span> <span class="o">{</span>
</span><span class='line'>  <span class="c"># display current state using ANSI colors</span>
</span><span class='line'>  <span class="nv">display</span><span class="o">=</span><span class="k">${</span><span class="nv">states</span><span class="p">//0/</span><span class="s1">$&#39;\e[0;30;44m &#39;</span><span class="k">}</span>
</span><span class='line'>  <span class="nb">echo</span> <span class="k">${</span><span class="nv">display</span><span class="p">//1/</span><span class="s1">$&#39;\e[0;30;45m &#39;</span><span class="k">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="nv">next_states</span><span class="o">=</span><span class="s2">&quot;&quot;</span>
</span><span class='line'>
</span><span class='line'>  <span class="c"># update cells</span>
</span><span class='line'>  <span class="k">for</span><span class="o">((</span><span class="nv">c</span> <span class="o">=</span> 0; c &lt; <span class="k">${#</span><span class="nv">states</span><span class="k">}</span>; c++<span class="o">))</span> <span class="o">{</span>
</span><span class='line'>      <span class="c"># next_states=${next_states}$(ca $(neigh ${c}) ${rule})</span>
</span><span class='line'>      <span class="c"># second ca() definition used, executes a bit faster</span>
</span><span class='line'>      <span class="nv">next_states</span><span class="o">=</span><span class="k">${</span><span class="nv">next_states</span><span class="k">}$(</span>ca <span class="k">${</span><span class="nv">c</span><span class="k">}</span> <span class="k">${</span><span class="nv">rule</span><span class="k">})</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="c"># synchronize states</span>
</span><span class='line'>  <span class="nv">states</span><span class="o">=</span><span class="k">${</span><span class="nv">next_states</span><span class="k">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Querying terminal size in Bash]]></title>
    <link href="http://isquared.nl//blog/2013/01/31/querying-terminal-size-in-bash/"/>
    <updated>2013-01-31T20:17:00+01:00</updated>
    <id>http://isquared.nl//blog/2013/01/31/querying-terminal-size-in-bash</id>
    <content type="html"><![CDATA[<p>Today I stumbled upon the Bash variables <code>COLUMNS</code> and <code>LINES</code>. These look
neat as, <em>if they actually worked</em>, would mean not having to call <code>tput</code> to
get the current size of the terminal.<br/>
<strong>Bzzzt!</strong> Bad luck. These variables are only set when the interactive shell
receives a <code>SIGWINCH</code> signal, they are not available to scripts, exactly
where they are actually useful.
I&#8217;m not sure where you&#8217;d want to use these in an interactive shell apart
from useless gimmicks like having a clock in the corner of your terminal.</p>

<p>I wanted to use these to redraw the screen on a window resize in a new
Bash hack that I&#8217;m working on. Like so:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">trap </span>on_resize SIGWINCH
</span><span class='line'><span class="k">function </span>on_resize<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  do_stuff <span class="k">${</span><span class="nv">COLUMNS</span><span class="k">}</span> <span class="k">${</span><span class="nv">LINES</span><span class="k">}</span>
</span><span class='line'>  <span class="c"># ...etc.</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>As some sort of masochistic challenge, I&#8217;m using only pure Bash, no
external commands, in the program I&#8217;m working on.
So I had to come up with a way to get the dimensions of the terminal
screen without resorting to <code>tput</code>.</p>

<p>The terminal escape sequence <code>ESC-[18t</code> makes the terminal respond with
its dimensions. This can be used in the following way to query the terminal
for its size:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">function </span>term_size <span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="o">{</span> <span class="nb">echo</span> -ne <span class="se">\\</span>e<span class="o">[</span>18t <span class="o">&amp;&amp;</span> <span class="nb">read</span> -s -r -d t size; <span class="o">}</span> &lt;&gt; /dev/tty
</span><span class='line'>  <span class="nb">echo</span> <span class="k">${</span><span class="nv">size</span><span class="p">#*;</span><span class="k">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>For example:</p>

<pre><code>hessch@substrate:~$ term_size
51;72
</code></pre>

<p><em>Update:</em> The function above hangs on the <code>read</code> in some cases. Echoing using
<code>read -p</code> is more elegant and does not suffer from hanging.
Also especially on some versions of MacOS X <code>echo -ne</code> doesn&#8217;t grok <code>\e</code> for
escape. The following works better:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">function </span>term_size<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="nb">read</span> -p <span class="s1">$&#39;\e[18t&#39;</span> -s -r -d t size <span class="o">}</span>
</span><span class='line'>  <span class="o">}</span> &lt;&gt; /dev/tty
</span><span class='line'>  <span class="nb">echo</span> <span class="k">${</span><span class="nv">size</span><span class="p">#*;</span><span class="k">}</span>;
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The following two functions help accessing either the columns or the rows part:</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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">function </span>term_cols <span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="nv">s</span><span class="o">=</span><span class="k">$(</span>term_size<span class="k">)</span>; <span class="nb">echo</span> <span class="k">${</span><span class="nv">s</span><span class="p">/*;</span><span class="k">}</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">function </span>term_rows <span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="nv">s</span><span class="o">=</span><span class="k">$(</span>term_size<span class="k">)</span>; <span class="nb">echo</span> <span class="k">${</span><span class="nv">s</span><span class="p">/;*</span><span class="k">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>These can be used as default values when the variables <code>COLUMNS</code> and <code>LINES</code>
are unset. Like so:</p>

<pre><code>hessch@substrate:~$ echo ${COLUMNS:-$(term_cols)}
72
hessch@substrate:~$ echo ${LINES:-$(term_rows)}
51
</code></pre>

<p>That saves some useless terminal I/O when <code>COLUMNS</code> and <code>LINES</code> are available.</p>
]]></content>
  </entry>
  
</feed>
