<?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>JeeLabs &#187; Sensors</title>
	<atom:link href="http://jeelabs.org/tag/sensors/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeelabs.org</link>
	<description>Computing stuff tied to the physical world</description>
	<lastBuildDate>Tue, 22 May 2012 22:18:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Hard disk power &#8211; bonus</title>
		<link>http://jeelabs.org/2011/06/02/hard-disk-power-bonus/</link>
		<comments>http://jeelabs.org/2011/06/02/hard-disk-power-bonus/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 22:01:49 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[JeeNode]]></category>
		<category><![CDATA[Power]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=13687</guid>
		<description><![CDATA[Ok, there&#8217;s now a design for a high-side power switch which can power disk drives up and down at will. Wait a minute&#8230; You&#8217;re not supposed to power down disk drives just like that! It might be in the middle of a disk write. Even journaled disks are at risk, because journaling usually covers meta [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, there&#8217;s now <a href="/2011/06/01/hard-disk-power-3/">a design</a> for a high-side power switch which can power disk drives up and down at will.</p>

<p><em>Wait a minute&#8230;</em></p>

<p>You&#8217;re not <em>supposed</em> to power down disk drives just like that! It might be in the middle of a disk write. Even journaled disks are at risk, because journaling usually covers meta data (directories, files sizes, allocation maps, etc) &#8230; but not the data itself. So an unfortunate power down could leave the disk in an awful state: sure, the diks will be scanned and fixed on startup, but even then, some of the data blocks might contain inconsistent data. <em>Whoops &#8211; bad idea!</em></p>

<p>One solution would be to add a JeeLink to the computer, and have it send out the power down command only after it finishes flushing and unmounting the disk. It&#8217;ll take some scripting, depending on the OS, but it&#8217;s all doable. Also, this isn&#8217;t really for disks which need to be online most of the time &#8211; for that, the normal hard disk spin down and idling modes will be fine.</p>

<p>But I&#8217;d like it to be a bit more automatic than that. I don&#8217;t want to have to remember to turn off the disks. Nor tie it to a specific time of day, or day-of-the-week. The whole point of these disks, is that I rarely need them. Some disks may stay off for weeks, even months.</p>

<p>Here&#8217;s an idea: by adding a <em>current sensor</em> to each disk power supply line, we could monitor disk activity and make sure that power is never shut off while a disk is &#8220;doing something&#8221;. By adding a bit of extra logic in the sketch, we could implement a timer so that the disk will only be powered down if the disk has been idle for say 15 minutes. Most operating systems have a periodic flush in place, so that changes always get flushed out to disk fairly soon after they have been buffered by the OS. If nothing has happened for a while, then we know there&#8217;s no important change pending.</p>

<p>OK, how do you measure the amount of current a circuit draws? Easy: insert a small resistance in series with the load, and measure the voltage drop. For the same reasons as before, we can&#8217;t do this &#8220;low side&#8221;, i.e. in the ground connection. But high-side would be fine:</p>

<p><img src="http://jeelabs.org/wp-content/uploads/2011/05/screen_shot_2011_05_30_at_020054.png" alt="Screen Shot 2011 05 30 at 02.00.54" /></p>

<p>With 1A of current, we get (using Ohm&#8217;s E=IxR law): E = 1 x 0.1 = 0.1V voltage drop across the resistor. And since the high side of the resistor is tied to &#8220;+&#8221;, all we need to do is connect the other side to an analog input.</p>

<p>The nice thing about the power control circuit presented yesterday, is that it has a MOSFET between + and the disk drive power pin. And MOSFETs are really very much like a small resistor when turned on. <em>So we can simply use the MOSFET itself as a sense resistor:</em></p>

<p><img src="http://jeelabs.org/wp-content/uploads/2011/05/screen_shot_2011_05_30_at_015425.png" alt="Screen Shot 2011 05 30 at 01.54.25" /></p>

<p>Here are the characteristics of the P-MOSFET I&#8217;m going to try this with:</p>

<p><img src="http://jeelabs.org/wp-content/uploads/2011/05/screen_shot_2011_05_30_at_020651.png" alt="Screen Shot 2011 05 30 at 02.06.51" /></p>

<p>As you can see, at 3.3V, the MOSFET acts almost exactly like a 0.1Ω resistor: 0.1V drop at 1A &#8211; <em>perfect!</em></p>

<p>There is still one problem though: when the MOSFET is turned <em>off</em>, the voltage on the low side will be at ground level, which is 8.7V below the JeeNode&#8217;s &#8220;ground&#8221;. So we can&#8217;t just tie it to an analog input pin, it would fry the ATmega. That&#8217;s is why I added a 10 kΩ resistor: it will still be a very &#8220;bad&#8221; input signal when the MOSFET is off, but the resistor will limit the current to less than 1 mA, and it will flow through the internal ESD protection diode. That amount of current should be harmless.</p>

<p>So now we have a way to sense the current. When the disk draws 1A, the analog input will be at 0.1V below 3.3V, i.e. 3.2V, which can easily be measured. Since the ADC resolution is 3.3 mV, this means that a change in power consumption as small as 33 mA could in principle be detected by this setup. Should be accurate enough to detect a disk spinning up or down and the seek actuator moving.</p>

<p><em>I&#8217;ve ordered a bunch of parts and will report when something useful comes out of these experiments.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2011/06/02/hard-disk-power-bonus/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Gas flow measurement artifacts</title>
		<link>http://jeelabs.org/2011/03/14/gas-flow-measurement-artifacts/</link>
		<comments>http://jeelabs.org/2011/03/14/gas-flow-measurement-artifacts/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 23:01:59 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=13256</guid>
		<description><![CDATA[The raw gas consumption graph always looks a bit odd: Green is gas flow, red is electricity consumption. This is the same oddity I described two years ago on this weblog. The values are calculated from the last rotation time of the meter, but with gas flow things are a bit different: gas consumption is [...]]]></description>
			<content:encoded><![CDATA[<p>The raw gas consumption graph always looks a bit odd:</p>

<p><img src="http://jeelabs.org/wp-content/uploads/2011/03/screen_shot_2011_03_13_at_125945.png" alt="Screen Shot 2011 03 13 at 12.59.45" /></p>

<p>Green is gas flow, red is electricity consumption.</p>

<p>This is the same oddity I described <a href="http://jeelabs.org/2009/02/07/measurement-anomalies/">two years ago</a> on this weblog. The values are calculated from the last rotation time of the meter, but with gas flow things are a bit different: gas consumption is not continuous but a discrete on/off process, with some &#8220;modulation&#8221; once on.</p>

<p>So instead of each of those &#8220;tapering off&#8221; effects, what really happens is that the flow stops completely for a while and then resumes again later on.</p>

<p>This is an example of where the measurements need to be &#8220;fixed&#8221; (!), by injecting fake data points. It also illustrates how you can&#8217;t really know anything about consumption <em>between</em> disk rotation pulses.</p>

<p>The vertical grid lines in the above graph are spaced 500 l/h (resp. 500 W) apart, btw.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2011/03/14/gas-flow-measurement-artifacts/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Meet the new Room Board v2</title>
		<link>http://jeelabs.org/2010/11/28/meet-the-new-room-board-v2/</link>
		<comments>http://jeelabs.org/2010/11/28/meet-the-new-room-board-v2/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 23:01:12 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Home automation]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10833</guid>
		<description><![CDATA[For some time now, the Room Board kit has been outfitted with a new PIR sensor: It&#8217;s nicely low-power, but unfortunately it has a pin-out which differs from the ELV model, even with 3 pins! So I&#8217;ve decided to make a new Room Board v2, which drops support for the 8-pin ePir to allow the [...]]]></description>
			<content:encoded><![CDATA[<p>For some time now, the <a href="/rb1">Room Board</a> kit has been outfitted with a <a href="/2010/08/30/new-pir-motion-sensor/">new PIR sensor</a>:</p>

<p><img src="http://files.jeelabs.org/2010/08/dsc_1866.jpg" alt="" /></p>

<p>It&#8217;s nicely low-power, but unfortunately it has a pin-out which differs from the ELV model, <em>even with 3 pins!</em></p>

<p>So I&#8217;ve decided to make a new <a href="/rb2">Room Board v2</a>, which drops support for the 8-pin ePir to allow the new PIR sensor to be mounted in two different ways.</p>

<p>Here&#8217;s the board, with a solder drop already applied for the SHT11 (much easier to solder it in that way):</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2345.jpg" alt="Dsc 2345" /></p>

<p>Things have been moved around a bit, but the basic setup hasn&#8217;t changed. The 3 pins in the top left are still for the ELV PIR, and the 1-wire DS18B20 option is still there (with <em>fixed</em> pinout, yeay!).</p>

<p>Here is the board with SHT11 and LDR soldered on:</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2348.jpg" alt="Dsc 2348" /></p>

<p>And here are the two ways to attach the new PIR sensor:</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_23501.jpg" alt="Dsc 2350" />
<img src="http://files.jeelabs.org/2010/11/dsc_23491.jpg" alt="Dsc 2349" /></p>

<p>That second setup is the most compact, but also the most inconvenient one if you ever need to make changes or reach the headers. Note that the PIR pins were soldered in as far out as possible, and that the LDR was bent sideways a bit:</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2354.jpg" alt="Dsc 2354" /></p>

<p>I would advise to use the first setup where possible.</p>

<p>Having said that, here&#8217;s a complete Room Node with the (relatively) &#8220;compact&#8221; layout:</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2355.jpg" alt="Dsc 2355" /></p>

<p><em>Bit of a hodge-podge, but that&#8217;s what you get when everything is kept modular.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/11/28/meet-the-new-room-board-v2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Spectrum Analyzer</title>
		<link>http://jeelabs.org/2010/11/26/spectrum-analyzer/</link>
		<comments>http://jeelabs.org/2010/11/26/spectrum-analyzer/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 23:01:47 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[AVR]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Displays]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10816</guid>
		<description><![CDATA[Intrigued by this post, I wanted to try the same thing with the Graphics Board. So here goes: A real-time Spectrum Analyzer, with due credit to &#8220;deif&#8221; on the Arduino forum for making Tom Roberts&#8217; simple 8-bit FFT implementation available (three more people are credited in the source code). On the above display you can [...]]]></description>
			<content:encoded><![CDATA[<p>Intrigued by this <a href="http://arduino.cc/blog/2010/11/16/arduino-realtime-audio-spectrum-analyzer-with-video-out/">post</a>, I wanted to try the same thing with the <a href="http://jeelabs.org/gb1">Graphics Board</a>.</p>

<p>So here goes:</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2330.jpg" alt="Dsc 2330" /></p>

<p>A real-time Spectrum Analyzer, with due credit to &#8220;deif&#8221; on the <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286718155">Arduino forum</a> for making Tom Roberts&#8217; simple 8-bit FFT implementation available (three more people are credited in the <a href="http://code.jeelabs.org/libraries/Ports/examples/glcdSpectrum/fix_fft.cpp">source code</a>). On the above display you can see a typical &#8220;power spectrum&#8221;, with one dominant frequency plus harmonics at fixed intervals.</p>

<p>The sketch can be found <a href="http://code.jeelabs.org/libraries/Ports/examples/glcdSpectrum/">here</a>:</p>

<p><img src="http://files.jeelabs.org/2010/11/screen_shot_2010_11_23_at_001425.png" alt="Screen Shot 2010 11 23 at 00.14.25" /></p>

<p>This is almost the same code as the <a href="/2010/11/23/100-khz-dso/">100 KHz DSO</a> sketch, just extended with FFT.</p>

<p>The LCD is refreshed at maximum speed. As you can see, the lag of the LCD itself is actually quite useful in this context. This did bring a bug to the surface: I&#8217;ve noticed that the <a href="/2010/11/19/speedier-graphics/">speed-up</a> I implemented for the ST7565 was slightly too fast for this chip. After running for a while, the display would just turn black and stop refreshing.</p>

<p>So I changed these two lines in ST7565::spiwrite() :</p>

<p><img src="http://files.jeelabs.org/2010/11/screen_shot_2010_11_22_at_234810.png" alt="Screen Shot 2010 11 22 at 23.48.10" /></p>

<p>&#8230; to this, slightly slower but equivalent code:</p>

<p><img src="http://files.jeelabs.org/2010/11/screen_shot_2010_11_22_at_234843.png" alt="Screen Shot 2010 11 22 at 23.48.43" /></p>

<p>I&#8217;ve also updated my version of the <a href="http://jeelabs.org/pub/old-jeefiles/ST7565.zip">ST7565</a> ZIP file accordingly.</p>

<p>One more note about this code is that it uses most of the available RAM now: the 1 Kb buffer in the ST7565 library, plus two 256-char arrays to store 256 datapoints for running the FFT on.</p>

<p>With code such as this, it would actually be possible to get rid of the ST7565 buffer, since we&#8217;re re-constructing the entire display each time.</p>

<p><em>But for now, I&#8217;ll just leave it at this&#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/11/26/spectrum-analyzer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>2-channel Logic Analyzer</title>
		<link>http://jeelabs.org/2010/11/25/2-channel-logic-analyzer/</link>
		<comments>http://jeelabs.org/2010/11/25/2-channel-logic-analyzer/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 23:01:27 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[AVR]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Displays]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10789</guid>
		<description><![CDATA[Let&#8217;s continue the tiny lab-instrument series ;) Here&#8217;s a logic analyzer which takes 512 samples of 2 bits (DIO2 and AIO2): The &#8220;trace&#8221; starts when either of the inputs changes. I&#8217;ve enabled the internal pull-ups, so in this example you can see that DIO2 has no signal. The AIO2 signal is from a JeeNode running [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s continue the <a href="/2010/11/23/100-khz-dso/">tiny lab-instrument</a> series ;)</p>

<p>Here&#8217;s a logic analyzer which takes 512 samples of 2 bits (DIO2 and AIO2):</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2318.jpg" alt="Dsc 2318" /></p>

<p>The &#8220;trace&#8221; starts when either of the inputs changes. I&#8217;ve enabled the internal pull-ups, so in this example you can see that DIO2 has no signal. The AIO2 signal is from a JeeNode running the Arduino IDE&#8217;s built-in &#8220;ASCIItable&#8221; demo, which sends out a bunch of characters at 9600 baud (I took the signal from the USB-BUB connector).</p>

<p>Here is the <a href="http://code.jeelabs.org/libraries/Ports/examples/glcdTracer/glcdTracer.pde">glcdTracer.pde</a> sketch which implements this:</p>

<p><img src="http://files.jeelabs.org/2010/11/screen_shot_2010_11_20_at_172406.png" alt="Screen Shot 2010 11 20 at 17.24.06" /></p>

<p>Lots of trickery with bits. To keep memory use very low, I&#8217;m storing the 512 samples in a 128-byte buffer (512 x 2 bits = 128 x 8 bits). Low values are drawn as a pixel, high values are drawn as a little vertical line.</p>

<p>The code includes a minimal triggering mechanism, i.e. it waits for either of the input signals to change before collecting 512 samples.</p>

<p>Samples are collected at about 10 KHz, but this can easily be changed (up to ≈ 200 KHz with the current code).</p>

<p>Note that it would be possible to double the number of samples to 1024 and display them as 8 groups of 2 signals, but then you&#8217;ll have to really squeeze the output to fit it onto the 64&#215;128 pixels on the display.</p>

<p>BTW, there&#8217;s some shadowing visible on the display &#8211; has to do with how the chip drives the GLCD, no doubt.</p>

<p><em>Soooo&#8230; now we also have a portable Logic Analyzer!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/11/25/2-channel-logic-analyzer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>100 KHz DSO</title>
		<link>http://jeelabs.org/2010/11/23/100-khz-dso/</link>
		<comments>http://jeelabs.org/2010/11/23/100-khz-dso/#comments</comments>
		<pubDate>Mon, 22 Nov 2010 23:01:34 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[AVR]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Displays]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10763</guid>
		<description><![CDATA[You might have been wondering why I created the digital-to-analog converter a few days ago. Well, because I needed a test signal&#8230; to build this thing: You&#8217;re looking at a &#60;cough> Digital Storage Scope &#60;/cough> with 100 KHz bandwidth :) First of all: please don&#8217;t expect too much. There is no signal conditioning and no [...]]]></description>
			<content:encoded><![CDATA[<p>You might have been wondering why I created the <a href="/2010/11/21/bleep/">digital-to-analog converter</a> a few days ago.</p>

<p>Well, because I needed a test signal&#8230; to build this thing:</p>

<p><img src="http://files.jeelabs.org/2010/11/dsc_2307.jpg" alt="Dsc 2307" /></p>

<p>You&#8217;re looking at a &lt;cough> <em>Digital Storage Scope</em> &lt;/cough> with 100 KHz bandwidth :)</p>

<p>First of all: please don&#8217;t expect too much. There is no signal conditioning and no triggering whatsoever, and there are no external controls. This is simply a <a href="http://jeelabs.org/jn5">JeeNode</a> plus a <a href="http://jeelabs.org/gb1">Graphics Board</a>. It&#8217;s using the built-in ADC, with the conversion clock pushed quite a bit higher than what the Arduino&#8217;s analogRead() function will do. This speed comes at the cost of conversion accuracy, which isn&#8217;t so important since the Graphics Board display only has 6-bit vertical resolution anyway.</p>

<p>The screenshot shows a 1 KHz sine (from that <a href="/2010/11/21/bleep/">Bleep!</a> thing, obviously). As you can see, one cycle more-or-less covers the entire x-axis. So that&#8217;s about 128 samples per millisecond. This is not the maximum value, the ADC can also work twice as fast &#8211; i.e. with a division factor of 4 (ADPS2:0 = 2). This translates to 4 µs per sample.</p>

<p>Using the <a href="http://en.wikipedia.org/wiki/Nyquist–Shannon_sampling_theorem">Nyquist–Shannon sampling theorem</a> again, you can detect a frequency if you sample it at least twice per cycle, so that would have to be a cycle of at least 8 µs, i.e. over 100 KHz. <em>Which is why I decided to call this thing a 100 KHz DSO :)</em></p>

<p>The code tries to get as many samples as possible into a little 128-byte buffer before doing the rest of the work. The graphics display has a fairly limited response time, so I&#8217;m refreshing the display at 5 Hz (it&#8217;s still visible up to 50 Hz, but only just&#8230;).</p>

<p>I find it pretty amazing what an MPU such as the ATmega can do these days, with just a few lines of C code. Here&#8217;s the entire <a href="http://code.jeelabs.org/libraries/Ports/examples/glcdScope/glcdScope.pde">glcdScope.pde</a> sketch:</p>

<p><img src="http://files.jeelabs.org/2010/11/screen_shot_2010_11_19_at_025810.png" alt="Screen Shot 2010 11 19 at 02.58.10" /></p>

<p>The rest of the code is in the same <a href="http://jeelabs.org/pub/old-jeefiles/ST7565.zip">modified ST7565 library</a> as used in the past few days.</p>

<p>There&#8217;s lots of room for expansion, this code uses less than 4 Kb.</p>

<p><em>So there you have it &#8211; a very crude, but functional, oscilloscope!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/11/23/100-khz-dso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meet the Heading Board</title>
		<link>http://jeelabs.org/2010/10/26/meet-the-heading-board/</link>
		<comments>http://jeelabs.org/2010/10/26/meet-the-heading-board/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 22:01:04 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[JeePlug]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10328</guid>
		<description><![CDATA[Here&#8217;s another plug which didn&#8217;t work initially, but as always it was a simple mistake in the software (and a not-so-clear datasheet) which prevented me from using this thing: The Heading Board is based on a somewhat unusual HDPM01 combination sensor by HopeRF, containing a 2-axis compass / magnetometer and a &#8230; temperature + pressure [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s another plug which <a href="/2010/03/25/not-quite-a-compass-yet/">didn&#8217;t work initially</a>, but as always it was a simple mistake in the software (and a <em>not-so-clear</em> datasheet) which prevented me from using this thing:</p>

<p><img src="http://files.jeelabs.org/2010/10/dsc_2157.jpg" alt="Dsc 2157" /></p>

<p>The <a href="http://jeelabs.org/hb1">Heading Board</a> is based on a somewhat unusual <a href="http://www.hoperf.com/sensor/compass.htm">HDPM01</a> combination sensor by HopeRF, containing a 2-axis compass / magnetometer and a &#8230; <em>temperature + pressure sensor</em>. My interest in this thing was the compass, which is relatively low-cost compared to most other options out there.</p>

<p>There&#8217;s now a HeadingBoard class in the Ports library to make this thing sing. Note that it&#8217;s called a &#8220;board&#8221; and not a &#8220;plug&#8221; because it requires two ports and sits as a mini-board on top of a JeeNode (same as the Room Board):</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_24_at_173920.png" alt="Screen Shot 2010 10 24 at 17.39.20" /></p>

<p>This board is a somewhat awkward match for the ports concept, because it needs a 32 KHz clock to function. I&#8217;ve hooked that up to the IRQ pin, which is reprogrammed by HeadingBoard::begin() to generate that clock using Timer 2, so you may have to jump through some hoops to use this if other ports use the IRQ pin for a different purpose. A more general approach would be to generate the required 32 KHz on-board with an NE555, as is done in an upcoming <a href="/2010/10/10/generating-ir-pulses/">Infrared Plug</a> &#8211; but that requires extra board space (or components on both sides of the pcb).</p>

<p>Here is the &#8220;heading&#95;demo.pde&#8221; sketch, now added to the Ports library as example:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_24_at_174020.png" alt="Screen Shot 2010 10 24 at 17.40.20" /></p>

<p>Sample output:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_24_at_171702.png" alt="Screen Shot 2010 10 24 at 17.17.02" /></p>

<p>I haven&#8217;t figured out the conversion from X-/Y-axis values to compass heading yet. There is some sensitivity to how the board is positioned horizontally &#8211; this could be compensated by detecting the angular position using a <a href="http://heelabs.org/gp1">Gravity Plug</a>. But as you can see, there is a clear variation in readings as I turned the JeeNode + Heading Board around the Z axis.</p>

<p>So if you&#8217;re into robots: a Heading Board plus a Gravity Plug is all you need to determine your absolute orientation in all the 3 axes in space, i.e. X, Y, and Z.</p>

<p><em>Onwards!</em></p>

<p>PS. Here&#8217;s a crazy idea: we could use the Heading Board to create a door-open sensor. Simply attach this thing to a door, and track the Z-axis orientation!</p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/10/26/meet-the-heading-board/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Meet the Proximity Plug</title>
		<link>http://jeelabs.org/2010/10/25/meet-the-proximity-plug/</link>
		<comments>http://jeelabs.org/2010/10/25/meet-the-proximity-plug/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 22:01:22 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[JeePlug]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10320</guid>
		<description><![CDATA[The Proximity Plug was created a while back, but at the time I couldn&#8217;t get the chip to respond properly. Turns out that this was just some silly mistake in the code, so now all is well and ready for use: This plug uses an MPR084 to support up to 8 capacitive touch sensors. These [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://jeelabs.org/yp1">Proximity Plug</a> was created a while back, but at the time I couldn&#8217;t get the chip to respond properly. Turns out that this was just some silly mistake in the code, so now all is well and ready for use:</p>

<p><img src="http://jeelabs.org/wp-content/uploads/2010/03/DSC_1267.jpg" alt="DSC_1267.jpg" border="0" width="604" height="349" /></p>

<p>This plug uses an MPR084 to support up to 8 capacitive touch sensors. These can be created in any shape you like, using some conductive board, film, or tape. There&#8217;s a solder jumper to set one of two I2C addresses, so up to 16 sensors can be hooked up to a single port.</p>

<p>Here&#8217;s a little test setup:</p>

<p><img src="http://files.jeelabs.org/2010/10/dsc_2154.jpg" alt="Dsc 2154" /></p>

<p>Capacitive sensing can be fairly tricky to get right &#8211; the sensors may respond slightly differently, cross-talk between each sensor, electromagnetic noise pick-up, etc. But this chip does a lot of the work for us.</p>

<p>There are many configurations settings, and I&#8217;ve only started to scratch the surface so far. The current setup is configured to only report a single touch at a time, and does auto-calibration on startup. I&#8217;m still seeing some cases where things lock up and may have to be reset (in software), so the interface class for this thing is very basic for now &#8211; simply giving acces to the individual registers from I2C.</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_24_at_130133.png" alt="Screen Shot 2010 10 24 at 13.01.33" /></p>

<p>I&#8217;ve added a &#8220;proximity&#95;demo.pde&#8221; sketch to the Ports library to demonstrate the use of this plug:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_24_at_131036.png" alt="Screen Shot 2010 10 24 at 13.10.36" /></p>

<p>It will print a message whenever a &#8220;key-press&#8221; is detected. The commented-out code prints out the following ID string extracted from the chip:</p>

<pre><code>    #reescale,PN:MPR084,QUAL:EXTERNAL,VER:1_0_0
</code></pre>

<p>Note that the MPR084 chip wants a 100 KHz I2C bus.</p>

<p>One thing I&#8217;d like to try with this thing, is to create some input buttons with it using the Carrier Board box. It would be nice if the sensors can be made sensitive enough to reliably work with a bit of copper on the <em>inside</em> of the box, then you wouldn&#8217;t even have to drill holes or make any cutouts to be able to control what&#8217;s inside. Otherwise, perhaps a slit for adhesive / conductive copper tape, covered up with plastic foil?</p>

<p><em>More detective work needed&#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/10/25/meet-the-proximity-plug/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wireless mousetrap</title>
		<link>http://jeelabs.org/2010/10/22/wireless-mousetrap/</link>
		<comments>http://jeelabs.org/2010/10/22/wireless-mousetrap/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 22:01:36 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[JeeNode]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10288</guid>
		<description><![CDATA[Mathias Johansson recently sent me a description of his project which is just too neat to pass up. So here goes &#8211; photos by him and most of the text is also adapted from what he told me in a few emails. I&#8217;ll let Mathias introduce his project: It is late autumn here in Sweden [...]]]></description>
			<content:encoded><![CDATA[<p>Mathias Johansson recently sent me a description of his project which is just too neat to pass up. So here goes &#8211; photos by him and most of the text is also adapted from what he told me in a few emails.</p>

<p>I&#8217;ll let Mathias introduce his project:</p>

<blockquote>
  <p>It is late autumn here in Sweden and the mice starts to search for a winter home. They do normally stay outside modern constructions but I have a croft that is over 100 years old and they tend to like my attic. Mice are pretty cute, and I wish them no harm, but they damage my ceilings! Therefore I have to catch them in traps and transport them deep into the forest and release them near the brink of a stream.</p>
</blockquote>

<p>Some properties of each of the three traps built so far:</p>

<ul>
<li>Does not harm the mouse</li>
<li>Immediately reports which trap is closed on a webpage</li>
<li>Disables itself if the alarm system is turned on for longer periods of absence</li>
</ul>

<p>Here&#8217;s the mousetrap, ready to go:</p>

<p><img src="http://files.jeelabs.org/2010/10/mouse_trap.jpg" alt="Mouse Trap" /></p>

<p><em>With a guest&#8230;</em></p>

<p><img src="http://files.jeelabs.org/2010/10/mouse_in_trap.jpg" alt="Mouse in Trap" /></p>

<p>And here the status page indicating which traps have been sprung:</p>

<p><img src="http://files.jeelabs.org/2010/10/homepage.jpg" alt="Homepage" /></p>

<p>The schematic was implemented on what looks like a mini breadboard, here&#8217;s the <a href="http://fritzing.org/">Fritzing</a> version of it:</p>

<p><img src="http://files.jeelabs.org/2010/10/musetrap_v0_1_bb.jpg" alt="Musetrap v0 1 bb" /></p>

<p>The infrared receiver was salvaged from a BoeBot and is used to detect the presence of a guest to spring the trap. Note that by the time it detects <em>something</em>, the tail of the mouse will be mostly inside the trap, so this is a gentle as it gets &#8211; <em>well, if you&#8217;re a mouse&#8230;</em></p>

<p>Mathias concludes with:</p>

<blockquote>
  <p>Feel free to publish the pictures (and text) in your &#8220;success story&#8221; forum or elsewhere on your web-page if you think they are of interest to others or inspire new uses for the JeeNode.</p>
</blockquote>

<p>Thanks, Mathias, for sharing your ideas and your delightful rodent-friendly project!</p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/10/22/wireless-mousetrap/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Reporting motion</title>
		<link>http://jeelabs.org/2010/10/21/reporting-motion/</link>
		<comments>http://jeelabs.org/2010/10/21/reporting-motion/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 22:01:34 +0000</pubDate>
		<dc:creator>jcw</dc:creator>
				<category><![CDATA[AVR]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Home automation]]></category>
		<category><![CDATA[LowPower]]></category>
		<category><![CDATA[Sensors]]></category>

		<guid isPermaLink="false">http://jeelabs.org/?p=10265</guid>
		<description><![CDATA[Yesterday&#8217;s post presented a new sketch which did everything the old sketch did, except report motion. The reason was that the requirements for reporting motion are quite different from the rest: it has to be reported right away &#8211; using ACKs, time-outs, and retries to make sure this message is properly received. The latest version [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday&#8217;s <a href="/2010/10/19/room-node-next-steps/">post</a> presented a new sketch which did everything the old sketch did, except report motion. The reason was that the requirements for reporting motion are quite different from the rest: it has to be reported <em>right away</em> &#8211; using ACKs, time-outs, and retries to make sure this message is properly received.</p>

<p>The latest version of <a href="http://code.jeelabs.org/libraries/RF12/examples/roomNode/roomNode.pde">roomNode.pde</a> now adds the missing logic. And it does indeed get a lot messier &#8211; doubling the total number of lines in the source code.</p>

<p>Here is the new loop() code:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_19_at_223741.png" alt="Screen Shot 2010 10 19 at 22.37.41" /></p>

<p>The key change is that there is now a check for &#8220;pir.triggered()&#8221; which will be called outside all normal scheduling actions. Note that this code is still using scheduler.pollWaiting(), so the code is still spending most of its time in power-down mode.</p>

<p>Except that now, we&#8217;re also setting up a pin-change interrupt for the PIR sensor:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_19_at_224016.png" alt="Screen Shot 2010 10 19 at 22.40.16" /></p>

<p>The new code to handle these PIR triggers is as follows:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_19_at_224214.png" alt="Screen Shot 2010 10 19 at 22.42.14" /></p>

<p>So instead of folding this complicated case into the rest of the code, when a PIR trigger goes off, we now simply send that packet out and wait for the ACK, repeating it a few times if necessary. The normal measurement and reporting tasks are not affected by any of this, other than that the measurement scheduling is postponed a bit to avoid triggering another report right away.</p>

<p>The new <a href="/2010/08/30/new-pir-motion-sensor/">PIR motion sensor</a> turns out to be quite convenient, because it has an on-board trimpot to set the re-trigger timeout. As long as motion is detected more often than this threshold, the PIR output will remain 1, so there is no need to play tricks in software to avoid constant triggers. We&#8217;ll get one pin change for the start of motion, and another one when no motion has been detected <em>for a preset amount of time</em>.</p>

<p>Having said that, I&#8217;ve implemented a similar <em>re-triggerable one-shot</em> mechanism in software anyway, because my older nodes use the ELV PIR sensor, which send out a pulse for each motion trigger. So all ON pulses within 30 seconds of each other get coalesced into one.</p>

<p>To illustrate that the system is still doing almost nothing most of the time, I added a debug mode which prints a &#8220;.&#8221; on each iteration of loop(). In normal Arduino sketches, this would cause an incessant stream of characters to be printed out, but in this sketch there are just a few:</p>

<p><img src="http://files.jeelabs.org/2010/10/screen_shot_2010_10_19_at_221235.png" alt="Screen Shot 2010 10 19 at 22.12.35" /></p>

<p>Motion detection now works more or less independently of the normal measure / report tasks.</p>

<p>There are still some rough edges, but I expect this new code to perform considerably better in terms of battery lifetime already. The dreaded battery rundown problem when the central node is not reachable should be gone. All that remains are a few attempts (I&#8217;ve set it to 5) whenever the PIR sensor turns on or off. In both cases the ACK has to be received within 10 milliseconds &#8211; after that the sketch enters power-down mode again.</p>

<p>The new code should also make it much easier to add sensor types (switches, hall-effect, 1-wire, barometer).</p>

<p>FWIW, this code needs 8238 bytes (without serial I/O), so it&#8217;ll still easily fit in an ATmega168. Without SHT11 (which uses floating point) that drops to 5682 bytes, including the RF12 driver. <em>How&#8217;s that for a WSN node!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeelabs.org/2010/10/21/reporting-motion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.508 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-23 10:46:33 -->

