<?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>GigaMegaBlog &#187; .Net</title>
	<atom:link href="http://www.gigamegablog.com/category/programming/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gigamegablog.com</link>
	<description>Powered by GigaMegaWatts</description>
	<lastBuildDate>Sun, 05 Feb 2012 16:39:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>FEZ XBee Sensor: Hat Trick</title>
		<link>http://www.gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/</link>
		<comments>http://www.gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 21:34:26 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[FEZ]]></category>
		<category><![CDATA[Netduino]]></category>
		<category><![CDATA[nimbits]]></category>
		<category><![CDATA[Pachube]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=1011</guid>
		<description><![CDATA[As mentioned at the end of my Watching the Watcher article, the Netduino Plant Light project is going to take a sharp turn at this point, losing both the Netduino and the Plant Light.  I&#8217;m going to spin off some &#8230; <a href="http://www.gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As mentioned at the end of my <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher article</a>, the <a href="http://gigamegablog.com/tag/netduino/">Netduino Plant Light project</a> is going to take a sharp turn at this point, losing both the Netduino and the Plant Light.  I&#8217;m going to spin off some of the code into a new project, a FEZ XBee Sensor.</p>
<p>Like its predecessor, the XBee Sensor is a <a href="http://www.microsoft.com/en-us/netmf/default.aspx">.Net Micro Framework device</a>, which uses an <a href="http://www.digi.com/xbee/">XBee</a> wireless transceiver to post data to the Internet by way of a Python middleman.</p>
<p>I’m structuring the code to be more flexible, supporting a variety of sensors and logging to a variety of databases.  Personally, I&#8217;m using it to measure plant soil moisture, light levels, temperature and humidity, as described in the &#8220;Hardware Configuration&#8221; section below.</p>
<p>If you decide to use a different mix of sensors (as I&#8217;m sure you will), you&#8217;ll need to make a small change to the C# code, as shown in the Programmer’s Show and Tell section below.  I&#8217;m aiming for a more generic device configuration, where all  sensor devices run exactly the same code, and all sensor configuration is done through Python.</p>
<p>Since a new project gives me an excuse to start playing with new hardware, I&#8217;ve also switched from using the <a href="http://www.netduino.com">Netduino</a> to a rival Micro Net Framework product, the <a href="http://www.ghielectronics.com/catalog/product/256">FEZ Panda</a>.</p>
<p>I&#8217;m not abandoning the Netduino: my own Netduino continues to perform its duties as a Plant Light Controller, and I&#8217;ll do my best to continue to support the Netduino in the XBee Sensor source code.  It’s relatively easy to switch the code between a FEZ and Netduino target.  I’ll point the code changes that are required in the Programmer’s Show and Tell section .</p>
<p>Also, the Python code used in this article is compatible with the Netduino Plant Light controller code from <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a>, so you can have both a Netduino Plant Light Controller and an XBee sensor reporting data to the Python code if you like, or even just the Netduino.</p>
<h2>The FEZ Panda</h2>
<p>The FEZ Panda is one of a line of products from GHI Electronics: Fez Mini, Panda, Panda II and Domino.  The Fez Mini is similar to the Netduino Mini &#8212; both mimic the form factor and pinout of the Basic Stamp &#8212; while the Pandas are similar to the Netduino.  The Domino is a more powerful beast, using a chipset that supports USB Host.</p>
<p style="text-align: center;"><div class="img aligncenter" style="width:620px;">
	<a href="http://www.ghielectronics.com/catalog/product/256"><img src="http://www.ghielectronics.com/images/fpn2_features.jpg" alt="FEZ Panda II" width="620" height="400" /></a>
	<div>FEZ Panda II</div>
</div>
<p>Compared to the Netduino, the Pandas (both versions I and II) have a few advantages that will come in handy when acting as a remote sensor.</p>
<p>1. More pins: 54 digital I/Os, as opposed to the Netduino&#8217;s (and Arduino&#8217;s) 13, and 3 COM ports to the Netduino’s 2.  More analog pins would have been even better, but the Panda only has 6, same as the other platforms.</p>
<p>2. Native code.  This one is huge: the .Net code can invoke &#8220;unmanaged&#8221; native code, which has full access to the microprocessor&#8217;s capabilities, including microsecond-level timing.  This eliminates the Micro Net Framework&#8217;s biggest disadvantage to the Arduino.</p>
<p>3. Ability to store data in flash memory.  The FEZ firmware includes a class that allows .Net code read/write access to 4K of flash memory, analogous to the Arduino&#8217;s Flash library.</p>
<p>4. More documentation!  This one might not excite you as much as it does me (whee!), but GHI&#8217;s <a href="http://www.tinyclr.com/">TinyCLR</a> site offers a ton of documentation covering pretty much every feature of the FEZ platform and the underlying Net Micro Framework.  I’d particularly like to point out the Beginner&#8217;s Guide to .Net Micro Framework, which I feel is still the best publication of any type covering the MNF, and much of which is also applicable to the Netduino.  A Tutorials section was recently added to the TinyCLR site, which has rapidly expanded to cover a lot of very useful features, again many of them applicable to the Netduino.  (Both the Beginners Guide and the Tutorials section can be found on the <a href="http://www.tinyclr.com/support/">TinyCLR Support page</a>).</p>
<p>Back in the <a href="http://gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/">Netduino: A Little Help From Its Friends article</a>, I used an Arduino as a helper to the Netduino.  It handled a couple of actions that the Netduino (and Micro Net Framework) couldn’t do: read data from the DHT11 temperature/humidity sensor and saving settings to Flash memory.  The FEZ Panda can actually do both these things itself.    Smarter than the average bear!</p>
<p>By the way, the difference between the Panda and Panda II is that the latter contains a micro SD card socket, and adds female headers for most of the additional digital pins, which are repositioned to be accessible even when an Arduino shield is in place.  I&#8217;m using Panda Is (<a href="http://www.ghielectronics.com/catalog/product/135">currently being sold off by GHI at the ridiculously low price of $15</a>), but everything that I&#8217;m doing in this project will also work on a Panda II.   The code will work almost unchanged – all you have to do is remove the Project Reference to <em>FEZPanda_&#8230;</em> and replace it with <em>FezPandaII_&#8230;</em>, as shown in the screenshot.</p>
<div class="img aligncenter size-full wp-image-1018" style="width:475px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/Panda2Reference.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/Panda2Reference.png" alt="Selecting Panda II Assembly" width="475" height="404" /></a>
	<div>Selecting Panda II Assembly</div>
</div>
<h2>Hardware Configuration</h2>
<p>At this point, the XBee Sensor project is geared towards supporting analog sensors plus one particular digital sensor, the DHT11/DHT22 temperature and humidity sensor. I’m using the analog ports as moisture and light sensors, but any analog sensor that can run on 3.3V should work without code changes.</p>
<p>The XBee Sensors are intended to be used without displays, but when first configuring them it’s handy to connect an LCD to see what they’re doing (or failing to do). So, I added an optional “Debug LCD”, which displays the current sensor readings, as well as any Exceptions or other error messages.</p>
<p>I’ve written the code so that, if the LCD isn’t connected, it shrugs and keeps going.  However, if your device seems to behave erratically when the LCD is disconnected, you can disable use of the LCD by removing the DEBUG_LCD compiler flag (as shown in the Programmer&#8217;s Show And Tell section below).</p>
<p>You can also select the type of LCD using a compiler flag.  LCD support is basically the same as in the Netduino Plant Light Controller code, with the addition of the <a href="http://www.adafruit.com/products/292">Adafruit i2c / SPI character LCD backpack</a> &#8212; more details on that support are also in the Programmer&#8217;s Show And Tell section.</p>
<p>If you are using an LCD, you’ll probably want to add a button to D7, to toggle the backlight on or off.</p>
<h2>Soil Moisture Sensors</h2>
<p>The soil moisture sensors use the same approach as in the <a href="http://www.instructables.com/id/Garduino-Gardening-Arduino/">Garduino</a> project.  I built mine from</p>
<ul>
<li>A pair of galvanized nails.  I think any nails will do, as long as they&#8217;re galvanized and big-assed, I’m using Tree Island Gold 4” 20d Hot Dip Galvanized nails</li>
<li>2 lengths of 20 AWG wire, long enough to go from the plant pot to the Panda</li>
<li>a 10K resistor, connecting the analog in to ground</li>
</ul>
<p>As you can see from the photo, one end of each wire is soldered to a nail, then covered with heat shrink tubing to keep it attached tight.  The other end of the wires connect to the Panda.  One wire connects directly to 3.3V, and the other other wire is split: it connects directly to an analog port, then connects through a 10K resistor to ground.</p>
<p style="text-align: center;"><div class="img aligncenter size-large wp-image-1017" style="width:640px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/MoistureSensorWIringCorrected.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/MoistureSensorWIringCorrected-1024x764.jpg" alt="Moisture Sensor Wiring - Click to Enlarge" width="640" height="477" /></a>
	<div>Moisture Sensor Wiring - Click to Enlarge</div>
</div>
<p>I found that the screw connectors on the Adafruit Wing Protoboard is ideal for this setup, since the screw connectors firmly hold the wires in place , and the protoboard layout makes it easy to add the resistor-to-ground connection.  The Adafruit board also provides 4 spare screw connectors, in the upper-right of the above photo – I used mine to provide the extra 3.3V connections required for this project.</p>
<p>The Garduino actually uses 5V, but 3.3V works just as well for this purpose, with similar calibration.  My oldest moisture sensor has been in service for almost 3 months now, with no apparent degradation of the nails or weird behaviour in the voltage readings.  (No electrocuted plants either – the 10K resistor ensures that the current is too low to hurt either plants or humans).</p>
<p>The light sensor is a garden variety (nyuk nyuk) cadium sensor that uses the exact same circuit as the moisture sensors: one wire connected to 3.3V, and the other split between an analog pin and ground through a 10K resistor.</p>
<p>Here is what the XBee Sensor looks like with all its accoutrements:</p>
<div class="img aligncenter size-large wp-image-1014" style="width:640px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/100_0021.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/100_0021-1024x764.jpg" alt="FEZ XBee Sensor - Up and Running" width="640" height="477" /></a>
	<div>FEZ XBee Sensor - Up and Running</div>
</div>Here is an alternative configuration.  This one uses a Serial LCD, the <a href="http://www.seeedstudio.com/depot/grove-base-shield-p-754.html?cPath=132_134">SeeedStudio Grove Base Shield</a>, and connects the moisture sensor wires to a <a href="http://www.seeedstudio.com/depot/grove-protoshield-p-772.html?cPath=175">Grove Prototype Twig</a>.  The prototype twig works pretty well for connecting the moisture sensors, since it has plenty of room for the resistor connections to ground, and it supports 2 sensors per twig.  However, it uses 5V by default, so I snipped the power cable and wired it to 3.3V instead.</p>
<div class="img aligncenter size-large wp-image-1015" style="width:640px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/100_0026.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/100_0026-1024x764.jpg" alt="FEZ XBee Sensor - The Next Generation" width="640" height="477" /></a>
	<div>FEZ XBee Sensor - The Next Generation</div>
</div>
<h2>Temperature/Humidity Sensor</h2>
<p>I have the DHT11 from the <a href="http://gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/">A Little Help From Its Friends</a> article connected to one of my XBee Sensor configurations, and the DHT11&#8242;s big brother, the <a href="http://www.sparkfun.com/products/10167">DHT22</a>, connected to another.</p>
<p>The code used to read from the 2 devices is identical – the only difference is how the .Net code parses the data to retrieve the temperature and humidity values.</p>
<p>As mentioned earlier, the Panda&#8217;s support for native “RLP” (Runtime Loadable Procedures) code means that it can handle the microsecond-level timing required by the DH22 and DHT11.</p>
<p>The RLP code that I’m using comes from <a href="http://code.tinyclr.com/project/339/dht11-temperature-sensor-using-rlp/">this project on GHI&#8217;s TinyCLR site</a>.  The description of the project only mentions the DHT11, but the RLP code works for the DHT22 too.</p>
<p>I&#8217;ve modified the code slightly to prevent an infinite loop if anything goes wrong with the communication, and added a few comments to explain why the code is doing what it&#8217;s doing. My modified version, along with a compiled .elf file and all of the files needed to build the .elf, can be <a href="http://gigamega-micro.googlecode.com/files/DHT11%20DHT22%20RLP.zip">downloaded</a> from <a href="http://code.google.com/p/gigamega-micro/">my Google Code project page.</a> </p>
<p>(By the way, if you Google for the DHT11 or DHT22 datasheet, you&#8217;ll probably find a &#8220;Chinglish” version that&#8217;s awfully hard to understand.  A better datasheet can be found <a href="http://www.humiditycn.com/pic/20119221814042568.pdf">here</a>: it refers to the RHT21, but that&#8217;s identical to the DHT22 as far as the communication is protocol is concerned).</p>
<p>The native code isn&#8217;t something that you copy and paste into Visual Studio alongside your C# code – instead, it is built using a separate piece of open source software with the charming name of Yagarto (Yet Another GNU ARM Toolchain).</p>
<p>An introduction to generating RLPs with Yagarto can be found in <a href="http://wiki.tinyclr.com/index.php?title=RLP_Getting_Started">TinyCLR&#8217;s tutorial</a>.  I&#8217;d recommend you use <a href="http://www.itcrowd.be/getting-started-with-ghi-rlp">this more extensive tutorial</a> instead, which covers a few small but important steps skipped by the TinyCLR tutorial.</p>
<p>However, if you&#8217;d rather not learn Yet Another Anything at this time, the good news is that you can just use the .elf file that is included with the source code for this article.  It should work with any DHT11 or DHT22 connected to any of the FEZ devices that use the USBizi100 chipset: Fez Mini, Panda, or Panda II.</p>
<p>You will have to get your own unlocking code from GHI, to paste into the Visual Studio project. It&#8217;s a quick and painless, if somewhat mystifying, process:</p>
<p>1. Create a MyGHI account here: <a href="http://www.tinyclr.com/register/">http://www.tinyclr.com/register/</a></p>
<p>2. Once registered, login and click on the My Account link.</p>
<p>3. Click on the RLP Access Code link</p>
<p>4. Click the checkbox to agree to the &#8220;Technology Access Agreement&#8221; (which I assume is the whole point of this process), click Submit and your access code will be e-mailed to you.</p>
<p>The access code is pasted into the Visual Studio project, as shown in the Programmer&#8217;s Show and Tell section below.  The first time you run the unlock command on a FEZ device, it sets aside 10K for RLP use, then reboots.  The device remains unlocked after that, until the next time you update the firmware.</p>
<p>I&#8217;m not sure what exactly the unlock command does to your FEZ device, but based on my experience it’s a safe thing to try.  It doesn&#8217;t cause any instability or change the way that you debug your code.  If you decide you&#8217;d rather have the 10K back for .Net code, then you can remove RLP support by reloading the FEZ firmware.</p>
<p>I should point out one &#8220;gotcha&#8221; regarding the DHT11/DHT22 support, which probably applies to any RLP code that is timer-dependent.  You need to invoke the RLP subroutines from the main thread of the .Net application, not from a timer or event handler.  When I tried reading invoking the code from the timer thread that reads the other sensors, I found that the code ran slightly too slowly to keep up with the signals being sent from the DHT22 (which explains why I modified the code to break out of an infinite loop).  When invoked from the main thread, the code is rock solid – I haven’t noticed any failed readings in the weeks that I&#8217;ve been running it.</p>
<p>You might be wondering if RLP support is worth all the trouble.  If all you want is to support the DHT11/22, then you actually have an alternative to RLP: <a href=" http://code.tinyclr.com/project/289/dht11---temperature-and-humidity-sensor/">this TinyCLR Code project</a> describes an alternative approach using just managed C# code and a clever hardware hack (which would probably also work with a Netduino, by the way).  However,  I really think RLP is worth learning, since it opens up support for all kinds of accessories previously off-limits to Micro Net Framework devices, such as Graphical LCDs and audio input.  For examples, <a href="http://code.tinyclr.com/#do=searchProjects&amp;keywords=rlp">do a search of &#8220;RLP&#8221; in the TinyCLR Code section</a>.  Pretty much anything that the Arduino supports can (in theory) also be supported for Fez using RLP.</p>
<h2>XBee</h2>
<p>The XBee configuration at both the FEZ and Python end is the same as in the <a href="http://gigamegablog.com/2011/08/03/netduino-meets-world/">Netduino Meets World</a> article, with one exception. The Python code will now be using the XBee in API mode, and its XBee (but not the one at the FEZ end) must therefore have its API mode enabled.</p>
<p>The easiest way to do this is to open a console connection to the XBee (as described in Netduino Meets World), and enter</p>
<pre>+++
ATAP 1
ATWR</pre>
<p>Or, if you prefer, you can use the X-CTU Windows application to turn on API mode.</p>
<div class="img aligncenter size-full wp-image-1020" style="width:461px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/XCTU.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/XCTU.png" alt="X-CTU setting for API Mode" width="461" height="594" /></a>
	<div>X-CTU setting for API Mode</div>
</div>
<p>Note that the XBee address at the FEZ still needs to be hard-coded as “1”, even if you are using multiple XBee Sensors, or both XBee Sensors and a Netduino Plant Light Controller.  This isn’t a problem yet, since the FEZ/Netduino code doesn’t care what it receives, and the Python code doesn’t use the address to identify what it is receiving.  That will change in a future stage of the project</p>
<h2>Python Middleware</h2>
<p>The Python code has the same role as in the <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a> article: it forwards the sensor readings to a data repository on the Internet.</p>
<p>I’ve expanded the Python code to support 2 different repositories: <a href="http://www.nimbits.com">Nimbits</a> and <a href="http://www.pachube.com">Pachube</a>.  I’ve also expanded the configuration file to give you a bit more control over which sensors are posted to which sites.</p>
<p>The Python code is compatible with the Netduino Plant Light controller that was created in my previous blog posts.</p>
<p>You can <a href="http://gigamega-micro.googlecode.com/files/SensorRelay.zip">download the Python code and sample configuration file</a> from <a href="http://code.google.com/p/gigamega-micro/">my Google Code project page</a>.  Note that I’ve renamed them to better reflect their role: SensorRelay.py.</p>
<p>The sample configuration file looks like this:</p>
<pre># Configuration file for SensorRelay.py
# ----------- General App Settings ------------
# XBEEPORT = \.COMxx &lt;-- on some systems, Windows COM port 
#   must be specified in this format
XBEEPORT = COMxx
# USBPORT = COMyy
LOGFILENAME = SensorRelay.log
LOGDATA = False
SENDTIME = True
DEBUG = True
# -------- Sensor Settings -----------
#  - sensor line format is &lt;Netduino Sensor ID&gt; 
# = &lt;Nimbits Data Point ID OR Pachube Datastream ID&gt;
#[,Update Interval in seconds]
[Nimbits 1]
NIMBITS_SERVER = http://app.nimbits.com
NIMBITS_USERID = you@wherever.com
NIMBITS_API_KEY = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
UPDATE_INTERVAL = 300
A1 = ASensor,60
A2 = AnotherSensor
T1 = TemperatureSensor,1500
H1 = HumiditySensor
[Pachube 1]
PACHUBE_FEED_ID = nnnnn
PACHUBE_API_KEY = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
UPDATE_INTERVAL = 300
A1 = ASensor,60
A3 = AThirdSensor
T1 = TemperatureSensor
H1 = HumiditySensor</pre>
<p>The settings are:</p>
<p>XBEEPORT = The serial port that the XBee is connected to.  On a Linux box, this would have a different format, like /dev/ttyUSBn.</p>
<p>USBPORT = The (very optional) serial port that an XBee Sensor is directly connected to.  (Technically, this would make it a FEZ USB/XBee Sensor – nice acronym!)</p>
<p>Note that you can use an XBEEPORT or a USBPORT, or both.  Just comment out or delete the one you aren’t using.</p>
<p>In the Python code in the <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a> article, I mentioned that the XBEEPORT setting could actually be set to the port of a USB-connected Netduino.  Why did I break that out to a separate USBPORT setting now?  The Python code now sends data to the XBEEPORT using the lower-level XBee API, while it still uses a generic Serial interface to a USB-connected device.</p>
<p>LOGFILENAME – The filename (or full path and filename) to which sensor data is logged in CSV format.  Note that, unlike the Python code in the <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a> article, errors and debug messages aren’t written to this file – they are written to a file named SensorRelayError.log instead, in the directory from which SensorRelay.py is run.</p>
<p>LOGDATA – This is used to enable or disable the logging of data to LOGFILENAME.   If your Python code is running on a ultra low power device like the Beagleboard, with just an SD card as its disk drive, then turning off data logging saves some wear-and-tear on the SD card.</p>
<p>SENDTIME – If true, the date and time will be sent to the XBeeSensor each minute.  You’ll want to leave this turned off if you’re using an XBee Sensor, but you should turn it on if you’re using the Netduino Plant Light Controller from my previous blog posts.</p>
<p>DEBUG – If true, debug messages will be written to both the console and the XBeeSensorError.log file.</p>
<p>The sensor configuration sections of the configuration file must always start with a name in square brackets, like “[Nimbits 1]”.  (The name can be whatever you like, actually, as long as you don’t use it more than once).  There must be at least 1 sensor configuration section, but you can have multiple sections if you want to send your data to multiple data repositories.</p>
<p>Personally, I use three: 1 for the public Nimbits app server (to test my code with the latest version of Nimbits), one for my personal Google App Server installation of Nimbits (to which I log more frequently), and one for Pachube, so that I can play around with its API too.</p>
<p>The Nimbits settings are identical to the ones used in the <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a> article – please see it for details.</p>
<p>The Pachube settings are almost the same as the Nimbits settings, but the lingo is somewhat different.  For details on getting started with Pachube, see my <a href="http://gigamegablog.com/2011/03/10/tweet-a-watt-beyond-the-twitter/">Tweet-A-Watt: Beyond the Twitter</a> article</p>
<p>PACHUBE_FEED_ID = The numeric feed ID.  (A Pachube Feed is a group of datastreams.  A datastream is the Pachube equivalent of a Nimbits Data Point.)  If you want to send different sensor readings to different feeds, you should create multiple Pachube sections in your configuration file (e.g. [Pachube 1], [Pachube 2]).</p>
<p>PACHUBE_API_KEY = A Pachube API key that you’ve generated, and which has write access to your feeds.</p>
<p>UPDATE_INTERVAL = As with Nimbits, this determines how often the sensor data will be posted to Pachube, in seconds.  Note that Pachube has a rate limiter that depends on the <a href="https://pachube.com/plans">type of plan</a> you have.  Each datastream update counts as a separate API call, so if you have 5 datastreams, that is 5 API calls.</p>
<p>SENSOR_ID = DATASTREAM_ID[, UPDATE_INTERVAL] = Determines which sensor reading received from the XBee Sensor will be sent to which Pachube datastream, optionally overriding the default update interval.  For example</p>
<pre>A1 = ASensor,60</pre>
<p>&#8230;means that sensor A1 received from the XBee Sensor will be sent to Pachube Datastream ASensor, every 60 seconds.</p>
<h1>Programmer’s Show and Tell</h1>
<h2>.Net Code</h2>
<p>As before, you can get the .Net code from <a href="http://code.google.com/p/gigamega-micro/">my Google Code page</a> in either of 2 ways:</p>
<ol>
<li>If you are familiar with Subversion, you use any SVN client (my favorite is <a href="http://tortoisesvn.net/">TortoiseSVN</a>) to get a copy of all the project files.  The SVN URL is <a href="https://gigamega-micro.googlecode.com/svn/trunk">https://gigamega-micro.googlecode.com/svn/trunk</a>, and the code for this article is in the XBeeSensor article.</li>
<li>Or, download the good old .zip file from the Downloads section of the Google Code project. <a href="http://gigamega-micro.googlecode.com/files/GMM_FEZXBeeSensor.zip">Here is a direct link to the code for this article</a>.</li>
</ol>
<p>I&#8217;m using the <a href="http://microliquidcrystal.codeplex.com/">MicroLiquidCrystal </a>library to add support for an i2c-connected LCD. The solution file will look for this project, and grumble if it can&#8217;t find it.  If you aren&#8217;t using an i2c LCD, you should remove the Reference to the MicroLiquidCrystal library from the project References list.  Otherwise, you&#8217;ll need to download the MicroLiquidCrystal source code and store it in the XBeeRemoteSensor solution folder..</p>
<p>While the .Net code is a totally separate project from the Netduino Plant Light controller, a lot of its contents will be familiar if you’ve read the Show and Tell sections of my previous blog posts.</p>
<p>Switching from the Netduino to the FEZ doesn’t require many changes to the code.  The underlying .Net Micro Framework codebase is 100% identical, and very little of the XBee Sensor code makes use of features that are specific to the Netduino or FEZ.  Where it does, I’ve used &#8220;#if&#8221; conditional compiler flags to include the correct code.</p>
<p>By the way, I’ve switched to putting compiler flags in the Project properties, as shown in the screenshot below, rather than hard-coding them with #define statements.  The default flag is “FEZ” – if you want to use a Netduino instead of a FEZ device, remove “FEZ” from the Conditional Compilation Symbols</p>
<div class="img aligncenter size-full wp-image-1016" style="width:736px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/Compiler-Flags.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/Compiler-Flags.png" alt="Compiler Flags" width="736" height="445" /></a>
	<div>Compiler Flags</div>
</div>
<p>In addition to getting the compiler flag right, the project’s References need to point to the right set of assemblies. For the FEZ Panda, use GHI’s libraries; for the Netduino, use SecretLabs’.  Your references lists should look like the one below – if you’ve got exclamation marks next to the GHIElectronics libraries, then perhaps you haven’t installed the FEZ SDK yet?  Otherwise, any problems are likely due to differences in the versions of the GHI libraries that I’m using and the ones you’re using – just delete the 3 GHI libraries from the References list, then add them back from the list on your PC.</p>
<div class="img aligncenter size-full wp-image-1019" style="width:264px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/10/References.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/10/References.png" alt="Project References List" width="264" height="238" /></a>
	<div>Project References List</div>
</div>
<p>The compiler flags take care of the rest.  For example, the “using” statements at the top of each class ensure that the proper assemblies are being used:</p>
<pre class="brush: csharp; title: ; notranslate">
#if FEZ
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;
#if DHT22 || DHT11
using GHIElectronics.NETMF.Native;
#endif
#else
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
#endif&lt;/pre&gt;
</pre>
<p>Near the top of Program.cs, you’ll find the following code:</p>
<pre class="brush: csharp; title: ; notranslate">
// !!!!!!!!!!!!!!!! USER MUST SET THE FOLLOWING 3 LINES!!!!!!!!!!!!!!!!!!!!!!!

const int NUM_ANALOG_SENSORS = 5; // number of analog sensors

#if FEZ

static FEZ_Pin.AnalogIn[] sensorPins = new FEZ_Pin.AnalogIn[] { FEZ_Pin.AnalogIn.An0, FEZ_Pin.AnalogIn.An1,

FEZ_Pin.AnalogIn.An2, FEZ_Pin.AnalogIn.An3, FEZ_Pin.AnalogIn.An4};

#else

static Cpu.Pin[] sensorPins = new Cpu.Pin[] { Pins.GPIO_PIN_A0, Pins.GPIO_PIN_A1, Pins.GPIO_PIN_A, Pins.GPIO_PIN_A3, Pins.GPIO_PIN_A4 };

#endif

static string[] sensorIDs = new

string[] { &quot;M1&quot;, &quot;M2&quot;, &quot;M3&quot;, &quot;M4&quot;, &quot;L1&quot;, &quot;T1&quot;, &quot;H1&quot; };

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
</pre>
<p>By default, this is configured for 5 analog sensors, A0 – A4, as well as a DHT22 providing temperature and humidity readings.  You’ll need to modify this to match your own configuration.  Note that, if using a DHT11 or DHT22, the 2 sensor IDs for temperature and humidity should be added to the end of the sensorIDs array.  The tags you use for sensorIDs can be anything you like, but they need to match the sensor IDs in the Python configuration file, SensorRelay.cfg.</p>
<p>Note that the above code uses a different syntax to reference analog pins on a FEZ device as compared to the Netduino.  This difference in syntax applies to the digital pins too.  While the pins might be in the same location on the outside, they map to very different CPU pins internally.</p>
<p>As mentioned earlier, I’ve added support for the <a href="http://www.adafruit.com/products/292">Adafruit i2c/SPI Character LCD backpack</a>.  This required very little code, since the backpack is supported by the <a href="http://microliquidcrystal.codeplex.com/">MicroLiquidCrystal .Net library</a> that I used in the Netduino Plant Light Controller code.</p>
<p>The backpack is enabled by adding MLC_I2C to the compiler flags.</p>
<p>There is only 1 I2C port on the FEZ devices (as with the Netduino), and the .Net Micro Framework is able to figure out which pins the i2c interface uses.  So, the i2c LCD initialization code just passes the number of rows and columns:</p>
<pre>lcd = new clsLCD_MLC(4, 20);</pre>
<p>Beyond that, the LCD interface is identical to the one used by parallel LCDs, as described in earlier articles about the Netduino Plant Light Controller.  One catch, though: I2C is quite slow compared to other LCD interfaces, and if you have multiple threads writing to the LCD, there is a good chance that one will interrupt another in mid-communication, causing the LCD to hang go all garbly.  To prevent this, I use the Monitor method of .Net’s Threading library:</p>
<pre class="brush: csharp; title: ; notranslate">
static string lcdLock = &quot;LockMe!&quot;;

. . .

try
{
	if (blnDisableLCD)
	{
		return;
	}

	// prevent other thread from writing to lcd at same time (mandatory for I2C LCD)
	Monitor.Enter(lcdLock);

	. . .

	for (int i = 0; i &lt;= intLastRow; i++)
	{
		lcd.SelectLine((byte)(i + 1), true);
		lcd.WriteStringToLCD(strLCDBuffer[i]);

	}
finally
{
	Monitor.Exit(lcdLock);
}
</pre>
<p>Support for the DHT11 or DHT22 temperature/humidity sensor is enabled by adding the &#8220;DHT11&#8243; or &#8220;DHT22&#8243; compiler flag.  As mentioned earlier, this makes uses of the FEZ support for native RLP code.  The DHT11/DHT22 code won’t work at all if you’re using a Netduino.</p>
<p>All RLP code is initialized in basically the same way:</p>
<p>-          Call RLP.Enable</p>
<p>-          Call RLP.Unlock, passing it the values that you received in the e-mail.  Just copy and paste the “RLP.Unlock” statement from the e-mail into the code.</p>
<p>-          Load the RLP code (an ELF file) from your projects Resources section</p>
<p>-          Call GetProcedure for each RLP function that you want to call.</p>
<pre class="brush: csharp; title: ; notranslate">

RLP.Enable();

//TODO - If your device isn't already unlocked,
//  you MUST paste YOUR ID and byte array into the code below
//RLP.Unlock();

byte[] elf_file = Resources.GetBytes(Resources.BinaryResources.dht11_rlp);
RLP.LoadELF(elf_file);

RLP.InitializeBSSRegion(elf_file);

ReadDHT = RLP.GetProcedure(elf_file, &quot;ReadDHT&quot;);
DHTSetup = RLP.GetProcedure(elf_file, &quot;Setup&quot;);

// We don't need this anymore
elf_file = null;
Debug.GC(true);
</pre>
<p>If the initialization succeeds, you can then call the DHTSetup function in the RLP code, passing it the pin that the DHT11 or DHT22 is connected to:</p>
<pre class="brush: csharp; title: ; notranslate">

// Call setup function - use Di4 for DHT22
if (DHTSetup != null)
{
	success = DHTSetup.Invoke((int)(FEZ_Pin.Interrupt.Di4));
}
if (success == 0)
{
	Debug_WriteToLCD(&quot;DHT Setup failed!&quot;);
	DHTSetup = null; // disable use of DHT22
}
else
{
	// give DHT time to stabilize
	Thread.Sleep(1000);
}
</pre>
<p>To read the temperature and sensor data, call the ReadDHT function.  It returns a 5-byte array:</p>
<pre>int intResult = ReadDHT.Invoke(bytArray);</pre>
<p>Up to this point, the code used for the DHT11 and DHT22 is 100% identical.  The only difference is how the 5-byte array is processed to extract the temperature and humidity:</p>
<pre class="brush: csharp; title: ; notranslate">

if ((intTotal &amp; 255) == bytArray[4])
{

#if DHT22
	int intValues = 256 * (bytArray[2] &amp; 0x7f) + bytArray[3];
	if ((bytArray[2] &amp; 0x80) != 0)
	{
		intValues *= -1;
	}
	fltTemperature = intValues;
	fltTemperature /= 10;
#endif
#if DHT11
	fltTemperature = bytArray[2];
#endif

	Debug_WriteToLCD(&quot;Temp &quot; + fltTemperature.ToString(&quot;F1&quot;));

#if DHT22
	intValues = 256 * bytArray[0] + bytArray[1];
	fltHumidity = intValues;
	fltHumidity /= 10;
#endif
#if DHT11
	fltHumidity = bytArray[0];
#endif

	Debug_WriteToLCD(&quot;Hum &quot; + fltHumidity.ToString(&quot;F1&quot;));
}
else
{
	Debug_WriteToLCD(&quot;Checksum failed&quot;);
}
</pre>
<h2>Python Code</h2>
<p>The Python code is based on that described in the <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a> article, but with some notable improvements.</p>
<p>I’ve rewritten the logging code to follow proper Python standards.  So, instead of dumping error messages and debug information in the same file that contains the sensor data, I’m using the standard <a href="http://docs.python.org/library/logging.html">Python logging library</a>:</p>
<pre class="brush: python; title: ; notranslate">

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s %(levelname)s %(message)s',

filename='SensorRelayError.log')

log = logging.getLogger()
</pre>
<p>Note that you can change the level of logging, and the log file name, by changing this line of code.  For example, if you wanted to have debug messages sent just to the console, but not the log file, change logging.DEBUG to logging.ERROR.</p>
<p>Exception logging now follows Python standards as well, with the full stack trace being written to the log.  For example:</p>
<pre class="brush: python; title: ; notranslate">

try:

    . . .

except:

    log.exception('Error sending to pachube, datapoint ' + dataPoint)
</pre>
<p>The resulting error message in the log includes all the fixings:</p>
<pre>2011-09-19 17:40:06,180 ERROR Error sending to pachube,
   datapoint PlantLight1
Traceback (most recent call last):
File "SensorRelay.py", line 51, in sendToPachube
pac.put()
File "build/bdist.linux-armv7l/egg/eeml/datastream.py", line 45, in put
conn.request('PUT', self._url, self._eeml.toeeml().toxml(),
   {'X-PachubeApiKey': self._key})
File "/usr/lib/python2.6/httplib.py", line 914, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python2.6/httplib.py", line 951, in _send_request
self.endheaders()
File "/usr/lib/python2.6/httplib.py", line 908, in endheaders
self._send_output()
File "/usr/lib/python2.6/httplib.py", line 780, in _send_output
self.send(msg)
File "/usr/lib/python2.6/httplib.py", line 739, in send
self.connect()
File "/usr/lib/python2.6/httplib.py", line 720, in connect
self.timeout)
File "/usr/lib/python2.6/socket.py", line 547, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):</pre>
<p>The Xbee is no longer being treated as a generic serial interface, as it was in the <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a> article.  Instead, I’m using the<a href="http://code.google.com/p/python-xbee/"> Python XBee library</a>, which reads and writes data using the XBee’s API.</p>
<p>To be honest, there is no great advantage to using the XBee API at this point.  I’ve found it to be quite stable – after the Python code opens the XBee port after startup, the port stays open and keeps working regardless of what’s going on at the sensor end of the connection.  The serial port interface to the XBee was just as stable. However, the API lets me send data to a specific remote sensor device, and lets me know which remote sensor device I’m receiving data from, something which will be necessary later in the project.</p>
<p>The code which communicates with the XBee is similar to the serial interface described in the Show and Tell section of <a href="http://gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Watching the Watcher</a>.  The only significant difference is that I can now define a callback to activated when data is received, rather than having to poll for incoming  data:</p>
<pre class="brush: python; title: ; notranslate">

if XBEEPORT:
    try:
        serXBee = serial.Serial(XBEEPORT, BAUDRATE, timeout=TIMEOUT)
        serXBee.close() # workaround for known problem when running on Windows
        serXBee.open()
        xbee = XBee(serXBee, callback=readXBeeData)
</pre>
<p>The callback function receives a “frame” as its parameter.  To get to the sensor data sent by the FEZ (i.e. the same data that would be received from the XBee when it is used as a serial device), just access the frame.data property.  Note that the frame has a bunch of other potentially useful properties, as shown in the code below.</p>
<pre class="brush: python; title: ; notranslate">

def readXBeeData(frame):
    global buf
    try:
        frame_id = frame['id']
        # source address is 2-bytes binary (e.g. x00x01)
        # this also works: source_addr = struct.unpack('&gt;h', frame['source_addr'])
        source_addr = ord(frame['source_addr'][0]) * 256 + ord(frame['source_addr'][1])
        # rssi (signal strength) is 1-byte binary
        rssi = ord(frame['rssi'])
        data = frame['rf_data']
        if DEBUG:
            print &quot;read_frame, id=&quot;, frame_id, &quot;, source_addr=&quot;, source_addr, &quot;, rssi=&quot;, rssi, &quot;, data=&quot;, data
            log.debug(&quot;read_frame, id=&quot; + str(frame_id) + &quot;, source_addr=&quot; + str(source_addr) + &quot;, rssi=&quot; + str(rssi) + &quot;, data=&quot; + data)
        if frame_id == &quot;rx&quot;:
            processXbeeData(data)
</pre>
<p>When sending data to the FEZ, you need to package the data into a frame.  I found that the syntax for doing this is surprisingly unGooglable: the Python XBee library is more commonly used to send the XBee a command (e.g. set D2 high), not a custom data string.  The trick is to format the data in a “TX” command.  Note that I’m adding an ending null to the data – this makes the Python code compatible with the Netduino Plant Light Controller code used in previous blog posts.</p>
<pre class="brush: python; title: ; notranslate">
        if xbee:
            strData = strPrefix + &quot;:&quot; + strCommand
            # HACK - append null to data to make it look like serial data to the other end
            xbee.send(&quot;tx&quot;, dest_addr = 'x00x01', data=strData + 'x00')
</pre>
<p>When sending data to Pachube from Python, I originally used the <a href="https://github.com/petervizi/python-eeml/">python-eeml library</a>, as described in the <a href="http://gigamegablog.com/2011/03/10/tweet-a-watt-beyond-the-twitter/">Tweet-A-Watt: Beyond the Twitter</a> article.  However, that library still uses the Pachube V1 API, which was limited to numeric datastream IDs.  Since the XML EEML format contains a bunch of optional data that I’m not using, I decided to simplify things and use Python’s standard <a href="http://docs.python.org/library/urllib2.html">urllib2 library</a>instead:</p>
<pre class="brush: python; title: ; notranslate">

        # Note - the following codes uses the V2 Pachube API and CSV data format
        url = 'http://api.pachube.com/v2/feeds/' + siteconfig[&quot;PACHUBE_FEED_ID&quot;]
           + '/datastreams/' + dataPoint + '.csv?_method=put'
        # HACK round to 3 decimal places and drop trailing zeros : technically not needed, but makes Pachube output nicer looking
        data = (&quot;%.3f&quot; % floatValue).rstrip('0').rstrip('.')
        headers = {'X-PachubeApiKey': siteconfig[&quot;PACHUBE_API_KEY&quot;]}
        if DEBUG:
            print url
            print data
            print headers
        req = urllib2.Request(url, data, headers)
        try:
            response = urllib2.urlopen(req)
        except urllib2.HTTPError, e:
            log.exception('Error code ' + e.code + ' sending to pachube, datapoint ' + dataPoint)
            return False
        except urllib2.URLError, e:
            log.exception('Reason code ' + e.reason + ' sending to pachube, datapoint ' + dataPoint)
            return False
</pre>
<p>Note the code adds an  “X-PachubeApiKey” setting to the HTTP header, something that isn&#8217;t well documented for the urllib2 library.</p>
<h2>Wrapping Up</h2>
<p>Whew, another super-sized article.  Believe it or not, it takes even longer to write than it does to read!  The upside is that I’ve had the code running for over a month now, so I can report that the FEZ XBee Sensor is a reliable platform with no[t too many] bugs.</p>
<p>I’m quite impressed with the FEZ Panda.  Its support for native code and for Output Compare (another Arduino feature that isn’t supported by the .Net Micro Framework) opens up a lot of new opportunities. GHI updates the firmware quite frequently – more often than Secret Labs does with Netduino – and I suspect they will be first out of the gate with support for the newly released <a href="http://blogs.msdn.com/b/netmfteam/archive/2011/10/04/version-4-2-rtm.aspx">.Net Micro Framework 4.2</a></p>
<p>Next, though, I’m going to turn my attention to the other end of the data stream, the data repositories.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netduino: Watching the Watcher</title>
		<link>http://www.gigamegablog.com/2011/08/23/netduino-watching-the-watcher/</link>
		<comments>http://www.gigamegablog.com/2011/08/23/netduino-watching-the-watcher/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 22:16:50 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Netduino]]></category>
		<category><![CDATA[nimbits]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=996</guid>
		<description><![CDATA[Note: This article is an installment in a series about building a plant light controller (and beyond) on the Netduino microcontroller platform.  For previous articles in the series, click here.  It’s been a few months now since the Netduino in this &#8230; <a href="http://www.gigamegablog.com/2011/08/23/netduino-watching-the-watcher/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Note: This article is an installment in a series about building a plant light controller (and beyond) on the Netduino microcontroller platform.  For previous articles in the series, click </em><em><a href="http://gigamegablog.com/tag/netduino/">here</a></em><em>.</em></p>
<p> It’s been a few months now since the Netduino in this project, with the help of <a href="http://www.sparkfun.com/products/10097">its Arduino cousin</a>, learned to <a href="http://gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/">measure the temperature and humidity</a> in the room.  It&#8217;s faithfully reporting this data on its LCD… I think.  Who really knows what it&#8217;s doing when I&#8217;m not around?  It might be sleeping, or watching Fox News, or doing God-knows-what with its &#8220;cousin&#8221;.</p>
<p> Clearly, this situation demands a nanny cam.  But my eyes ache at the thought of reviewing hours of footage of an LCD displaying temperature and humidity data (… I think).</p>
<p>Fortunately, now that the Netduino is <a href="http://gigamegablog.com/2011/08/03/netduino-meets-world/">connected to the Internet</a>, we have a better option: online data monitoring.</p>
<h2> The Asocial Network: Rise of the Machines</h2>
<p> You’ve probably read recently of a rising trend, <a href="http://en.wikipedia.org/wiki/Internet_of_Things">The Internet of Things</a>.  It is becoming increasingly easy to hook devices and sensors up to the Internet, where they can report their status, receive instructions, play Farmville, and murder us in our sleep.</p>
<p> The backbone of this system is the online data repository, which records the data and allows you to view the results..  I’ve written before of two of the early entrants in the field, <a href="http://www.pachube.com">Pachube </a>and <a href="http://www.nimbits.com">Nimbits</a>. </p>
<p><a href="http://oreilly.com/catalog/0636920013037"><img class="alignright size-medium wp-image-998" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/iot-194x300.jpg" alt="" width="194" height="300" /></a>In this article, I’ll be connecting the Netduino to Nimbits via a Python middleman.  As explained in <a href="http://gigamegablog.com/2011/08/03/netduino-meets-world/">my last article</a>, I prefer this approach to a common alternative, connecting the Netduino directly to an Ethernet connection.  If you’re interested in trying that approach instead, there’s <a href="http://oreilly.com/catalog/0636920013037">a whole book that shows you how</a>.</p>
<p> Both Pachube and Nimbits use a REST API to receive data from sensors.  In past articles, I showed the Python code I use to <a href="http://gigamegablog.com/2011/03/10/tweet-a-watt-beyond-the-twitter/">send Tweet-A-Watt data to Pachube</a> and <a href="http://gigamegablog.com/2011/03/28/tweet-a-watt-beyond-the-twitter-part-deux/">to Nimbits</a>.  I’m using the same API here.</p>
<p> My article on <a href="http://gigamegablog.com/2011/03/28/tweet-a-watt-beyond-the-twitter-part-deux/">using Tweet-A-Watt with Nimbits </a>also covers the process of creating an account on the Nimbits server, getting an API key, and creating Data Points.  You’ll need to do all these things in order to receive data from the Netduino.  Your Nimbits settings are saved in the Python configuration file, explained below.</p>
<h2>Netduino Configuration</h2>
<p>The Netduino hardware and software is unchanged from the previous stage of the project, <a href="http://gigamegablog.com/2011/08/03/netduino-meets-world/">Netduino Meets World</a>.  You’ll need to have XBees configured at both the Netduino and Python ends of the configuration – details are in <a href="http://gigamegablog.com/2011/08/03/netduino-meets-world/">Netduino Meets World</a>.</p>
<p>Well, actually, you don&#8217;t need XBees if the Netduino is located quite close to the PC that&#8217;s running Python.  This was true for the Netduino Meets World article as well, I just forgot to mention in there.  Since we&#8217;re using the XBees as a generic serial device, a USB connection will also work with no software changes needed.  I have one of my Netduino&#8217;s connected by USB to a Beagleboard XM running Python. </p>
<p>You can&#8217;t use the Netduino&#8217;s USB port for this, but you can connect the pins to TTL-to-USB adapter.  One option is the 3.3V FTDI cable that I described way back in the <a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Netduino: Time and Weather article</a>.  A slightly cheaper option is an FTDI breakout board – I&#8217;m using <a href="http://www.sparkfun.com/products/718 ">this one from Sparkfun</a> and can confirm that it works fine with the code accompanying this article.</p>
<h2>Configuring the Python Interface</h2>
<p>The Python code, TimeRelay.py, builds upon the foundation of the Python program used last time, TimeServer.py.  TimeServer was configured using command line switches – since there are a lot more settings now, I’ve switched to using a configuration file.  You can <a href="http://gigamega-micro.googlecode.com/files/TimeRelay.zip">download the Python code and sample configuration file</a> from <a href="http://code.google.com/p/gigamega-micro/">my Google Code page</a>, here.</p>
<p>The configuration file contains the following settings.   The ones that you have to fill in are marked in italics.</p>
<pre># Configuration file for TimeRelay.py
# SERIALPORT = \.COMxx &lt;-- Windows COM port must be specified in this format
SERIALPORT = /dev/ttyUSB0
LOGFILENAME = TimeRelay.log
DEBUG = True
NIMBITS_SERVER = http://app.nimbits.com
<em>NIMBITS_USERID = </em>
<em>NIMBITS_API_KEY = </em>
NIMBITS_UPDATE_INTERVAL = 300
# Sensor IDs - format is &lt;Netduino Sensor ID&gt; = &lt;Nimbits Data Point ID&gt;[,Nimbits Update Interval in seconds]
H1 = PlantRoomHumidity,1800
T1 = PlantRoomTemperature</pre>
<p>The first 3 settings correspond to the command line parameters in the program’s predecessor, as listed in the last article:</p>
<ul>
<li>SERIALPORT – Specifies the serial port that the XBee is connected to.  Note the unusual format of the serial port name for Windows PCs &#8212; this is required by the <a href="http://pyserial.sourceforge.net/">PySerial</a> library.</li>
<li>LOGFILENAME – The logfile has an expanded role – in addition to any error messages, it also records the data readings received from the Netduino in a comma-delimited format.  You can disable the local logging feature by leaving this setting blank (i.e. deleting “TimeRelay.log” from that line).</li>
<li>DEBUG – Turns on debug messages written to the console.  This is on by default, since it is quite useful for troubleshooting.</li>
</ul>
<p>The Nimbits settings are taken from your Nimbits account:</p>
<ul>
<li>NIMBITS_SERVER -  The default setting, app.nimbits.com, is the public Nimbits server.  If you don’t want to rub shoulders with the unwashed masses, you can setup your own private Nimbits server on Google App Engine – you would then enter your GAE server name here (e.g. whatever.appspot.com).  (Both Nimbits and GAE are free when used for this purpose.  I briefly described the process of setting up a Nimbits server in the “Rolling Your Own” section of <a href="http://gigamegablog.com/2011/03/28/tweet-a-watt-beyond-the-twitter-part-deux/">my Nimbits article</a>)</li>
<li>NIMBITS_USERID – This is the Gmail address you used when creating your Nimbits account.</li>
<li>NIMBITS_API_KEY – This key is e-mailed to you when you click the “Secret Key” toolbar button in your Nimbits server console. </li>
<li>NIMBITS_UPDATE_INTERVAL – This specifies how often Nimbits will be updated with the latest sensor reading.  The default is 300 seconds (i.e. 5 minutes), but you can override this for individual sensors on the sensor lines at the bottom of hte configuration file.  Note that the Netduino will send a new measurement every 60 seconds, regardless of what you configure here – the Python app will  send Nimbits an average of all the readings since the last update.</li>
</ul>
<p>The sensor settings are used to link the sensor IDs hard-coded in the Netduino application with the Data Point Names that you created in Nimbits.  The default settings assume Data Point names of PlantRoomTemperature and PlantRoomHumidity – if you use other names (as you might if you don’t actually have a Plant Room), then fill them in on these lines of the configuration file.</p>
<p>Note that the settings shown above will send a new humidity reading to Nimbits every 30 minutes, while the temperature will be sent using the default interval of 5 minutes.  Feel free to change this depending on how meteorologically active your home is.</p>
<h2>Activate Sensors</h2>
<p>After you’ve finished updating TimeRelay.cfg, run TimeRelay.Py and watch the console.</p>
<p>The program will start by listing the settings it found in the configuration file, then will open the serial port and wait for something to happen.</p>
<p>If a Netduino running the code from the last article is powered on,  and you left the “Debug” setting turned on in the TimeRelay.cfg file, you should see a temperature and humidity reading displayed within a minute.  A message showing the REST API call that sends the data to Nimbits should be displayed in 5 minutes (or whatever interval you used in the TimeRelay.cfg file). </p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/22-08-2011-8-32-54-PM.jpg"><img class="aligncenter size-full wp-image-1001" title="Python console receiving sensor data" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/22-08-2011-8-32-54-PM.jpg" alt="" width="670" height="423" /></a></p>
<p>Switch to your Nimbits web page, double-click on the Data Point in the left hand pane, and the Data Channels pane should update with the newly received value.  </p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/22-08-2011-8-33-38-PM.jpg"><img class="aligncenter size-large wp-image-1002" title="Nimbits Data Points" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/22-08-2011-8-33-38-PM-1024x198.jpg" alt="" width="640" height="123" /></a></p>
<p>There are a bunch of useful settings that you can experiment with in the Data Points dialog.  I use the Idle Alarm setting to tell me when something has gone wrong with Netduino/Python configuration, and the High and Low Value alert to tell me when something has gone terribly wrong with my home.</p>
<p>The Nimbits web page also has some nifty built-in graphing capabilities.  These have recently changed with the release of Nimbits 3.2, and will continue to evolve, so see the <a href="http://www.nimbits.com">Nimbits web page</a> and <a href="http://nimbits.blogspot.com/">Nimbits blog</a> for the latest.</p>
<p>Since I have a fairly large number of data points that I like to glance at from time to time, I wrote <a href="http://www.google.com/ig/directory?type=gadgets&amp;url=www.gigamegablog.com/gadgets/nimbits.xml">a Google Gadget</a> to display line charts in the iGoogle page.  I also wrote <a href="http://gigamegablog.com/2011/05/21/a-nimbits-gadget-minding-the-data-store/">a blog post describing its development</a>.  Check it out and let me know of any new features you’d like to see. (Or feel free to <a href="http://gigamega-micro.googlecode.com/files/Nimbits%20Google%20Gadget.zip">take the code</a> and add the features yourself).</p>
<h2>Programmer’s Show and Tell</h2>
<p>Although the Netduino code isn’t new, I haven’t previously explained in the sensor data handling.</p>
<p>The upload process is run on yet another timer.  This is hardcoded to occur every 60 seconds &#8212; nothing magical about that interval, and it could certainly be changed as needed.</p>
<p>Since we’re using the XBee as a generic serial interface, all the Netduino needs to do is write the data to the serial port.  The sensor ID is hard-coded, and each reading is ended with a CR/LF – a &#8220;crude but effective&#8221; message format. I haven’t noticed any problems with data being garbled or truncated:</p>
<pre class="brush: csharp; title: ; notranslate">

// upload sensor readings once a minute
timerUploadSensors = new Timer(new TimerCallback(uploadSensorData),
 null, 60000, 60000);

. . .
private static void uploadSensorData(object data)
{
 string strReading = &quot;&quot;;
 if (blnHumidityUpdated)
 {
  blnHumidityUpdated = false;
  // make copy of humidity reading, since it
  //    could be overwritten at any time
  strReading += &quot;H1:&quot; + strHumidity + &quot;rn&quot;;
 }
 if (blnTempUpdated)
 {
  blnTempUpdated = false;
  // make copy of temperature reading, since it
  //    could be overwritten at any time
  strReading += &quot;T1:&quot; + strTempDHT11 + &quot;rn&quot;;
 }
 uart.WriteToUART(strReading);
}
</pre>
<p>The Python code is a little more interesting.</p>
<p>First, I&#8217;ve added a workaround for a known problem with the PySerial library when running on Windows.  When PySerial tries to open the COM port it thinks that its already open – the workaround is to always close it before opening it.  Trippy but effective, and the workaround doesn’t cause problems on other OSes:</p>
<pre class="brush: python; title: ; notranslate">
ser = serial.Serial(SERIALPORT, BAUDRATE, timeout=TIMEOUT)
ser.close() # workaround for known problem when running on Windows
ser.open()
</pre>
<p>The code which reads TimeRelay.cfg demonstrates some of Python’s file- and string-handling power.  Five lines of code is all that is required to open a file, read its contents, parse the lines, and store them in a dictionary. </p>
<pre class="brush: python; title: ; notranslate">

def readConfigFile():

    #global config

    for line in open(CONFIGFILE):

        if line.strip()[0] != &quot;#&quot;: # skip comment lines

            parts = line.split(&quot;=&quot;, 1)

            if len(parts) == 2:

                config[parts[0].strip()] = parts[1].strip()
</pre>
<p>The sensor readings received from the Netduino are stored in a dictionary.  The key is the sensor ID (e.g. “T1”) and the value is a List with format:</p>
<pre>&lt;# of readings since last upload&gt;,
&lt;total of readings since last update&gt;,
&lt;date/time of last upload&gt; </pre>
<p>Python dictionaries are cool because they can store any object as their value, and the object type can be different for different entries in the same dictionary.  Less cool is the fact that Python throws an exception if you try to read a dictionary key that doesn’t exist yet, so be sure to check to see if an earlier reading is already stored there.</p>
<p>&nbsp;</p>
<pre class="brush: python; title: ; notranslate"> 
# add this reading to the sensor's list
if sensor in sensorValues:
    sensorValues[sensor][0] = sensorValues[sensor][0] + 1
    sensorValues[sensor][1] = sensorValues[sensor][1] + float_value
    if DEBUG:
        print &quot;found sensorValue&quot;, sensor, sensorValues[sensor]           
else:           
    sensorValues[sensor] = [1, float_value, datetime.datetime.now()]
    if DEBUG:
        print &quot;adding new sensorValue&quot;, sensor, sensorValues[sensor] 
</pre>
<p>Note that Python isn&#8217;t too picky about variable types except when it is.  If &#8220;<em>sensorValues[sensor][1]</em> &#8221;or &#8220;<em>float_value&#8221;</em> weren&#8217;t both floating point values, an Exception would be thrown when they are added together.</p>
<p>The code that sends the data to Nimbits uses the <a href="http://code.google.com/p/nimbits-server/wiki/CurrentValueService">CurrentValue REST API</a>.  This API has a dual role of writing new values and reading the most recent value, but we’re only using it to write data here.</p>
<p>The code starts out with a hack, to round the value to 3 decimal places before sending it. This is done for purely asthetic reasons, so that the readings displayed in the Nimbits web page look nice and tidy.  I call it a hack because rounding a number shouldn’t require this degree of string manipulation.  (Note to Pythonistas: I’m criticizing my code, not your language. Peace out.)</p>
<pre class="brush: python; title: ; notranslate"> 
# HACK round to 3 decimal places and drop trailing zeros
#  - technically not needed, but makes Nimbits output nicer looking
stringValue = (&quot;%.3f&quot; % value).rstrip('0').rstrip('.') 

try:
    LogMsg(dataPoint + &quot;,&quot; + stringValue)
    url = (NIMBITS_SERVER + &quot;/service/currentvalue?value=&quot; +
        stringValue + &quot;&amp;point=&quot; + dataPoint.replace(&quot; &quot;, &quot;+&quot;) +
   &quot;&amp;email=&quot; + NIMBITS_USERID +
        &quot;&amp;secret=&quot; + NIMBITS_API_KEY)

    urllib.urlopen(url)
    return True
except IOError:
    print 'Error sending to nimbits'
    print sys.exc_info()[0]
</pre>
<p>The REST API call is a 2-liner, another example of Python’s power and simplicity compared to .Net.  (Note to Microsoft Fanboys: I’m on your side. Peace out.)  The only trick is to replace spaces in the Data Point name with plus signs, this being a URL and all.</p>
<p>Note that it isn’t necessary to send a timestamp with the data – the CurrentValue API assumes the value has a current timestamp unless otherwise specified.  Good thing, that, since working with time zones in Python can be a nightmare.  (Note to Pythonistas: yeah, now I’m criticizing your language).</p>
<p>Unfortunately the Nimbits CurrentValue API doesn’t return a value to indicate whether the API call was successful, so the Python code won’t write an error message to the console or log file if something goes wrong.  My first indication that something is wrong is generally when Nimbits&#8217; &#8220;Idle Alarm&#8221; sends me an e-mail.</p>
<h2> Wrapping Up</h2>
<p>The Netduino project has admittedly become quite unwieldy, with each stage heaping on more hardware and/or software to the previous stage.    It&#8217;s unlikely that anyone but me has all of the Netduino hardware add-ons needed to make use of all the software&#8217;s features.</p>
<p>In the next article in the series, I&#8217;m going to switch to a slimmed-down Netduino software image for a sensor node, that consists of only a Netduino, an XBee, and a few new analog sensors.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/08/23/netduino-watching-the-watcher/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Netduino Meets World</title>
		<link>http://www.gigamegablog.com/2011/08/03/netduino-meets-world/</link>
		<comments>http://www.gigamegablog.com/2011/08/03/netduino-meets-world/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 00:09:09 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Beagleboard]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Netduino]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=920</guid>
		<description><![CDATA[[Updated August 6: Added a couple of tips to the section on using minicom to configure the XBee.] [Updated August 7: Added "Windows Weirdness" section with workarounds for problems with pySerial on Windows] Note: This article is an installment in &#8230; <a href="http://www.gigamegablog.com/2011/08/03/netduino-meets-world/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>[Updated August 6: Added a couple of tips to the section on using minicom to configure the XBee.]</em></p>
<p><em>[Updated August 7: Added "Windows Weirdness" section with workarounds for problems with pySerial on Windows]</em></p>
<p><strong>Note</strong>: <em>This article is an installment in a series about building a plant light controller (and beyond) on the Netduino microcontroller platform. For previous articles in the series, click <a href="http://gigamegablog.com/tag/netduino/">here</a>.</em></p>
<p>When <a href="http://gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/">last we saw it</a>, the Netduino project was a pretty smart plant light controller but a pretty dumb clock. The main problem is that it can&#8217;t figure out the time on its own – when it&#8217;s powered on I have to manually set the time using its menu.</p>
<p>C&#8217;mon, Netduino, you don&#8217;t need me for that! Haven&#8217;t you heard of the Internet?</p>
<h2>An Inconvenient Truth</h2>
<div class="img alignright size-full wp-image-924" style="width:348px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/07/Al-Gore.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/07/Al-Gore.jpg" alt="Give a hoot, don't compute!" width="348" height="480" /></a>
	<div>Give a hoot, don't compute!</div>
</div>As you probably know, it is quite possible to use a <a href="http://www.netduino.com/netduinoplus/specs.htm">Netduino Plus</a>, or a regular Netduino with an <a href="http://www.arduino.cc/en/Main/ArduinoEthernetShield">Ethernet shield</a>, to connect a Netduino directly to the Internet. In fact, O&#8217;Reilly recently published <a href="http://oreilly.com/catalog/0636920013037">a book starring the Netduino Plus</a> which shows you how to do that.</p>
<p>Instead of Ethernet, I decided to use an <a href="http://www.sparkfun.com/products/8664">Xbee Series 1</a> connection to a PC acting as an intermediary, partly because I already had that configuration in place to support <a href="http://gigamegablog.com/tag/tweet-a-watt/">Tweet-A-Watt monitoring</a>, but also because of certain advantages:</p>
<ul>
<li>Wired Ethernet connections aren&#8217;t practical for most parts of the home</li>
<li>XBee is cheaper than Wi-Fi, especially if you plan to use multiple Netduinos in various parts of the home (which we will, once we add sensor monitoring to the mix)</li>
<li>The Netduino is a relatively constrained development platform compared to a PC. So, it helps to limit the Netduino&#8217;s role to what&#8217;s required on the &#8220;front lines&#8221;, and have much of the code running on a PC acting as &#8220;command and control&#8221;. This, too, will become a bigger advantage when there are multiple Netduinos involved.</li>
</ul>
<p>The big downside to this approach is that you&#8217;re leaving a PC powered on 24/7. That adds up to a lot of wasted electricity, considering how low its workload is going to be. Dedicating a 120W+ PC to this project is absurdly excessive – do you really want to make Al Gore cry?  (Well, yeah, me too &#8211; but you know what I mean.)</p>
<p>Fortunately, there are an increasing number of ultra low power devices that are capable of acting as the PC for this purpose. As long as it has a USB port, an Internet connection and can run Python, then it&#8217;s good to go.</p>
<p>I&#8217;ve <a href="http://gigamegablog.com/tag/beagleboard/">written about the Beagleboard</a> in the past. When running Linux and the Python script in this project, a Beagleboard XM uses about 3W (as measured by a Kill-A-Watt meter).</p>
<p>By comparison, my “energy efficient” 2 year old Windows PC averages about 120W. My older PC averages about 200W. Considering that it&#8217;s able to serve as a full-fledged home server, the Beagleboard is incredible, and hopefully an indication of the future direction of home PCs.</p>
<p>Incidentally, the Netduino/Arduino/LCD combination used in this project burns well less than 1W, so using *duinos in your home projects is definitely an energy-friendly alternative.</p>
<div class="img alignleft size-full wp-image-925" style="width:338px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/07/tonido_plug.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/07/tonido_plug.png" alt="TonidoPlug Computer" width="338" height="374" /></a>
	<div>TonidoPlug Computer</div>
</div>A less expensive option, and the one that I&#8217;m using in this project, is the $99 <a href="http://www.tonidoplug.com/">TonidoPlug</a>. It comes with Ubuntu already installed, and a built-in Ethernet and USB Port. You can connect the XBee to the USB port directly if you want, and that will work fine for the purposes of this project.  However, if you want to run the <a href="http://www.tonido.com/software_what.html">Tonido software</a> then you&#8217;ll need a powered USB hub &#8212; the Tonido software requires a USB drive, and there&#8217;s only the 1 built-in port.</p>
<p>Like the Beagleboards I&#8217;ve found the TonidoPlug to be very reliable device, and it&#8217;s just as power efficient. It&#8217;s not easy to upgrade or replace the OS, but the built-in version of Ubuntu is more than adequate for the projects I have in mind.</p>
<p>If you decide to go with a Beagleboard, one of my past articles covers <a href="http://gigamegablog.com/2010/12/09/beagleboard-xm-and-angstrom-getting-the-big-dog-to-run-at-full-speed/">installing Angstrom and Python</a>, and <a href="http://elinux.org/BeagleBoardUbuntu">this eLinux page</a> is gospel if you&#8217;re installing Ubuntu.</p>
<p>As for the TonidoPlug, it comes with Ubuntu 9.04 (Jaunty Jack), Python 2.5, and <a href="http://www.tonidouser.com/doku.php?id=advanceduses:sshconnection">an SSH Server</a> out of the box. All you need to add for this project is the Python serial library and the GNU Screen utility for running the Python app in a background terminal session.</p>
<p>To install them, login as root through SSH, create then directory used by the apt package manager, then install a couple of packages:</p>
<pre>mkdir -p /var/cache/apt/archives/partial
apt-get update
apt-get install python-serial
apt-get install screen</pre>
<h2>Connecting an XBee to a PC</h2>
<p>Point-to-point communication ain&#8217;t no fun with just one point, so we&#8217;ll need to connect an XBee to both the PC and the Netduino.</p>
<p>At the PC end, whether you use a Beagleboard, TonidoPlug, or a full PC, you’ll need a USB adapter for the XBee.</p>
<p>There are many options out there. I’m using an <a href="http://www.adafruit.com/products/126">Adafruit XBee Adapter</a> and a <a href="https://www.adafruit.com/products/70&amp;zenid=cb83305a8ddc86cfc4cd5cada37938df">USB TTL-232 cable</a>. However, unless you happen to have a spare cable this is a relatively expensive option, since the adapter costs $10 and the cable costs $20. Other options that I’ve used are the $20 <a href="http://www.adafruit.com/products/247">Parallax XBee Adapter</a>, and SeeedStudio’s versatile $20 <a href="http://www.seeedstudio.com/depot/uartsbee-v31-p-688.html?cPath=109">UartSBee</a>.</p>
<p>Before connecting the XBee to the Netduino, you should configure the 2 XBees so that they will talk to one another.</p>
<p>By default, the XBee adapters are all configured as adapter 0 in PAN (network ID) 3332, and they&#8217;ll send their data to other adapter 0s. While this works fine if one XBee only sends, and the other XBee only receives, we&#8217;ll soon have the Netduino and PC chatting merrily away to one another. So, you should assign one of the XBees to have a different adapter ID (number 1 works fine), then set the other XBee&#8217;s destination address to be that same ID.</p>
<p>This <a href="http://www.ladyada.net/make/xbee/configure.html">page at Adafruit</a> covers the 2 options for configuring an XBee: the Windows-only X-CTU program, and entering AT commands from a serial terminal.</p>
<p>Whichever configuration method you use, you need to change the &#8220;MY&#8221; setting on the first XBee to 1, and the the &#8220;DL&#8221; setting on the other XBee to 1.  That&#8217;s it: the other defaults are fine.</p>
<p>I&#8217;d recommend using the X-CTU program if you&#8217;re getting started with XBees: it&#8217;s much more user friendly and foolproof than a serial terminal.   While you are in there, you should update the firmware of the XBees, something you can&#8217;t do from a serial terminal.</p>
<p>If you&#8217;re hardcore about using a TonidoPlug or Beagleboard as a PC, or want to avoid running X-CTU for other reasons, than a serial terminal is the way to go.</p>
<p>Personally, I&#8217;ve used minicom on a Beagleboard and TonidoPlug for this. In order to talk to the XBee you&#8217;ll need to run minicom as root and change some of the default settings. Connect an XBee in its adapter to the USB port, then:</p>
<ol>
<li>At the Linux command line, enter &#8220;minicom -s&#8221;.  If you plan to save your settings in a profile (a good idea), you should run as root: &#8220;sudo minicom -s&#8221;</li>
<li>Select &#8220;Serial port setup&#8221;</li>
<li>The serial port settings should be as shown in the screenshot below.  Press &#8220;E&#8221; to change the Bps to 9600, and press &#8220;F&#8221; to set Hardware Flow Control to &#8220;No&#8221;.  You might also need to change the Serial Device setting: its generally &#8220;/dev/ttyUSB0&#8243;, but if you have other USB devices connected: it might be /dev/ttyUSB1 or /dev/ttyUSB2, etc.</li>
<li>Press Enter to return to the minicom configuration menu, then select &#8220;Screen and keyboard&#8221;</li>
<li>Press &#8220;P&#8221; to turn on the Add Linefeed feature, and press &#8220;Q&#8221; to turn on Local Echo.</li>
<li>Press Enter to return to the configuration menu again.  To save these settings, choose one of the &#8220;Save setup&#8221; options.  To display the serial terminal,  select &#8220;Exit&#8221;.</li>
<li>The XBee is initially ready to receive and send data.  You&#8217;ll need to put it in command mode instead.  To enter command mode, press the &#8220;+&#8221; key 3 times (i.e. +++) but <em>don&#8217;t</em> press Enter.  The XBee should display OK.</li>
</ol>
<p style="text-align: center;"><div class="img aligncenter size-full wp-image-934" style="width:636px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/minicom.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/08/minicom.jpg" alt="Minicom settings for XBee configuration" width="636" height="302" /></a>
	<div>Minicom settings for XBee configuration</div>
</div>
<p>The correct terminal commands for the first XBee are:</p>
<pre>+++
ATMY 1
ATWR</pre>
<p>And for the second XBee</p>
<pre>+++
ATDL 1
ATWR</pre>
<p>The XBee should send back &#8220;OK&#8221; after each command.</p>
<p>If you aren&#8217;t able to see what you are typing, try turning on Local Echo again: press Ctrl-A then Z to display the menu, then press E.</p>
<p>Note that the XBee will automatically (and silently) exit configuration mode if you wait too long between commands, so if you aren&#8217;t getting the OK after an AT command, try entering +++ again.</p>
<h2>Connecting an XBee to a Netduino</h2>
<p>The hardware connection to the Netduino is relatively simple, because the Netduino uses the same 3.3V voltage level as the XBee and the Netduino’s serial pins talk the same language as the XBee.</p>
<p>The only complication is that the XBee uses an usually tight spacing for its pins, just 2mm apart.  This makes it difficult to connect jumper cables to the pins, and impossible to plug the XBee into a breadboard.  Most people use a breakout board to solve this problem, such as Sparkfun&#8217;s <a href="http://www.sparkfun.com/products/8276">XBee Breakout Board</a> or Adafruit&#8217;s <a href="http://www.adafruit.com/products/127">XBee Adapter PCB</a> (which is the PCB used in their Adapter Kit – it functions well as a breakout board).</p>
<p>As shown in the photo below, I plugged the XBee into a small breadboard using an Adafruit XBee Adapter.  This makes it easy to share the Netduino&#8217;s 3.3V pin with other devices besides the XBee, and it allows you to connect an LED to some of the XBee&#8217;s pins for troubleshooting:</p>
<table border="0">
<tbody>
<tr>
<th style="border-color: #000000;">XBee Pin</th>
<th>Connection</th>
</tr>
<tr>
<td>1</td>
<td>3.3V</td>
</tr>
<tr>
<td>2</td>
<td>Netduino RX (e.g D0)</td>
</tr>
<tr>
<td>3</td>
<td>Netduino TX (e.g. D1)</td>
</tr>
<tr>
<td>6</td>
<td>LED (lit when receiving, optional)</td>
</tr>
<tr>
<td>10</td>
<td>Ground</td>
</tr>
</tbody>
</table>
<p style="text-align: center;"><div class="img aligncenter size-full wp-image-927" style="width:368px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/07/XBee-Full.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/07/XBee-Small.jpg" alt="XBee To Netduino Connections" width="368" height="336" /></a>
	<div>XBee To Netduino Connections</div>
</div>
<h2>Running the Python Software</h2>
<p>Once the hardware is in place, the next step is to start the Python software running.</p>
<p>You&#8217;ll need to have pySerial installed.  If you followed my instructions for configuring <a href="http://gigamegablog.com/2010/12/09/beagleboard-xm-and-angstrom-getting-the-big-dog-to-run-at-full-speed/">Angstrom Linux on a Beagleboard</a>, or configuring Ubuntu on a TonidoPlug (earlier in this article), then you&#8217;re all set.  Otherwise, see the <a href="http://pyserial.sourceforge.net/pyserial.html#installation">install instructions on the pySerial pag</a>e.</p>
<p><a href="http://code.google.com/p/gigamega-micro/downloads/detail?name=TimeServer.py">Download the Python code</a> from my Google Code project. Save the file to any folder on the host PC – if you are using a TonidoPlug or Beagleboard running Linux, then your home folder is fine.</p>
<p>If you are using Linux, you&#8217;ll probably need to run the Python code as root in order to access the serial port:</p>
<p>i.e.</p>
<pre>sudo python TimeServer.py</pre>
<p>The command line parameters for the program are all optional:</p>
<pre>TimeServer.py [-nl] [-d] [-port xxxx]</pre>
<ul>
<li>-nl &#8211; turns off logging.  Otherwise, any errors will be written to the current directory in a file named controller.txt.  Hopefully this file won&#8217;t get large, but turning off logging is necessary if you are running the code from a read-only directory.</li>
<li>-d &#8211; turns on debug messages written to the console.</li>
<li>-port &#8211; specifies the serial port that the XBee is connected to.  The default is /dev/ttyUSB0. On a TonidoPlug or Beagleboard, that should be the right port. On a Windows PC, the port will have a totally different name, such as COM3 – check Device Manager if you don&#8217;t know which one to use.  If you are using Windows, see the &#8220;Windows Weirdness&#8221; section below.</li>
</ul>
<p>If you launch the program when connecting through SSH, you should first use the <a href="http://www.gnu.org/s/screen/">GNU Screen</a> utility to open a virtual command prompt, and run the program from there. Otherwise, the program will stop running when you disconnect from SSH.</p>
<p>To run screen, just type &#8220;screen&#8221;. You&#8217;ll be brought to a new command prompt, at which you run TimeServer.py as above.</p>
<p>When TimeRelay is up and running, you can disconnect from your screen session by pressing CTRL-A, then D.  This leaves the Python code running in the background.   To reconnect to the screen session, enter<em> screen –r –d</em>.</p>
<p>GNU Screen is handy for running a background process like this because you can reconnect at any time, from any place, and run <em>screen –r –d</em> to see the current output from the TimeServer.py program.  This is really helpful for debugging, and for restarting the Python code if (heaven forbid!) it should start misbehaving.</p>
<h3>Windows Weirdness</h3>
<p>Running the Python code on Windows presents a couple of other complications, besides that whole &#8220;global warming melting glaciers&#8221; thing.</p>
<p>If Python throws an &#8220;The system cannot find the file specified&#8221; Exception when it tries to open the serial port, you may have run into the <a href="http://stackoverflow.com/questions/2063257/trying-to-open-a-serial-port-with-pyserial-on-winxp-access-denied">problem described on StackOverflow here</a>. Try specifying the COM port as &#8221;\.COMxx&#8221;</p>
<p>e.g.</p>
<pre>-port \.COM10</pre>
<p>Hey, don&#8217;t ask me &#8212; try it.</p>
<p>Also, opening a serial port sometimes results in an &#8220;Access denied&#8221; exception on Windows if you don&#8217;t close it <em>before</em> opening it.  Like I said, don&#8217;t ask me.  Since closing the serial port before opening it doesn&#8217;t seem to cause any problems, I&#8217;ve updated <a href="http://code.google.com/p/gigamega-micro/downloads/detail?name=TimeServer.py">the Python code</a> with this fix.</p>
<h2>Running the Netduino Code</h2>
<p>You can get the Netduino code in one of 2 ways:</p>
<ol>
<li>If you are familiar with Subversion, you use any SVN client(my favorite is <a href="http://tortoisesvn.net/">TortoiseSVN</a>) to get a copy of all the project files.  The SVN URL is <a href="https://gigamega-micro.googlecode.com/svn/trunk">https://gigamega-micro.googlecode.com/svn/trunk</a>. If you want the older version of the code to match one of the past articles, get the corresponding revision. (See the revision list <a href="http://code.google.com/p/gigamega-micro/source/list">here</a>)</li>
<li>Or, download the good old .zip file from the Downloads section of the Google Code project. <a href="http://code.google.com/p/gigamega-micro/downloads/detail?name=GMM_NetduinoMeetsWorld.zip">Here is a direct link to the code for this article</a>.</li>
</ol>
<p>If the Python program is running, then you&#8217;ll know within a minute of powering on the Netduino whether everything is working correctly: the date and time will automatically be set correctly via the XBee connection. Tah-dah!</p>
<p>OK, OK, maybe that wasn&#8217;t worth a Tah-dah.  But, that&#8217;s not all: the LED you connected to the XBee&#8217;s receive pin will light up once a minute. Tah-dah!</p>
<p>Hmm, tough audience.</p>
<p>About the only other change to the Netduino software this time is that I finally added a Daylight Savings Time setting to the Netduino&#8217;s menu: you can turn DST off or on in the &#8220;Date&#8221; menu. (Tah-dah!) This is used when calculating the &#8220;Sun Up&#8221; and &#8220;Sun Down&#8221; times, if you are basing the plant light timer on those times. Purists will point out that an Internet-connected Netduino shouldn&#8217;t have to rely on a manual setting to know when DST is in effect, but we&#8217;ll ignore those purists for now.</p>
<h2>Programmer&#8217;s Show and Tell</h2>
<p>The Python code is admittedly very simple: all the better to learn Python programming from, right?</p>
<p>The XBee&#8217;s serial port connection is opened during startup. If the connection can&#8217;t be opened, the program will display an error message and terminate by calling the Python sys.exit function. If you had some problems getting the serial port working earlier, you&#8217;re no doubt well acquainted with this error message.</p>
<pre class="brush: python; title: ; notranslate">
try:
    ser = serial.Serial(SERIALPORT, BAUDRATE, timeout=TIMEOUT)
    ser.close() # workaround for known problem when running on Windows
    ser.open()
except:
    print &quot;Unable to open serial port &quot;, SERIALPORT, &quot;. See ya.&quot;
    sys.exit(1)
</pre>
<p>The main loop checks whether the time has changed (just the minute, actually – we&#8217;ll let the Netduino handle the seconds). If it has, it calls the sendDateTime() function. It then sleeps for awhile before repeating the loop.</p>
<pre class="brush: python; title: ; notranslate">
def displayTime():
    lastMin = -1
    while 1==1:
        try:
            currTime = datetime.datetime.now()
            if DEBUG:
                print &quot;in displayTime, currTime = &quot; + currTime.strftime(&quot;%Y-%m-%d %H:%M:%S&quot;)
            currMin = currTime.minute
            if lastMin != currMin:
                lastMin = currMin
                sendDateTime()
            time.sleep(15);
        except Exception:
            LogMsg(&quot;Error in displayTime&quot;)
            print sys.exc_info()[0]
</pre>
<p>Note that that the Exception handler is different from the one used when opening the serial port: it logs the error, displays some information about the error to the console (using the Python <a href="http://docs.python.org/library/sys.html#sys.exc_info">sys.exc_info</a> function), then optimistically keeps going. If there was no Exception handler, any exception in this loop, or in the functions called by this loop, would cause the application to terminate.</p>
<p>This &#8220;log it and keep going&#8221; approach is generally frowned upon in software design, but I&#8217;d recommend it for a simple program like this that runs in the background.  You should find that this application, and Python code that communicates via XBee in general, is very low maintenance: you can just start it, then forget about it.  You can occasionally check on the code using GNU Screen or by looking at the contents of the controller.txt error log.</p>
<p>The sendDateTime function just converts the date and time to the format that the Netduino is expecting it, then writes it to the serial port. Note that the &#8220;ser.flush()&#8221; function is used to make sure that the data is sent right away rather than being buffered &#8211; this is literally time-sensitive data.</p>
<pre class="brush: python; title: ; notranslate">
def sendCommand(strPrefix, strCommand):
    if ser:
        ser.write(strPrefix + &quot;:&quot; + strCommand + chr(0))
        ser.flush()

def sendDateTime():
    timeStr = time.strftime(&quot;%Y-%m-%d %H:%M&quot;)
    sendCommand(&quot;D&quot;, timeStr)
</pre>
<p>On the Netduino side, surprisingly little new code is required to talk to the XBee. We&#8217;re using the XBee as a serial port device, rather than making use of the XBee&#8217;s API (a more versatile option that I might explore in a future article). From the Netduino&#8217;s perspective, the XBee might be some guy sitting at a serial terminal, occasionally typing in a&#8221;set time&#8221; command. We’ve already implemented that support, back in the &#8220;<a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Netduino: Time and Weather</a>&#8221; article .</p>
<p>The XBee connection is opened during startup, using almost the exact same code as was used to open a serial connection to a PC terminal:</p>
<pre class="brush: csharp; title: ; notranslate">
// last parm should be true for UART terminal (to send
//   user confirmation), but false for UART XBee
uart = new clsUART(strUARTPort, 9600, 512, false);
</pre>
<p>The event handler is the same one that was used for the PC terminal: the event is raised when our generic serial port class, <em>clsUART</em>, receives some data. In fact, if you&#8217;re using the <a href="http://www.sparkfun.com/products/10097">SparkFun Serial LCD Kit</a>, this event handler is still used when the Netduino receives data from the Arduino, as explained in the &#8220;<a href="http://gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/">A Little Help From Its Friends</a>&#8221; article .</p>
<p>Sharing a serial command event handler between Arduino and the XBee works well, and is easy to implement in .Net. The Netduino doesn&#8217;t know, or need to know, who&#8217;s sending the command, and the .Net Micro framework ensures there isn&#8217;t any conflict between the 2 serial ports.</p>
<p>The only thing that&#8217;s changed here is that the XBee sends the date and time together in the same command:</p>
<pre>D: 2011-07-25 18:01</pre>
<p>So, I modified <em>clsUART</em> to check to see if the string is in this format, and it raises both a &#8220;date set&#8221; and &#8220;time set&#8221; event if it is.</p>
<pre class="brush: csharp; title: ; notranslate">
if (strDateParts.Length == 5)
{
    intHours = Int32.Parse(strDateParts[3]);
    intMinutes = Int32.Parse(strDateParts[4]);
    intSeconds = 0;
    blnTimeSet = true;
}
...
// tell rest of application that the date has been set
raiseCommand(strCommand);
if (blnTimeSet)
{
    // raise the time event too
    raiseCommand(&quot;T:&quot; + Program.Int_ToZeroPrefixedString(intHours, 2) + &quot;:&quot; + Program.Int_ToZeroPrefixedString(intMinutes, 2));
}
</pre>
<p>The event handler already knew how to handle date changes and time changes, so no code change was required there.</p>
<p>The only other significant change was modifying the menu to add a &#8220;Daylight Savings Time&#8221; switch. Since the menu code was designed to be easily extended – as explained in the <a href="http://gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/">Ordering Off the Menu</a> article  &#8211; this required just 1 new line to the strMenuItems array:</p>
<pre class="brush: csharp; title: ; notranslate">
&quot;2-1&quot;, &quot;Hour `HH`&quot;, &quot;_UD-`HH`&quot;,
&quot;2-1&quot;, &quot;Min `mm`&quot;, &quot;_UD-`mm`&quot;,
&quot;2-1&quot;, &quot;DST `DS`&quot;, &quot;_DST&quot;, // NEW - Daylight Savings Time setting
</pre>
<p>The format looks rather cryptic, but it will make more sense if you read the &#8220;Programmer Show and Tell&#8221; section of <a href="http://gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/">Ordering Off the Menu</a>.</p>
<p>The code in clsLCDMenu passes the &#8220;`DS`&#8221; keyword to its callback method for getting the current DST setting, and it passes the &#8220;_DST&#8221; keyword to the callback method for handling a new setting entered by the user.</p>
<p>For example, the code added to the setValueFromMenu() callback method for the &#8220;_DST&#8221; keyword is:</p>
<pre class="brush: csharp; title: ; notranslate">
else if (menuCode == &quot;_DST&quot;)
{
    // toggle DST
    blnUseDaylightSavingsTime = !blnUseDaylightSavingsTime;
    calculateSunriseAndSunset(DateTime.Now);
    if (blnUseDaylightSavingsTime)
    {
        SaveSettingToEEPROM(ADDR_DST, 2);
    }
    else
    {
        SaveSettingToEEPROM(ADDR_DST, 1);
    }
}
</pre>
<p>This recalculates the Sunrise and Sunset times (and updates the plant light timers if they are based on these times), then passes the new setting to the Arduino in the Sparkfun LCD Kit to save it to EEPROM.</p>
<p>I love it when a plan comes together!</p>
<h2>Wrapping Up</h2>
<p>I&#8217;ve found the XBee to be a very dependable add-on to the Netduino. I actually wrote the code used in this article back in May and have been running it continuously since then, and I&#8217;ve yet to have any cases where the XBee connection permanently drops or stops responding. In my experience, this is a big advantage over using an Ethernet connection – when the Netduino&#8217;s Ethernet connection drops it tends to stay down.</p>
<p>So, if the Xbee&#8217;s so great, why am I using it only to set the time?</p>
<p>Good question.</p>
<p>If you browse through the main Program.cs class in the source code, you&#8217;ll notice a new method called uploadSensorData, that I didn&#8217;t address in this article.</p>
<p>Stay tuned for the next step in the project, in which the Netduino talks back, and I draw together a couple of previously separate topics in my blog: the Netduino and <a href="http://www.nimbits.com">Nimbits</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/08/03/netduino-meets-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netduino: A Little Help From Its Friends</title>
		<link>http://www.gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/</link>
		<comments>http://www.gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 17:52:02 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=824</guid>
		<description><![CDATA[Note: This article is an installment in a series about building a plant light controller (and beyond) on the Netduino microcontroller platform.  For previous articles in the series, click here. If you’ve made the switch to programming with .Net Micro &#8230; <a href="http://www.gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Note: This article is an installment in a series about building a plant light controller (and beyond) on the Netduino microcontroller platform.  For previous articles in the series, click <a href="http://gigamegablog.com/tag/netduino/">here</a>.</em></p>
<p>If you’ve made the switch to programming with .Net Micro Framework devices like the <a href="http://www.netduino.com">Netduino</a> and <a href="http://www.ghielectronics.com/catalog/product/256">GHI Panda</a>, you inevitably find yourself asking the question: “What the heck do I do with all my Arduinos?”  They have a minimalistic IDE and no debugger to speak of.  They make lousy cat toys and anniversary gifts. (Unless you&#8217;re receiving one, that is.)  Who needs them?</p>
<p>Well, actually, you do. You might think that .Net’s “managed code” runtime environment is there to usher your program past the hardware, but it’s more like a bouncer protecting the hardware from your crummy code.   It’s great that your code can’t mess with the hardware, unless you intentionally <em>want</em> to mess with the hardware.</p>
<p>I ran into this problem when trying to upgrade the Light Controller’s analog temperature sensor with a digital “one-wire” sensor.  These types of temperature sensors have become quite common, and are generally much more accurate than analog sensors. While the Netduino’s firmware doesn’t officially support the one-wire standard yet (as of Version 4.1.0 Update 6), it is available in the GHI firmware, and I was planning to incorporate it into a Panda version of the Light Controller.</p>
<p>Unfortunately, not all “one wire” temperature sensors are created equally, and the one I have doesn’t follow the Dallas Semicondutors / Maxim <a href="http://en.wikipedia.org/wiki/1-Wire">1-wire standard</a>. It’s a <a href="http://www.seeedstudio.com/depot/electronic-brick-indoor-temp-humidity-sensor-p-683.html">Seeed Studios Temperature and Humidity Brick</a> (now replaced by a <a href="http://www.seeedstudio.com/depot/twig-temphumi-sensor-p-745.html?cPath=144_147">Twig version</a>) , both based on the DHT11/AM2302 chipset.</p>
<p>The interface to this standard is well documented (<a href="http://sheepdogguides.com/arduino/ar3ne1humDHT11.htm">quite enthusiastically documented, in fact</a>).  As demonstrated in the Arduino sample code, communicating with the chipset requires toggling a pin high-and-low at specific sequence of microseconds.</p>
<p>That’s microseconds, not milliseconds.  .Net MF doesn’t let you send signals at the microsecond level.  That’s dangerous, son.  Might shoot your eye out.</p>
<p>Wouldn’t it be nice if we could combine the productivity of managed C# code with the versatility of the Arduino’s AVR-C code library? Mush them together somehow, with solder and duct tape.  Hmmm…</p>
<p>Sadly, I happened to be out of duct tape, so I turned my attention to a <a href="http://www.sparkfun.com/products/10097">Serial Enabled LCD Kit</a> that I had recently bought from Sparkfun.  I was looking to replace the parallel LCD that comes with the <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=138">Seeed Grove Starter Bundle</a> with a serial LCD to free up some pins.</p>
<p>I hadn’t considered the upgradable firmware on this model as a big benefit – there isn’t much that you can do with an LCD beyond the basic set of commands that all serial LCDs support.  The kit actually incorporates an ATMega328 with the Arduino bootloader &#8212; a full Arduino, essentially.  The Arduino code reads the occasional LCD update command and passes it along to the LCD.  Between LCD updates, it sits about, twiddling its thumbs, waiting for something to do.  Hmmm…</p>
<p>Maybe we could use the Kit’s ATMega328 as an interface to the temperature sensor?  That’s so crazy, it might just work.</p>
<h2>The Sparkfun Serial Enabled LCD Kit</h2>
<p>And it does work.  (Most of the time, as I explain below.)</p>
<p>The Sparkfun Kit’s design makes it quite easy to implement this type of project.  It breaks out the standard 5 pins used by the FTDI cable (the serial-to-USB cable I previously used with the <a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Light Sensor’s dearly departed UART interface</a>), and also breaks out all of the Arduino pins not used by the LCD.</p>
<p>The LCD interface “firmware” is just a standard Arduino program, nothing weird, so it’s easy to merge in the sample code for reading the DHT11 sensor – mostly just copy and paste.</p>
<p>While I was at it, I also added some code to interface to the Arduino’s built-in EEPROM memory.</p>
<p>So, the end result is that the Plant Light Controller can now display the humidity, a more accurate temperature, and save the settings from the menu too.</p>
<p>Actually, the “more accurate” temperature is debatable.  The DHT11 chip always returns temperature as an integer, and always in Celcius.  It appears to truncate the actual temperature, rather than rounding it.  So, the temperature can be off by .9C, or 1.6F.  Humidity is similarly truncated to an integer.  But, hey, I’m not complaining – at $5, Seeed’s sensor is still a steal.</p>
<h2>Pin Assignments</h2>
<p>From the Netduino’s standpoint, not much changes from the previous installments of this project.  All communication with the Arduino goes through the same serial pins used by the LCD interface.  However, since the LCD now talks back, we need to connect a Netduino Serial Rx pin to the Serial LCD’s Kit TX pin, which is part of the FTDI breakout on the end of the backpack’s circuit board (the right end of the photo below).  My code uses Netduino&#8217;s COM2 (pins D2 and D3) for this.</p>
<div class="img aligncenter size-full wp-image-827" style="width:1024px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/04/HPIM0947.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/04/HPIM0947.png" alt="Sparkfun Serial LCD and Seeed Temperature/Humidity Sensor" width="1024" height="768" /></a>
	<div>Sparkfun Serial LCD and Seeed Temperature/Humidity Sensor</div>
</div>
<p>From the Serial Kit’s standpoint, the following pins are used:</p>
<p>-          The white JST plug contains the 5V, ground and RX pins, which we connect to the 5V, ground and TX (D3) pins of the Netduino</p>
<p>-          The TX pin at the end of the board is connected to the RX pin (D2) of the Netduino</p>
<p>-          The breakout pins at the bottom of the Serial Kit are used to connect to the Temperature/Humidity Sensor: specifically, the 5V, Ground and Analog 0 pins.</p>
<h2>User Interface</h2>
<p>Not much has changed here from the last installment of the project, either.  As shown in the photo below, I’ve used the leftover space on the Temperature row of the LCD to display the humidity instead of the Sunset time.</p>
<p>The number in parentheses is the temperature value from the sensor – the other temperature value is from the analog sensor, as added to the project in <a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">an earlier installment</a>.  Which one is more accurate depends on how well your analog sensor is behaving – as mentioned, the digital sensor’s temperature can be off by 0.9C, while my analog sensor is apparently a little high.</p>
<div class="img aligncenter size-full wp-image-826" style="width:1024px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/04/HPIM0962.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/04/HPIM0962.png" alt="Demonic LCD displaying strangely moderate temperature and humidity" width="1024" height="768" /></a>
	<div>Demonic LCD displaying strangely moderate temperature and humidity</div>
</div>
<p>I’ve also added a couple of new items to the “Timers” section of the menu, allowing you to disable the plant light timer.  This became necessary once I started saving the menu settings to EEPROM, since that ruined the handy Disable-the-timer-by-turning-the-gadget-off-and-on ™ feature.</p>
<h2>Programmer Show And Tell</h2>
<p>The Serial LCD Kit is now the 4<sup>th</sup> LCD interface supported by the code, joining the parallel LCD, the Matrix Orbital Serial LCD, and the Sparkfun Serial Backpack.  I considered making the LCD Kit fully compatible with the Sparkfun Backpack’s command set by changing the Arduino “firmware” code.  The 2 command sets are quite similar, differing only when in the cursor positioning and backlight control commands.</p>
<p>However, I like the <a href="https://github.com/jimbloom/Serial-LCD-Kit/wiki/Serial-Enabled-LCD-Kit-Datasheet">Serial LCD Kit’s API</a> better, so I subclassed the Backpack&#8217;s clsLCD_SF class and overrode the commands that differed.</p>
<p>Subclassing is supported the same way in .Net Micro Framework as in the full blown .Net:</p>
<pre class="brush: csharp; title: ; notranslate">

public class clsLCD_SFKit : clsLCD_SF
</pre>
<p>Overriding a class method is also done the standard C#, using the “new” keyword.  So, to replace the cursor positioning method with code that works with the LCD Kit’s firmware:</p>
<pre class="brush: csharp; title: ; notranslate">
new public void SelectLine(byte intLine, bool blnClearLine)
</pre>
<p>I added some new commands to the LCD class, used to receive data from the Serial Kit&#8217;s Arduino.  Since its unlikely that the other LCDs are going to do much talking, I didn’t add these  methods to the common <em>ILCD</em> Interface.  Instead, when the main program wants to check to see if the LCD is of the Serial Kit variety, it uses the “is” keyword, again just like in the full .Net Framework:</p>
<pre class="brush: csharp; title: ; notranslate">
if (lcd is clsLCD_SFKit)
{
// get the humidity
((clsLCD_SFKit)lcd).RequestHumidityAndTemp();
</pre>
<p>Data from the Serial Kit comes in through the Netduino&#8217;s serial RX pin, just like we used to read terminal commands through the UART interface.  So much like it, in fact, that I used the same event handler.  When a humidity reading or EEPROM setting comes back from the Serial Kit, the code raises a uart_Command event, as described  back in the <a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Time and Weather article</a>.</p>
<p>There is actually one big difference between the Serial Kit’s behaviour and the UART Telnet terminal, though.  The Telnet terminal could send us a command at any time, so an asynchronous interface using an event was necessary.  The LCD, on the other hand, sends data only when we ask for it.  It would have been possible, therefore, to read the data synchronously after we send the request, using code like the following:</p>
<pre class="brush: csharp; title: ; notranslate">
public void RequestHumidityAndTemp()
{
byte[] command = new byte[2];
command[0] = CMD_SPECIAL;
command[1] = 71;
lcd.Write(command, 0, command.Length);
// give the LCD time to retrieve the data
Thread.Sleep(1000);
intBytesRead = lcd.Read(readBuffer, intBufferOffset, lcd.BytesToRead);
. . .
}
</pre>
<p>This has the advantage of making the context of the data we are reading obvious, but the disadvantage of introducing timing problems.  What if the LCD doesn’t respond fast enough, or the response isn’t received at all?  How long should we wait for the LCD to respond, and at what point does the Netduino decide that a response isn’t going to be received, and carries on?</p>
<p>Asynchronous communication does away with that problem.  In fact, you can unplug the LCD altogether, and the Netduino will faithfully carry on with its other duties, turning on and off the plant light.  It won’t receive any humidity readings, and its request to save menu settings won’t be performed (good luck using the menu without an LCD, by the way), but the Netduino doesn&#8217;t notice.</p>
<p>The downside of asynchronous communication is that data doesn’t necessarily come back when you want it.  You’ll see this when you first plug in the Netduino – although it requests the humidity from the Arduinio during startup, the response may not be received before the first “display the temperature” timer fires.  As a result, it may take another 30 seconds (the interval of the temperature timer) before the humidity is displayed.</p>
<p>The code I added to the Arduino to save settings to EEPROM takes advantage of the <a href="http://www.arduino.cc/en/Reference/EEPROM">Arduino EEPROM library</a> &#8211; the library makes it simple.  One minor twist is how to handle the very first interaction between Netduino and Arduino.  The Arduino has no idea whether it has any settings saved – it just returns whatever happens to be in the address you&#8217;ve requested.  The first time, this will be 0s.  So, all settings are saved as non-zero values: I add 1 to the values where necessary.</p>
<p>One other design decision worth mentioning is the issue of which settings to save, and when to save them.  I decided to save the date, but not the time, since it’s likely that the date will be unchanged, or very slightly changed, when you power the Netduino back on, but the time will almost certainly have changed, perhaps by hours.</p>
<p>The other downside of saving the time is that you’d have to do it every minute, putting wear and tear on the EEPROM.  It is best to write to EEPROM as little as possible: in this case, only when the user changes a setting in the menu.</p>
<p>Fortunately, I already had a callback method for responding to the user&#8217;s menu selections (as described in the <a href="http://gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/">Ordering Off the Menu</a> article), so I added code like the following to that method.</p>
<pre class="brush: csharp; title: ; notranslate">
static void setValueFromMenu(string menuCode, Int16 intValue)
{
. . .
if (menuCode == &quot;_CELCIUS&quot;)
{
. . .
SaveSettingToEEPROM(ADDR_TEMP_FORMAT, 2); // 2 means Celcius
</pre>
<h2>With Friends Like That…</h2>
<p>This configuration actually did a good job of proving the point about unmanaged code: it’s awfully easy to crash the microcontroller when running it.</p>
<p>When I got things up and running, I found that the LCD would freeze at some point, generally a few hours after powering it on.  The Netduino soldiered on, faithfully turning the plant light off and on, so clearly it was the Arduino that dropped the ball.</p>
<p>Commenting out the code that requests the temperature and humidity reading caused the problem to go away, so whatever was going wrong involved the DHT11 interface.</p>
<p>The right thing to do would be to debug the Arduino’s DHT11 code, but the easy thing to do was to just “reboot” the Arduino on a regular basis.</p>
<p>Crude, but effective.  I’ve had this configuration running for over a month now, and it works like a charm.</p>
<p>The “rebooting” is done by using a transistor to turn the Arduino’s power off and on.  This requires a hardware change: instead of connecting the Sparkfun LCD Kit’s ground pin directly to the Netduino, I used a small breadboard to route the connection through a transistor.  The transistor is controlled using the D12 pin.</p>
<p>Specifically, the configuration I used (shown in the photo) is:</p>
<p>-          Collector pin of 2N2222 transistor to LCD Kit&#8217;s ground</p>
<p>-          Emitter pin of 2N2222 to Netduino ground</p>
<p>-          Base pin of 2N2222 to D12 pin of Netduino</p>
<p>-         Base pin of 2N2222 to ground through pushbutton &#8211; this can be used to manually boot the LCD Kit Arduino if necessary</p>
<div class="img aligncenter size-full wp-image-843" style="width:1152px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/04/ArduinoResetCircuit.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/04/ArduinoResetCircuit.png" alt="Arduino Reset Circuit" width="1152" height="864" /></a>
	<div>Arduino Reset Circuit</div>
</div>
<p>The Arduino is powered up during the Netduino code’s startup:</p>
<pre class="brush: csharp; title: ; notranslate">
arduino = new OutputPort(SecretLabs.NETMF.Hardware.Netduino.Pins.GPIO_PIN_D12, false);
arduino.Write(true); // turn on Arduino
Thread.Sleep(2000); // give Arduino a chance to do its initialization
lcd = new clsLCD_SFKit(SerialPorts.COM2, 9600, 2, 16);
</pre>
<p>I added a new method to reset the power to the LCD Kit’s Arduino by temporarily setting D12 low:</p>
<pre class="brush: csharp; title: ; notranslate">
static void ToggleArduino()
{
arduino.Write(false);
Thread.Sleep(1000);
arduino.Write(true);
// let Arduino do its initialization
Thread.Sleep(2000);
// restore the brightness setting
lcd.SetBrightness(bytBrightness);
</pre>
<p>The new method is called when the Netduino hasn’t received a response from the Arduino for over an hour.  It asks for the temperature and humidity every 30 seconds, so an hour is obviously lenient.  If you need the temperature/humidity readings to be more reliable, you should shorten this interval:</p>
<pre class="brush: csharp; title: ; notranslate">
// if we haven't received any data from the Arduino for over an hour, reboot it
if (datlastArduinoRead != DateTime.MinValue)
if (DateTime.Now.Subtract(datlastArduinoRead).Hours &gt; 0
datlastArduinoRead = DateTime.MinValue; // prevent another reboot
ToggleArduino();
</pre>
<p>The voltage out of the Netduino’s digital pins is 5 volts, so why bother with the transistor – why not power the Arduino directly from D12?  The problem is current: the Netduino (and pretty much every microcontroller under the sun) only allows a trickle of current to flow through its pins.  You can power an LED with it, but anything more power hungry needs to get its voltage another way.</p>
<h2>Wrapping Up</h2>
<p>This installment of the Light Controller project is admittedly off on somewhat of a tangent: connecting a temperature sensor to a Netduino via a Serial LCD interface is not a common configuration.</p>
<p>However, offloading some of the Netduino’s responsibilities onto another processor is actually quite a handy technique.  There are a lot of microcontrollers out there, each with its own libraries of code capable of doing some things that a Netduino can’t (yet), so when looking to add a new feature it’s smart to think “outside the box”.</p>
<p>One other improvement I’ve made to the project is to put the source code into a proper repository, rather than just linking each article to a .zip file.  I&#8217;ve created a Google Code project named <a href="http://code.google.com/p/gigamega-micro/">gigamega-micro</a>.</p>
<p>You can get the code for each of my Netduino articles (starting with <a href="http://gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Let There Be Light</a>) in 2 ways:</p>
<p>-          If you are familiar with Subversion use SVN to get the latest code.  If you want the older version of the code to match one of the past articles, get the corresponding revision (see the revision list here <a href="http://code.google.com/p/gigamega-micro/source/list">http://code.google.com/p/gigamega-micro/source/list</a>)</p>
<p>-          Or, download the good old .zip file from the <a href="http://code.google.com/p/gigamega-micro/downloads/list">Downloads section of the Google Code project</a>. Here is a <a href="http://gigamega-micro.googlecode.com/files/GMM_ALittleHelpFromItsFriends.zip">direct link to the code for this article</a>.</p>
<p>The modified Arduino code for the Sparkfun LCD Kit can also be found in the Downloads section of the Google Code page (<a href="http://gigamega-micro.googlecode.com/files/SFE_SerialLCDSketch.zip">direct link to .zip file</a>).  90% of that code is copied from the <a href="https://github.com/jimbloom/Serial-LCD-Kit">original Sparkfun firmware</a> or from <a href="http://sheepdogguides.com/arduino/ar3ne1humDHT11.htm">Sheepdog Software&#8217;s DHT11 page</a>.  I&#8217;ve left the original authors&#8217; headers in the code.</p>
<p>Don’t worry, I haven’t forgotten the “road map” of hooking the Netduino up to an XBee.  We’ll get back on track in a future article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Netduino: Ordering Off the Menu</title>
		<link>http://www.gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/</link>
		<comments>http://www.gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 23:42:26 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=680</guid>
		<description><![CDATA[The source code for this article can be downloaded here: LightControllerWithMenu.zip. This is the 5th in a series of projects for the Netduino and Seeed Studio’s Grove Starter Bundle. The first four articles in the series were: Netduino Enters the &#8230; <a href="http://www.gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>The source code for this article can be downloaded here: <a href="http://gigamegablog.com/files/LightControllerWithMenu.zip">LightControllerWithMenu.zip</a>.</em></p>
<p>This is the 5th in a series of projects for the <a href="http://www.netduino.com/">Netduino</a> and <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=138">Seeed Studio’s Grove Starter Bundle</a>.</p>
<p>The first four articles in the series were:</p>
<ol>
<li><a href="http://gigamegablog.com/2010/12/20/netduino-enters-the-grove/">Netduino Enters the Grove</a></li>
<li><a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Netduino: Time and Weather</a></li>
<li><a href="http://">Netduino: Let There Be Light</a></li>
<li><a rel="bookmark" href="http://gigamegablog.com/2011/01/26/netduino-here-comes-the-night/">Netduino: Here Comes The Night</a></li>
</ol>
<p>Today, my friends, the voice of the people has been heard, and the reign of an oppressive dictator shall finally end.</p>
<p>For too long (about a month-and-a-half, to be specific,  since my <a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Netduino: Time and Weather</a> post), we’ve had only one way to enter the date and time and other settings: the user-hostile serial connection.  It forced us to drag our notebooks over to the Netduino, open serial terminals, enter obscure commands, and other things too loathsome to mention.  Is this any way to live?</p>
<p>The people want freedom.  The freedom to just walk up to a Netduino and set the date and time at the click of a button.  The freedom to choose Celcius or Fahrenheit, at the click of a button.  (Though only imperialists use Fahrenheit, you know.) The freedom to turn off the LCD backlight – well, you get the idea.</p>
<p>In short, the people want a menu system.</p>
<p>This new menu system will follow the orders of one person only: you the user.  Well, technically, also me, the programmer.  And if you choose to <del datetime="2011-02-15T23:08:53+00:00">fix my bugs</del> customize my code, then also you (again), the programmer.  Oh, and the reviled serial connection is going to remain in, um, a strictly unofficial capacity to ensure an orderly transition.</p>
<h2>Pin Assignments</h2>
</p>
<p>The pin assignments are unchanged from the previous blog post, <a rel="bookmark" href="http://gigamegablog.com/2011/01/26/netduino-here-comes-the-night/">Netduino: Here Comes The Night</a>.  The changes in this installment of the project are purely software.</p>
<h2>User Interface</h2>
</p>
<p>To invoke the snazzy new menu system, take the Red pill &#8212; I mean, press the Red button.  (For those who aren’t using the Seeed Grove hardware system, the red button is connected to D7, and the green to D8.  In Grove terminology, this is a button “twig” connected to the D7/D8 plug on the Grove stem).</p>
<p>Throughout the menu system, the buttons are used as follows (aaah &#8211; a user manual!):</p>
<ul>
<li>Red button  click – scroll down</li>
<li>Green button click – scroll up</li>
<li>Red button double-click – select a menu item</li>
<li>Green button double-click – exit the current menu</li>
</ul>
<p>Some of the menus allow you to change a numeric value, like the hour of the day.  In these menus:</p>
<ul>
<li>Red button click – increase the value by 1</li>
<li>Green button click- decrease the value by 1</li>
<li>Red or Green button press and hold – repeatedly increase or decrease the value of the number</li>
<li>Red button double-click – save the current value of the number and exit the current menu</li>
<li>Green button double-click – exit the current menu without saving</li>
</ul>
<h2>Programmer Show And Tell</h2>
</p>
<p>The heart of this update to the project, and the part you are most likely to want to change, is the menu configuration.   I didn’t want to reinvent the wheel, so I carefully looked through the work that had already been done on creating a menu system for .Net Micro Framework devices.  When I couldn&#8217;t find what I wanted on the first page of the Google results, I got annoyed and reinvented the wheel.</p>
<p>Near the top of Program.cs, you’ll find the following array definition:</p>
<pre class="brush: csharp; title: ; notranslate">
static string[] strMenuItems = new string[] {
&quot;1&quot;, &quot;Date `yy`-`MM`-`dd`&quot;, &quot;1-1&quot;,
&quot;1&quot;, &quot;Time `HH`:`mm`&quot;, &quot;2-1&quot;,
&quot;1&quot;, &quot;Timers&quot;, &quot;3-1&quot;,
&quot;1&quot;, &quot;Settings&quot;, &quot;4-1&quot;,
&quot;1-1&quot;, &quot;Year `yy`&quot;, &quot;_UD-`yy`&quot;,
&quot;1-1&quot;, &quot;Month `MM`&quot;, &quot;_UD-`MM`&quot;,
&quot;1-1&quot;, &quot;Day `dd`&quot;, &quot;_UD-`dd`&quot;,
&quot;2-1&quot;, &quot;Hour `HH`&quot;, &quot;_UD-`HH`&quot;,
&quot;2-1&quot;, &quot;Min `mm`&quot;, &quot;_UD-`mm`&quot;,
&quot;3-1&quot;, &quot;Light On `HH:mm+`&quot;, &quot;3-2&quot;,
&quot;3-1&quot;, &quot;Light Off `HH:mm-`&quot;, &quot;3-3&quot;,
&quot;3-2&quot;, &quot;Manual `HH:mm+`&quot;, &quot;3-2-1&quot;,
&quot;3-2&quot;, &quot;Sunset `HH:mm_`&quot;, &quot;_SUNSET&quot;,
&quot;3-3&quot;, &quot;Manual `HH:mm-`&quot;, &quot;3-3-1&quot;,
&quot;3-3&quot;, &quot;Sunrise `HH:mm*`&quot;, &quot;_SUNRISE&quot;,
&quot;3-2-1&quot;, &quot;Hour `HH+`&quot;, &quot;_UD-`HH+`&quot;,
&quot;3-2-1&quot;, &quot;Min `mm+`&quot;, &quot;_UD-`mm+`&quot;,
&quot;3-3-1&quot;, &quot;Hour `HH-`&quot;, &quot;_UD-`HH-`&quot;,
&quot;3-3-1&quot;, &quot;Min `mm-`&quot;, &quot;_UD-`mm-`&quot;,
&quot;4-1&quot;, &quot;Temp Fmt `TD`&quot;, &quot;4-1-1&quot;,
&quot;4-1&quot;, &quot;Backlight `LB`&quot;, &quot;_BACKLITE&quot;,
&quot;4-1&quot;, &quot;Brightness `BR`&quot;, &quot;_UD-`BR`&quot;,
&quot;4-1-1&quot;, &quot;Celcius&quot;, &quot;_CELCIUS&quot;,
&quot;4-1-1&quot;, &quot;Fahrenheit&quot;, &quot;_FAHR&quot;
};
</pre>
<p>One thing you’ll notice right away is that this should be a 2 dimensional array (i.e. <em>string[,]</em>), but isn’t.  Oddly, there is no such thing as a 2-dimensional array in the .Net Micro Framework.    Instead, you can have arrays of arrays (e.g. <em>string[][] strMenuItems = new string[20][],</em> where the 2nd-level array can be of a different size in each element of the main array.  This weirded me out, so I went with a 1-dimensional array instead.</p>
<p>Each menu item consists of 3 strings:<br />
-	A menu ID – this must be the same for each item in that level of the menu<br />
-	A caption, which can contain embedded keywords delimited with the backquote character (`)<br />
-	The result of selecting (double-clicking) that menu item, which can be the ID of a submenu to display, or an action (actions are prefixed with an underscore).</p>
<p>So, for example, the first level menu has 4 items that appear on the LCD like this:</p>
<pre class="brush: csharp; title: ; notranslate">
Date 11-02-14
Time 18:05
Timers
Tools
</pre>
<p>The first 2 items contain keywords that are replaced at run-time with the current date and time.<br />
Selecting the first item in this menu displays sub-menu “1-1”, which looks like</p>
<pre class="brush: csharp; title: ; notranslate">
Year 11
Month 02
Day 14
</pre>
<p>Selecting any of these menus selects an action, such as &#8220;_UD-`yy`&#8221; &#8212; this displays an “Up/Down” menu for setting the year.  More on that below.</p>
<p>I’ve added a new class to the project, <em>clsLCDMenu</em>, and given it sole responsibility for displaying the menu and handling all button input.  This class is intended to be a generalized menu handler: it knows  how to display lines of a menu and allow the user to navigate through the menu using the buttons, but it knows nothing about how to handle the actions selected by the user.</p>
<p>This design results in a fairly extendable and reusable  menu.  There are no hard-coded limits on the # of elements in a menu of the # of levels of submenus.  To add new menu items, or create an entirely different menu system,  I won’t have to change any of the code in clsLCDMenu.   Instead, I just change the strMenuItems array, above, and add some “action handler” logic to some callback methods in <em>Program.cs</em>, described below.</p>
<p>Since clsLCDMenu “owns” the LCD and buttons when the menu is up, I have to make sure that the existing code never tries to write to the LCD or respond to a button click when the menu is up.  I do this by turning off the timers and “unhooking” the button event handlers, as follows:</p>
<pre class="brush: csharp; title: ; notranslate">
static void launchMenu()
{
  // turn off the timers that update the display
  timerTemperature.Dispose();
 timerTime.Dispose();

  //unhook the button event handlers
  buttonRed.OnInterrupt -= buttonRed_OnInterrupt;
  buttonGreen.OnInterrupt -= buttonGreen_OnInterrupt;

  // buttonGreen = up, buttonRed = down
  menu = new clsLCDMenu(strMenuItems, lcd, buttonGreen, buttonRed, getStringForMenu, getValuesForMenu,     setValueFromMenu);
}
</pre>
<p>The “-=” statement that unhooks the event handlers will look freaky to anyone who hasn’t encountered it in .Net before, since neither side of the “-=” is a numeric value.  This syntax removes the main class’s button  event handlers from a virtual “list” of handlers for the event.  It isn&#8217;t all that commonly used in .Net, since event handlers are automatically “unhooked” when the class that contains the event handlers is destroyed, such as when a form is closed.</p>
<p>The constructor for the clsLCDMenu class looks like this:</p>
<pre class="brush: csharp; title: ; notranslate">
public clsLCDMenu(string[] strItems, ILCD lcd, InterruptPort buttonUp, InterruptPort buttonDown,
MenuCallback getCaption, MenuGetValue getValue, MenuSetValue setValue)
</pre>
<p>The caller passes a reference to the LCD and “up” (green) and “down” (red) buttons, along with 3 callback methods.  The callback methods add the “business logic” to the menu system, if you will: they fill in the keywords in the menu captions, and handle the menu actions.  Specifically, there are 3 types of callbacks:</p>
<ul>
<li><em>MenuCallback </em>– gets passed a menu caption containing keywords (e.g. &#8220;Light On `HH:mm+`&#8221;), and passes back the caption to be displayed to the user (e.g. Light On 20:30”.</li>
<li><em>MenuGetValue </em>– gets passed an “up/down” menu definition (e.g. &#8220;_UD-`MM`&#8221;) and passes back the current value, minimum value and maximum value to be used for the up/down menu.</li>
<li><em>MenuSetValue </em>– gets passed an action that needs to be taken: either the changed value from an up/down menu (e.g. the user has changed the hour setting on the clock), or some other action such as &#8220;_SUNSET&#8221; (the user has set the “Light On” timer to sunset.)</li>
</ul>
<p>Callback methods in .Net require 2 things:<br />
1)	A “delegate” definition.  For example, the definitions of the 3 callback methods used by clsLCDMenu are:</p>
<pre class="brush: csharp; title: ; notranslate">
public delegate string MenuCallback(string s);
public delegate bool MenuGetValue(string menuType, out Int16 start, out Int16 min, out Int16 max, out byte increment);
public delegate void MenuSetValue(string menuType, Int16 value);
</pre>
<p>2)	The actual method to be executed when the callback is invoked.  References to these 3 methods are passed to the clsLCDMenu constructor by the launchMenu() method, shown earlier.  The constructor saves these references in variables of the “delegate” type.  For example, the MenuCallback is saved by clsLCDMenu as:</p>
<pre class="brush: csharp; title: ; notranslate">
private MenuCallback menuGetCaption;

…

public clsLCDMenu(string[] strItems, ILCD lcd, InterruptPort buttonUp, InterruptPort buttonDown,
MenuCallback getCaption, MenuGetValue getValue, MenuSetValue setValue)

…

this.menuGetCaption = getCaption;
</pre>
<p>When clsLCDMenu needs to call one of the callback methods, it uses its reference variable, calling it as if it was a method.  For example:</p>
<pre class="brush: csharp; title: ; notranslate">
string strMenuText = menuGetCaption(((menuItem)lstMenu[intMenu]).StrCaption);
</pre>
<p>I won’t give an explanation of what the callback methods do.  They are actually quite straightforward: just a bunch of “if” and “switch” statements that examine the parms to figure out what kind of data they are dealing with, then returning the corresponding settings or taking the corresponding action.</p>
<p>Two other features that are worth explaining, though, are the buttons’ double-click and auto-repeat handlers.  These both rely on timers, which are a pleasure to work with in .Net compared to the alternatives that you need to hack together in other microcontroller platforms.</p>
<p>The double-click is a click followed by another click (duh).  As every new (or elderly) PC user learns the hard way, the difference between a double-click and 2 single clicks is the amount of time in between.</p>
<p>So, the code which handles the first click sets a timer.  If the timer goes off before another click occurs, then that was a single click, and the code handles it accordingly.  If a second click occurs before the timer expires, that’s a double click.</p>
<p>The code which sets the double-click timer is:</p>
<pre class="brush: csharp; title: ; notranslate">
timerButtonDown = new Timer(new TimerCallback(buttonClick), &quot;Down&quot;, DOUBLECLICK_DELAY, -1);
</pre>
<p>The DOUBLECLICK_DELAY is a constant, in milliseconds, which determines how fast Granny has to move to pull off a double-click.  I ended up setting it to 400 ms, which was short enough that I didn’t accidentally double-click when I wanted to make 2 separate clicks.</p>
<p>The “buttonClick” timer event handler now contains the logic that was previously in the button interrupt event: a click isn&#8217;t a click until the timer goes off:</p>
<pre class="brush: csharp; title: ; notranslate">
private void buttonClick(object data)
{
  if ((string)data == &quot;Down&quot;)
  {
    // cancel the button click timer
    if (timerButtonDown == null)
    {
      // oops, someone already cancelled it, so we should ignore it
      return;
    }
    timerButtonDown.Dispose();
    timerButtonDown = null;
    blnButtonDownClicked = false; // no longer waiting for double-click
    goDown();
</pre>
<p>You&#8217;ll notice some seemingly unnecessary null handling.  Here’s the thing&#8230;</p>
<p>If the user clicks the button a second time, then we want to cancel this timer event: it’s a double-click action, not a single-click.  In theory, disposing a timer should cancel the timer event.  However, when testing that code I found that double-clicking would often result in both the double-click and single-click action being performed, since the timer event wasn’t cancelled by disposing the timer object.  Setting the timer to null didn’t cancel the event either.  </p>
<p>So, I ended up adding code to the timer event to see if the timer had been set to null, and aborting the event if it had.  Crude, but effective, and a lot more reliable than polling the button a la Arduino.</p>
<p>To implement button auto-repeat, I used the button “push-and-hold” timer (as described in the <a rel="bookmark" href="http://gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Netduino: Let There Be Light</a> article), and had it re-invoke the timer if the button was still being held down:</p>
<pre class="brush: csharp; title: ; notranslate">
private void buttonHold(object data)
{
  if ((string)data == &quot;Down&quot;)
  {
  …
  if (!buttonDown.Read())
  {
    // not being held down anymore
    return;
  }
  intDownRepeatCount += 1;
  int delay = BUTTONREPEAT_DELAY;
  if (intDownRepeatCount &gt;= 4)
    delay = TURBOREPEAT_DELAY;
    timerButtonDown = new Timer(new TimerCallback(buttonHold), &quot;Down&quot;, delay, -1);
</pre>
<p>As you can see, I implemented auto-repeat the same way as most alarm clocks: the number advances relatively slowly at first (BUTTONREPEAT_DELAY is 500 ms), then more quickly after a couple of seconds (TURBOREPEAT_DELAY) is 200 ms.</p>
<h2>Next Steps</h2>
</p>
<p>At this point in the project, we have a reasonably functional plant light controller (and clock and temperature display).</p>
<p>Although using the new menu to set the date and time is definitely a lot more user friendly than the deposed serial port system (boo, hiss), it&#8217;s still a pain to have to re-enter each menu setting after a power outage.  So, a battery backup and/or saving the menu settings to flash memory would be a nice feature, and I’ll definitely be adding that at some point.</p>
<p>However, the more exciting enhancement is to give the Netduino something to display on its LCD other than the time and temperature.  There is a world of data swirling around the Netduino: twitterers tweeting, bloggers blogging, weather forecasters <del datetime="2011-02-15T23:21:20+00:00">making stuff up</del> forecasting.  Wouldn’t it be cool if our Netduinos could dip into that datastream and display some of that info on its LCD?</p>
<p>There are 2 main options for implementing this: using a <a href="http://www.arduino.cc/en/Main/ArduinoEthernetShield">Netduino-compatible Ethernet shield</a> to connect directly to the Internet, or using a wireless <a href="http://www.digi.com/products/wireless-wired-embedded-solutions/zigbee-rf-modules/point-multipoint-rfmodules/xbee-series1-module.jsp#overview">XBee</a> device to connect to a PC.  The first option has the very strong advantage of being a standalone solution, but I’ll be going down the second path – it has the even stronger advantage of me having already written most of the code.  </p>
<p>So, if you’re interested in following me there, you’ll want to invest in a couple of XBees, and a couple of hardware interfaces for connecting the XBees to your Netduino and your PC.  More on that in my next article.</p>
<p>The source code for this article can be downloaded here: <a href="http://gigamegablog.com/files/LightControllerWithMenu.zip">LightControllerWithMenu.zip</a>. As before, it contains a reference to the Micro Liquid Crystal library, so you should download it as well, and place it in a folder that is side-by-side with my LightControllerWithMenu folder (e.g. c:projectsLightControllerWithMenu and c:projectsMicroLiquidCrystal).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/02/15/netduino-ordering-off-the-menu/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Netduino: Here Comes The Night</title>
		<link>http://www.gigamegablog.com/2011/01/26/netduino-here-comes-the-night/</link>
		<comments>http://www.gigamegablog.com/2011/01/26/netduino-here-comes-the-night/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 00:03:34 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=660</guid>
		<description><![CDATA[This is the 4th in a series of projects for the Netduino and Seeed Studio’s Grove Starter Bundle. The first three articles in the series were: Netduino Enters the Grove Netduino: Time and Weather Netduino: Let There Be Light As &#8230; <a href="http://www.gigamegablog.com/2011/01/26/netduino-here-comes-the-night/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the 4th in a series of projects for the <a href="http://www.netduino.com">Netduino</a> and <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=138">Seeed Studio’s Grove Starter Bundle</a>.</p>
<p>The first three articles  in the series were:</p>
<ol>
<li><a href="http://gigamegablog.com/2010/12/20/netduino-enters-the-grove/">Netduino Enters the Grove</a></li>
<li><a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Netduino: Time and Weather</a></li>
<li><a href="http://gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Netduino: Let There Be Light</a></li>
</ol>
<p>As I hinted at the end of the previous article, there is an easy way to automatically set the plant light to turn on when it starts to get dark.  It&#8217;s a light-sensing photoresistor (<a href="http://www.seeedstudio.com/depot/electronic-brick-light-sensoranalog-p-474.html?cPath=144_148">like this</a>), and we&#8217;re not going to use it because</p>
<ol>
<li>There isn&#8217;t one in the Grove Starter Pack</li>
<li>I kinda thought the easiest way would be to calculate the sunset time instead</li>
</ol>
<p>Using an algorithm to calculate sunset time is actually relatively foolproof, being unaffected by storm clouds, cat attacks, or awestruck bystanders staring at your way-cool plant light controller.</p>
<p>It does however, require 2 additional pieces of information:<br />
- your geographic location<br />
- your timezone, including daylight savings time</p>
<p>The geographic location is, specifically, the longitude and latitude.  There are zillions of sources for that on the Internet.  One of the handiest is <a href="http://www.wolframalpha.com/">Wolfram Alpha</a>, the Google of calculations. Just type in &#8221; latitude longitude [your city]&#8220;, and it will spit out the numbers.  Type in &#8220;[your city]sunset&#8221;, and it will tell you what result the algorithm should be giving you for today.</p>
<p>We all know what timezone we are in, but calculating the start and end date for Daylight Savings Time is too convoluted for most programmers, including me.  It becomes pretty easy to determine if your Netduino is Internet connected, but since we aren&#8217;t there yet I&#8217;ll follow the same approach as the prestigious <a href="http://www.nrc-cnrc.gc.ca/eng/services/hia/sunrise-sunset.html">National Research Council Canada&#8217;s Sunrise/Sunset calculator</a>: leave it unimplemented.  (As they put it: &#8220;Add one hour to listed times when Daylight Saving Time is in effect.&#8221;)</p>
<p>I decided to use the sunset calculation algorithm from<a href="http://www.codeproject.com/KB/recipes/SolarCalculator.aspx"> this CodeProject article: Solar Calculator</a>.  This API is relatively simple and self-contained.  The &#8220;LongituteTimeZone&#8221; parameter mentioned in the article threw me for a loop &#8211; I fruitlessly Googled &#8220;Longitute&#8221; before realizing that was a typo.  This parameter represents your time zone: it is the offset from UTC (aka Greenwich Mean Time) in hours, times 15.    (Turns out each timezone represents 15 degrees of longitude &#8211; who knew!)</p>
<p>The algorithm makes extensive use of the trigometry calculations from the .Net Math class, none of which exist in the .Net Micro Framework.  Fortunately, all of them do exist, with the exact same parameters, in <a href="http://www.microframework.nl/2009/01/15/math-library-compatible-with-full-net/">Elze Kool&#8217;s exMath library</a>.  This the same library that I used to calculate the temperature in the <a href="http://gigamegablog.com/2010/12/20/netduino-enters-the-grove/">first article of this series</a>.</p>
<p>So, to change my code to work correctly for your location, you&#8217;ll need to change the following 4 values, which are near the beginning of Program.cs in the source code:</p>
<pre class="brush: csharp; title: ; notranslate">

// settings for Toronto Canada
const double MY_LONGITUDE = -79.38;
const double MY_LATITUDE = 43.65;
const int UTC_OFFSET = -5;
const bool USE_DAYLIGHT_SAVINGS = false;
</pre>
<p>Note that the longitude and latitude are in decimal format. If you&#8217;ve forgotten your high school geography, negative values are for south of the equator and west of the Prime Meridian, and to convert &#8220;minutes&#8221; of longitude and latitude to decimals, divide them by 60.</p>
<h2>Pin Assignments</h2>
</p>
<p>If you are using a Parallel LCD, then nothing changes from the list of pin assignments in the <a href="http://gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Let There Be Light article</a>.</p>
<p>If you are using a Serial LCD, then you probably already changed my pin assignments, since they weren&#8217;t at all suitable for a Serial LCD.  (As before, you should comment out one of the #define statements at the top of Program.cs to select your LCD type).  I changed the code to use:</p>
<ul>
<li>UART Serial connection &#8211; this changes to COM1 (pins 0 and 1)</li>
<li>LCD Serial connection &#8211; this uses COM2</li>
<li>Relay twig &#8211; this moves from D0 to D13</li>
</ul>
<h2>User Interface</h2>
</p>
<p>The sunrise calculation is done after the Netduino knows the current date and time.  Both of these are still entered using Terminal commands sent over the UART serial connection, as described in the <a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Time and Weather</a> article.</p>
<p>By default, the Light On time is set to 15 minutes before sunset, and the Light Off time is set to 11 pm.  You can, of course, override either these using the &#8220;+&#8221; and &#8220;-&#8221; Terminal commands described in the <a href="http://gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Let There Be Light</a> article.</p>
<p>If you have an 16&#215;2 LCD (or larger), it will display the Sunset time on the 2nd row, next to the temperature.  This has little practical value other than to confirm that the sunset times are being calculated correctly (and impress friends who are easily impressed).  You can comment it out if you like in the <em>displayTemperature()</em> method.</p>
<p>Speaking of the accuracy of the sunset calculation: it isn&#8217;t all that accurate for me (in Toronto Canada).  Depending on the day of the year, it is 5-10 minutes earlier than what Wolfram Alpha and other web sites calculate.  I get the same result when I run the CodeProject code on a Windows PC, so whatever is responsible isn&#8217;t MathEx or the .Net Micro Framework. For the purposes of a plant light, 5-10 minutes is close enough.</p>
<h2>Programmer Show and Tell</h2>
</p>
<p>The most interesting code change this time is something that didn&#8217;t work as expected.  As described in the <a href="http://gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Let There Be Light article</a>, I&#8217;m using the exotic and mysterious <a href="http://msdn.microsoft.com/en-us/library/ee433565.aspx">ExtendedTimer</a> class to raise events for turning the light on and off.  This class has a Period parm, which is how often you want the timer event to repeat.  Since we are now recalculating the &#8220;light on&#8221; time on a daily basis, I wanted to turn off the period.  The <a href="http://msdn.microsoft.com/en-us/library/ee432238.aspx">MSDN docs for the ExtendedTimer constructor </a> say you do this with Timeout.Infinite</p>
<pre class="brush: csharp; title: ; notranslate">
tmrLightOn = new ExtendedTimer(new TimerCallback(SetLightState),
  true, datAlarm,
  new TimeSpan(Timeout.Infinite));
</pre>
<p>Unfortunately, this doesn&#8217;t work, not on a Netduino anyway.  It throws an &#8220;Argument out of range&#8221; exception.  The best workaround I could find was to set it to the maximum TimeSpan value.</p>
<pre class="brush: csharp; title: ; notranslate">
TimeSpan tsRepeat = TimeSpan.MaxValue;

if (!blnLightOnAtSunset)
{
   // repeat timer at same time every day
   tsRepeat = new TimeSpan(1, 0, 0, 0);
}

tmrLightOn = new ExtendedTimer(
  new TimerCallback(SetLightState),
  true, datAlarm, tsRepeat);
</pre>
<p>The other piece of code that I&#8217;ll point out is the use of a custom event to notify the main class that the user has entered a date and time.  The <em>clsUART</em> class has a <em>UART_DataReceived</em> event that fires every time something is entered by the user in a serial terminal.  It handles things that it knows how to do (like set the system date and time), then fires off an event to notify the rest of the application that the command was received.  This allows you to cleanly separate the serial port logic in clsUART from the &#8220;plant light&#8221; logic in the main application class.</p>
<p>For example, the code in clsUART that handles the Date command includes the following:</p>
<pre class="brush: csharp; title: ; notranslate">
DateTime currentDayTime = new DateTime(intYear,
  Int16.Parse(strDateParts[1]),
  Int16.Parse(strDateParts[2]),
  DateTime.Now.Hour,
  DateTime.Now.Minute, DateTime.Now.Second);

Utility.SetLocalTime(currentDayTime);

// tell rest of application that the date has been set
raiseCommand(strCommand);

if (blnSendResponse)
{
  WriteToUART(&quot;OK&quot;);
  return true;
}
</pre>
</p>
<p>The <em>raiseCommand</em> method looks like this:</p>
<pre class="brush: csharp; title: ; notranslate">
public event CommandEventHandler Command;

private bool raiseCommand(string strCommand)
{
   CommandArgs args = new CommandArgs(strCommand);
   // raise event using Command delegate
   Command(this, args);
   return args.blnHandled;
}
</pre>
</p>
<p>It uses a parm passed to the <em>CommandEventHandlers </em>to determine if some other part of the program recognized the command and handled it.  The return code is ignored in the above &#8220;date command&#8221; logic (since clsUART already handled it), but it is important for commands that <em>clsUART </em>doesn&#8217;t know how to handle, like setting turning the plant light on or off.  If it gets a false parm back, it displays an error message to the user. (Well, it actually displays a &#8220;?&#8221; and buzzes a little, but you get the idea.)</p>
<p>Currently, the only <em>CommandEventHandler </em>is in <em>Program.cs</em>.  It is created during startup by the following:</p>
<pre class="brush: csharp; title: ; notranslate">
uart = new clsUART(strUARTPort, 9600, 50, true);
uart.Command += new CommandEventHandler(uart_Command);
</pre>
</p>
<p>The event handler includes this:</p>
<pre class="brush: csharp; title: ; notranslate">
static void uart_Command(object sender, CommandArgs e)
{
   if (command == '-')
   {
      e.blnHandled = setLightTime(e.StrCommand.Substring(2), false);
   }
   else if (command == 'D')
   {
      blnDateSet = true;
       // set default light timer if date and time have been set for the first time
      setDefaultTimers();
  }
</pre>
</p>
<p>So, the code uses the <em>e</em> parm to return a confirmation that it took care of the command (if it did).</p>
<p>That&#8217;s it for this installment &#8211; a simple change that could have been simpler.  (Clearly <a href="http://en.wikipedia.org/wiki/George_Vernon_Hudson">George Vernon Hudson</a> wasn&#8217;t a programmer.)</p>
<p>Next up, I&#8217;ll be adding a menu system for things like setting the date and time.  I notice that the <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=138">current version (1.0b) of the Grove Starter Kit</a> now includes a 16&#215;2 LCD, rather than the tiny 8&#215;2 model that the beta Starter Kit shipped with, so I&#8217;ll use that as the minimum screen size for the menu.</p>
<p>The source code for this article can be downloaded here: <a href="http://www.gigamegablog.com/files/LightControllerV2.zip">LightControllerV2.zip</a>.  As before, it contains a reference to the <a href="http://microliquidcrystal.codeplex.com/">Micro Liquid Crystal library</a>, so you should download it as well, and place it in a folder that is side-by-side with my LightController folder (e.g. <em>c:projectsLightControllerV2</em> and <em>c:projectsMicroLiquidCrystal</em>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/01/26/netduino-here-comes-the-night/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netduino: Let There Be Light</title>
		<link>http://www.gigamegablog.com/2011/01/08/netduino-let-there-be-light/</link>
		<comments>http://www.gigamegablog.com/2011/01/08/netduino-let-there-be-light/#comments</comments>
		<pubDate>Sun, 09 Jan 2011 03:26:09 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=618</guid>
		<description><![CDATA[This is the 3rd in a series of projects for the Netduino and Seeed Studio’s Grove Starter Bundle. This installment is intended to create a plant light that automatically switches on and off at a pre-set time of the day &#8230; <a href="http://www.gigamegablog.com/2011/01/08/netduino-let-there-be-light/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the 3rd in a series of projects for the <a href="http://www.netduino.com/">Netduino</a> and <a href="http://www.seedstudio.com">Seeed Studio</a>’s <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=138">Grove Starter Bundle</a>.</p>
<p>This installment is intended to create a plant light that automatically switches on and off at a pre-set time of the day (well, more usefully, the night).  It is inspired by the “Garduino” project, which was<a href="http://blog.makezine.com/archive/2008/12/garduino_gardening_arduino.html"> published in Make Magazine</a> and can also be <a href="http://www.instructables.com/id/Garduino-Gardening-Arduino/">found on Instructables</a>.</p>
<p>This project builds on the foundation set by the earlier two articles.  If you want to actually get the project working yourself, you&#8217;ll probably need to browse the earlier articles, especially the part about the serial connection to the PC.</p>
<p>The first two articles  in the series were:</p>
<p><a href="http://gigamegablog.com/2010/12/20/netduino-enters-the-grove/">Netduino Enters the Grove</a></p>
<p>and</p>
<p><a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Netduino: Time and Weather</a></p>
<p>As the project develops it will soon be necessary to move beyond the Grove’s components (that 8&#215;2 display, in particular, is cramping my style).  First, though, we’re going to bring another Grove component into the act: the <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle#Relay_Twig">Relay twig</a>.</p>
<p>The Relay twig is used to switch the plant light off and on.   To connect the relay to the plant light, we first need to splice open an AC extension cord.</p>
<p>Now, I know that Edison fellow has been spreading the word about AC power being dangerous and what-not.  Sounds scary, don&#8217;t it?  Well, it&#8217;s true!  Ask <a href="http://en.wikipedia.org/wiki/Topsy_(elephant)">Topsy the Elephant</a>.</p>
<p>Seriously, though, various unpleasant things <em>can</em> happen if you hook the relay up incorrectly, but fortunately the risk is mainly to the relay, and your self-esteem.  However, since you don&#8217;t want your relay Twig to end up like poor Topsy,  I&#8217;ll spend much of this article covering the process of  making that connection.</p>
<p>You actually have a couple of options: build or buy.</p>
<h2>Option 1 &#8211; Modify an Extension Cord</h2>
</p>
<p>Here&#8217;s the plan: The Relay twig acts as a on/off switch for the extension cord.  The twig has two little green screw connectors.  The &#8220;live&#8221; wire of the extension cord needs to be cut open, and the 2 exposed ends need to be inserted into those 2 green connectors.  Sounds simple, and it is.</p>
<p>The following photo shows a modified 2-prong extension.  It also shows the connection to the Relay twig, but don&#8217;t worry about that for now &#8211; it is explained in the &#8220;Connecting the Relay Twig&#8221; section, below.</p>
<div class="img alignnone size-large wp-image-626" style="width:537px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/01/HPIM0942.jpg"><img src="/wp-content/uploads/2011/01/HPIM0942-768x1024.jpg" alt="Two-pronged extension cord connected to Grove Relay" width="537" height="716" /></a>
	<div>Two-pronged extension cord connected to Grove Relay</div>
</div>
<p>The process of modifying the extension cord isn&#8217;t complicated or dangerous. Anything you do wrong will be evident before you get to the stage where you&#8217;ve got the extension cord plugged into the wall.  However, it does requires some soldering and some common sense.  If you&#8217;re not confident about your abilities at either of these, consider Option 2, below. </p>
<p>The extension cord you use doesn&#8217;t need to be anything special &#8211; the cheapest one at Wal-Mart is good enough.  If your plant light has a three prong plug then, of course, you need to buy a three prong extension cord.</p>
<p>The best guide to what&#8217;s required (and the one I originally followed) is the one in the Make magazine Garduino article. The Instructables version of Garduino refers you to 2 other sites.  Personally, I found the <a href="http://www.glacialwanderer.com/hobbyrobotics/?p=9">Hobby Robotics article</a> to be confusing (so many wires!) and the <a href="http://www.sparkfun.com/tutorials/119">Sparkfun article</a> to be downright intimidating (you don&#8217;t have to pull a power receptacle out of the wall for this project).  As far as I know the Make Magazine article isn&#8217;t available to non-subscribers, but it just so happens that someone (not me) has posted a PDF of this article <a href="https://docs.google.com/viewer?url=http://cm.cdn.fm/fakeup/dow-make/cmweb/entry_assets/MAKE18_Garduino_brnd.pdf">here</a>.  To modify the extension cord for use with Relay twig, follows steps 7a-7c.</p>
<p>The Make magazine article shows how to modify a two-prong extension cord.  If your plant light requires a 3-prong cord, then the only difference is the process of selecting the right wire to cut and splice.  </p>
<p>It <strong><em>must </em></strong>be the &#8220;live&#8221; one, which for both 2- and 3-prong cords is the one connected to the narrower blade of the plug.  Generally, the corresponding wire in the cord is aligned with the blade of the plug (i.e. if the blade is on the left, you need to cut the cord on the left).   However, to make sure that you&#8217;ve selected the right one before cutting it, nick the cord to expose the copper underneath, then use a multimeter to check connectivity with the narrower blade of the plug.  (If you picked the wrong cord, it&#8217;s safe to cover the nick with electrical tape, as I did with the 3-prong extension cord in the photo below.)</p>
<div class="img alignnone size-large wp-image-627" style="width:716px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/01/HPIM0946.jpg"><img src="/wp-content/uploads/2011/01/HPIM0946-1024x768.jpg" alt="Three-pronged extension cord connected to Seeed Relay Brick" width="716" height="537" /></a>
	<div>Three-pronged extension cord connected to Seeed Relay Brick</div>
</div>
<p></p>
<h2>Option 2 &#8211; Buy a Netduino-Friendly Extension Cord</h2>
<p></p>
<p>A product called the &#8220;<a href="http://powerswitchtail.com/default.aspx">PowerSwitch Tail</a>&#8221; recently became available.  It is specifically intended to be hooked up to microcontroller circuits, such as the Arduino and Netduino.  It contains a 5V relay similar to the one in the Grove starter kit &#8211; if you go this route, you can ignore the Grove relay.  You&#8217;ll have to connect a wire from the Powerswitch to the D0 pin of the Netduino (or modify my code to use whichever pin you&#8217;d like).  Then, just skip ahead to the &#8220;First Test&#8221; section below.  You can read more about the PowerSwitch on the <a href="http://www.adafruit.com/index.php?main_page=product_info&amp;products_id=268">Adafruit product page</a> and in Adafruit&#8217;s forums.</p>
<p>I haven&#8217;t tried a PowerSwitch, but I&#8217;m 99.9% sure it will work fine with the Netduino and this project.</p>
<h2>Connecting the Relay Twig</h2>
<p>You should have two wires with exposed tips coming from your extension cord.  As you probably figured out, you need to connect each wire into one of the screw connectors on the Relay twig.  Ah, but which goes into which?</p>
<p>Unfortunately, Seeed didn&#8217;t put any markings on the v0.9 Relay twig to help you out.  The <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle">Datasheet</a> and <a href="http://garden.seeedstudio.com/index.php?title=Project_Five_%E2%80%93_Relay_Control">tutorial </a>on Seeed&#8217;s web site don&#8217;t offer any guidance on this either.  (&#8220;<em>If in doubt contact a professional such as a licensed electrician for help</em>&#8220;.  Uh, yeah, good luck with that.)</p>
<p>However, the HLS8L-DC5V relay happens to be the exact same model as used in Seeed&#8217;s Electronic Brick relay, and the Brick relay is well documented in <a href="http://www.instructables.com/id/SEEED-Studio-Arduino-5V-Relay-module-Digita/">this Instructables article</a> and in <a href="http://www.seeedstudio.com/forum/viewtopic.php?f=4&#038;t=683&#038;start=0&#038;hilit=relay">this Seeed Forum post</a>.</p>
<p>The Grove relay has removed one of the Brick&#8217;s 3 screw connectors, meaning that the only way you can hook it up is &#8220;normally open&#8221;.  This means that the extension cord <strong>won&#8217;t</strong> (yeah, &#8220;open&#8221; means &#8220;off&#8221; &#8211; go figure) conduct electricity when your Netduino project is powered off.</p>
<p>The 2 screw connectors are, then, are the &#8220;Common&#8221; and &#8220;NO&#8221; connectors shown in the Instructables article.  As with its big brother, the Seeed Relay Brick, the twig&#8217;s Common connector is on the left (when the screw connectors are facing you) and Normally Open is on the right.  See the photos in this post.</p>
<p><strong>Important Note</strong>: this is true for the &#8220;0.9&#8243; version of the twig, which is the first version that was sold.  If your twig doesn&#8217;t say 0.9 on it, then I&#8217;d strongly suggest you double-check this information, either by using a multimeter or by checking the Seeed product page or forum.  Seeed recently posted an article about <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle_V1.0b">version 1.0 of the Grove Starter Bundle</a>.  The Relay twig photo on that page looks more like a Relay forest, so if your twig is bristling with relays then all bets are off!</p>
<p>To check continuity with a multimeter, you want to confirm that the &#8220;Common&#8221; left-hand screw connector is connected to the middle pin at one end of the black relay box, and the other screw connector is connected to one of the 2 pins at the other end of the black relay box. I think the best illustration of the orientation of the pins for this relay is the one in the <a href="http://www.seeedstudio.com/forum/viewtopic.php?f=4&amp;t=683&amp;p=2661&amp;hilit=relay#p2661">Seeed forum thread</a>.</p>
<div class="img alignnone size-large wp-image-628" style="width:716px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/01/HPIM0940.jpg"><img src="/wp-content/uploads/2011/01/HPIM0940-1024x768.jpg" alt="Grove Relay Brick - hooked up and ready to rock" width="716" height="537" /></a>
	<div>Grove Relay Brick - hooked up and ready to rock</div>
</div>
<p>OK, so at this point you should have an UNPLUGGED extension cord that is connected to an unplugged relay twig.   This is the time to ensure that you&#8217;ve firmly and securely connected the extension cord to the relay.  Tug  <em>hard </em>on the relay twig to make sure that it doesn&#8217;t come loose from the extension cord.  </p>
<p>Carefully inspect the points at which the wires from the extension cord are plugged into the screw connectors of the Grove twig.  There must not be any exposed metal from the wire.  If there is, insert the wire further into the screw connector or, if the exposed metal is simply too long, snip it shorter.</p>
<p>That cord-to-relay connection is the only dangerous (to you) part of the setup, and you definitely don&#8217;t want to have a wire come loose after you plug it in!</p>
<p>Incidentally, if you Googled for information about the HLS8L-DC5V relay, you may have been unsettled to find that there isn&#8217;t much out there, aside from a bunch of pretend-datasheet-sites gaming Googling search engine.  However, I&#8217;ve had 2 of the Seeed bricks with this relay in daily service for about 6 months now, and never had a problem with either of them.  So, for what its worth, I&#8217;m pretty comfortable with this relay, safety-wise.</p>
<h2>Initial Test</h2>
</p>
<p>I&#8217;ve written a small test project, <a href="http://www.gigamegablog.com/files/RelayTester.zip">RelayTester</a>, that you can use to test turning the relay off and on.  Pressing the green button (connected to D8) toggles the relay.</p>
<p>Start by unplugging everything from the Grove shield.  Reconnect to the Grove shield just 2 twigs: the one with the red and green buttons (connected to plug D7/D8) and the Relay twig (connected to D0, and to an UNPLUGGED extension cord).  Yes, there, is such a thing as D0 on the Grove shield, off to one end, as shown in the photo in the &#8220;Final Configuration&#8221; section, below.</p>
<p>Deploy the test project to the Netduino.  For this part of the test, you can leave the Netduino plugged into the USB port of the PC.</p>
<p>The red light on the relay may briefly go on and then off when the Netduino boots up.  Press the green button on the button twig, and the red light should come on and stay on.  Press the green button again to turn it off.</p>
<p>Do you hear a fairly loud clicking noise from the black relay box each time the red light goes on or off?  If not, something is wrong.</p>
<p>If the red light on the relay works, but there is no click, try using a different cable between the Relay twig and the Netduino.  If that doesn&#8217;t help, try a different connector than D0 (you&#8217;ll have to change the test program code accordingly, of course).</p>
<p>If the red light doesn&#8217;t come on at all, check that the connectors are plugged into the Grove shield correctly (buttons in D7/D8, relay in D0, and nothing else connected), and that the project was deployed to the Netduino correctly.  (It will display messages to the Visual Studio Debug window when turning the relay on or off).</p>
<p>If that’s not the problem, then you might have a bad relay twig and should check the Seeed forums or e-mail them.</p>
<h2>Live Test</h2>
</p>
<p>I don&#8217;t think there is much risk to the Netduino if things aren&#8217;t hooked up correctly.  The Netduino isn&#8217;t exposed to the AC current &#8211; that&#8217;s the whole idea of the relay.  The biggest risk is to the relay itself, and possibly to whatever you have plugged into your extension cord.  However, as an extra precaution, I&#8217;d suggest you have as little as possible connected to the Netduino: the Grove shield, the button twig and the relay twig.</p>
<p>Also, I&#8217;d suggest you power the Netduino from a DC adapter rather than the PC&#8217;s USB port.  The concern isn’t that the relay is power-hungry, but that you want to protect your PC’s USB port if things go wrong.    (If you haven&#8217;t run the Netduino with that DC adapter before, rerun the above &#8220;Initial Test&#8221; with the extension cord still unplugged from the wall.)</p>
<p>OK, so it&#8217;s all been fun and games so far, but no fooling around for this test. Remember Topsy!</p>
<ol>
<li>Plug the plant light (or a cheap test light) into the extension cord.</li>
<li>Plug the extension cord into the wall.</li>
<li>Plug the DC adapter into the Netduino.</li>
<li>Press the green button.  Let there be light!</li>
<li>Leave the light turned on for awhile, periodically touching the extension cord, the wires leading from the extension cord to the relay, and black relay box to make sure it isn’t getting hot.  The cord and wires shouldn&#8217;t get warm at all; the relay box will be very slightly warm.</li>
</ol>
<p>One last (I promise!) comment about safety: ideally you should never make any adjustment to the relay/extension cord/light setup with the extension cord plugged in.  When hooking things up, and when adjusting the setup, unplug the extension cord first.  Keep an eye on those 2 screw terminals on the Relay twig and the wires inserted into them &#8212; that&#8217;s the danger zone.  Don&#8217;t pile anything on top of them, don&#8217;t let those wires get snagged on something.</p>
<h2>Final Configuration</h2>
</p>
<p>OK, let&#8217;s bring the rest of the Grove twigs back on stage.  (Not you, Prototype Twig, we aren&#8217;t ready for you yet.  Oh, and Tilt Switch twig, um, you can run along home.  We&#8217;ll keep you in our files, and we&#8217;ll call if we need to do any tilting).</p>
<p>The configuration is the same as in the previous project, Time and Weather, with the addition of the Relay twig:</p>
<ul>
<li> D0/D1 &#8211; Relay</li>
<li>D2 &#8211; jumper to TX pin of serial header on breadboard</li>
<li>D3 &#8211; jumper to RX pin of serial header on breadboard</li>
<li>D4/D5 &#8211; right side of LCD stem, lower connector</li>
<li>D6/D7 &#8211; piezo buffer twig (only D6 is used)</li>
<li>D7/D8 &#8211; button twig</li>
<li>D9/D10 &#8211; bottom of LCD stem, right connector</li>
<li>D11/D12 &#8211; bottom of LCD stem, left connector</li>
<li>D13 &#8211; right side of LCD stem, upper connector</li>
<li>A0 &#8211; modified potentiometer (unused for Grove LCD, or any other LCD without a software backlight control)</li>
<li>A2 &#8211; temperature twig</li>
</ul>
<div class="img alignnone size-large wp-image-625" style="width:537px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/01/HPIM0951.jpg"><img src="/wp-content/uploads/2011/01/HPIM0951-768x1024.jpg" alt="Final Configuration of the Netduino and Grove components.  Can't see the forest for the trees!" width="537" height="716" /></a>
	<div>Final Configuration of the Netduino and Grove components.  Can't see the forest for the trees!</div>
</div>
<p>By now, you&#8217;ve probably noticed that I have a strange aversion to pin D1.  What&#8217;s up with that?</p>
<p>Well, I have 2 Netduinos, one for development and one for testing.  My test Netduino suffered an unfortunate accident, resulting in it being, um, &#8220;differently abled&#8221; on the D1 pin.</p>
<p>Wait, what?   The guy who&#8217;s  giving you safety tips electrocuted his Netduino?</p>
<p>Well, not on this project &#8211; honest!  I&#8217;m actually not sure at what point it stopped working, but I suspect it occurred while experimenting with the not-particularly-dangerous-but-not-Netduino-friendly <a href="http://www.zachhoeken.com/danger-shield-v1-0">Danger Shield</a>.  (See my &#8220;Spiderman: The Musical&#8221; project for details).</p>
<p>The source code for the LightController project can be downloaded <a href="http://www.gigamegablog.com/files/LightController.zip">here</a>.</p>
<p>As with the test project, press (and, this time, <em>hold</em>) the green button to manually turn the relay (and light) on and off.  You can also program it to turn off and on at a certain time, using the handy serial port connection from the previous project.  (Stop groaning, we&#8217;ll get rid of the serial port in a later project, I promise.)</p>
<p>The 2 new commands are:</p>
<pre class="brush: bash; title: ; notranslate">
+:hh:mm

Sets the time at which the light will come on
</pre>
<pre class="brush: bash; title: ; notranslate">
-:hh:mm

Sets the time at which the light will go out.
</pre>
<p>There is no default on and off time &#8211; you have to set them manually for now.  (Since you have to set the Netduino&#8217;s clock manually, there wouldn&#8217;t be much point to having default timer settings).</p>
<p>I&#8217;ve also added some new button features, pretty much exhausting the possibilities for the 2-button twig:</p>
<ul>
<li>Press the red button: Toggles LCD between the regular time/temperature display, and a display of the  Light On and Light Off times.   If all you see is &#8220;+&#8221; and &#8220;-&#8221;, with no times, then you need to set the times using the serial terminal &#8220;+&#8221; and &#8220;-&#8221; commands, as described above.</li>
<li>Press and hold red button: Toggles the serial port off and on, as described in the &#8220;<a href="http://gigamegablog.com/2010/12/29/netduino-time-and-weather/">Time and Weather</a>&#8221; article.</li>
<li>Press the green button: toggles the first row of the LCD between the current time and a countdown to the next light &#8220;event&#8221;.  That is, if the light is currently on, it shows a countdown to when the light will go off.  And vice versa.</li>
<li>Press and hold green button: toggles the light off and on.</li>
<li>Press and hold red and green button: clears the light on and light off timer.  Also makes your fingers hurt.</li>
</ul>
<h2>Programmer Show And Tell</h2>
</p>
<p>The new code has a few features worth mentioning.</p>
<p>The light on/off timers are implemented using the <a href="http://msdn.microsoft.com/en-us/library/cc561915.aspx">ExtendedTimer</a> class.  This is the lesser known of the 2 .Net Framework timers.  It is better suited than the Timer class for time events that occur at specific times of day, rather than at intervals.</p>
<p>For example, the code to set the &#8220;light on&#8221; timer is:</p>
<pre class="brush: csharp; title: ; notranslate">
// set the timer to go off at this date, and every 24 hours after that
tmrLightOn = new ExtendedTimer(new TimerCallback(SetLightState), true, datAlarm, new TimeSpan(1, 0, 0, 0));
</pre>
<p>Since we want the light to come on at the same time each day, the ExtendedTimer constructor does all the work.  There is no need to reset the timer for the next day when the timer event fires.</p>
<p>The countdown timer takes advantage of the fact that, in .Net, subtracting one date from another returns a TimeSpan that gives the difference between them:</p>
<pre class="brush: csharp; title: ; notranslate">
// relay is off, display time to next light-off
string strCountdown;
if (datNextOn == DateTime.MinValue)
{
    strCountdown = &quot;Not set&quot;;
} else
{
   TimeSpan timeTo = datNextOn.Subtract(DateTime.Now);
   strCountdown = timeTo.ToString();
}
lcd.SelectLine(1, true);
lcd.WriteStringToLCD(strCountdown);
</pre>
<p>Note that DateTime (and TimeSpan) objects can&#8217;t be null &#8211; an unset DateTime has a value of DateTime.MinValue.</p>
<p>And lastly, this projects makes extensive use of the 2 pushbuttons.  I really like the fact that all the button features can be implemented in the .Net MF without polling.  </p>
<p>Buttons can be configured as InterruptPorts.  The InterruptPort constructor has a parm that lets you specify when the event should be triggered &#8212; when you press the button, when you release the button, or both. The following code specifies both:</p>
<pre class="brush: csharp; title: ; notranslate">
buttonRed = new InterruptPort(Pins.GPIO_PIN_D7, true,
   SecretLabs.NETMF.Hardware.Netduino.ResistorModes.Disabled,
   SecretLabs.NETMF.Hardware.Netduino.InterruptModes.InterruptEdgeBoth);
</pre>
<p>The event handler needs to handle 2 cases: a short push and a push-and-hold.  The handler can&#8217;t know which it is until the button is released.  On the other hand, the user would like to have some confirmation of the push-and-hold action before letting go.  The answer is to set a timer (the regular kind) on the button press.  If the button is released before the timer goes off, that&#8217;s a short push.  If the timer expires first, then that&#8217;s a push-and-hold.  I use a 2-second timer.</p>
<p>Here&#8217;s the button&#8217;s event handler.  The same event handler is fired when the button is pressed and when it is released.   The <em>state </em>parm tells you which event it is.</p>
<pre class="brush: csharp; title: ; notranslate">
static void buttonRed_OnInterrupt(uint port, uint state, DateTime time)
{

  if (state == 1)
  {
     // start the button hold timer
    timerButtonRed = new Timer(new TimerCallback(buttonHold),
       buttonRed, BUTTON_DELAY, BUTTON_DELAY);
  }
  else
  {
     // cancel the button hold timer
     if (timerButtonRed != null)
     {
        timerButtonRed.Dispose();
      }
      if (blnButtonHeld)
      {
         // timer went off, so ignore the release
         blnButtonHeld = false;
         return;
      }

      // normal button press - handle it

      . . .
</pre>
<p>Note that .Net MF timers are turned off using the .Dispose method &#8211; there is no property for setting a timer&#8217;s active state.</p>
<p>Last, here&#8217;s the timer&#8217;s event handler.  I decided to have the red and green button share the same button timer, so a parm is passed to indicate which button it is.  </p>
<p>A boolean variable is used to tell the button&#8217;s event handler to ignore the button&#8217;s release event when the user eventually lets go.  </p>
<p>Note that, in order to implement the double-button-hold feature for clearing the timers, the code checks the state of the other button using the .Read method, same as you would if you used polling to check the buttons.</p>
<pre class="brush: csharp; title: ; notranslate">
private static void buttonHold(object data)
{

  // tell the button release event to ignore it - we're handling it
  blnButtonHeld = true;

  if ((InterruptPort)data == buttonRed)
  {
     // cancel the button hold timer - otherwise, this event will go off again if user keeps button pressed
     timerButtonRed.Dispose();

     // if both buttons are held down, clear the light timers
     if (buttonGreen.Read())
     {
        // cancel the green button's timer
        timerButtonGreen.Dispose();

        clearTimers();
     }
     . . .
</pre>
<p>So what&#8217;s next for this project?  Needless to say, this project is badly in need of an improved user interface, so a menu system can be used to replace (or supplement) the serial port commands.  This will require that we say bye-bye to the tiny 8&#215;2 Grove LCD.</p>
<div>But first, we&#8217;ll let Mother Nature handle one of the settings.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/01/08/netduino-let-there-be-light/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netduino: Time and Weather</title>
		<link>http://www.gigamegablog.com/2010/12/29/netduino-time-and-weather/</link>
		<comments>http://www.gigamegablog.com/2010/12/29/netduino-time-and-weather/#comments</comments>
		<pubDate>Wed, 29 Dec 2010 21:18:29 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=552</guid>
		<description><![CDATA[Note: The source code for the project described in this post can be downloaded here. This post is a continuation of my &#8220;Netduino Enters the Grove&#8221; article.   Building on the project in that post, I&#8217;m going to make the &#8230; <a href="http://www.gigamegablog.com/2010/12/29/netduino-time-and-weather/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Note: The source code for the project described in this post <a href="http://www.gigamegablog.com/files/Netduino_ClockAndTemperature.zip">can be downloaded here</a>.</strong></p>
<p>This post is a continuation of my &#8220;<a href="http://gigamegablog.com/2010/12/20/netduino-enters-the-grove/">Netduino Enters the Grove</a>&#8221; article.   Building on the project in that post, I&#8217;m going to make the <a href="http://www.netduino.com/netduino/">Netduino</a> a more productive member of society by having it display the time, in addition to the temperature.</p>
<p>I&#8217;m also going to add to the mix a couple more &#8220;twigs&#8221; from the <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=138">Seeed Grove Starter Kit</a>: the <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle#LCD_Module_Twig">8 x 2 LCD</a>, and the <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle#Piezo_Buzzer_Twig">piezo buzzer</a>.</p>
<p>Lastly, I&#8217;m going to make use of the Netduino&#8217;s serial port to show how to make it communicate with a PC.</p>
<h2><strong>Adding the Grove Parallel LCD</strong></h2>
<div class="img alignright size-medium wp-image-560" style="width:450px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/HPIM0921.jpg"><img src="/wp-content/uploads/2010/12/HPIM0921-300x160.jpg" alt="The Seeed Grove LCD - all the news that 8 x 2 can fit.   Click to enlarge." width="450" height="240" /></a>
	<div>The Seeed Grove LCD - all the news that 8 x 2 can fit.   Click to enlarge.</div>
</div>
<p>The Grove Starter Kit comes with a rather odd LCD: a cramped 8 x 2 board bristling with 24 pins, 6 of them for voltage and 6 for ground.</p>
<p>Since documentation isn&#8217;t Seeed&#8217;s strong suit, this has led to some head-scratching about the best way to connect the LCD to an Arduino. I wasn&#8217;t too optimistic about getting it to work with a Netduino, which is one of the reasons I went with a serial LCD in my earlier post.</p>
<p>However, it turned out to be relatively straightforward to connect, thanks to <a href="http://microliquidcrystal.codeplex.com/">Szymon Kobalczyk&#8217;s excellent MicroLiquidCrystal library</a>.</p>
<p>The LCD connectors that you need to use are the 2 on the right and the 2 on the bottom. The pins are labelled on the back of the LCD&#8217;s  &#8221;stem&#8221; board &#8211; clockwise from the upper right  connector (and ignoring the voltage and ground pins) they are RW, NC (unused), RS, EN, D4, D5, D6 and D7. These are the pins used in almost any LCD library based on the HD44780 chipset, including one of the constructors of the MicroLiquidCrystal library. (MicroLiquidCrystal supports other types of connections that use fewer digital ports, but for the purpose of testing the Grove LCD&#8217;s default configuration I&#8217;ll stick to the more traditional GPIO connection for this project).</p>
<p>The 2 key lines of code are:</p>
<pre class="brush: csharp; title: ; notranslate">
GpioLcdTransferProvider lcdProvider =
     new GpioLcdTransferProvider(rs, rw, enable, d4, d5, d6, d7);
Lcd lcd = new Lcd(lcdProvider);
</pre>
<p>In my project, I&#8217;ve added a wrapper class to MicroLiquidCrystal in order to make to compatible with the 2 other devices I use when testing: a Matrix Orbital serial LCD and a Sparkfun Serial LCD Backpack (<a href="http://gigamegablog.com/2010/12/20/netduino-enters-the-grove/">as described in my earlier article</a>). So, the code which calls the above methods is in the <em>clsLCD_MLC</em> constructor in the attached source code:</p>
<pre class="brush: csharp; title: ; notranslate">
public clsLCD_MLC(Cpu.Pin rs, Cpu.Pin rw, Cpu.Pin enable, Cpu.Pin d4,
    Cpu.Pin d5, Cpu.Pin d6, Cpu.Pin d7, byte rows, byte cols)
{
// NOTE - RW pin is needed for Seeed's Grove LCD
lcdProvider = new GpioLcdTransferProvider(rs, rw, enable, d4, d5, d6, d7);
//lcdProvider = new GpioLcdTransferProvider(rs, enable, d4, d5, d6, d7);
lcd = new Lcd(lcdProvider);
SetScreenSize(rows, cols);
lcd.Write(&quot;hello, world!&quot;);
Thread.Sleep(500); // greet the world and give the LCD time to get its act in order
</pre>
<p>The call to this code specifies what pins are being used. The configuration shown in the photos uses the following:</p>
<pre class="brush: csharp; title: ; notranslate">
lcd = new clsLCD_MLC(Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D13, Pins.GPIO_PIN_D5,
Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D11, Pins.GPIO_PIN_D12, 2, 8);
</pre>
<p>So, the 4 Grove cables are connected to the Grove shield using (clockwise from the upper right): D13/NC, D4/D5, D9/D10, DD11/D12. Actually, I&#8217;m pretty sure that any 4 connectors (or 7 pins) would work just as well. I went with these in order to save the serial port pins and one of the PWM pins  for other uses.</p>
<p>The <a href="http://garden.seeedstudio.com/index.php?title=Project_Six_%E2%80%93_LCD_Demonstration">LCD tutorial in the Grove documentation</a> suggests that a 6 pin connection is also possible (minus the RW pin), but I couldn&#8217;t get that to work with either the Arduino or Netduino.</p>
<p>By the way, if you are trying your Grove LCD for the first time and nothing appears on the screen, the first thing to check is the contrast control. This is a little metallic potentiometer on the LCD &#8220;stem&#8221; board &#8211; it looks like a brass screw-head. If you don&#8217;t see a line of block characters when you first power-up the LCD, then turn the potentiometer counter-clockwise, then try again.</p>
<p>There are a few drawbacks to the Grove LCD compared to other parallel LCDs. The first and most obvious is the size &#8211; 8 x 2 characters is OK for the time and temperature, but won&#8217;t be enough for future projects. The backlight is &#8220;always on&#8221;, with no easy way to control that. Presumably, it can be controlled by connecting one (hopefully not all 4!) of the connectors&#8217; voltage pins to a digital PWM pin. However, I haven&#8217;t tried this myself yet). The 2 connectors on the bottom, combined with the stiff connector cables, makes mounting the LCD somewhat of a mechanical challenge, as you can see in the photo.</p>
<p>And yet it works. I tested the Netduino Time/Temperature gadget for a couple of days, and the LCD didn&#8217;t display any garbled characters or have any other problems.</p>
<h2>Adding the Grove Piezo Buzzer</h2>
<p>The buzzer connection is quite straightforward. You can connect it to any digital pin if you just want it to buzz, or to a PWM pin if you want to give it a greater musical range. The Netduino has just four PWM pins, 5, 6, 9 and 10. For the purpose of this project, I&#8217;m using pin 6.</p>
<p>Since PWM is not supported by the underlying Micro Net Framework, its implementation is left up to the hardware maker. As with Seeed Studios, documentation doesn&#8217;t seem to be Secret Labs&#8217; strong suit &#8211; they definitely know how to keep a secret. This makes the process of controlling the buzzer a little tricky to figure out. I found the best source to be the full-featured and well-documented code in this <a href="http://forums.netduino.com/index.php?/topic/831-music-with-a-piezo-speaker/">post by Ray Mckaig on the Netduino forums</a>.</p>
<p>This is a low-end buzzer, so its musical range runs the gamut from annoying to tortuous. The following code makes 2 types of sounds: an annoying ding-a-ling somewhat like a cordless phone (when the parm is true), or a tortuous beeeeeep that my cat really, really dislikes.</p>
<pre class="brush: csharp; title: ; notranslate">
public static void Beep(bool blnUp)
{

blnBeeping = true;
float fltFreq = 10;
int intDuration = 1000;
if (!blnUp)
{
fltFreq = 30;
intDuration = 1000;
}

uint period = (uint)(1000000 / fltFreq);
buzzer.SetPulse(period, period / 2);
Thread.Sleep(intDuration);
buzzer.SetDutyCycle(0);

}
</pre>
<h2>Setting the time through a serial port</h2>
<div class="img alignright size-medium wp-image-561" style="width:450px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/HPIM0926.jpg"><img src="/wp-content/uploads/2010/12/HPIM0926-300x204.jpg" alt="Netduino's serial connection - click to enlarge" width="450" height="306" /></a>
	<div>Netduino's serial connection - click to enlarge</div>
</div>One of the most noticeable differences between the .Net Micro Framework and the Arduino is that it is considerably more difficult to have a PC send commands to a NMF device. The Arduino uses the USB connection for this, but the NMF reserves the USB connection for use by the debuggers.</p>
<p>(Secret Labs has recently added a firmware feature that allows your program to use the USB port as a serial device, and use one of the Netduino&#8217;s serial ports for deploying code and debugging, but I haven&#8217;t tried that out yet.)</p>
<p>When using a Netduino serial port for communication with a PC, you&#8217;ve got 2 problems: the voltage level sent and received on the Netduino&#8217;s pins (3.3V) is much lower than what the PC sends and receives, and the communication protocol used by the Netduino (TTL) is not the same as what the PC uses (RS-232).</p>
<p>Fortunately, there is a relatively inexpensive device that solves both problems: a <a href="http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm">3.3V FTDI cable</a>. This is widely available at hobby electronics retailers such as <a href="http://www.adafruit.com/index.php?main_page=product_info&amp;products_id=70">Adafruit</a> and <a href="http://www.sparkfun.com/products/9717">Sparkfun</a>. If you use an <a href="http://www.ladyada.net/make/boarduino/">Adafruit Boarduino</a>, <a href="http://www.solarbotics.com/products/kardw/">Solarbotics Ardweeny</a>, <a href="http://www.netduino.com/netduinomini/specs.htm">Secret Labs&#8217; own Netduino Mini</a>, or some other microcontroller-based device that doesn&#8217;t include a USB port, then you probably already have this cable.</p>
<p>With the cable, connection of the Netduino to a PC pretty simple. Only 3 of the cable&#8217;s coloured connectors are used: the black cable (ground) should be connected to ground, the orange cable (TX) should be connected to the RX pin of one of the Netduino&#8217;s 2 COM RX pins (pin 0 or 2) and the yellow cable (RX) to one of the Netduino&#8217;s TX pins (1 or 3).</p>
<p>In the photo of my setup, I&#8217;ve inserted a 5 pin male header <a href="http://www.sparkfun.com/products/116">like this</a> into the breadboard.   You&#8217;ll need to adjust the pins in the header slightly so that they stick out about the same amount on both sides of the header.  Since I&#8217;m using COM2 on the Netduino,  the white jumper cable goes from the breadboard to pin 2 and the yellow jumper to pin 3.</p>
<p>The code to open the COM port is in the constructor of my &#8220;clsUART&#8221; class:</p>
<pre class="brush: csharp; title: ; notranslate">
public clsUART(string strPort, Int16 intBaud, int intReadBufferLen, bool blnSendResponse)
{

SerialPort UART = new SerialPort(strPort, intBaud, Parity.None, 8, StopBits.One);
UART.Open();
UART.DataReceived += new SerialDataReceivedEventHandler(UART_DataReceived);
Debug.Print(strPort + &quot; Opened at baud &quot; + intBaud);
WriteToUART(&quot;Hello World&quot;);
</pre>
<p>And the call to this constructor is:</p>
<pre class="brush: csharp; title: ; notranslate">
uart = new clsUART(SerialPorts.COM2, 9600, 50, true);
uart.Command += new CommandEventHandler(uart_Command);
</pre>
<p>A couple of things to note about using the MNF&#8217;s SerialPort:<br />
- In order to use the Net MF&#8217;s SerialPort class, the Project References must include a reference to Microsoft.SPOT.Hardware.Serial. This isn&#8217;t included by Visual Studio in a new Netduino project by default &#8211; it has to be added manually<br />
<div class="img alignright size-medium wp-image-562" style="width:300px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/WinPuTTY1.png"><img src="/wp-content/uploads/2010/12/WinPuTTY1-300x235.png" alt="PuTTY settings, with some (partially overwritten) terminal commands in the background.  Click to enlarge" width="300" height="235" /></a>
	<div>PuTTY settings, with some (partially overwritten) terminal commands in the background.  Click to enlarge</div>
</div>- The SerialPort constructor allows you to specify not only the COM port, but also the baud rate and the other, more esoteric serial connection settings. Be sure that the serial terminal program on your PC it using the same settings. In my case, I&#8217;m using PuTTY, and the serial settings are as shown to the right. The only settings that I changed from the default were Flow Control (set it off) and Local Echo (force it on, in order  to see what you are typing).</p>
<p>One of the nice things about the FTDI cable is that the chip which handles the RS-232 communications with the PC is embedded in the cable, and therefore it is ready to go as soon as you plug the cable into the PC. You can then use PuTTY (or your serial terminal of choice) to connect to whatever COM port the PC assigns to the cable. If there is nothing at the other end of the cable, other terminal screen will remain empty, but you won&#8217;t get any errors either.</p>
<div class="img alignright size-medium wp-image-563" style="width:300px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/WinPuTTY2.png"><img src="/wp-content/uploads/2010/12/WinPuTTY2-300x289.png" alt="More PuTTY settings - note the Local Echo option.  Click to enlarge" width="300" height="289" /></a>
	<div>More PuTTY settings - note the Local Echo option.  Click to enlarge</div>
</div>The Netduino is not too picky about its own COM port &#8211; you can power it on with nothing connected to the COM port pins and it will happily open that COM port without complaint.</p>
<p>However, if you &#8220;hot plug&#8221; the FTDI cable into your Netduino when it is already up and running, you&#8217;ll likely find that the connection doesn&#8217;t automagically start working &#8211; you have to reset the Netduino&#8217;s COM port. I added some code to handle this by pressing and holding the red button. This toggles the COM state on or off, sends a message  to the LCD, Visual Studio&#8217;s Debug window, and the PC serial&#8217;s terminal, and makes a buzzer noise (the annoying one when the port goes down, the tortuous one when the port comes back up).</p>
<p>If your PC&#8217;s serial terminal displays &#8220;Hello world&#8221; when the Netduino boots up, or &#8220;Hello again world&#8221; when you toggle the port open with the red button, then the Netduino is yours to command. It knows the following commands:</p>
<pre class="brush: bash; title: ; notranslate">
Set time:
T:hh:mm[:ss]
e.g. T:14:35

Set date:
D:yyyy-mm-dd
e.g. D:2010-12-29

Set temperature format (Celcius or Fahrenheit):
F:F|C
e.g. F:C

Set LCD backlight:
L:ON|OFF
e.g. L:OFF

Set LCD brightness:
B:nnn where nnn is 0-255
e.g. B:128
</pre>
<p>The Netduino will respond to a valid command by sending &#8220;OK&#8221; to the terminal.  Generally the LCD will immediately be updated with whatever setting you changed. However, in the case of the 8 x 2 Grove LCD setting the date and changing the backlight or brightness has no effect.</p>
<p>Should you enter a command that the Netduino doesn&#8217;t recognize, it will send a &#8220;?&#8221; to the terminal and making the annoying sound with the buzzer, so type carefully!</p>
<p>All things considered, this is probably the simplest way to set the time on the Netduino, but also the least convenient.  (A clock that has to be set using a serial port &#8211; Grandma&#8217;s worst nightmare!).</p>
<p>In future posts, I plan to demonstrate a few other methods: an on-screen menu (more convenient, but  lots of coding), an Ethernet shield (very convenient for the user &#8211; it sets itself &#8211; but not so convenient if you don&#8217;t happen to have an Ethernet port nearby) and a wireless <a href="http://www.digi.com/products/wireless/point-multipoint/xbee-series1-module.jsp#overview">XBee</a> connection (very very convenient, très cool, and my platform of choice for a lot of projects).</p>
<p><strong>Note</strong>: The source code for the project described in this post can be downloaded <a href="www.gigamegablog.com/files/Netduino_ClockAndTemperature.zip">here</a>.  The .zip file contains 2 folders: one (ClockAndTemperature) with my source and one (MicroLiquidCrystal) with the <a href="http://microliquidcrystal.codeplex.com/">MicroLiquidCrystal</a> library.  The latter is a separate project that is loaded by the ClockAndTemperature solution file.  The 2 folders should therefore be stored in the same parent folder.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2010/12/29/netduino-time-and-weather/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Netduino Enters the Grove</title>
		<link>http://www.gigamegablog.com/2010/12/20/netduino-enters-the-grove/</link>
		<comments>http://www.gigamegablog.com/2010/12/20/netduino-enters-the-grove/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 19:41:55 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=494</guid>
		<description><![CDATA[Note: The source code for the temperature LCD program described in this article can be downloaded here. I recently received one of Seeed Studio&#8217;s new Grove Starter Bundles. Since many others will put GROVE through its paces using an Arduino &#8230; <a href="http://www.gigamegablog.com/2010/12/20/netduino-enters-the-grove/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Note:</strong> The source code for the temperature LCD program described in this article can be downloaded <a href="http://www.gigamegablog.com/files/NetduinoSerialLCDTester.zip">here</a>.</p>
<p>I recently received one of <a href="http://seeedstudio.com/depot/">Seeed Studio&#8217;</a>s  new <a href="http://www.seeedstudio.com/depot/grove-starter-bundle-p-709.html?cPath=129&amp;zenid=3f85557292097af045b80d02208d8051">Grove Starter Bundles</a>.  Since many others will put GROVE through its paces using an Arduino &#8212; and Seeed recently posted a <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle#Projects">series of projects</a> that do just that &#8212; I thought it would be interesting to try it out with a <a href="http://netduino.com/">Netduino</a> instead.</p>
<p>For those unfamiliar with these two products, Grove is a set of plug-and-use electronics components, like sensors and controls, intended to be used with an Arduino-compatible shield.  The Netduino is a <a href="http://www.microsoft.com/netmf/default.mspx">.Net Micro Framework</a>-based system that uses the same form factor and pinout as the Arduino.</p>
<p><strong>Why Grove?</strong></p>
<div class="img alignright size-full wp-image-511" style="width:448px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/NetduinoSerialLCD.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2010/12/NetduinoSerialLCD.jpg" alt="Netduino meets Seeed Grove" width="448" height="336" /></a>
	<div>Netduino meets Seeed Grove</div>
</div>The Grove system (and Seeed&#8217;s previous generation <a href="http://www.seeedstudio.com/depot/electronic-brick-starter-kit-p-506.html?cPath=48_69&amp;zenid=72db1b539ddbfd68fd0db4bb4423f4d4">Electronic Bricks</a>) are great for prototyping.  Wiring components to a breadboard-based Arduino system can be rather frustrating, since you have to be sure that all the wires and components stay firmly plugged in.  Buttons and potentiometers are particularly tricky.  With the Grove system, wiring a component to an Arduino is a snap, literally. Each component connects using a latched cable, ensuring that things stay put.</p>
<p>The closest competitor to Grove that I know of is the <a href="http://www.phidgets.com/">Phidgets</a> systems. Seeed&#8217;s product is considerably less expensive and, in my experience, the quality is just as good.  The Phidgets system, on the other hand, has top quality documentation, and can be directly interfaced with PCs without using an *duino go-between.</p>
<p>The advantages of GROVE over Seeed&#8217;s Electronic Bricks are, frankly, yet to be revealed.  The GROVE components can use 2 pins, not just 1.  In some cases this allows one component (they&#8217;re called twigs, actually) to include 2 separate items, such as 2 pushbuttons or 2 LEDs.</p>
<p>However, I think the real reason for the double-pin support is that the &#8220;twigs&#8221; contain edge connectors which would allow them to be directly connected to one another. You can see what I mean by looking at <a href="http://garden.seeedstudio.com/index.php?title=GROVE_-_Starter_Bundle">the photos of the various components on this page</a>.  Those markings on the edges of each twig&#8217;s circuit board (VCC, GND, D1, D2 etc.) are pads that align with those on other twig&#8217;s boards.   I&#8217;m honestly not sure where that is leading, since the Grove was just released and the documentation is a work in progress, but I assume that the goal isn&#8217;t just to reduce cable usage.  Stay tuned.</p>
<p><strong>Why Netduino?</strong></p>
<p>If you are a programmer, or learning to become one, then the advantages of Secret Lab&#8217;s Netduino over the Arduino are clear.</p>
<p>The Netduino&#8217;s IDE is Microsoft&#8217;s venerable Visual Studio 2010, which absolutely bristles with features when compared to the Arduino&#8217;s IDE.   The free <a href="http://www.microsoft.com/express/Windows/">Visual Studio C# 2010 Express</a> is well suited to Netduino  development, since the extra features found in the other Visual Studio versions generally don&#8217;t apply to microcontroller programming.</p>
<p>And, even more importantly, the Netduino supports In Circuit Debugging, using nothing more than a USB cable. No more trial-and-error debugging and testing! As Joe Biden would say, that is a <a href="http://www.huffingtonpost.com/2010/03/23/joe-bidens-life-one-big-f_n_510272.html#s75533">Big F&#8217;ing Deal</a>!</p>
<p>If you aren&#8217;t a Windows user,the the disadvantages of the Netduino over the Arduino are also clear.  &#8216;Nuff said.  The Arduino also has a larger and more established hobbyist community, and is probably a better choice for somebody new to coding.</p>
<p>The Netduino has a close competitor, the <a href="http://www.tinyclr.com/hardware/16/fez-panda/">FEZ Panda</a> from GHI.  GHI has actually been in the .Net Micro Framework game a lot longer than Secret Labs, and their firmware and documentation are therefore much, much better.  When Netduino first came along this summer, it had a clear price advantage over GHI&#8217;s first Arduino-compatible board, the Domino.  GHI quickly responded with a budget board called the Panda, Secret Labs responded with a feature-rich board, the <a href="http://netduino.com/netduinoplus/specs.htm">Netduino Plus</a>, and the fight is on!</p>
<p>But, back to the point of this article: Netduino&#8217;s adventures in the Grove.</p>
<p><strong>Digital Components</strong></p>
<p>The first things I tried were some basic digital components, and they worked pretty much seamlessly.</p>
<div class="img alignright size-medium wp-image-509" style="width:300px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/SeeedGrove.jpg"><img src="/wp-content/uploads/2010/12/SeeedGrove-300x225.jpg" alt="Grove shield and twigs" width="300" height="225" /></a>
	<div>Grove shield and twigs</div>
</div>As shown in the photo, the basic GROVE shield fits on top of the Netduino. In keeping with the botanological theme, the shield is called a &#8220;stem&#8221;, actually, but since I can&#8217;t quite wrap my mind around a stem with twigs sticking out of it, I&#8217;ll call it a shield.  (I&#8217;ll use the term twig for the component boards, though, since I don&#8217;t know what else to call them).</p>
<p>I tried connecting a button twig and LED twig (2 per twig in each case), and programmed them so that the buttons triggered the lights to glow and dim, using PWM.  Initially, the button event (yes, the .Net Micro Framework fully supports raised events, just like Bill Gates invented <img src='http://www.gigamegablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ) didn&#8217;t fire.  A bit of trial and error revealed that the pulldown resistor had to be disabled, which is easily done in the source code.</p>
<p>The Netduino has relatively limited PWM support when compared to the Arduino (you can set the period, but frequency is fixed at 10Khz), but it worked fine with the LEDs.   GHI&#8217;s firmware allows the frequency to be set, which might come in handy with the Grove&#8217;s piezo buzzer.</p>
<p>I&#8217;m using a serial LCD connected to digital pin 3 and the 5V and Ground pins.  That setup works as expected.  The Grove Starter Bundle includes a parallel LCD,  However, since the Netduino has 2 serial ports, neither of which are used to program or debug the board, and its support for parallel LCDs is less well established than the Arduino&#8217;s a Serial LCD might be the best way to go with the Netduino any way.</p>
<p>I&#8217;m using an elderly <a href="http://www.matrixorbital.com/">Matrix Orbital</a> serial LCD, but the <a href="http://www.sparkfun.com/products/258">Sparkfun Serial LCD Backpack</a> is a relatively inexpensive way to convert a parallel LCD to serial, including 4&#215;20 LCDs.  I&#8217;ve included support for it in the attached source code &#8212; just comment out the corresponding <em>#define</em> at the top of <em>Program.cs</em>.  I took advantage of the .Net Compact Framework&#8217;s support for Interfaces to create compatible classes for the 2 serial LCD APIs.</p>
<p>Incidentally, both the analog and digital pins of the Netduino supply 5V, even though the processor uses 3.3V,  which improves compatibility with Arduino shields.  However, while the digital pins can accept 5V input, the analog pins (or, more accurately, the analog-to-digital converter) cannot go beyond 3.3V. That presents a problem when using 5V sensors and controls like the Grove&#8217;s.</p>
<p><strong>Analog Components</strong></p>
<p>For example, the potentiometer twig would, when turned all the way up, flood the ADC and cause all of the analog pins to read weird values.  The proper solution for this is to connect the pot (and any other analog twig you use) through a circuit that converts the 5V signal to 3.3V or lower.</p>
<p>A voltage divider works well for something like a pot, since accuracy isn&#8217;t all that important. However, I tried a more accurate (though more cumbersome) approach using <a href="http://www.sparkfun.com/products/8745">Sparkfun&#8217;s Logic Level Converter</a>.</p>
<div class="img alignright size-medium wp-image-510" style="width:300px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/VoltageLevelConverter.jpg"><img src="/wp-content/uploads/2010/12/VoltageLevelConverter-300x225.jpg" alt="Sparkfun Logic Level Converter - Simplicity is for wimps!" width="300" height="225" /></a>
	<div>Sparkfun Logic Level Converter - Simplicity is for wimps!</div>
</div>In theory, this converter takes 5V signals and steps them down to a 3.3V signal.  In practice, things are a little more complicated.  You need to connect the converter to the 5V line, and to the 3.3V line, and to ground (actually to ground twice, once on the 5V side and once on the 3.3V side). And, of course, you need to connect the signal from the twig to the converter, and the output from the converter to the analog in pin on the shield.   All of which makes for a very messy setup, as you can see from the photo.</p>
<p>Lastly, to make things interesting, Sparkfun decided to step the signal down to 2.5V, not 3.3V as the product description suggests.  The step up, on the other hand, always goes to 5V.  Presumably, this decision was made to allow compatibility with microprocessors that use other voltage levels, but it means an extra step (pun intended) when what you want is a 3.3V signal.</p>
<p>Generally, you would correct the reading in code (by multiplying it by 3.3/2.5).  Another option is to use the Netduino&#8217;s AREF connector to feed in the actual analog voltage you want to use.  So, I connected it to AREF to a 2.5V signal from the Sparkfun converter, requiring yet another pair of wires &#8211; a connection to the 5V bus on the input side, and a connection from the output side to AREF.</p>
<p>Messy, but effective. The pot twig&#8217;s signal now moves smoothly from 0 to 1023 while staying well within the Netduino&#8217;s tolerance.</p>
<p>Next up, the temperature sensor twig.  I tried the same connection approach as with the pot. Actually, since the Sparkfun Logic Level Converter only supports 2 input signals, I setup a second converter on the breadboard for this.  While the converter correctly stepped the analog voltage down, the resulting temperature calculation was 34C (93F).  This overshot the correct reading by about 12C.</p>
<p>I&#8217;m not 100% sure what the cause is, but I think the problem is that the temperature twig&#8217;s sensor uses a logarithmic scale, and simple fractional conversions don&#8217;t work in that world.  (If anyone knows differently, please post a comment with an explanation).</p>
<p>A good solution, which has been <a href="http://forums.netduino.com/index.php?/topic/835-i2c-devices-using-the-i2cbus-class/">described in the Netduino forums</a>, is to use a temperature sensor that connects via I2C rather than an analog pin.  However, I went with a hack.  The analog signal returned by the Grove system&#8217;s temperature sensor (assuming you are using it for room temperature, and aren&#8217;t in Hell) is safely below the 3.3V threshold supported by the Netduino&#8217;s ADC.   So, you can get away with connecting it directly to the shield, and the same temperature calculation formula used with the Arduino then works correctly with the Netduino.</p>
<p>Well, it almost works.   The formula in the <a href="http://garden.seeedstudio.com/index.php?title=Project_Seven_-_Temperature">Grove system&#8217;s tutorial</a> makes use of the Arduino&#8217;s (technically, <a href="http://www.nongnu.org/avr-libc/">AVR Libc</a>&#8216;s) log() function, which calculates a natural logarithm.  The .Net Micro Framework doesn&#8217;t have a log() function.  .Net&#8217;s Math function was pared down for size, and log() didn&#8217;t make the cut.</p>
<p>I first tried an alternative formula, <a href="http://www.seeedstudio.com/forum/viewtopic.php?f=4&amp;t=565&amp;hilit=temperature+brick">taken from a forum posting for the older Electronic Brick temperature sensor</a>.  This came close, but was about 0.5C too high.</p>
<p>So, I next tried incorporating <a href="http://www.microframework.nl/2009/01/15/math-library-compatible-with-full-net/">Elze Kool&#8217;s exMath</a> library, which includes a log() function.  After waiting, and waiting, for the logarithm calculation to complete,  I broke into the debugger (again, in-circuit debugging is a Big Freaking Deal!!) and found it caught in an infinite loop.</p>
<pre class="brush: csharp; title: ; notranslate">
while (partial &gt;= double.Epsilon)
{
   if (x &gt;= newBase)
   {
      fractional += partial;
      x = x / newBase;
   }
   partial *= 0.5F;
   x *= x;
}
</pre>
<p>The comparison of <em>partial</em> to <em>epsilon</em> kept returning <em>true</em>, even though the debugger showed the value of <em>partial </em>to be 0.  In fact, entering <em>partial &gt; epsilon</em> in Visual Studio&#8217;s Immediate window correctly returned <em>false </em>- only the compiled code was getting it wrong.</p>
<p>I can only assume that this is a bug in the compiler &#8212; epsilon is, after all, the mother of all edge cases. Adding <em>(partial == 0)</em> to the while loop&#8217;s condition fixed the problem.  The temperature calculated by this formula is almost dead-on.</p>
<p>This leaves us with one last problem: the hack of using the &#8220;raw&#8221; signal from the 5V temperature sensor isn&#8217;t compatible with the earlier hack of feeding a 2.5 voltage into the AREF pin.  Since the AREF problem is easily fixed in software, I changed the AREF signal to 5V, and doubled the reading from the potentiometer twig.</p>
<div class="img alignright size-medium wp-image-515" style="width:300px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2010/12/DrOctopus.jpg"><img src="/wp-content/uploads/2010/12/DrOctopus-300x225.jpg" alt="Watch it Spidey, it's Dr Octopus!" width="300" height="225" /></a>
	<div>Watch it Spidey, it's Dr Octopus!</div>
</div>I really like Seeed Studio&#8217;s products, and the Grove looks like a solid, low-cost starter bundle for *duino experimentation and prototyping.  I&#8217;m not entirely convinced of the advantages of the Grove over the older Electronic Brick system.  The new connector cables are quite stiff, and since the twigs don&#8217;t have mounting holes they tend to stick up in the air like, um, branches of a tree. However, the twigs&#8217; edge connectors are innovative, and it will be interesting to see what uses they are put to.</p>
<p><strong>Source Code Notes</strong></p>
<p>A few notes on the hardware setup used by my code:</p>
<ol>
<li>The button twig is connected to D7/D8, and the LED twig to D9/D10.</li>
<li>The temperature sensor twig is connected to A2/A3,</li>
<li>The potentiometer twig is connected to A0. As explained this connection is via  the Sparkfun Logic Level Converter.  The &#8220;D1&#8243; (why D?) pin of the pot is actually connected by a jumper cable to the RI pin of the Converter, and the corresponding RO pin of the Converter to the A0 pin of the shield.  If you want to skip the hassle of the analog voltage conversion, you can omit the potentiometer.  It is used only to set the backlight level of the LCD.  Just comment out the call to <em>setLCDBrightness</em> in <em>Program.cs</em>.</li>
<li>The Serial LCD is connected to D3.  You can run the code without a serial LCD by commenting out both <em>#define</em> statements at the top of <em>Program.cs</em>.  You can see the temperature value in the Visual Studio Debug output window, and the buttons and LEDs will still work as normal.</li>
</ol>
<p>The MathEx library is included in its entire, original form, except for the one change I made as explained above.  The change is commented with date 12/12/10.</p>
<p>And one final note:  if you are thinking that a temperature display is a horrible waste of the Netduino&#8217;s capabilities, I agree entirely.  This is just a starting point for a series of refinements that I&#8217;ll blog about in the future.  I currently have various Arduinos scattered about my house, controlling plant lights, displaying Twitter feeds and weather forecasts, and logging temperature data.   The code required a lot of trial-and-error debugging, and relies on the use of a <a href="http://beagleboard.org/">Beagleboard</a> as a go-between to the Internet.  I&#8217;m looking forward to seeing how much more (or less?) the Netduino can achieve.</p>
<p><strong><a href="http://www.gigamegablog.com/files/NetduinoSerialLCDTester.zip">The source code for the temperature LCD program described in this article can be downloaded here</a></strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2010/12/20/netduino-enters-the-grove/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>kitsrus Introduction to LCDs &#8211; Part 2: Hello Internet</title>
		<link>http://www.gigamegablog.com/2009/05/28/kitsrus-introduction-to-lcds-part-2-hello-internet/</link>
		<comments>http://www.gigamegablog.com/2009/05/28/kitsrus-introduction-to-lcds-part-2-hello-internet/#comments</comments>
		<pubDate>Thu, 28 May 2009 17:02:47 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=202</guid>
		<description><![CDATA[A little while ago I wrote about an electronics kit from kitusrus that interfaces an LCD to a PC through its parallel port. Like all kitsrus stuff it was fun to build, and the instructions included with the kit do &#8230; <a href="http://www.gigamegablog.com/2009/05/28/kitsrus-introduction-to-lcds-part-2-hello-internet/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A little while ago <a href="http://gigamegablog.com/2009/04/18/kit-construction-the-kitsrus-introduction-to-lcds/">I wrote about an electronics kit</a> from kitusrus that interfaces an LCD to a PC through its parallel port.  Like all <a href="http://kitsrus.com/">kitsrus</a> stuff it was fun to build, and the instructions included with the kit do a great job of explaining the design of the circuit.  </p>
<p>However, I was a little surprised that they didn&#8217;t include the source code for the Windows program that communicates with the board.  Sending a &#8220;hello world&#8221; message to the LCD is fine for verifying that the kit works, but an LCD connecting to a PC could be used for so much more.  </p>
<p>When Googling for some .Net code that I could use as a starting point for writing my own interface, I was delighted to find that somebody had already done most of the work for me.  An <a href="http://www.codeproject.com/KB/cs/cspplcds.aspx">article on The Code Project site</a> describes the construction of a homebrew parallel port LCD connection, and includes the C# .Net code that the creator used to send data to the LCD.  Out of curiosity I downloaded the code and ran the .exe to see what happened, and I was astounded to see it successfully writing The Code Project&#8217;s RSS feed to the kitsrus LCD, under Vista no less. &#8220;Hello World&#8221;, indeed.</p>
<p>The Code Project article&#8217;s creator wasn&#8217;t using the kitrsrus kit, but because his LCD is based on a similar controller chip, and by a lucky coincidence in the selection of parallel port pins, the code mostly worked. The only problem was that the data wasn&#8217;t scrolling across the LCD as intended, but was stuck in the last column of the display, writing only to that one position.  The data was getting across, it just wasn&#8217;t being positioned correctly.  This is a pretty common and easily solved problem when writing data to an LCD, as I&#8217;ll explain below.</p>
<p>(In order to preserve your sanity and mine, I&#8217;ll refrain some referring to &#8220;the Code Project project&#8221; and the &#8220;kitsrus kit&#8221;, and call them the &#8220;CP project&#8221; and &#8220;the kit&#8221;.  Apologies to their respective trademark owners.)</p>
<p>Although there is no &#8220;standard interface&#8221; for connecting an LCD to a parallel port, there is a fairly close correspondence between the parallel port&#8217;s pins and the pins used by all LCDs that use an HD44780-compatible controller chip.  (Most LCDs intended for use by hobbyists are compatible with this standard, dating back to the late 90s.  The <a href="http://en.wikipedia.org/wiki/HD44780_Character_LCD">Wikipedia entry for HD44780</a> links to an Everyday Practical Electronics article from 1997.)  </p>
<p>The CP project used an LCD based on an old Samsung KS0066 chip, and the kit contains an LCD based on the KS0070 and manufactured in 1999, and both of those are HD44780-compatible.</p>
<p>The Code Project author wrote 2 articles that contain all the technical information you need to know in order to understand his .Net source code: <a href="http://www.codeproject.com/KB/cs/csppleds.aspx">this article covers the parallel port&#8217;s pins</a>, and <a href="http://www.codeproject.com/KB/cs/cspplcds.aspx">this one covers the LCD&#8217;s</a>.  The illustration below is linked to his second article.</p>
<p>Both the parallel port and the LCD use 8 data pins, D0 through D7. Not surprisingly, both the CP project and the kit wire the 2 sets of pins in a one-to-one correspondence, D0 to D0, D1 to D1, etc.  The data sent by the .Net code arrives just fine at the LCD, then.</p>
<p>LCDs based on the HD44780 interface also have 3 control pins: RS (register select), R/W (read/write) and E (enable).   Since LCDs don&#8217;t have much to say, both the CP project and the kit do the same thing with the R/W pin &#8211; wire it to ground, putting it in a permanent write state.  </p>
<p>By a happy coincidence, both the CP project and the kit happened to wire parallel port pin C0 to the E pin of the LCD &#8211; without pin C0 turning things off and on, nothing would have made it to the LCD. There is a non-intuitive pattern of setting the enable pin low then high then low again that is necessary to write data to the LCDs &#8212; this seems to be the thing that trips up most novice LCD programmers, but the CP project&#8217;s source code does a nice job of commenting this code so that you can understand what&#8217;s going on.</p>
<p>The only area where the 2 approaches differ is in the selection of the RS pin: the CodeProject board uses pin C2  while the kitsrus board uses C1. (See the CP project&#8217;s pinout diagram below). Since this pin is used to tell the LCD whether it is receiving data or instructions, and the pin needs to be high for data, this difference should have caused everything being sent to the LCD to the treated as instructions, resulting in a jumpy cursor but no characters on the screen.  However, by another lucky coincidence, the parallel port pin used by the kit, C1, is reversed &#8211; it is normally high and is set to low by sending it a &#8220;1&#8243;.  This results in everything sent to the LCD being treated as data &#8212; characters with no cursor control, exactly what we got. </p>
<div class="img aligncenter" style="width:600px;">
	<a href="http://www.codeproject.com/KB/cs/cspplcds.aspx"><img src="http://www.codeproject.com/KB/cs/cspplcds/circuit_with_potentiometer.gif" alt="Parallel port connections to the LCD, by Levent Saltuklaroglu, courtesy of The Code Project" width="600" height="500" /></a>
	<div>Parallel port connections to the LCD, by Levent Saltuklaroglu, courtesy of The Code Project</div>
</div>
<p>To adapt the CP project&#8217;s code to the kit, the only change required is to redirect all signals intended for C2 to C1, and flip the bit from allow for the fact that kit&#8217;s pin is reversed.</p>
<p>I decided to implement this change by adding a go-between method that would convert the instructions sent by the CodeProject code to the ones required by the kitsrus board:</p>
<pre class="brush: csharp; title: ; notranslate">
        private void writeToControl(int intValue)
        {
            int intModifiedValue = intValue;
            if ((intValue &amp; 4) &gt; 0)
				// if C2 is being set  high, set C1 high by sending it a 0
                intModifiedValue = intModifiedValue &amp; 253;
            else
				// else, if C2 is being set low, set C1 low by sending it a 1
                intModifiedValue = intModifiedValue | 2;

            PortAccess.Output(intControl, intModifiedValue);
        }
</pre>
<p>And that&#8217;s it &#8212; the kit can now be fully controlled by the CP project&#8217;s code.  </p>
<p>This is quite cool, since it breathes new life into a 10-year old kit.  When originally introduced the kit had only a command line interface that would only run in DOS &#8211; real DOS, not the command line in Windows XP.  However, the .Net code works just fine under Vista and Windows 7.  By tinkering with the code you can now use the LCD as a remote display for whatever you like: RSS feeds, e-mail, twitter.  A poor geek&#8217;s <a href="http://www.chumby.com/">Chumby</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2009/05/28/kitsrus-introduction-to-lcds-part-2-hello-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

