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

<channel>
	<title>coolfactor blog</title>
	<atom:link href="http://www.coolfactor.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coolfactor.org/blog</link>
	<description>for geeks</description>
	<lastBuildDate>Tue, 05 Jul 2011 17:47:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Debugging</title>
		<link>http://www.coolfactor.org/blog/2011/05/10/debugging/</link>
		<comments>http://www.coolfactor.org/blog/2011/05/10/debugging/#comments</comments>
		<pubDate>Mon, 09 May 2011 23:58:00 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=108</guid>
		<description><![CDATA[After a particularly frustrating marathon debugging session on Sunday, I was inspired to write a poem. Why won&#8217;t it work? I stare at the screen of the hateful machine I check all the details in the documentation While the error &#8230; <a href="http://www.coolfactor.org/blog/2011/05/10/debugging/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After a particularly frustrating marathon debugging session on Sunday, I was inspired to write a poem.<br />
<span id="more-108"></span></p>
<blockquote><p>
Why won&#8217;t it work?<br />
I stare at the screen<br />
of the hateful machine</p>
<p>I check all the details<br />
in the documentation<br />
While the error prevails<br />
with my growing frustration</p>
<p>I stare at the screen<br />
of the hateful machine<br />
Why won&#8217;t it work?</p>
<p>I read through the code<br />
Line after line<br />
Will it explode?<br />
It all looks fine</p>
<p>Why won&#8217;t it work?</p>
<p>Can this not be solved by logic<br />
Rather than a gin and tonic?</p>
<p>I go for a walk<br />
to clear my head<br />
I wonder which detail<br />
I could have misread</p>
<p>Why won&#8217;t it work?</p>
<p>I don&#8217;t believe it<br />
I try it once more<br />
The testing reveals<br />
That it&#8217;s broken for sure</p>
<p>I stare at the screen<br />
of the hateful machine<br />
Why won&#8217;t it work?</p>
<p>After hours and hours<br />
using all of my powers<br />
I can prove that nothing is wrong<br />
Why won&#8217;t it work?</p>
<p>My eyes are red<br />
It&#8217;s time for bed<br />
I take a break<br />
And eat some bread</p>
<p>I stare at the screen<br />
of the hateful machine<br />
Why won&#8217;t it work?</p>
<p>My ideas exhausted<br />
I ask for assistance<br />
This has to be better<br />
than endless persistence</p>
<p>I explain the problem<br />
from the beginning<br />
My head is spinning<br />
He listens</p>
<p>Words pass my mouth<br />
at such a pace<br />
Desperately trying<br />
not to lose face</p>
<p>As I realise that something<br />
just isn&#8217;t quite right<br />
I dig a bit deeper<br />
Because this just might</p>
<p>Be the answer, the light<br />
The end of the fight<br />
With wishful delight<br />
I forsee<br />
the end of the night</p>
<p>I fix and I test<br />
and, embarrassed, I jest<br />
that a schoolboy would make<br />
this sort of mistake</p>
<p>But it works now<br />
&lt;yawn&gt;<br />
I&#8217;m going to bed<br />
In the morning once more<br />
I&#8217;ll be using my head</p>
<p>I&#8217;ll write the next feature<br />
And pray the next bug,<br />
That most nasty creature,<br />
Won&#8217;t be so smug</p>
<p>I dream:<br />
&#8220;Why won&#8217;t it work?&#8221;
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2011/05/10/debugging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically downloading Orange bills</title>
		<link>http://www.coolfactor.org/blog/2011/02/09/automatically-downloading-orange-bills/</link>
		<comments>http://www.coolfactor.org/blog/2011/02/09/automatically-downloading-orange-bills/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 21:52:29 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=104</guid>
		<description><![CDATA[I&#8217;ve been getting annoyed recently with Orange&#8217;s policy of deleting user accounts from their website after relatively short periods of inactivity. I don&#8217;t want to have to log into their website just to avoid having to register for a new &#8230; <a href="http://www.coolfactor.org/blog/2011/02/09/automatically-downloading-orange-bills/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting annoyed recently with Orange&#8217;s policy of deleting user accounts from their website after relatively short periods of inactivity. I don&#8217;t want to have to log into their website just to avoid having to register for a new account the next time I want to use it.</p>
<p>So I wrote a script to log in on my behalf. While it&#8217;s logged in, it may as well do something useful, so it downloads the PDF versions of my bills, skipping bills which it has already downloaded.</p>
<p>It&#8217;s in perl and uses WWW::Mechanize to do most of the work.</p>
<p>You can pull the source code using monotone from mtn.coolfactor.org (branch org.coolfactor.scraping.orange) or you can <a href="http://mtn.coolfactor.org/viewmtn.py/branch/changes/org.coolfactor.scraping.orange">browse it here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2011/02/09/automatically-downloading-orange-bills/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Laser Interferometry</title>
		<link>http://www.coolfactor.org/blog/2011/02/07/laser-interferometry/</link>
		<comments>http://www.coolfactor.org/blog/2011/02/07/laser-interferometry/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 16:41:10 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=93</guid>
		<description><![CDATA[This weekend saw the Space Expansion Party at London Hackspace. I brought along a laser pointer, and set myself the task of building a laser interferometer out of whatever I could find lying around. I wanted to build a Michelson &#8230; <a href="http://www.coolfactor.org/blog/2011/02/07/laser-interferometry/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This weekend saw the Space Expansion Party at <a href="http://london.hackspace.org.uk/">London Hackspace</a>. I brought along a laser pointer, and set myself the task of building a laser interferometer out of whatever I could find lying around.<br />
<span id="more-93"></span><br />
I wanted to build a <a href="http://en.wikipedia.org/wiki/Michelson_interferometer">Michelson interferometer</a>. This type of interferometer has been used to provide evidence for special relativity and to detect gravity waves, but its main attraction here is that it can be made with a small number of relatively simple components.</p>
<p>The parts required are:</p>
<p>* A laser<br />
* A beam splitter<br />
* Two mirrors<br />
* Lenses for magnification<br />
* Miscellaneous bits and pieces for mounting/alignment</p>
<p>I had with me a (very) cheap laser pointer. Sellotape kept the button held down so that the laser would stay on, and it rested comfortably upon a Greg Egan novel.</p>
<p>For a beam splitter, I eventually managed to find a CD jewel case. Hardly great optics, but it did split the beam.</p>
<p>I tried using CDs for mirrors initially until somebody managed to find a couple of hard drive platters. CDs are effective mirrors in a way, but the hard drive platters are far better for this.</p>
<p>There was a nearby drawer containing chunky electrolytic capacitors which made ideal objects to make stands out of. Sellotape and Blu-tack made it fairly easy to stand one of the mirrors up, and Blu-tack and a Helping Hand borrowed from the soldering station held the other mirror in such a way that it was possible to make fine adjustments to it.</p>
<p>The magnifying glass from the Helping Hands (again mounted with Blu-tack and capacitors) diverged the beam a little bit. Because the optical components are less than ideal, it&#8217;s necessary to magnify the image of the beam in order to see interference patterns in it.</p>
<p>There were a couple of hemispherical lenses lying around which served to further magnify the beam. One right after the first lens (again supported with a capacitor and Blu-tack) and another one Blu-tacked on top of a pint glass projected the beam onto a make-shift screen consisting of an A3 sheet of paper stuck to a floor-standing lamp.</p>
<p>Without using the sorts of optics that one would expect to find in a laser optics laboratory, this was never going to be perfect, but after turning the lights off we did notice that there were in fact interference fringes visible which moved around with the (quite considerable) noise and vibration in the room.</p>
<p>Here&#8217;s the setup:</p>
<p><a href="http://www.coolfactor.org/photos/picture.php?/6417/category/327"><img alt="" src="http://www.coolfactor.org/photos/galleries/gavan/2011_02_06/IMG_8993.JPG" title="Michelson interferometer" class="aligncenter" width="800" height="600" /></a></p>
<p>I found a fog machine so that I could take a photograph of the beam in the dark:</p>
<p><a href="http://www.coolfactor.org/photos/picture.php?/6423/category/327"><img alt="" src="http://www.coolfactor.org/photos/galleries/gavan/2011_02_06/IMG_9003.JPG" title="Beam path" class="aligncenter" width="800" height="600" /></a></p>
<p>Finally, if you look carefully you can see the interference fringes here. The camera unfortunately doesn&#8217;t do a great job of picking this up. You&#8217;re looking for moving fringes (from tiny movements of the experiment) rather than the places where the whole beam moves quickly as a result of larger movements:</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Ua_OptH7ofE?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Ua_OptH7ofE?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2011/02/07/laser-interferometry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vision and chessboards</title>
		<link>http://www.coolfactor.org/blog/2010/10/01/vision-and-chessboards/</link>
		<comments>http://www.coolfactor.org/blog/2010/10/01/vision-and-chessboards/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 17:29:01 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Lightscript]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=79</guid>
		<description><![CDATA[One of my goals for Lightscript is to be able to perform automatic calibration of moving lights. A concept central to Lightscript&#8217;s handling of moving lights is that they should all use the same co-ordinate system, but that requires knowledge &#8230; <a href="http://www.coolfactor.org/blog/2010/10/01/vision-and-chessboards/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of my goals for Lightscript is to be able to perform automatic calibration of moving lights. A concept central to Lightscript&#8217;s handling of moving lights is that they should all use the same co-ordinate system, but that requires knowledge of the position and orientation of the lights. I&#8217;ve been through several attempts at coming up with an automated way of estimating the pose of the lights, but so far all of the attempts have been met with accuracy issues or other fundamental problems.</p>
<p>My latest approach has been to use a digital camera and apply computer vision techniques. To this end, I&#8217;ve been been playing with <a href="http://opencv.willowgarage.com/">OpenCV</a>.<br />
<span id="more-79"></span><br />
Early results are encouraging. I threw together a simple 6&#215;9 chessboard image on a piece of A4 paper and took several photographs of it. This is a pretty standard technique for camera calibration, and there seem to be a fair few examples of this around on the web. OpenCV has some nice functions to find such chessboards in images and then to use the results to estimate the camera parameters.</p>
<p>So I had a go. I threw my test images at it, obtained the camera parameters, and then used them to reproject an array of cubes onto the original images. I&#8217;m rather impressed by the accuracy, which is far greater than I&#8217;d imagined. Here is the result. Click for high-resolution images if you don&#8217;t mind waiting a while for them to load.</p>
<p><a href="http://www.coolfactor.org/blog/wp-content/uploads/2010/10/IMG_8852_cubes.jpg"><img src="http://www.coolfactor.org/blog/wp-content/uploads/2010/10/IMG_8852_cubes-1024x768.jpg" alt="" title="Cubes 1" width="450" height="337" class="aligncenter size-large wp-image-81" /></a><br />
<a href="http://www.coolfactor.org/blog/wp-content/uploads/2010/10/IMG_8853_cubes.jpg"><img src="http://www.coolfactor.org/blog/wp-content/uploads/2010/10/IMG_8853_cubes-1024x768.jpg" alt="" title="Cubes 2" width="450" height="337" class="aligncenter size-large wp-image-82" /></a><br />
<a href="http://www.coolfactor.org/blog/wp-content/uploads/2010/10/IMG_8854_cubes.jpg"><img src="http://www.coolfactor.org/blog/wp-content/uploads/2010/10/IMG_8854_cubes-1024x768.jpg" alt="" title="Cubes 3" width="450" height="337" class="aligncenter size-large wp-image-83" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2010/10/01/vision-and-chessboards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hardware compatiblility</title>
		<link>http://www.coolfactor.org/blog/2010/08/22/hardware-compatiblility/</link>
		<comments>http://www.coolfactor.org/blog/2010/08/22/hardware-compatiblility/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 15:46:44 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=76</guid>
		<description><![CDATA[I&#8217;ve spent a substantial chunk of this weekend upgrading a server which was somewhat lacking in discspace. It&#8217;s a fairly old machine and as such doesn&#8217;t have SATA, but that&#8217;s not a showstopper. One PCI SATA card later, and a &#8230; <a href="http://www.coolfactor.org/blog/2010/08/22/hardware-compatiblility/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent a substantial chunk of this weekend upgrading a server which was somewhat lacking in discspace.</p>
<p>It&#8217;s a fairly old machine and as such doesn&#8217;t have SATA, but that&#8217;s not a showstopper. One PCI SATA card later, and a couple of 2TB SATA hard drives, and it&#8217;s good to go. In theory.</p>
<p>Except the SATA card was failing to recognise the hard drives.<br />
<span id="more-76"></span><br />
I wanted to see if upgrading the BIOS in the SATA card would help, but unfortunately while I could find a newer BIOS image from the chipset manufacturer, the card manufacturer had used an unsupported flash chip and so their flash utility wouldn&#8217;t work. The card manufacturer hasn&#8217;t published their own on their website, so no go there.</p>
<p>I also wanted to see if upgrading the BIOS in the motherboard would help. It was hard finding a floppy disc that wasn&#8217;t unformattable due to age, and the BIOS is old enough that while it can boot from a USB floppy drive, it didn&#8217;t like the modern USB memory stick that I tried. Eventually I found a floppy that just about worked, and got the BIOS upgraded.</p>
<p>That didn&#8217;t help.</p>
<p>I then noticed that I had another machine with the exact same motherboard. I plugged the SATA card into that one, and lo and behold it recognised the drive.</p>
<p>I stripped the machines down to more or less the bare minimum, swapped every component I could (even down to the power supply) and still, one machine found the hard drives, and the other didn&#8217;t. After swapping the motherboards, neither worked.</p>
<p>Eventually, after a lot of head-scratching, I discovered the difference.</p>
<p>One of the machines was used as a desktop PC, and hence had a mouse plugged in.</p>
<p>Plugging a mouse into the server made it spring into life, and for as long as a mouse is plugged in, it reliably detects the SATA drives and boots happily.</p>
<p>To say that I am confused by this behaviour is an understatement. But there you have it, a mouse makes SATA go.</p>
<p>The motherboard in question is an ASRock K7S8X. The SATA card is a Lycom ST-125 (based on the Silicon Image 3124 chip). The drives are WD Caviar Green 2TB.</p>
<p>If you think you can explain this behaviour, please do leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2010/08/22/hardware-compatiblility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New photo gallery</title>
		<link>http://www.coolfactor.org/blog/2010/08/05/new-photo-gallery/</link>
		<comments>http://www.coolfactor.org/blog/2010/08/05/new-photo-gallery/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 13:01:14 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=73</guid>
		<description><![CDATA[For years, I&#8217;ve had a simple public photo gallery hidden away with a semi-private URL, built with swiggle, which is a very simple gallery program which generates static indexes and thumbnails. It&#8217;s quite efficient, but not especially pretty. It&#8217;s time &#8230; <a href="http://www.coolfactor.org/blog/2010/08/05/new-photo-gallery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For years, I&#8217;ve had a simple public photo gallery hidden away with a semi-private URL, built with swiggle, which is a very simple gallery program which generates static indexes and thumbnails. It&#8217;s quite efficient, but not especially pretty. It&#8217;s time to change that.<br />
<span id="more-73"></span><br />
I&#8217;ve recently been playing with Piwigo, and so far I&#8217;m rather liking it. It&#8217;s much prettier, and seems considerably less heavyweight than Gallery2, which I&#8217;ve used elsewhere. It seems to handle presenting galleries and images in a visually pleasant way which is easier to navigate than the index which swiggle generated, it can cope with &#8220;uploading&#8221; images via a shell script, which is essential for me given the way I manage the photos from my camera. It also has a permissions system, so that I can restrict access to certain photos as is occasionally necessary, rather than excluding them from the gallery entirely.</p>
<p>So as of now, my new photo gallery is available at <a href="http://www.coolfactor.org/photos/">http://www.coolfactor.org/photos/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2010/08/05/new-photo-gallery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hacking the Wii Motion Plus</title>
		<link>http://www.coolfactor.org/blog/2010/01/31/hacking-the-wii-motion-plus/</link>
		<comments>http://www.coolfactor.org/blog/2010/01/31/hacking-the-wii-motion-plus/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 21:14:35 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=65</guid>
		<description><![CDATA[I&#8217;ve been looking for a 3-axis gyroscope recently, and I came across the Wii Motion Plus. Fortunately, other people have done the hard work of reverse engineering the protocol and written this up elsewhere. In short, it&#8217;s a nice simple &#8230; <a href="http://www.coolfactor.org/blog/2010/01/31/hacking-the-wii-motion-plus/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking for a 3-axis gyroscope recently, and I came across the Wii Motion Plus. Fortunately, other people have done the hard work of reverse engineering the protocol and written this up <a href="http://randomhacksofboredom.blogspot.com/2009/06/wii-motion-plus-arduino-love.html">elsewhere</a>. In short, it&#8217;s a nice simple I2C interface.</p>
<p>So I bought one.<br />
<span id="more-65"></span><br />
To have a little play with it, I knocked up a simple parallel port I2C interface on some breadboard, using a bunch of random NPN transistors that I had lying around. It doesn&#8217;t help that the parallel port on my PC (like most PCs) runs at 5V and the Wii Motion Plus wants 3V3, but that&#8217;s what transistors and breadboard are for, after all.</p>
<div id="attachment_66" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.coolfactor.org/blog/wp-content/uploads/2010/01/IMG_8568.jpg"><img src="http://www.coolfactor.org/blog/wp-content/uploads/2010/01/IMG_8568-768x1024.jpg" alt="" title="I2C interface" width="450" height="600" class="size-large wp-image-66" /></a><p class="wp-caption-text">I2C interface on breadboard</p></div>
<p>What are the LEDs for, you may ask? Well, I had to figure out which parallel port pin was hooked up to which wire somehow, didn&#8217;t I? It was easier to recycle and old cable knocked up years ago for another hack than to go out and get a new 25 pin D plug and spend time with the soldering iron.</p>
<p>The Wii Motion Plus is the small white thing in the background, just in front of the power supply.</p>
<p>So I implemented some simple I2C bitbanging code and after shaking the last of the bugs out, I was ecstatic to see some numbers coming out of it that seemed to represent the physics of what I was doing to the device.</p>
<p>Obviously, I couldn&#8217;t leave it at that. I wanted to know how it behaved in a slightly more complex test case. So after speeding up the I2C code a bit to get closer-to-realtime readings, I devised a cunning demonstration.</p>
<p>I used SDL and OpenGL to knock up a cube, rotating around its centre. Instead of various non-interactive pretty spinning things that you can do with a cube to make a demo, in this case I integrated the readings from the Wii Motion Plus to form a rotation matrix. Rotating the Wii Motion Plus causes similar rotation to apply to the cube.</p>
<p>After guessing at some scaling factors, I got &#8220;close enough&#8221;, and I was rather impressed with the responsiveness of it all. Other than the few times when the wires fell out while I was moving it, the system was responsive and quite intuitive. It did drift a little, as expected with a gyro and also as expected when I&#8217;m not taking samples as often as I could. I think a proper hardware or microcontroller I2C implementation would be less prone to overload and be able to integrate more accurately.</p>
<p>Here&#8217;s the video:</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/7aj-JIishVo&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/7aj-JIishVo&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>Update: You can pull the source code using monotone from mtn.coolfactor.org (branch org.coolfactor.demo.wiimotionplus), or you can <a href="http://mtn.coolfactor.org/viewmtn.py/branch/changes/org.coolfactor.demo.wiimotionplus">browse it here</a>.</p>
<p>Note: This isn&#8217;t polished code, it&#8217;s just a hack. It works for the purpose of my demo, but it may not work for yours.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2010/01/31/hacking-the-wii-motion-plus/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Dead slug</title>
		<link>http://www.coolfactor.org/blog/2009/12/30/dead-slug/</link>
		<comments>http://www.coolfactor.org/blog/2009/12/30/dead-slug/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 14:25:52 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=53</guid>
		<description><![CDATA[My slug died. No, not the sort that shrivels up when it comes across salt, but my Linksys NSLU2. As it turns out, the power supply is known to be a bit flaky. Again, dodgy electrolytic capacitors. Who&#8217;d have thought &#8230; <a href="http://www.coolfactor.org/blog/2009/12/30/dead-slug/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My slug died. No, not the sort that shrivels up when it comes across salt, but my <a href="http://www.coolfactor.org/blog/2007/07/29/nslu2-and-netbsd/">Linksys NSLU2</a>.</p>
<p>As it turns out, the <a href="http://www.nslu2-linux.org/wiki/Info/PowerSupply">power supply</a> is known to be a bit flaky. Again, dodgy electrolytic capacitors. Who&#8217;d have thought it, eh?<br />
<span id="more-53"></span><br />
The challenge this time was cracking the case open. It&#8217;s a wall-wart power supply, and these things are generally glued shut from the inside. With the aid of a (very) sharp knife, I managed to cut open enough of it to stand a chance of prising the rest apart.</p>
<p>And lo, another popped 1000uF 10V capacitor.</p>
<div id="attachment_54" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.coolfactor.org/blog/wp-content/uploads/2009/12/IMG_8540.jpg"><img src="http://www.coolfactor.org/blog/wp-content/uploads/2009/12/IMG_8540-1024x768.jpg" alt="" title="NSLU2 PSU" width="450" height="337" class="size-large wp-image-54" /></a><p class="wp-caption-text">NSLU2 power supply cracked open</p></div>
<p>See the bulge on the green capacitor on the far left? Exactly.</p>
<p>After making sure that the large 400 volt capacitor was discharged (yes, really), I replaced the popped capacitor with one I had lying around, and (very) carefully gave it a whirl. Perfect.</p>
<p>Since there&#8217;s another capacitor of the same type on the board, and since I didn&#8217;t use a brand new component to replace it, I didn&#8217;t really fancy sticking the thing back together with glue. But copious amounts of electrical tape should do the trick for now.</p>
<div id="attachment_59" class="wp-caption aligncenter" style="width: 460px"><a href="http://www.coolfactor.org/blog/wp-content/uploads/2009/12/IMG_8541.jpg"><img src="http://www.coolfactor.org/blog/wp-content/uploads/2009/12/IMG_8541-1024x768.jpg" alt="" title="NSLU2 PSU re-assembled" width="450" height="337" class="size-large wp-image-59" /></a><p class="wp-caption-text">The power supply re-assembled</p></div>
<p>The slug lives.</p>
<hr />
Disclaimer: Since we&#8217;re dealing with high voltages here, I really ought to say that high voltages are dangerous and that power supplies are glued shut for a reason. Unless you <em>really</em> know what you&#8217;re doing, don&#8217;t mess with the mains. Switch mode power supplies contain high voltages even after they are unplugged from the mains. Mains electricity can and does kill people. I will <em>not</em> be responsible for any injuries or death which you bring upon yourself or others because you didn&#8217;t use your brain.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2009/12/30/dead-slug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Haskell, I/O and Monads</title>
		<link>http://www.coolfactor.org/blog/2009/12/28/haskell-io-and-monads/</link>
		<comments>http://www.coolfactor.org/blog/2009/12/28/haskell-io-and-monads/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 16:50:08 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=47</guid>
		<description><![CDATA[I wanted to revisit writing code in Haskell, and in doing so try to understand the I/O model a bit better. I spent quite some time reading texts and tutorials on monads, and discovered that most of them are utterly &#8230; <a href="http://www.coolfactor.org/blog/2009/12/28/haskell-io-and-monads/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I wanted to revisit writing code in Haskell, and in doing so try to understand the I/O model a bit better. I spent quite some time reading texts and tutorials on monads, and discovered that most of them are utterly inaccessible unless you already understand monads.</p>
<p>Fortunately for me, I came across <a href="http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html">this blog post</a> which gave a very good introduction to the concepts involved, while being down to earth enough that it didn&#8217;t require prior comprehension of monads.</p>
<p>Armed with this new level of understanding, I thought the best way to apply it would be to attempt an implementation of the UNIX sort program.<br />
<span id="more-47"></span><br />
Now, there are plenty of noddy implementations of sort around on the web. Most of them look something like this:</p>
<pre>
main :: IO ()
main = interact (unlines . sort . lines)
</pre>
<p>This is all well and good, but actually it&#8217;s not much good for understanding I/O. It just takes a single input stream, sorts it and outputs it. The magic is all wrapped up in <code>interact</code>, so it&#8217;s all invisible and rather boring.</p>
<p>Now, real UNIX sort takes a bunch of filenames as arguments, and sorts them all into one giant output. That sounds more interesting. So let&#8217;s now have a play with Haskell&#8217;s <code>do</code> notation.</p>
<pre>
main :: IO ()
main = do
     x <- getArgs
     y <- mapM (readFile) x
     (putStr . unlines . sort . lines . concat) y
</pre>
<p>That's more like it. Let's take a closer look.</p>
<p>Essentially, each line in the <code>do</code> block takes values which are wrapped in a monad and passes them into the next line nicely unwrapped. So, <code>getArgs</code> returns type <code>IO [String]</code>, and <code>readFile</code> takes <code>FilePath</code>, which is compatible with <code>String</code>. The <code>do</code> block does the job of extracting the <code>[String]</code> from <code>IO [String]</code>.</p>
<p><code>mapM</code> is just like <code>map</code>, but deals with functions returning monadic types. By the time we get to use <code>y</code>, it has type <code>[String]</code> where each string is the contents of a file.</p>
<p>Then we compose a function to apply to the list. I could have written the last line as <code>putStr (unlines (sort (lines (concat y))))</code>, but I find the brackets ugly. <code>putStr</code> has type <code>String -> IO ()</code>, which takes the string we want to print and returns the <code>IO ()</code> that <code>Main</code> needs.</p>
<p>I find this code fairly straightforward to understand (and Haskell's powerful type checker made sure that by the time it compiled it was correct) but I wanted to check my understanding of the magic of the <code>do</code> block by rewriting it as a one-liner.</p>
<pre>
main :: IO ()
main = getArgs >>= mapM (readFile) >>= putStr . unlines . sort . lines . concat
</pre>
<p>This is a bit harder to understand than the <code>do</code> block at first sight, but not immensely so once you realise the parallel. The <code>do</code> construct is just syntactic sugar, and this is more or less what it is translated to. For details of why, and of what <code>>>=</code> means, refer to the tutorial I linked to above.</p>
<p>It can also be written the other way round:</p>
<pre>
main :: IO ()
main = putStr . unlines . sort . lines . concat =<< mapM (readFile) =<< getArgs
</pre>
<p>I'm not sure which one is easier to read.</p>
<p>It's also possible to nicely separate out the monadic nastiness from the pure function dealing with strings:</p>
<pre>
main :: IO ()
main = forallfiles transform

forallfiles :: (String -> String) -> IO ()
forallfiles f = getArgs >>= mapM (readFile) >>= putStr . f . concat

transform :: String -> String
transform = (unlines . sort . lines)
</pre>
<p>While <code>forallfiles</code> might not be the best name in the world for this, it does at least wrap up the nastiness into a single function, leaving <code>transform</code> as a pure function operating on a <code>String</code>. Pure functions are the staple of functional programming, and it is nice to keep as much of the program pure as possible. If <code>transform</code> were more substantial, this would likely make the program easier to understand and to maintain.</p>
<p>So what about this <code>IO ()</code> type? Well, the easiest way to think about it is as an opaque type just representing some kind of I/O. And what is I/O? Well, I/O is actually a change in the state of the outside world. It's quite easy to imagine that with <code>putStr</code>. The world (let's say your screen) before putStr is as it is, after <code>putStr</code> the screen has an extra string printed at the bottom. The <em>change</em> in the state of the world is the outputting of the string, and it is that change that is returned from the function.</p>
<p>But what about input? Well, the answer is that input is also <em>returned</em> in the <code>IO ()</code> type. For example, <code>getArgs</code> has type <code>IO [String]</code>. There is no input to the function. The <code>[String]</code> part gets passed on to something more useful (in this case, <code>mapM (readFile)</code>) and the <code>IO ()</code> part is taken care of by the monad. It is this <code>IO ()</code> part that represents the change of state of the outside world. But what actually is this change of state? Well, in this case it's the fact that the arguments have been got. In this case it just helps with the ordering of the function evaluation by providing a data dependency that the monad can use to sequence the I/O. If we were reading a line from a file though, it could represent something more concrete like the read pointer in the file.</p>
<p>Ultimately though, it's not important exactly what gets wrapped up in <code>IO ()</code>. That's why it's opaque. But every function that does any I/O at all will return that type, and the return values (ie changes in the state of the outside world) will be combined by the IO monad in the right order. What this represents is ensuring that all the I/O (and hence any computations necessary to support that I/O) is done in the right order.</p>
<p>Of course, it's entirely likely that there isn't any real data being passed around in <code>IO ()</code>. The compiler is probably being clever and doing the ordering that the monad does in such a way that it's safe for functions which return <code>IO ()</code> to have side effects, so that there is no way in which a function can have side effects without being ordered safely by the compiler. I think that's a pretty neat way of wrapping up side effects in return values, even if it's hard to understand at first.</p>
<p>This is by no means a formal exploration of monads or the full extent of Haskell's I/O system. There are plenty of texts covering that already. But writing this has helped me to understand it a bit better, so hopefully it will help you too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2009/12/28/haskell-io-and-monads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data recovery</title>
		<link>http://www.coolfactor.org/blog/2009/11/13/data-recovery/</link>
		<comments>http://www.coolfactor.org/blog/2009/11/13/data-recovery/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 17:45:33 +0000</pubDate>
		<dc:creator>gavan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.coolfactor.org/blog/?p=43</guid>
		<description><![CDATA[Earlier this year, my home file-and-everything-else server suffered a failure of both case fans which went unnoticed because it&#8217;s sitting in a hard to get to part of a cupboard and NetBSD doesn&#8217;t (yet) have drivers for the environmental monitoring &#8230; <a href="http://www.coolfactor.org/blog/2009/11/13/data-recovery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Earlier this year, my home file-and-everything-else server suffered a failure of both case fans which went unnoticed because it&#8217;s sitting in a hard to get to part of a cupboard and NetBSD doesn&#8217;t (yet) have drivers for the environmental monitoring hardware on the motherboard.</p>
<p>The constantly increased temperature in the case rapidly caused the failure of a head in the hard drive. Unfortunately, I only had a partial backup of the data so I was quite keen to recover as much as possible from the failed device.<br />
<span id="more-43"></span><br />
After I&#8217;d spent a few days trying to grab things with dd and friends with partial success, it became evident that it would become more and more difficult to grab more data off it as time went by. So I decided to call in the professionals.</p>
<p>I found a local outfit here in Peterborough called <a href="http://www.pcimage.co.uk/">PCImage</a> and their price was favourable compared to the competition in Cambridge and they were local, so I left my drive with them. After letting their equipment try to drag as much data off the drive as it could, they eventually took the drive apart and replaced the head stack in order to take a proper image.</p>
<p>They managed to produce a 100% error-free image of the drive this way, and they were very helpful indeed. And because it turned out to be easier to replace the head stack than to let the imager continue its futile effort, they were nice enough to not charge me extra for replacing the heads.</p>
<p>The server&#8217;s been up and running happily with a nice shiny new drive, a newer version of NetBSD and all of my data back where it should be.</p>
<p>Thanks, <a href="http://www.pcimage.co.uk/">PCImage</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coolfactor.org/blog/2009/11/13/data-recovery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

