<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/FabienRoyer/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/FabienRoyer/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/FabienRoyer/Posts</link>
    <language>en</language>
    <pubDate>Sat, 25 May 2013 12:36:17 GMT</pubDate>
    <lastBuildDate>Sat, 25 May 2013 12:36:17 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>3</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Using the Adafruit Arduino Logger Shield on a Netduino</title>
      <description><![CDATA[<p><strong>C9 Netduino Shield Series - Using Arduino Shields with a Netduino - Part II</strong></p><h4>Introduction</h4><p>In our <a href="http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care">previous article</a>, we examined what an Arduino shield is, how to build a simple custom shield and discussed how to quickly identify shields that are good candidates for a Netduino adaptation versus shields that may not be.</p><p>In this article, we’ll take a <a href="https://www.adafruit.com/products/243">popular Arduino Logger Shield produced by Adafruit</a> and we’ll interface it with a Netduino / Plus microcontroller</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B10%5D-2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B6%5D-4.png" alt="image" width="240" height="188" border="0"></a></p><p>The Arduino Logger Shield is an excellent one to start with because it offers immediate benefits to a Netduino / Plus user:</p><ul><li>Time-keeping </li><li>SD card storage </li><li>Two user-controllable LEDs </li><li>A small prototyping area </li><li>An onboard 3.3v voltage regulator for clean analog readings and power decoupling </li></ul><p>In our <a href="http://netduinohelpers.codeplex.com/SourceControl/list/changesets">C# data logging application</a>, we'll interact with the time keeper, the SD card storage and its 'card detect' pin, the two LEDs as well as a temperature sensor (not included with the shield).</p><p>Before diving into the details associated with the hardware, you may want to take a look at the C# objects representing the hardware:</p><p><pre class="brush: csharp">
public static readonly string SdMountPoint = &quot;SD&quot;;
public static OutputPort LedRed = new OutputPort(Pins.GPIO_PIN_D0, false);
public static OutputPort LedGreen = new OutputPort(Pins.GPIO_PIN_D1, false);
public static InputPort CardDetect = new InputPort(Pins.GPIO_PIN_D3, true, Port.ResistorMode.PullUp);
public static readonly Cpu.Pin ThermoCoupleChipSelect = Pins.GPIO_PIN_D2;
public static DS1307 Clock;
public static Max6675 ThermoCouple;
</pre></p><p>and their initialization:</p><p><pre class="brush: csharp">
public static void InitializePeripherals() {
    LedGreen.Write(true);
    Clock = new DS1307();
    ThermoCouple = new Max6675();
    InitializeStorage(true);
    InitializeClock(new DateTime(2012, 06, 14, 17, 00, 00));
    ThermoCouple.Initialize(ThermoCoupleChipSelect);
    TemperatureSampler = new Timer(new TimerCallback(LogTemperature), null, 250, TemperatureLoggerPeriod);
    LedGreen.Write(false);
}
</pre></p><p>The SD card, represented by the <strong>SdMountPoint</strong> string, communicates with the application over SPI. The presence of the SD card in the reader is determined through the <strong>CardDetect</strong> input pin.</p><p>The LEDs are simple outputs that we'll turn ON / OFF as the peripherals gets initialized and file I/Os take place with the SD card.</p><p>The clock communicates with the application over the I2C protocol. The clock's most important functions are accessed through the <em>Set()</em> and <em>Get()</em> methods respectively used to set the time once and to get updated time stamps afterward.</p><p>The thermocouple communicates over SPI with the application. It exposes a <em>Read()</em> method which caches a raw temperature sample accessed through the <em>Celsius</em> and <em>Fahrenheit</em> properties.</p><p>Note: the Netduino Plus already features a built-in microSD card reader, in which case, having another one on the shield is not really needed. Except for this hardware difference, everything else discussed within this article applies equally to the regular Netduino and the Netduino Plus.</p><h4>Interfacing with the Arduino Logger shield’s hardware</h4><p>Adafruit is pretty good about making usable products and generally provides Arduino libraries to use with their hardware. Indeed, the Arduino Logger Shield is <a href="http://www.ladyada.net/make/logshield/index.html">well documented</a> and comes with two C&#43;&#43; libraries: <a href="https://github.com/adafruit/SD">SD</a> which implements a <a href="http://www.ladyada.net/make/logshield/sd.html">FAT file system and supporting low-level SD card I/O functions</a>. <a href="https://github.com/adafruit/RTClib">RTCLib</a> which wraps the I2C interface required to communicate with the <a href="http://www.ladyada.net/make/logshield/rtc.html">DS1307 real time clock.</a></p><h5>The SD Card Interface</h5><p>Let’s deal with the SD card reader and the file system first: a quick review of <a href="https://github.com/adafruit/SD/blob/master/SD.h">SD.h</a> reveals two C&#43;&#43; classes:</p><ul><li>class File : public Stream {} exposing standard read, write, seek, flush file access functions. </li><li>class SDClass {} exposing storage management such as file and directory operations. </li></ul><p>This is good news because the .NET Micro Framework on the Netduino already supports file streams and directory management through the use of the <a href="http://msdn.microsoft.com/en-us/library/hh400764">.NET MF System.IO assembly</a>. This assembly comes with the <a href="http://www.netduino.com/downloads/MicroFrameworkSDK.msi">.NET MF SDK</a> port to the Netduino.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004%5B3%5D-1.jpg"><img title="clip_image004" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image004_thumb-1.jpg" alt="clip_image004" width="172" height="379" border="0"></a></p><p>By the same token, interfacing with an SD card is provided by an assembly built by Secret Labs named SecretLabs.NETMF.IO which comes with the <a href="http://www.netduino.com/downloads/">Netduino SDK</a>.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-6.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B3%5D-6.png" alt="image" width="640" height="114" border="0"></a></p><p>SecretLabs.NETMF.IO provides two functions for 'mounting' and 'un-mounting' an SD card device and <a href="http://en.wikipedia.org/wiki/FAT_file_system">the associated FAT file system</a> so that it can be made usable by the .NET MF through assemblies such as <a href="http://msdn.microsoft.com/en-us/library/hh400764">System.IO.</a></p><p>It's important to note that the SecretLabs.NETMF.IO assembly must not be deployed with an application targeting the <a href="http://www.netduino.com/netduinoplus/specs.htm">Netduino Plus</a>: on boot, the .NET Micro Framework implementation specific to the Netduino Plus automatically detects and mounts the SD card if one is present in its microSD card reader. This functionality is redundant with the MountSD / Unmount functions provided by the SecretLabs.NETMF.IO assembly which is only needed on Netduino SKUs without a built-in SD card reader.</p><h5>How does the .NET MF interact with the SD card through the shield?</h5><p>At this point, it's a good time to review the Arduino Logger Shield's pin-out and the <a href="http://www.ladyada.net/make/logshield/design.html">shield's schematics</a>:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B16%5D-2.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B10%5D-4.png" alt="image" width="472" height="422" border="0"></a></p><p>As we know from our previous article, pins D10-D13 map to the SPI interface and pins A4-A5 map to the I2C interface of the Netduino. On the shield's schematics, the SPI interface leads us to the SD &amp; MMC section of the diagram, connected through a <a href="http://www.ladyada.net/wiki/partselector/ic?s%5b%5d=74ahc125n#logic">74HC125N logic-level shifter chip</a> indicated as IC3A-D.</p><p>The role of the logic-level shifter is to ensure that logic voltages supplied to the SD card do not exceed 3.3v, even if they come from a microcontroller using 5v logic levels, such as the Arduino. When using an SD card with a Netduino, a level-shifter is not required since all logic levels run at 3.3v on the AT91SAM7x chip but it doesn't interfere with any I/O operations either when the voltage is already 3.3v.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B20%5D-3.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B12%5D-4.png" alt="image" width="640" height="468" border="0"></a></p><p>The SD card reader in itself is just a passive connector, giving access to the controller built into the SD card. It also provides a mechanical means (i.e. switches) of detecting the presence of a card in the reader (see JP14 pin 1) as well as detecting if the card is write-protected (see JP14 pin 2). We'll make use of the card detection pin in the sample temperature logging application later on.</p><p>For background on how SD cards work, the following application note <a href="http://alumni.cs.ucr.edu/~amitra/sdcard/Additional/sdcard_appnote_foust.pdf">&quot;Secure Digital Card Interface for the MSP430&quot;</a> is excellent and much easier to digest than the extensive <a href="https://www.sdcard.org/downloads/pls/simplified_specs/">'simplified' SD card protocol specifications provided on the SD Card Association site</a>. The following table taken from the <a href="http://alumni.cs.ucr.edu/~amitra/sdcard/Additional/sdcard_appnote_foust.pdf">&quot;Secure Digital Card Interface for the MSP430&quot;</a> shows the pin out of an SD card and the corresponding SPI connections:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012%5B3%5D-1.jpg"><img title="clip_image012" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image012_thumb-1.jpg" alt="clip_image012" width="285" height="247" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014%5B3%5D-1.jpg"><img title="clip_image014" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image014_thumb-1.jpg" alt="clip_image014" width="624" height="253" border="0"></a></p><p>An SD standard-compliant card can support 3 distinct access modes, each one providing different performance characteristics:</p><ul><li>SD 1-bit protocol: synchronous serial protocol with one data line, one clock line and one line for commands. The full SD card protocol command set is supported in 1-bit mode. </li><li>SD 4-bit protocol: this mode is nearly identical to the SD 1-bit mode, except that the data is multiplexed over 4 data lines, yielding up to 4x the performance of SD 1-bit mode. The full SD card protocol command set is supported in 4-bit mode. </li><li>SPI mode: provide a standard SPI bus interface (/SS, MOSI, MISO, SCK). In SPI mode, the SD card only supports a subset of the full SD card protocol but it is sufficient for implementing a fully functional storage mechanism with a file system. </li></ul><p>As you might have guessed, the .NET Micro Framework on the Netduino <a href="http://netduino.com/downloads/netduinofirmware/netduinofirmware.zip">makes use of the SD card in SPI mode</a> (see \DeviceCode\Drivers\BlockStorage\SD\SD_BL_driver.cpp). The block-oriented SD card I/Os are abstracted thanks to the FAT file system provided by the System.IO assembly (see \DeviceCode\Drivers\FS\FAT\FAT_FileHandle.cpp and FAT_LogicDisk.cpp).</p><p>The role of the SecretLabs.NETMF.IO assembly on the Netduino (or its built-in equivalent on the Netduino Plus) is to initialize the SD card in SPI mode during the 'mounting' process by sending the proper set of commands as defined in the <a href="https://www.sdcard.org/downloads/pls/simplified_specs/">SD Card protocol</a>.</p><p>In the <a href="http://netduinohelpers.codeplex.com/SourceControl/list/changesets">C# code of the AdafruitNetduinoLogger sample application</a>, which we will review as a whole later on in the code walkthrough section, the following function takes care of the SD card initialization:</p><p><pre class="brush: csharp">
public static void InitializeStorage(bool mount) {
    try {
        if (mount == true) {
            StorageDevice.MountSD(SdMountPoint, SPI.SPI_module.SPI1, Pins.GPIO_PIN_D10);
        } else {
            StorageDevice.Unmount(SdMountPoint);
        }
    } catch (Exception e) {
        LogLine(&quot;InitializeStorage: &quot; &#43; e.Message);
        SignalCriticalError();
    }
}
</pre></p><p>Once mounted, the file system is accessed through System.IO calls such as this:</p><p><pre class="brush: csharp">
using (var tempLogFile = new StreamWriter(filename, true)) {
    tempLogFile.WriteLine(latestRecord);
    tempLogFile.Flush();
}
</pre></p><p>Using the <a href="http://msdn.microsoft.com/en-us/library/hh423706">StreamWriter class</a> in this context made sense for writing strings as used in the sample application:</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016%5B3%5D-1.jpg"><img title="clip_image016" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image016_thumb-1.jpg" alt="clip_image016" width="203" height="201" border="0"></a></p><p>However, there are many other file I/O classes available in System.IO that may be better suited depending on the scenario.</p><h5>The DS1307 real time clock</h5><p>Our next step is to examine the interface with the DS1307 real time clock (RTC). We'll start by extracting the most important parts of the <a href="http://datasheets.maxim-ic.com/en/ds/DS1307.pdf">DS1307 datasheet</a> and reviewing how it's wired up on the shield's schematics.</p><h5>DS1307 features</h5><ul><li>Real-Time Clock (RTC) Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of the week, and Year with Leap-Year Compensation Valid Up to 2100 </li><li>56-Byte, Battery-Backed, General-Purpose RAM with Unlimited Writes </li><li>I2C Serial Interface </li><li>Programmable Square-Wave Output Signal </li><li>Automatic Power-Fail Detect and Switch Circuitry </li><li>Consumes Less than 500nA in Battery-Backup Mode with Oscillator Running </li></ul><p>Note: If you need to measure the time something takes in milliseconds, a time granularity that the DS1307 clock does not provide, you can use the <a href="http://msdn.microsoft.com/en-us/library/ee437011">Utility functions provided by the .NET Micro Framework</a> like this:</p><p><pre class="brush: csharp">
var tickStart = Utility.GetMachineTime().Ticks;

// &lt;...code to be timed...&gt;

var elapsedMs = (int)((Utility.GetMachineTime().Ticks - tickStart) / TimeSpan.TicksPerMillisecond);
</pre></p><p>This timing method relies on the CPU's internal tick counter and is not 100% accurate due to the overhead of the .NET MF itself but may be sufficient in most scenarios. In addition, the internal tick counter rolls over every so often, something that should be taken into account in production code.</p><h5>DS1307 register map</h5><p>Accessing the clock's features comes down reading and writing to and from a set of registers as described on page 8 of the datasheet.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image018%5B3%5D.jpg"><img title="clip_image018" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image018_thumb.jpg" alt="clip_image018" width="624" height="263" border="0"></a></p><p><a href="http://datasheets.maxim-ic.com/en/ds/DS1307.pdf">Page 9 of the DS1307 datasheet</a> provides more details about the square wave generation function of the clock, which we will not be using here. The generated square wave signal is available on the shield through connector JP14 on pin 3 as you can see on the schematics below and can be used to provide a slow but reliable external clock signal to another device such as a microcontroller.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image020%5B3%5D.jpg"><img title="clip_image020" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image020_thumb.jpg" alt="clip_image020" width="624" height="111" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image022%5B3%5D.jpg"><img title="clip_image022" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image022_thumb.jpg" alt="clip_image022" width="435" height="382" border="0"></a></p><h5>DS1307 I2C bus address</h5><p>The final piece of the puzzle needed before we can use the DS1307 is the device's address on the I2C data bus and its maximum speed (specified at 100 KHz on page 10 of the datasheet). The device address is revealed on page 12 as being 1101000 binary (0x68) along with the two operations modes (Slave Receiver and Slave Transmitter) of the clock. The 8th bit of the address is used by the protocol to indicate whether a 'read' or a 'write' operation is requested.</p><p>Note: I2C devices sometime make use of 10-bit addresses. If you aren't familiar with the I2C data bus, you should read the section of the datasheet starting on page 10 which provides a good foundation for understanding how I2C generally works.</p><p>It can be summarized as follows:</p><ul><li>I2C is a 2-wire serial protocol with one bidirectional data line referred to as SDA and one clock line, referred to as SCL. </li><li>The I2C bus is an open-drain bus (i.e. devices pull the bus low to create a '0' and let go of the bus to create a '1'). To achieve this, I2C requires a pull-up resistor on the SCL and SDA lines between 1.8K ohms and 10K ohms. I2C devices do not need to provide pull-ups themselves if the bus already has them. </li><li>The I2C master (i.e. the Netduino microcontroller) always provides the clock signal, generally between 100 KHz (or lower) for standard speed devices or 400 KHz for high-speed devices. There's also a <a href="http://www.i2c-bus.org/fast-mode-plus/">'Fast Mode Plus'</a> allowing for speeds up to 1MHz on devices supporting it. There can be more than one master on the bus even though this is uncommon. </li><li>An I2C device can have a 7-bit or 10-bit address, allowing for multiple I2C devices to be used on the same bus. </li><li>I2C read and write operations are transactions initiated by the I2C master targeting a specific device by address. Some I2C slave devices can notify their master that they need to communicate using a bus interrupt. </li><li>A transaction is framed by 'start' and 'stop signals, with each byte transferred requiring an acknowledgement signal. </li></ul><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image9.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb2-1.png" alt="image" width="640" height="202" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image6%5B1%5D.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb1.png" alt="image" width="640" height="195" border="0"></a></p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image3.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb-4.png" alt="image" width="640" height="194" border="0"></a></p><p>At this point, we have all the pieces needed to communicate with the RTC using I2C transactions.</p><h5>Using the I2C protocol with the .NET Micro Framework</h5><p>On the Arduino, the library used with the shield to communicate with the DS1307 is a <a href="https://github.com/adafruit/RTClib/blob/master/RTClib.cpp">C&#43;&#43; library called RTClib</a>. The <a href="https://github.com/adafruit/RTClib/blob/master/RTClib.h">header</a> of the library declares a <strong>DateTime</strong> class, similar in functionality to the standard <a href="http://msdn.microsoft.com/en-us/library/hh422126">.NET Micro Framework DateTime class provided by System</a> in the mscorlib assembly. We'll use the standard .NET MF data type to work with the clock instead.</p><p>The next declared class is RTC_DS1307 which implements the driver for the DS1307 chip using the <a href="http://arduino.cc/it/Reference/Wire">Wire library to wrap the I2C protocol</a>. The .NET Micro Framework also <a href="http://msdn.microsoft.com/en-us/library/hh435266">supports the I2C protocol</a> through to the <a href="http://msdn.microsoft.com/en-us/library/hh435127">Microsoft.SPOT.Hardware assembly</a>. Here again, we'll use the .NET MF implementation of I2C in order to communicate with the clock. However, the I2C transaction patterns implemented by the C&#43;&#43; driver can still provide a useful guide for writing a C# driver for the DS1307 when you don't know where to begin just based on the datasheet.</p><p>For instance, the following <a href="https://github.com/adafruit/RTClib/blob/master/RTClib.cpp">functions taken from RTClib.cpp</a> shows the call sequence used with the Wiring API to address the date and time registers of the clock:</p><p><pre class="brush: csharp">
int i = 0; //The new wire library needs to take an int when you are sending for the zero register

void RTC_DS1307::adjust(const DateTime&amp; dt) {
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(i);
    Wire.write(bin2bcd(dt.second()));
    Wire.write(bin2bcd(dt.minute()));
    Wire.write(bin2bcd(dt.hour()));
    Wire.write(bin2bcd(0));
    Wire.write(bin2bcd(dt.day()));
    Wire.write(bin2bcd(dt.month()));
    Wire.write(bin2bcd(dt.year() - 2000));
    Wire.write(i);
    Wire.endTransmission();
}

DateTime RTC_DS1307::now() {
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(i);
    Wire.endTransmission();
    Wire.requestFrom(DS1307_ADDRESS, 7);
    uint8_t ss = bcd2bin(Wire.read() &amp; 0x7F);
    uint8_t mm = bcd2bin(Wire.read());
    uint8_t hh = bcd2bin(Wire.read());
    Wire.read();
    uint8_t d = bcd2bin(Wire.read());
    uint8_t m = bcd2bin(Wire.read());
    uint16_t y = bcd2bin(Wire.read()) &#43; 2000;
    return DateTime (y, m, d, hh, mm, ss);
}
</pre></p><p>The final class is RTC_Millis, a utility class converting time data into milliseconds, effectively providing the functionality of the DateTime.Millisecond property on the .NET MF.</p><p>Having assessed that the functionality of RTClib only handles date and time registers and knowing the role of the other clock registers, we can proceed with implementing a complete <a href="http://netduinohelpers.codeplex.com/SourceControl/list/changesets">DS1307 C# driver</a>, supporting the square wave and RAM functions, using the native I2C protocol support of the .NET Micro Framework.</p><p>The driver starts by defining key constants matching the clock registers according to the datasheet:</p><p><pre class="brush: csharp">
[Flags]
// Defines the frequency of the signal on the SQW interrupt pin on the clock when enabled
public enum SQWFreq { SQW_1Hz, SQW_4kHz, SQW_8kHz, SQW_32kHz, SQW_OFF };

[Flags]
// Defines the logic level on the SQW pin when the frequency is disabled
public enum SQWDisabledOutputControl { Zero, One };

// Real time clock I2C address
public const int DS1307_I2C_ADDRESS = 0x68;

// Start / End addresses of the date/time registers
public const byte DS1307_RTC_START_ADDRESS = 0x00;
public const byte DS1307_RTC_END_ADDRESS = 0x06;

// Start / End addresses of the user RAM registers
public const byte DS1307_RAM_START_ADDRESS = 0x08;
public const byte DS1307_RAM_END_ADDRESS = 0x3f;

// Square wave frequency generator register address
public const byte DS1307_SQUARE_WAVE_CTRL_REGISTER_ADDRESS = 0x07;

// Start / End addresses of the user RAM registers
public const byte DS1307_RAM_START_ADDRESS = 0x08;
public const byte DS1307_RAM_END_ADDRESS = 0x3f;

// Total size of the user RAM block
public const byte DS1307_RAM_SIZE = 56;
</pre></p><p>Next the driver defines an I2C device object representing the clock:</p><p><pre class="brush: csharp">
// Instance of the I2C clock
protected I2CDevice Clock;
</pre></p><p>In the class constructor, the I2C clock device is initialized, specifying its address and speed in KHz:</p><p><pre class="brush: csharp">
public DS1307(int timeoutMs = 30, int clockRateKHz = 50) {
    TimeOutMs = timeoutMs;
    ClockRateKHz = clockRateKHz;
    Clock = new I2CDevice(new I2CDevice.Configuration(DS1307_I2C_ADDRESS, ClockRateKHz));
}
</pre></p><p>The driver retrieves the date and time from the clock through a Get function returning a <strong>DateTime</strong> object.</p><p><pre class="brush: csharp">
public DateTime Get() {
    byte[] clockData = new byte [7];

    // Read time registers (7 bytes from DS1307_RTC_START_ADDRESS)
    var transaction = new I2CDevice.I2CTransaction[] {
    I2CDevice.CreateWriteTransaction(new byte[] {DS1307_RTC_START_ADDRESS}),
        I2CDevice.CreateReadTransaction(clockData)
    };

    if (Clock.Execute(transaction, TimeOutMs) == 0) {
        throw new Exception(&quot;I2C transaction failed&quot;);
    }

    return new DateTime(
        BcdToDec(clockData[6]) &#43; 2000, // year
        BcdToDec(clockData[5]), // month
        BcdToDec(clockData[4]), // day
        BcdToDec(clockData[2] &amp; 0x3f), // hours over 24 hours
        BcdToDec(clockData[1]), // minutes
        BcdToDec(clockData[0] &amp; 0x7f) // seconds
    );
}
</pre></p><p>Let's break it down:</p><ul><li>A 7-byte array is allocated which will receive the raw date and time data registers, starting at address DS1307_RTC_START_ADDRESS (0x00) and ending at DS1307_RTC_END_ADDRESS (0x06). </li><li>An I2C transaction object is allocated, comprising two parameters: <ul><li>A 'write' transaction object telling the DS1307 device which register address to start reading data from. In this case, this is DS1307_RTC_START_ADDRESS (0x00), the very first time-keeping register. </li><li>A 'read' transaction object specifying where the clock's time-keeping data registers will be stored, implicitly defining the total number of bytes to be read and acknowledged. </li></ul></li><li>Clock.Execute is the function calling into the .NET MF I2C interface to run the prepared transactions. The second parameter specifies a time out value expressed in milliseconds before the transaction fails, resulting in a generic exception being thrown. </li><li>When the transactions succeed, a DateTime object is instantiated with the 7 time-keeping registers returned by the 'read' transaction. Each register is converted from <a href="http://en.wikipedia.org/wiki/Binary_coded_decimal">Binary Coded Decimal</a> form to decimal form using a custom utility function: </li></ul><p><pre class="brush: csharp">
protected int BcdToDec(int val) {
    return ((val / 16 * 10) &#43; (val % 16));
}
</pre></p><p>Conversely, the driver provides a Set function to update the clock's time-keeping registers. Because the driver doesn't expect a response from the DS1307 in this scenario, the I2C transaction is write-only. The fields of the <strong>DateTime</strong> parameter corresponding to the time -keeping registers are converted from decimal form to <a href="http://en.wikipedia.org/wiki/Binary_coded_decimal">BCD</a> form and stuffed in a 7-byte array before executing the transaction.</p><p><pre class="brush: csharp">
public void Set(DateTime dt) {
    var transaction = new I2CDevice.I2CWriteTransaction[] {
        I2CDevice.CreateWriteTransaction(new byte[] {
            DS1307_RTC_START_ADDRESS,
            DecToBcd(dt.Second),
            DecToBcd(dt.Minute),
            DecToBcd(dt.Hour),
            DecToBcd((int)dt.DayOfWeek),
            DecToBcd(dt.Day),
            DecToBcd(dt.Month),
        DecToBcd(dt.Year - 2000)} )
    };

    if (Clock.Execute(transaction, TimeOutMs) == 0) {
        throw new Exception(&quot;I2C write transaction failed&quot;);
    }
}
</pre></p><p>The rest of the functions provided by the C# driver implement the other DS1307 features, such as</p><ul><li>SetSquareWave </li><li>Halt </li><li>SetRAM </li><li>GetRAM </li><li>The [] operator used to access a specific clock register </li><li>WriteRegister </li></ul><p>In all case, these functions are wrappers around the 'read' and 'write' I2C transaction model, involving the appropriate DS1307 registers as defined in the datasheet.<strong>&nbsp;</strong></p><h4>Using the Adafruit Arduino Logger Shield as a temperature logger</h4><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image15.png"><img title="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb6.png" alt="image" width="640" height="426" border="0"></a></p><p>To illustrate the points discussed so far, we'll use the Adafruit Arduino Logger shield with a Netduino and a <a href="http://www.adafruit.com/products/269">MAX6675 thermocouple amplifier</a> for the purpose of recording ambient temperature samples at ten second intervals.</p><p>Each record includes a date, a time and the temperature expressed in Celsius and Fahrenheit. The records are written to daily files in CSV format for easy export to a spreadsheet, making the application easily adaptable for acquiring data from different sensors:</p><table width="302" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td valign="bottom" width="73"><p><strong>Date</strong></p></td><td valign="bottom" width="83"><p><strong>Time</strong></p></td><td valign="bottom" width="62"><p><strong>Celsius</strong></p></td><td valign="bottom" width="82"><p><strong>Fahrenheit</strong></p></td></tr><tr><td valign="bottom" width="73"><p>6/14/2012</p></td><td valign="bottom" width="83"><p>15:35:00:05</p></td><td valign="bottom" width="62"><p>18.75</p></td><td valign="bottom" width="82"><p>65.75</p></td></tr><tr><td valign="bottom" width="73"><p>6/14/2012</p></td><td valign="bottom" width="83"><p>15:35:10:05</p></td><td valign="bottom" width="62"><p>18</p></td><td valign="bottom" width="82"><p>64.4</p></td></tr><tr><td valign="bottom" width="73"><p>6/14/2012</p></td><td valign="bottom" width="83"><p>15:35:20:05</p></td><td valign="bottom" width="62"><p>18.5</p></td><td valign="bottom" width="82"><p>65.29</p></td></tr><tr><td valign="bottom" width="73"><p>6/14/2012</p></td><td valign="bottom" width="83"><p>15:35:30:05</p></td><td valign="bottom" width="62"><p>18</p></td><td valign="bottom" width="82"><p>64.4</p></td></tr><tr><td valign="bottom" width="73"><p>6/14/2012</p></td><td valign="bottom" width="83"><p>15:35:40:05</p></td><td valign="bottom" width="62"><p>18</p></td><td valign="bottom" width="82"><p>64.4</p></td></tr><tr><td valign="bottom" width="73"><p>6/14/2012</p></td><td valign="bottom" width="83"><p>15:35:50:05</p></td><td valign="bottom" width="62"><p>18.75</p></td><td valign="bottom" width="82"><p>65.75</p></td></tr></tbody></table><p>&nbsp;</p><h5>Device Connections</h5><p>Instead of permanently soldering the temperature sensor to the prototyping area of the shield, <a href="http://www.sparkfun.com/search/results?term=F%2FF&amp;what=products">female / female jumper wires</a> were used to make connections between the shield's own pin headers as well as the thermocouple's male pin headers.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/LoggerShieldBoard3.png"><img title="LoggerShieldBoard" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/LoggerShieldBoard_thumb.png" alt="LoggerShieldBoard" width="640" height="434" border="0"></a></p><p>The following table enumerates these connections:</p><table width="515" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top" width="243"><p><strong>Shield Pin</strong></p></td><td valign="top" width="270"><p><strong>Destination Pin</strong></p></td></tr><tr><td valign="top" width="244"><p>3v (Power header)</p></td><td valign="top" width="270"><p>Max6675 VCC</p></td></tr><tr><td valign="top" width="244"><p>GND (Power or Digital I/O header)</p></td><td valign="top" width="270"><p>Max6675 GND</p></td></tr><tr><td valign="top" width="244"><p>D13 (Digital I/O header, SPI CLK)</p></td><td valign="top" width="270"><p>Max6675 CLK (SPI CLK)</p></td></tr><tr><td valign="top" width="244"><p>D12 (Digital I/O header, SPI MISO)</p></td><td valign="top" width="270"><p>Max6675 DO (SPI MISO)</p></td></tr><tr><td valign="top" width="244"><p>D2 (Digital I/O header, used as SPI /SS)</p></td><td valign="top" width="270"><p>Max6675 CS (SPI /SS)</p></td></tr><tr><td valign="top" width="244"><p>L1 (LEDS header)</p></td><td valign="top" width="270"><p>D1 (Digital I/O header)</p></td></tr><tr><td valign="top" width="244"><p>L2 (LEDS header)</p></td><td valign="top" width="270"><p>D0 (Digital I/O header)</p></td></tr><tr><td valign="top" width="244"><p>CD (SD card detect)</p></td><td valign="top" width="270"><p>D3 (Digital I/O header)</p></td></tr></tbody></table><h5>&nbsp;</h5><h5>Reading temperature using an Adafruit Max6675 Thermocouple amplifier breakout board</h5><p>The <a href="http://datasheets.maxim-ic.com/en/ds/MAX6675.pdf">Max6675 thermocouple amplifier chip</a> on the breakout board is a read-only SPI device. When the CS pin (SPI /SS) of the device is asserted with a 1ms delay before reading, the chip returns a 12-bit value on its DO pin (SPI MISO) corresponding to the temperature measured by a <a href="http://en.wikipedia.org/wiki/Thermocouple">K-type Thermocouple</a> wire. The resulting <a href="http://netduinohelpers.codeplex.com/SourceControl/list/changesets">C# driver for the Max6675</a> is short:</p><p><pre class="brush: csharp">
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace Maxim.Temperature{
    public class Max6675 : IDisposable {
        protected SPI Spi;

        public void Initialize(Cpu.Pin chipSelect) {
            Spi = new SPI(
            new SPI.Configuration(
            chipSelect, false, 1, 0, false, true, 2000, SPI.SPI_module.SPI1)
            );
        }

        public double Celsius {
            get { return RawSensorValue * 0.25; }
        }

        public double Farenheit {
            get { return ((Celsius * 9.0) / 5.0) &#43; 32; }
        }

        protected UInt16 RawSensorValue;
        protected byte[] ReadBuffer = new byte[2];
        protected byte[] WriteBuffer = new byte[2];

        public void Read() {
            RawSensorValue = 0;
            Spi.WriteRead(WriteBuffer, ReadBuffer);
            RawSensorValue |= ReadBuffer[0];
            RawSensorValue &lt;&lt;= 8;
            RawSensorValue |= ReadBuffer[1];

            if ((RawSensorValue &amp; 0x4) == 1) {
                throw new ApplicationException(&quot;No thermocouple attached.&quot;);
            }

            RawSensorValue &gt;&gt;= 3;
        }

        public void Dispose() {
            Spi.Dispose();
        }

        ~Max6675() {
            Dispose();
        }
    }
}
</pre></p><h5>Temperature logger application walkthrough</h5><p>Let's review the key parts of the <a href="http://netduinohelpers.codeplex.com/SourceControl/list/changesets">temperature logging application code</a> and how it interacts with the devices connected to the shield.</p><p><pre class="brush: csharp">
public static readonly string SdMountPoint = &quot;SD&quot;;
</pre></p><p>Defines an arbitrary string used to refer to the SD card when using StorageDevice.MountSD and StorageDevice.Unmount functions.</p><p><pre class="brush: csharp">
public static readonly int TemperatureLoggerPeriod = 10 * 1000; // milliseconds
</pre></p><p>Defines the interval between temperature samples.</p><p><pre class="brush: csharp">
public static OutputPort LedRed = new OutputPort(Pins.GPIO_PIN_D0, false);
</pre></p><p>Defines an output connected to pin D0 controlling the state of the red LED on the shield.</p><p><pre class="brush: csharp">
public static OutputPort LedGreen = new OutputPort(Pins.GPIO_PIN_D1, false);
</pre></p><p>Defines an output connected to pin D1 controlling the state of the green LED on the shield.</p><p><pre class="brush: csharp">
public static InputPort CardDetect = new InputPort(
    Pins.GPIO_PIN_D3,
    true,
    Port.ResistorMode.PullUp);
</pre></p><p>Defines an input connected to pin D3 used to determine if an SD card is inserted in the SD socket.</p><p><pre class="brush: csharp">
public static ManualResetEvent ResetPeripherals = new ManualResetEvent(false);
</pre></p><p>Defines a manual reset event object that will be used in the main application loop to determine when to re-initialize the shield's peripherals.</p><p><pre class="brush: csharp">
public static readonly Cpu.Pin ThermoCoupleChipSelect = Pins.GPIO_PIN_D2;
</pre></p><p>Defines D2 as the SPI chip select pin connected to the Max6675 Thermocouple board.</p><p><pre class="brush: csharp">
public static Timer TemperatureSampler;
</pre></p><p>Defines an instance of a timer object which will drive temperature sampling.</p><p><pre class="brush: csharp">
public static DS1307 Clock;
</pre></p><p>Defines an instance of the DS1307 real time clock driver.</p><p><pre class="brush: csharp">
public static Max6675 ThermoCouple;
</pre></p><p>Defines an instance of the Max6675 thermocouple driver.</p><p><pre class="brush: csharp">
public static ArrayList Buffer = new ArrayList();
</pre></p><p>Defines an array list instance which will be used as a temporary buffer when the SD card is removed from its socket.</p><p>The application's main loop is only concerned about the state of the peripherals:</p><ul><li>It initializes the devices connected to the shield </li><li>It waits indefinitely for a signal indicating that a hardware error occurred </li><li>It disposes of the current device instances and starts over </li></ul><p><pre class="brush: csharp">
public static void Main() {
    while (true) {
        InitializePeripherals();
        ResetPeripherals.WaitOne();
        ResetPeripherals.Reset();
        DeInitializePeripherals();
    }
}
</pre></p><p><strong>InitializePeripherals</strong> indicates that it is working by controlling the green LED on the shield. Its role is focused on object creation and initialization.</p><p><pre class="brush: csharp">
public static void InitializePeripherals() {
    LedGreen.Write(true);
    Clock = new DS1307();
    ThermoCouple = new Max6675();
    InitializeStorage(true);
    InitializeClock(new DateTime(2012, 06, 14, 17, 00, 00));
    ThermoCouple.Initialize(ThermoCoupleChipSelect);
    TemperatureSampler = new Timer(
    new TimerCallback(LogTemperature),
    null,
    250,
    TemperatureLoggerPeriod);
    LedGreen.Write(false);
}
</pre></p><p>If the initialization of a peripheral fails, the shield will quickly blink its LEDs, indefinitely:</p><p><pre class="brush: csharp">
public static void SignalCriticalError() {
    while (true) {
        LedRed.Write(true);
        LedGreen.Write(true);
        Thread.Sleep(100);
        LedRed.Write(false);
        LedGreen.Write(false);
        Thread.Sleep(100);
    }
}
</pre></p><p>The clock initialization function only sets the clock date and time when it is unable to find a file named 'clockSet.txt' on the SD card, ensuring that the initialization of the DS1307 only happens once in the <strong>InitializePeripherals</strong> function or until the file is deleted.</p><p><pre class="brush: csharp">
public static void InitializeClock(DateTime dateTime) {
    var clockSetIndicator = SdMountPoint &#43; @&quot;\clockSet.txt&quot;;

    try {
        if (File.Exists(clockSetIndicator) == false) {
            Clock.Set(dateTime);
            Clock.Halt(false);
            File.Create(clockSetIndicator);
        }
    } catch (Exception e) {
        LogLine(&quot;InitializeClock: &quot; &#43; e.Message);
        SignalCriticalError();
    }
}
</pre></p><p>The <strong>LogTemperature</strong> function is the callback invoked by the Timer object every 10 seconds. The function indicates that it is working by turning the red LED on the shield ON and OFF.</p><p><pre class="brush: csharp">
public static void LogTemperature(object obj) {
    LedRed.Write(true);
}
</pre></p><p>The function reads the current time from the clock with Clock.Get() and takes a temperature sample with ThermoCouple.Read().</p><p><pre class="brush: csharp">
var tickStart = Utility.GetMachineTime().Ticks;
var now = Clock.Get();
ThermoCouple.Read();
var elapsedMs = (int)((Utility.GetMachineTime().Ticks - tickStart) / TimeSpan.TicksPerMillisecond);
</pre></p><p>Then, it concatenates a string containing the date, time and temperature expressed in Celsius and Fahrenheit, with each field separated by commas.</p><p><pre class="brush: csharp">
var date = AddZeroPrefix(now.Year) &#43; &quot;/&quot; &#43; AddZeroPrefix(now.Month) &#43; &quot;/&quot; &#43; AddZeroPrefix(now.Day);
var time = AddZeroPrefix(now.Hour) &#43; &quot;:&quot; &#43; AddZeroPrefix(now.Minute) &#43; &quot;:&quot; &#43; AddZeroPrefix(now.Second) &#43; &quot;:&quot; &#43; AddZeroPrefix(elapsedMs);
var celsius = Shorten(ThermoCouple.Celsius.ToString());
var farenheit = Shorten(ThermoCouple.Farenheit.ToString());
var latestRecord = date &#43; &quot;,&quot; &#43; time &#43; &quot;,&quot; &#43; celsius &#43; &quot;,&quot; &#43; farenheit;
</pre></p><p>To make the data more manageable, daily temperature files are created as needed, each one starting with the column headers expected for parsing the values in CSV format.</p><p><pre class="brush: csharp">
var filename = SdMountPoint &#43; BuildTemperatureLogFilename(now);
if (File.Exists(filename) == false) {
    using (var tempLogFile = new StreamWriter(filename, true)) {
        tempLogFile.WriteLine(&quot;date,time,celsius,fahrenheit&quot;);
    }
}
</pre></p><p>The temperature sampling application lets the user remove the SD card from its socket so that the CSV files can be moved over to a PC for processing without losing data in the meantime. In order to do this, the application checks the state of the 'Card Detect' pin before attempting file system I/Os.</p><p>When the SD card is not present, the latest temperature record is preserved in the array list buffer until the SD card is put back in its socket. The array list data is then flushed to storage.</p><p><pre class="brush: csharp">
if (CardDetect.Read() == false) {
    using (var tempLogFile = new StreamWriter(filename, true)) {
        if (Buffer.Count != 0) {
            foreach (var bufferedLine in Buffer) {
                tempLogFile.WriteLine(bufferedLine);
            }
            Buffer.Clear();
        }
        tempLogFile.WriteLine(latestRecord);
        tempLogFile.Flush();
    }
} else {
    LogLine(&quot;No card in reader. Buffering record.&quot;);
    Buffer.Add(latestRecord);
}
</pre></p><p>The temperature logging function expects to run out of memory if the array list buffer grows too large, in which case, all the records get purged. Other memory management strategies could be used to mitigate data loss in this case. However, this depends entirely on the requirements of the data logging application and is out of scope for this discussion.</p><p><pre class="brush: csharp">
catch (OutOfMemoryException e) {
    LogLine(&quot;Memory full. Clearing buffer.&quot;);
    Buffer.Clear();
}
</pre></p><p>The temperature logging function also handles file system exceptions caused by the removal of the SD card and reacts by signaling the <strong>ResetPeripherals</strong> event. In turn, this lets the application's main loop know that the peripherals, and most specifically the SD card, need to be recycled and initialized again in order to recover from the error.</p><p><pre class="brush: csharp">
catch (IOException e) {
    LogLine(&quot;IO error. Resetting peripherals.&quot;);
    Buffer.Add(latestRecord);
    ResetPeripherals.Set();
}
</pre></p><h5>Conclusion</h5><p>In this article, we took a shield designed for the Arduino and learned how to critically review the Arduino code libraries supporting it, drawing parallels with features offered by the .NET Micro Framework. This process allowed us to identify areas in the Arduino code which were not necessary to port over to C# such as SD card and file system handlers. It also allowed us to see the similarities in the way the Arduino and the Netduino handle I2C communications.</p><p>Most importantly, we also learned the importance of reviewing a device's schematics and component datasheets to ensure that important features have not been omitted and potentially incorrectly implemented when considering using an unknown library: in the case of RTClib, we saw that the implementation was limited to the basic date and time functions of the DS1307, leaving out other useful features such as the clock's built-in RAM and the square wave generation functions.</p><p>In our next article, we'll take on a much more complex shield and we will learn how to analyze Arduino libraries in depth before porting them from C/C&#43;&#43; to C#.</p><h6>Bio</h6><p>Fabien is the Chief Hacker and co-founder of Nwazet, a start-up company located in Redmond WA, specializing in Open Source software and embedded hardware design. Fabien's passion for technology started 30 years ago, creating video games for fun and for profit. He went on working on mainframes, industrial manufacturing systems, mobile and web applications. Before Nwazet, Fabien worked at MSFT for eight years in Windows Core Security, Windows Core Networking and Xbox. During downtime, Fabien enjoys shooting zombies and watching sci-fi.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/FabienRoyer/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:21e6180e991b4430b459a0b00157f766">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Using-the-Adafruit-Arduino-Logger-Shield-on-a-Netduino</comments>
      <itunes:summary>C9 Netduino Shield Series - Using Arduino Shields with a Netduino - Part II IntroductionIn our previous article, we examined what an Arduino shield is, how to build a simple custom shield and discussed how to quickly identify shields that are good candidates for a Netduino adaptation versus shields that may not be. In this article, we’ll take a popular Arduino Logger Shield produced by Adafruit and we’ll interface it with a Netduino / Plus microcontroller  The Arduino Logger Shield is an excellent one to start with because it offers immediate benefits to a Netduino / Plus user: Time-keeping SD card storage Two user-controllable LEDs A small prototyping area An onboard 3.3v voltage regulator for clean analog readings and power decoupling In our C# data logging application, we&#39;ll interact with the time keeper, the SD card storage and its &#39;card detect&#39; pin, the two LEDs as well as a temperature sensor (not included with the shield). Before diving into the details associated with the hardware, you may want to take a look at the C# objects representing the hardware: 
public static readonly string SdMountPoint = &amp;quot;SD&amp;quot;;
public static OutputPort LedRed = new OutputPort(Pins.GPIO_PIN_D0, false);
public static OutputPort LedGreen = new OutputPort(Pins.GPIO_PIN_D1, false);
public static InputPort CardDetect = new InputPort(Pins.GPIO_PIN_D3, true, Port.ResistorMode.PullUp);
public static readonly Cpu.Pin ThermoCoupleChipSelect = Pins.GPIO_PIN_D2;
public static DS1307 Clock;
public static Max6675 ThermoCouple;
 and their initialization: 
public static void InitializePeripherals() {
    LedGreen.Write(true);
    Clock = new DS1307();
    ThermoCouple = new Max6675();
    InitializeStorage(true);
    InitializeClock(new DateTime(2012, 06, 14, 17, 00, 00));
    ThermoCouple.Initialize(ThermoCoupleChipSelect);
    TemperatureSampler = new Timer(new TimerCallback(LogTemperature), null, 250, TemperatureLoggerPeriod);
    LedGreen.Write(false);
}
 The SD car</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Using-the-Adafruit-Arduino-Logger-Shield-on-a-Netduino</link>
      <pubDate>Thu, 23 Aug 2012 17:30:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Using-the-Adafruit-Arduino-Logger-Shield-on-a-Netduino</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/fa8f6217-ff20-4c2e-aa7a-ad2a9863a393.png" height="100" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/cfee8783-651c-4d70-a424-095683cef757.png" height="220" width="220"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/bbbe9892-676d-4b3e-b08b-f29ae87996c5.png" height="288" width="512"></media:thumbnail>      
      <dc:creator>Fabien Royer</dc:creator>
      <itunes:author>Fabien Royer</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Using-the-Adafruit-Arduino-Logger-Shield-on-a-Netduino/RSS</wfw:commentRss>
      <category>.NET Micro Framework</category>
      <category>Hardware</category>
    </item>
  <item>
      <title>What Is an Arduino Shield and Why Should My Netduino Care?</title>
      <description><![CDATA[<p><strong>C9 Netduino Shield Series - Using Arduino Shield with Netduino - Part I</strong> </p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001_thumb1%5B2%5D.jpg"><img title="clip_image001_thumb1" border="0" alt="clip_image001_thumb1" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image001_thumb1_thumb.jpg" width="236" height="240"></a>&nbsp;<br>Photo courtesy of <a href="http://tronixstuff.wordpress.com/">John Boxall</a> </p><h3>Introduction</h3><p>When the <a href="http://www.arduino.cc/en/Guide/Introduction">Arduino</a> Duemilanove microcontroller appeared in 2005, it featured a set of female pin headers exposing most of the pins of the ATmega168 for easy hacking and for connecting accessory boards known as 'Shields'. The purpose of a shield is to provide new plug-and-play functionality to the host microcontroller, such as circuit prototyping, motion control, sensor integration, network and radio communication, or gaming interfaces, without worrying too much about the hardware implementation details. Seven years after the birth of the original Arduino, new shields keep coming out and are being cataloged on <a href="http://shieldlist.org/">http://shieldlist.org/</a>, a testament to the versatility of the design. It is also simple to build a DIY shield when nothing out there will meet your needs or when you want to understand how the shield concept works from the ground up. </p><p>In their infinite wisdom, Secret Labs, the makers of the <a href="http://www.netduino.com/">Netduino</a>, adopted the same Arduino form factor and header pin out to let .NET Micro Framework users tap into the vast array of Arduino shields on the market. Yet, there's always one hurdle that needs to be overcome: in order to give access to their hardware functions easily, many Arduino shields provide <a href="http://www.arduino.cc/playground/Main/GeneralCodeLibrary">sample sketches</a> (a.k.a. C/C&#43;&#43; <a href="http://wiring.org.co/">Wiring programs</a>) and <a href="http://arduino.cc/en/Reference/Libraries">libraries</a> also <a href="http://arduino.cc/en/Reference/HomePage">written in C/C&#43;&#43;</a> designed to be used within the <a href="http://arduino.cc/en/Guide/Windows#toc6">Arduino IDE</a>. Unfortunately, Arduino sketches and libraries aren't compatible with the Visual Studio environment and the .NET runtime: they need to be adapted in order to make use of the shield's hardware. </p><p>The goal of this series of articles is to attempt to demystify what an Arduino shield is. To do this, we'll start by building one from scratch. Then, we'll present a generic approach for selecting Netduino-compatible Arduino shields and adapting Arduino code to interface with the .NET Micro Framework. </p><h5>Selecting Arduino shields for use with Netduino / Plus</h5><p>Arduino shields using hardware components interfaced over protocols such as <a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus">SPI</a>, <a href="http://www.i2c-bus.org/">I2C</a>, <a href="http://www.maxim-ic.com/products/1-wire/flash/overview/index.cfm">1-Wire</a> or serially over a <a href="http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter">UART</a> are generally good candidates for a Netduino adaptation because the .NET Micro Framework supports these protocols natively and can do bulk I/O transfers, yielding good performance. </p><p>However, if a shield requires <a href="http://en.wikipedia.org/wiki/Bit_banging">bit-banging</a> data on GPIOs (i.e. communicating data serially, such as SPI, I2C, RS-232, in software by toggling GPIO lines individually instead of using dedicated hardware interfaces) or has very low I/O latency requirements, it may not be practical or even possible to use the shield on a Netduino / Plus. </p><p>The reason for this is simple: the Arduino runs native code and can access hardware registers directly with a latency orders of magnitude lower than what the .NET Micro Framework can achieve on a Netduino / Plus where toggling GPIOs means going through multiple framework layers while running interpreted code. The maximum raw I/O toggling frequency on a Netduino / Plus clocked at 48 MHz <a href="http://fabienroyer.wordpress.com/2011/01/22/netduino-gpio-speed-test/">was measured around ~8.4KHz</a> which is slow compared to the few MHz achievable on an Arduino clocked at 16 MHz. </p><p>Fortunately, there are possible workarounds and strategies </p><ul><li>Whenever an Arduino library bit-bangs SPI data on GPIOs, regardless of the pins used to do it, it can be replaced by using the standard SPI interface on the Netduino / Plus. </li><li>The Netduino / Plus has significantly more RAM available than the Arduino and can transfer larger SPI data buffer in a single shot, dramatically reducing I/O latency. For instance, <a href="http://fabienroyer.wordpress.com/2011/09/14/driving-an-adafruit-st7565-negative-lcd-display-with-a-netduino/">driving a display shield would greatly benefit from this method</a> where a frame is cached in RAM on the Netduino / Plus then sent in one shot over SPI to the hardware display driver.</li></ul><p>The bottom line is that it is always a good idea to review how the Arduino code interfaces with a given shield before proceeding with a purchase or starting a conversion project. This review process is also facilitated by <a href="http://shieldlist.org/">http://shieldlist.org</a> which shows which pins are being used to drive a shield. For example, the <a href="http://shieldlist.org/adafruit/logger">Adafruit Industries Logger Shield</a> uses hardware SPI (pins D10-D13) for the SD card and I2C (pins A4-A5) for the DS1307 real time clock, making it a perfect adaptation candidate for the Netduino / Plus as we'll see in our next article.</p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B18%5D.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B8%5D-6.png" width="250" height="196"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B19%5D-2.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B9%5D-1.png" width="250" height="224"></a></p><p>It's also very important to know what features are available on the .NET Micro Framework running on the Netduino / Plus: some things come standard with the .NET Micro Framework which normally require add-ons libraries on the Arduino such as file system and networking support. </p><p>Finally, it is wise to search code repositories such as <a href="http://www.codeplex.com/">CodePlex</a>, <a href="https://bitbucket.org/">BitBucket</a> and <a href="https://github.com/">GitHub</a> for hardware drivers and libraries before undertaking writing one in C# from scratch based on component datasheets. This extends to the <a href="http://forums.netduino.com/index.php?/forum/15-project-showcase/">Netduino</a> and the <a href="http://www.tinyclr.com/forum">TinyCLR</a> community forums where many people have posted drivers in discussion threads. </p><h4>Building a shield from scratch to meet specific requirements</h4><p>Recently, we were asked if it was possible to connect our <a href="http://nwazet.com/touch-display-module">Touch Display module</a> designed for a <a href="http://www.netduino.com/netduinogo/specs.htm">Netduino Go!</a> to a <a href="http://www.netduino.com/netduino/specs.htm">Netduino</a> / <a href="http://www.netduino.com/netduinoplus/specs.htm">Plus</a>. By doing a bit of research and seeing how the driver for the Touch Module works, this can be done by building a simple custom shield composed of a few parts connecting the Netduino pin headers to a Netduino Go! socket breakout board like so: </p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/FinishedCustomShield%5B3%5D.jpg"><img title="FinishedCustomShield" border="0" alt="FinishedCustomShield" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/FinishedCustomShield_thumb%5B1%5D.jpg" width="250" height="166"></a><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/GoTouchDisplayOnNetduino%5B3%5D.jpg"><img title="GoTouchDisplayOnNetduino" border="0" alt="GoTouchDisplayOnNetduino" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/GoTouchDisplayOnNetduino_thumb%5B1%5D.jpg" width="250" height="267"></a> </p><h5>High-Level Software Interface</h5><p>To frame the rest of this article, the communication interface with the shield is done using SPI and a GPIO used for synchronization. The communication protocol details are wrapped in the <i>Nwazet.Go.Display.Imaging.VirtualCanvas</i> class which needs to be initialized with the SPI and GPIO parameters matching the pin out of the shield: </p><pre><pre class="brush: csharp">
var canvas = new VirtualCanvas(TouchEventHandler, WidgetClickedHandler);

canvas.Initialize(
    displaySpi: SPI.SPI_module.SPI1,
    displayChipSelect: Pins.GPIO_PIN_D9,
    displayGPIO: Pins.GPIO_PIN_D8,
    speedKHz: 5000);
</pre>

</pre><p>From that point on, all interactions with the shield are done through <i>Draw*</i> methods followed by a call to the <i>Execute() </i>method which handles sending and receiving SPI data packets. The <i>VirtualCanvas</i> class also provides methods for creating widgets such as buttons, receiving touch screen events and setting the screen orientation. </p><p>For example, the following code snippet draws and updates a progress bar and uses one of the proportional fonts built into the display: </p><pre><pre class="brush: csharp">
public static void Main() {
    var canvas = new VirtualCanvas();
    canvas.Initialize(
        displaySpi: SPI.SPI_module.SPI1,
        displayChipSelect: Pins.GPIO_PIN_D9,
        displayGPIO: Pins.GPIO_PIN_D8,
        speedKHz: 5000);
    var fontInfo = new DejaVuSans9().GetFontInfo();
    canvas.DrawFill(0xFFFF);
    canvas.DrawString(5, 144, (ushort)BasicColor.Black, fontInfo.ID, &quot;Progress&quot;);
    for (var progress = 1; progress &lt;= 100; progress&#43;&#43;) {
        canvas.DrawProgressBar(
            70, 140,
            75, 12,
            RoundedCornerStyle.All,
            RoundedCornerStyle.All,
            (ushort)BasicColor.Black,
            (ushort)GrayScaleValues.Gray_128,
            (ushort)GrayScaleValues.Gray_30,
            (ushort)BasicColor.Green,
            progress);
        Thread.Sleep(100);
        canvas.Execute();
    }
}
</pre>

</pre><h5>Netduino Go! Socket Pin Out</h5><p>In order to build the shield, we need to start with mapping out the connections between the Go! bus socket and the header pins of the shield. </p><p>The Go! socket pin out was designed by Secret Labs to be compatible with <a href="http://gadgeteer.codeplex.com/releases/view/72208">Gadgeteer modules supporting the following socket types</a>: S (SPI), U (UART), X (3 GPIO) as documented in the <a href="http://gadgeteer.codeplex.com/downloads/get/273357">.NET Gadgeteer Mainboard Builder's Guide v 1.8, page 6</a>. This makes our little shield compatible with a Gadgeteer board as long as it is connected to an S socket. As far as other .NET Micro Framework boards are concerned, they should also work fine if they can drive an SPI slave device at 5 MHz, the minimum SPI clock frequency required by the Touch Display module. </p><p><b><i></i></b></p><h6>Gadgeteer Socket Types</h6><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B2%5D-3.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb-3.png" width="500" height="433"></a> </p><h6>Netduino Go! Socket</h6><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B5%5D-5.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B1%5D-2.png" width="500" height="375"></a> </p><p>The <a href="http://www.netduino.com/netduino/specs.htm">hardware specifications of the Netduino</a> / Plus tells us that the Netduino GPIOs correspond exactly to the <a href="http://arduino.cc/en/Main/ArduinoBoardUno">Arduino Uno GPIOs</a>: </p><ul><li>digital pins 0-1: UART 1 RX, TX </li><li>digital pins 2-3: UART 2 RX, TX </li><li>digital pins 5-6: PWM, PWM </li><li>digital pins 7-8: UART 2 RTS, CTS </li><li>digital pins 9-10: PWM, PWM </li><li>digital pins 11-13: SPI MOSI, MISO, SPCK </li><li>analog pins 4-5: I2C SDA, SCL </li></ul><p>With this information, we can proceed with the creation of schematics to bridge the gap between the two worlds. </p><h5>Shield schematics</h5><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/What%20is%20a%20shield%20schematics%5B2%5D-1.png"><img title="What is a shield schematics" border="0" alt="What is a shield schematics" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/What%20is%20a%20shield%20schematics_thumb-1.png" width="500" height="350"></a> </p><h5>How does this custom shield work?</h5><p>The Netduino Go! bus is designed around the <a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus">SPI protocol</a> (see Go! socket pins 6-10) which the Netduino / Plus can speak easily, making a Netduino Go! module or a <a href="http://www.ghielectronics.com/catalog/category/275/">S-type Gadgeteer module</a> appear like any other SPI device to a Netduino / Plus. </p><p>You will notice that the following pins aren't connected on the Go! socket for the sake of simplification: </p><ul><li>Pin 2 (5v power): the Touch Display module operates on 3.3v, therefore the 5v power supply is not needed but could be connected to the 5v header of the Netduino to be fully compliant. </li><li>Pin 4 and 5 (UART): the Touch Display module does not make use of the serial interface during normal operation, so these lines can remain disconnected. However, to be fully compliant, Pin 4 (RX) and 5 (TX) on the Go! socket could be respectively connected to Netduino pin D1 (TX) and D0 (RX). </li><li>The fact that these lines aren't connected in this specific scenario would cause another module requiring a UART and/or 5v to not work obviously. </li></ul><p>While the SPI part is straight forward, there's a bit more to the Go! bus electrical specification that must be taken into account: the Netduino Go! bus also uses its GPIO pin on boot (see Go! socket pin 3) to control the behavior of modules based on ARM Cortex chips: when the GPIO pin is held HIGH on module power-up, the ARM Cortex chip enters its bootloader mode and waits to be flashed with new firmware over the Go! bus UART (see Go! socket pins 4-5). The ARM Cortex bootloader remains active until the ARM Cortex chip is reset or power-cycled. </p><p>This is important to know for two reasons: </p><ol><li>The Touch Display module is powered by an ARM Cortex M3 chip. </li><li>On boot, a Netduino / Plus sets all of its I/O pins HIGH, preventing the Touch Display from booting its firmware, which is undesirable. The reason for the I/O pins being set HIGH is documented on <a href="http://www.atmel.com/Images/doc6120.pdf">page 5 of the ATMEL AT91SAM7X datasheet</a> which states that the pins on Parallel IO Controller A and B (PA0 - PA30 and PB0 - PB30) are pulled-up input at reset. The pins stay in that HIGH state until they're reconfigured by the Tiny CLR and the C# application itself. </li></ol><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002%5B4%5D.gif"><img title="clip_image002" border="0" alt="clip_image002" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/clip_image002_thumb%5B4%5D.gif" width="500" height="273"></a></p><p>For this reason, the custom shield is designed to control the power supply of the Touch Display module through a general-purpose <a href="http://www.onsemi.com/pub_link/Collateral/2N4403-D.PDF">2N4403</a> <a href="http://www.onsemi.com/pub_link/Collateral/2N4403-D.PDF">PNP transistor</a> (see T1_PNP on the shield schematics) connected to pin D7: it is only when the base of the transistor is asserted LOW that power flows to the Touch Display module, countering the behavior of the Netduino / Plus on boot. In addition, the Netduino / Plus controls the state of the Go! bus GPIO pin through D8, asserting it LOW before powering up the Touch Display module. </p><p>About the 2N4403 transistor: any other PNP transistor, or a <a href="http://www.electronics-tutorials.ws/transistor/tran_6.html">P-Channel MOSFET</a>, capable of switching at least 150mA continuously, the maximum current consumption of the touch display with some headroom, would have worked equally as well. The 2N4403 used here is more than adequate: </p><p><a href="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image%5B8%5D-1.png"><img title="image" border="0" alt="image" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/image_thumb%5B2%5D-4.png" width="356" height="337"></a> </p><p>In the context of this shield, the PNP transistor is used as a switch, either fully ON or OFF, as opposed to being used as an amplifier. To this end, a 1K ohm resistor is used between the base of the transistor and Netduino / Plus pin D7 (POWER_CTRL) to ensure that the transistor is fully saturated but also limiting the maximum current sunken through pin D7 and potential damage being done to the ATMEL chip. The 10K ohm pull-up resistor placed between the base of the transistor and the 3.3v power rail ensures that the transistor will always be turned off by default, even when pin D7 is floating (i.e. not specifically declared as an Input or as an Output and driven HIGH or LOW by the C# application). </p><p>The PowerUpDisplay function summarizes the interaction with the module through the shield on boot: </p><pre><pre class="brush: csharp">
// Pin connected to the transistor controlling the display's power supply
public static OutputPort PowerTransistor = new OutputPort(Pins.GPIO_PIN_D7, true);

public static void PowerUpDisplay() {
    // Ensure that the GPIO pin in low to prevent the display module to start in bootloader mode
    var goBusGPIO = new OutputPort(Pins.GPIO_PIN_D8, false);
    // Power up the display module
    PowerTransistor.Write(false);
    // Always wait 250ms after power-up to ensure that the display module is fully initialized before sending commands
    Thread.Sleep(250);
    goBusGPIO.Dispose();
}
</pre>

</pre><p><b></b></p><h5>Refactoring a Netduino Go! C# driver to work on a regular Netduino / Plus</h5><p>The final step to get the Touch Display module working outside of its natural environment involved refactoring its <a href="https://bitbucket.org/fabienroyer/nwazet.go/src/b24909aff18e/Library/Nwazet.Go.SDT028ATFTLCDTS/Nwazet.Go.SDT028ATFTLCDTS/Imaging/VirtualCanvas.cs">C# driver (VirtualCanvas.cs)</a>, eliminating the idiosyncrasies specific to Netduino Go! bus. <a href="http://www.netduino.com/downloads/">Go! modules are supposed to implement the <i>GoModule</i> interface as defined by the Netduino Go! SDK</a>. Because the regular Netduino / Plus SDK has no knowledge of this interface, it's necessary to strip out any references and API calls specific to the Go! framework, leaving only what's absolutely required to communicate with the Touch Display module over SPI and maintaining the disposable nature of the class. For more details on Go! SDK, please refer to <a href="http://forums.netduino.com/index.php?/forum/26-netduino-go/">the Netduino Go! community forums</a> and <a href="http://wiki.netduino.com/List-of-all-GO-Modules.ashx">the source code of the existing module drivers</a> as it is currently the best source of documentation. </p><p>This step is akin to the work required when adapting an Arduino library to run on the .Net Micro Framework, only in this case, the task is easier since we're dealing with a C# driver to begin with instead of going from C/C&#43;&#43; to C#. </p><p>Starting from the top of VirtualCanvas.cs, the following changes were made in the Netduino / Plus version of the driver: </p><ul><li>Removed <ul><li><i>using GoBus;</i> </li></ul></li><li>Replaced <ul><li><i>public class VirtualCanvas : GoModule</i> </li><li><i>with: public class VirtualCanvas : IDisposable</i> </li></ul></li><li>Replaced <ul><li><i>public void Initialize(GoSocket socket, uint speedKHz = 25000)</i> </li><li><i>with: public void Initialize(SPI.SPI_module displaySpi, Cpu.Pin displayChipSelect, Cpu.Pin displayGPIO, uint speedKHz = 25000). The core of the function simply initializes the SPI interface.</i> </li></ul></li><li>Replaced <ul><li><i>protected override void Dispose(bool disposing)</i> </li><li><i>with: public void Dispose() also removing the following calls:</i> <ul><li><i>SetSocketPowerState(false); this call is used by the GoModule object model to control when a socket is powered ON / OFF and is no longer applicable when the VirtualCanvas class is not derived from GoModule.</i> </li><li><i>base.Dispose(disposing); by the same token, deriving from GoModule requires overriding the behavior of the Dispose function and calling the base class at the end, something that is no longer needed now that the class implements the regular IDisposable interface.</i> </li></ul></li></ul></li><li>Moved <ul><li><i>GoBusIrqEvent.Reset(); from WaitUntilGoBusIrqIsAsserted()</i> </li><li><i>to: Execute(Synchronicity sync = Synchronicity.Synchronous) taking into account the higher latency of the Netduino / Plus</i> </li></ul></li></ul><p>The rest of the code remained unchanged. <a href="http://netduinohelpers.codeplex.com/">The Netduino / Plus Touch Display driver</a> and test application for this custom shield can be downloaded from the <a href="http://netduinohelpers.codeplex.com/">Netudino Helpers</a> project on CodePlex in the \Samples\Coding4Fun directory.</p><h4>Conclusion</h4><p>With nearly 300 known Arduino shields on the market, there's a wide variety of plug-and-play functionality waiting to be leveraged by the Netduino community, sometime with little or no software work required. When all else fails, building a shield from scratch to get a desired feature onto a Netduino / Plus is a relatively simple process only requiring reading component datasheets and some patience with a soldering iron or a small breadboard. In our next article, we'll put these guidelines to the test with a simple and popular off-the-shelf data logger shield made by Adafruit Industries. </p><h4>Appendix</h4><p>To build the shield interfacing with the [nwazet Touch Display, you will need the following parts: </p><blockquote><h5>Custom shield Eagle schematics</h5><ul><li><a href="https://bitbucket.org/fabienroyer/nwazet.channel9.articles/src/d33fe2c170e9/WhatIsAShield">Custom shield</a> </li></ul><h5>Bill of materials (~$15 for the shield w/o the [nwazet Touch Display module)</h5><ul><li>1 <a href="http://nwazet.com/touch-display-module">[nwazet Touch Display module</a> </li><li>1 <a href="http://nwazet.com/gocable10">10cm FCI connection cable</a> </li><li>1 <a href="https://www.adafruit.com/products/187">Adafruit DIY shield for Arduino</a> </li><li>1 <a href="http://www.proto-advantage.com/store/p/Netduino_GO_IDC_Adapter.php">ProtoAdvantage IDC Cable Breakout Board</a> </li><li>1 <a href="http://components.arrow.com/part/detail/40492237S7076394N5236">PNP Transistor 2N4403</a> </li><li>1 <a href="http://components.arrow.com/part/detail/39827066S7077451N5146">1K ohm resistor</a> </li><li>1 <a href="http://www.digikey.com/product-detail/en/CF14JT10K0/CF14JT10K0TR-ND/1741265?cur=USD">10K ohm resistor</a> </li><li>1 <a href="http://www.radioshack.com/product/index.jsp?productId=2049745">22 AWG solid core wire</a> </li><li>1 <a href="http://www.radioshack.com/product/index.jsp?productId=2062725">0.32&quot; diameter 60/40 rosin-core solder</a> </li></ul><h5>Eagle libraries</h5><ul><li><a href="http://www.ladyada.net/library/pcb/eaglelibrary.html">Adafruit Eagle library</a> (Netduino shield part) </li><li><a href="https://bitbucket.org/fabienroyer/nwazet.go/src">[nwazet Eagle library</a> (Go Socket part) </li></ul><h5>Netduino Go! Wiki</h5><ul><li><a href="http://wiki.netduino.com/Netduino-GO-Module-Builders-Guide.ashx">Netduino GO! Module Builder's Guide</a> (documents the Go! bus specifications) </li></ul></blockquote><h4>Bio</h4><p>Fabien is the Chief Hacker and co-founder of Nwazet, a start-up company located in Redmond WA, specializing in Open Source software and embedded hardware design. Fabien's passion for technology started 30 years ago, creating video games for fun and for profit. He went on working on mainframes, industrial manufacturing systems, mobile and web applications. Before Nwazet, Fabien worked at MSFT for eight years in Windows Core Security, Windows Core Networking and Xbox. During downtime, Fabien enjoys shooting zombies and watching sci-fi.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/FabienRoyer/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7615d43a7c264770886ca093015f17a6">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care</comments>
      <itunes:summary>C9 Netduino Shield Series - Using Arduino Shield with Netduino - Part I  &amp;nbsp;Photo courtesy of John Boxall  IntroductionWhen the Arduino Duemilanove microcontroller appeared in 2005, it featured a set of female pin headers exposing most of the pins of the ATmega168 for easy hacking and for connecting accessory boards known as &#39;Shields&#39;. The purpose of a shield is to provide new plug-and-play functionality to the host microcontroller, such as circuit prototyping, motion control, sensor integration, network and radio communication, or gaming interfaces, without worrying too much about the hardware implementation details. Seven years after the birth of the original Arduino, new shields keep coming out and are being cataloged on http://shieldlist.org/, a testament to the versatility of the design. It is also simple to build a DIY shield when nothing out there will meet your needs or when you want to understand how the shield concept works from the ground up.  In their infinite wisdom, Secret Labs, the makers of the Netduino, adopted the same Arduino form factor and header pin out to let .NET Micro Framework users tap into the vast array of Arduino shields on the market. Yet, there&#39;s always one hurdle that needs to be overcome: in order to give access to their hardware functions easily, many Arduino shields provide sample sketches (a.k.a. C/C&amp;#43;&amp;#43; Wiring programs) and libraries also written in C/C&amp;#43;&amp;#43; designed to be used within the Arduino IDE. Unfortunately, Arduino sketches and libraries aren&#39;t compatible with the Visual Studio environment and the .NET runtime: they need to be adapted in order to make use of the shield&#39;s hardware.  The goal of this series of articles is to attempt to demystify what an Arduino shield is. To do this, we&#39;ll start by building one from scratch. Then, we&#39;ll present a generic approach for selecting Netduino-compatible Arduino shields and adapting Arduino code to interface with the .NET Micro Framework.  Selecting Arduino shields </itunes:summary>
      <itunes:duration>119</itunes:duration>
      <link>http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care</link>
      <pubDate>Mon, 23 Jul 2012 05:30:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care</guid>
      <media:thumbnail url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_100.jpg" height="56" width="100"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_220.jpg" height="123" width="220"></media:thumbnail>
      <media:thumbnail url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_512.jpg" height="287" width="512"></media:thumbnail>
      <media:group>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.mp3" expression="full" duration="119" fileSize="1910521" type="audio/mp3" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.mp4" expression="full" duration="119" fileSize="11060612" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.webm" expression="full" duration="119" fileSize="4474071" type="video/webm" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.wma" expression="full" duration="119" fileSize="975323" type="audio/x-ms-wma" medium="audio"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.wmv" expression="full" duration="119" fileSize="13062199" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_high.mp4" expression="full" duration="119" fileSize="24485532" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_mid.mp4" expression="full" duration="119" fileSize="17151789" type="video/mp4" medium="video"></media:content>
        <media:content url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1_Source.wmv" expression="full" duration="119" fileSize="27616607" type="video/x-ms-wmv" medium="video"></media:content>
        <media:content url="http://smooth.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.ism/manifest" expression="full" duration="119" fileSize="6076" type="video/x-ms-wmv" medium="video"></media:content>
      </media:group>      
      <enclosure url="http://media.ch9.ms/ch9/70b8/f8690703-ee3d-40c8-a10b-7d77701d70b8/ArduinoNetduino1.wmv" length="13062199" type="video/x-ms-wmv"></enclosure>
      <dc:creator>Brian Peek, Fabien Royer</dc:creator>
      <itunes:author>Brian Peek, Fabien Royer</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/What-Is-an-Arduino-Shield-and-Why-Should-My-Netduino-Care/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Saving energy with the .NET Micro Framework</title>
      <description><![CDATA[ <p>Our home is equipped with a relatively old gas heater, built in 1996. It still works great, has been serviced regularly since it was installed and there is no good reason to replace it yet. However, it isn’t as energy efficient as more recent models.</p><p>The other aspect of this gas water heater is that it keeps the water hot 24/7, 365 days a year whether we need it or not. In my home, we generally only need hot water in the morning between 7 and 9 AM and in the evening, from 5 to 9 PM. On weekends, our schedule is a bit whacky and we need hot water from 8 AM to 9PM.</p><p>So, 30 hours for week days &#43; 26 hours for weekends, that’s 56 hours / week where hot water is actually needed, as opposed to 168 hours / week when the heater is just left alone. In order words, in our house, we only really need a third of the water heater energy that we normally consume.</p><p>To make matters worse, the water heater was installed in the garage by the builder and it gets pretty cold during the winter time.</p><p>Considering that&nbsp;<a href="http://www.energysavers.gov/your_home/water_heating/index.cfm/mytopic=12760">~25% of our heating bill goes into heating water</a>, I felt compelled to stop this senseless waste.</p><p>The idea that I came up with was to design a scheduler, configured to follow our weekly hot water usage pattern and capable of lowering the water heater temperature down to a minimum during off-hours.</p><p>I wanted it to be cheap to build with easy-to-find parts and&nbsp;<strong>very&nbsp;</strong>reliable as my wife does not appreciate cold showers: I decided to use a&nbsp;<a href="http://www.netduino.com/netduinomini/specs.htm">netduino-mini micro-controller</a>, an AdaFruit&nbsp;<a href="http://www.adafruit.com/index.php?main_page=product_info&amp;cPath=42&amp;products_id=264">DS1307 real-time clock</a>&nbsp;and a servo to adjust the temperature of the water heater.</p><p>Here’s what the end result looks like in action:</p><p><a href="http://www.youtube.com/watch?v=QEmMS5qdOcI&amp;feature=player_embedded">Startup sequence</a>&nbsp;and&nbsp;<a href="http://www.youtube.com/watch?v=ntumJIyvUzw&amp;feature=player_embedded">Manual override sequence</a></p><p>The slow moving speed of the servo is intentional in the application in order to minimize wear and tear on the servo’s gears and the overall assembly.</p><p>&nbsp;</p><div><div><strong>Application Overview</strong></div><ul><li>Every 60 seconds, the application checks the current date and time against a weekly schedule tracking daily timeframes when the gas water heater should be turned ON and when it should be turned OFF. </li><li>When it is time to turn the heater ON, the program first applies power the servo actuating the thermostat's dial and then tells the servo to turn the dial until it reaches the High Heat position.&nbsp;The servo power is then removed.&nbsp; </li><li>Conversely, when the time to turn the heater OFF comes, the same steps occur but this time, turning the dial all the way in the opposite direction. </li><li>The configuration of the schedule and the clock is done through a serial interface </li><li>The user can override the schedule by pressing a button which immediately turns the water heat ON. Pressing the button again resumes the normal schedule&nbsp;tracking process. </li></ul></div><div><strong>Architecture</strong></div><div>&nbsp;</div><div><p>The application is built on the open source&nbsp;<a href="http://netduinohelpers.codeplex.com">'netduino.helpers' library</a>&nbsp;which provides a set of hardware drivers written in C# targeting the netduino family of .Net Micro Framework micro-controllers.</p><p>&nbsp;</p><p>The drivers used by this application are:</p><ul><li><em>DS1307.cs</em>:&nbsp;This class implements a complete driver for the&nbsp;<a href="http://pdfserv.maxim-ic.com/en/ds/DS1307.pdf">Dallas Semiconductors / Maxim DS1307 I2C real-time clock</a>. The clock has 56 bytes of battery-backed memory which the application uses to serialize and deserialize the weekly schedule data. </li></ul><ul><li><em>HS6635HBServo.cs</em>: This class implements the driver for the&nbsp;<a href="http://www.hitecrcd.com/products/digital/digital-sport/hs-6635hb.html">HiTech HS-6635HB servo</a>.&nbsp;While this class has only been tested with this particular servo, the implementation is generic enough&nbsp;and can be applied to many other brands of servos. </li></ul><ul><li><em>SerialUserInterface.cs</em>: This class provides building blocks needed to display and receive data over a serial communication port. User input is handled in a interrupt-driven manner and results in a callback when the 'Enter' key is pressed. It also provides input value storage, basic input validation suitable for menu options and state management to track input sequences. </li></ul><ul><li><em>PushButton.cs</em>: This class provides a wrapper around the InterruptPort class of the .Net Micro Framework and makes it easy to use momentary switch in an application without polling inputs. </li></ul></div><p>&nbsp;</p><p><strong>Application Details</strong></p><p>Walking through the application, there are some details worth noting:</p><p>The beginning of the application starts with a conditional compilation definition based on the hardware that you're targeting. Because the netduino boards have different format factors and on-board devices, pin assignments will vary.</p><p>By default, the application is targeting the mini: &nbsp;<pre class="brush: csharp">#define NETDUINO_MINI</pre>.</p><p>Any other definition would target the regular netduino. I was unable to test with the netduino Plus, so there's no provision for it in the code yet.</p><p><pre class="brush: csharp">&#65279;#define NETDUINO_MINI

using System;
using System.Threading;
using System.Collections;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using netduino.helpers.Hardware;
using netduino.helpers.SerialUI;
using netduino.helpers.Servo;
using System.IO.Ports;
</pre></p><p>You must remember to include the proper reference to the Secret Labs assembly for the platform as well. If you don't your code might run, but expect very weird GPIO behavior <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /></p><p><pre class="brush: csharp">&#65279;#if NETDUINO_MINI
    // You must ensure that you also have the reference set to SecretLabs.NETMF.Hardware.NetduinoMini in the project
    // You must also remove the SecretLabs.NETMF.Hardware.Netduino if it was there.
    using SecretLabs.NETMF.Hardware.NetduinoMini;
#else
    // You must ensure that you also have the reference set to SecretLabs.NETMF.Hardware.Netduino in the project
    // You must also remove the SecretLabs.NETMF.Hardware.NetduinoMini if it was there.
    using SecretLabs.NETMF.Hardware.Netduino;
#endif
</pre></p><p>Most of the core objects in the application last for the lifetime of the application, except for the SerialUserInterface object which may be recycled if a communication failure occurs.</p><p><pre class="brush: csharp">&#65279;
namespace WaterHeaterController {
    public class Program {

#if NETDUINO_MINI
        private static readonly OutputPort _servoPowerEnable = new OutputPort(Pins.GPIO_PIN_16, false);
        private static readonly PushButton _pushButton = new PushButton(Pin: Pins.GPIO_PIN_17, Target: PushButtonHandler);
        private static readonly OutputPort _ledOverride = new OutputPort(Pins.GPIO_PIN_13, false);
        private static readonly OutputPort _ledServoPowerEnable = new OutputPort(Pins.GPIO_PIN_15, false); 
        private static readonly PWM _ledLowHeat = new PWM(Pins.GPIO_PIN_18);
        private static readonly PWM _ledHighHeat = new PWM(Pins.GPIO_PIN_19);
        private static readonly HS6635HBServo _servo = new HS6635HBServo(Pins.GPIO_PIN_20,minPulse: 700, centerPulse: 1600);
        private static SerialUserInterface _serialUI = new SerialUserInterface(Serial.COM2);
#else
        private static readonly OutputPort _servoPowerEnable = new OutputPort(Pins.GPIO_PIN_D3, false);
        private static readonly PushButton _pushButton = new PushButton(Pin: Pins.ONBOARD_SW1, Target: PushButtonHandler);
        private static readonly OutputPort _ledOverride = new OutputPort(Pins.GPIO_PIN_D2, false);
        private static readonly OutputPort _ledServoPowerEnable = new OutputPort(Pins.GPIO_PIN_D4, false);
        private static readonly PWM _ledLowHeat = new PWM(Pins.GPIO_PIN_D5);
        private static readonly PWM _ledHighHeat = new PWM(Pins.GPIO_PIN_D6);
        private static readonly HS6635HBServo _servo = new HS6635HBServo(Pins.GPIO_PIN_D9,minPulse: 700, centerPulse: 1600);
        private static SerialUserInterface _serialUI = new SerialUserInterface();
#endif
        private static readonly Schedule _schedule = new Schedule();
        private static readonly Status _status = new Status();
        private static readonly DS1307 _clock = new DS1307();
</pre></p><p>The following constants reference absolute servo positions expressed in degrees. Depending on the physical configuration of the servo installation (vertical, horizontal, left or right of the thermostat), you may need to change these values so that the servo moves in the correct direction.</p><p>The values below correspond to an 'upside down' servo (arm pointing downwards) placed on the left of the gas valve.</p><p><pre class="brush: csharp">        private const uint LowHeat = 180;
private const uint Center = 100;
private const uint HighHeat = 0;</pre></p><p>When the application starts, it attempts to detect if the real-time clock was ever configured properly.</p><p>If an exception occurs, caused by a faulty initialization of the DateTime object normally returned by _clock.Get(), a default date time is assigned to the clock and the schedule held in the user-backed memory of the clock is filled with zeros and the internal oscillator of the clock is finally started.</p><p><pre class="brush: csharp">        private static void InitializeClock() {
            try {
                _clock.Get();
            } catch (Exception e) {
                Debug.Print(&quot;Initializating the clock with default values due to: &quot; &#43; e);
                byte[] ram = new byte[DS1307.DS1307_RAM_SIZE];
                _clock.Set(new DateTime(2011, 1, 1, 12, 0, 0));
                _clock.Halt(false); 
                _clock.SetRAM(ram);
            }
        }</pre></p><p>The next step initializes the position of the servo:&nbsp;in an attempt to avoid sudden or harsh movements of the thermostat dial, the application expects the user to have positioned the arm of the servo manually at a 90 degree angle before powering ON the controller: with the servo arm's position centered, the call to _servo.Center() will hardly result in any motion at all.</p><p><pre class="brush: csharp">                        InitializeClock();

            Log(&quot;\r\nWater Heater Controller v1.0\r\n&quot;); 
            Log(&quot;Initializing...&quot;);
            LoadSchedule();

            PowerServo(true);
            Log(&quot;Centering servo&quot;);
            _servo.Center();
            Log(&quot;Setting heater on high heat by default&quot;);
            _servo.Move(Center, currentHeat);
            Log(&quot;Running...&quot;);
            PowerServo(false);
</pre></p><p>It's important to note that all calls to move the servo are prefixed with a PowerServo() call: the controller board was designed to control the 5 volt power supply to the servo through a transistor which gets activated / deactivated through that call. At the same time, an LED is turned ON / OFF indicating when the servo is moving.</p><p>To ensure that the motion of the servo is always nice and slow, preventing wear and tear on the gas valve as much as possible, _servo.Move() operates the servo with one degree increments at a time, with a short pause in between steps:</p><p><pre class="brush: csharp">        // Slowly moves the servo from a position to another
        public void Move(uint startDegree, uint endDegree, int delay = 80) {
            if (delay &lt;= 1) {
                delay = 10;
            }

            if (startDegree &lt; endDegree) {
                for (var degree = startDegree; degree &lt;= endDegree; degree&#43;&#43;) {
                    Degree = degree;
                    Thread.Sleep(delay);
                }
            } else {
                for (var degree = startDegree; degree &gt; endDegree; degree--) {
                    Degree = degree;
                    Thread.Sleep(delay);
                }
            }

            Release();
        }</pre></p><p>&nbsp;</p><p>The Degree property converts a degree value from 0 to 180 into servo 'pulses' ranging from 900 to 2100, based on the HS-6635HB specs,&nbsp;using a mapping function described here:&nbsp;<a href="http://rosettacode.org/wiki/Map_range#C">http://rosettacode.org/wiki/Map_range#C</a>.</p><p>Note that the servo's spec will not always match the actual capabilities of the servo and you may need to tweak these min / max pulse values after testing your specific servo like this:</p><p><pre class="brush: csharp">public static void Main() {
            using (var servo = new HS6635HBServo(Pins.GPIO_PIN_D9))
            {
                servo.Center();
                servo.Move(90, 0, 25);

                while (true)
                {
                    servo.Move(0, 180, 25);
                    servo.Move(180, 0, 25);
                }
            }
        }</pre></p><p>In my case, I discovered that degree 0&nbsp;corresponds to 700 instead of 900 called by the specs.</p><p>Once the initialization completes, the main loop of the application runs indefinitely or until a command to shutdown is provided. The main job if the loop is to check time against the water heater schedule and to respond to user input events.</p><p>User interactions take place over a serial port on the netduino with all the&nbsp;heavy lifting performed by the SerialInterface.cs class: it makes it easy to build simple menus and gather user-input in an event-driven fashion to avoid polling the serial port.</p><p>When a menu option is recognized or a CR/LF was provided on a free-form field, a callback takes place to a method with the context required to process the user input.</p><p>The main menu of the application shows the flow:</p><p>&nbsp;<pre class="brush: csharp">        public static void MainMenu(SerialInputItem item) {
            var SystemStatus = new ArrayList();
            _status.Display(SystemStatus, _clock, _schedule);

            _serialUI.Stop();

            _serialUI.AddDisplayItem(Divider); 
            _serialUI.AddDisplayItem(SystemStatus);
            _serialUI.AddDisplayItem(&quot;\r\n&quot;);
            _serialUI.AddDisplayItem(&quot;Main Menu:\r\n&quot;);
            _serialUI.AddInputItem(new SerialInputItem { Option = &quot;1&quot;, Label = &quot;: Show Schedule&quot;, Callback = ShowSchedule });
            _serialUI.AddInputItem(new SerialInputItem { Option = &quot;2&quot;, Label = &quot;: Set Schedule&quot;, Callback = SetSchedule });
            _serialUI.AddInputItem(new SerialInputItem { Option = &quot;3&quot;, Label = &quot;: Set Clock&quot;, Callback = SetClock, Context = 0 });
            _serialUI.AddInputItem(new SerialInputItem { Option = &quot;4&quot;, Label = &quot;: Swith Heater ON / Resume Schedule&quot;, Callback = SwitchHeaterOn });
            _serialUI.AddInputItem(new SerialInputItem { Option = &quot;X&quot;, Label = &quot;: Shutdown&quot;, Callback = Shutdown });
            _serialUI.AddInputItem(new SerialInputItem { Callback = RefreshMainMenu });

            _serialUI.Go();
        }</pre></p><p>Managing the user interface happens between 'bookend' calls to _serialUI.Stop() which disables the serial port interrupts and clear up any previously defined UI and and _serialUI.Go() which&nbsp;re-enables serial port interrupts and reset the state of the input buffer.</p><p>The display of text to the user is handled which successive calls to&nbsp;_serialUI.AddDisplayItem() which will display the text in the order where it was provided.</p><p>Defining user-input is done in the same manner, with successive calls to&nbsp;_serialUI.AddInputItem() which takes the following parameters:</p><p>Option: defines an entry in a list of one or more options that the user can pick from. This is an optional parameter. When omitted, the user input will be free form, in which case, there must only be one input item presented to the user at a time.</p><p>Label: a text label shown next to the Option field. This is an optional parameter. If the Option field is omitted, the Label should be provided to let the user know what kind of free-form input is format is expected. For example:</p><p><pre class="brush: csharp">_serialUI.AddInputItem(new SerialInputItem { Label = &quot;End Hour (00-23)?&quot;, Callback = SetSchedule, Context = 4, StoreKey = &quot;sched.endHour&quot; });
</pre></p><p>Callback: a mandatory delegate method to be called when the user hits the 'Enter' key. If one or more Option parameter was specified, the user will be shown a error message if he did not provide a valid input instead of calling the delegate method. Providing a Callback parameter alone allows defining a 'catch all' handler.</p><p>Context: an optional integer value used to manage state transitions when multiple successive user input steps are needed to complete a form. For example:</p><p><pre class="brush: csharp">switch (item.Context) {
                case 0:
                    _serialUI.Store.Clear();
                    _serialUI.AddDisplayItem(Divider);
                    _serialUI.AddDisplayItem(&quot;Set Clock:\r\n&quot;);
                    _serialUI.AddInputItem(new SerialInputItem { Label = &quot;Year (YYYY)?&quot;, Callback = SetClock, Context = 1, StoreKey = &quot;clock.YYYY&quot; });
                    break;
                case 1:
                    _serialUI.AddInputItem(new SerialInputItem { Label = &quot;Month (01-12)?&quot;, Callback = SetClock, Context = 2, StoreKey = &quot;clock.MM&quot; });
                    break;
                case 2:
                    _serialUI.AddInputItem(new SerialInputItem { Label = &quot;Day (01-31)?&quot;, Callback = SetClock, Context = 3, StoreKey = &quot;clock.DD&quot; });
                    break;
                case 3:...</pre></p><p>StoreKey: optional parameter used to preserve the user's input in a dictionary where the StoreKey is the name of the value provided by the user. &nbsp;In the above example, the call to _serialUI.Store.Clear(); ensures that the dictionary is empty before gathering the user's input.</p><p>Other things that are worth mentioning about the code:&nbsp;the .Net Micro Framework on the netduino is Spartan by design so that it can fit well within the constraints of the Atmel ARM 7 chip. As a result, things that many programmers may take for granted aren't always there or may only be partially supported, such as: Generics, Reflection, Serialization, dynamic AppDomains creation, etc.&nbsp;Therefore, one has to expect making trade-offs and accept that the code will not always be as 'pure' as it could be otherwise.</p><p>This is one of the reasons for creating the netduino.helpers library which aims to provide re-usable building blocks relevant to the netduino platform, attempting to lower the barrier to entry to embedded hardware development for folks coming from a pure software development background.</p><p>&nbsp;</p><p><strong>Building the Gas Water Heater Controller board</strong></p><p><strong>Electronic components</strong></p><p>This Gas Water Heater controller board is built around the following:</p><ul><li>1&nbsp;<a href="http://www.netduino.com/netduinomini/specs.htm">netduino-mini</a> </li><li>1&nbsp;<a href="http://www.adafruit.com/index.php?main_page=product_info&amp;cPath=42&amp;products_id=264">DS1307 real-time clock</a></li><li>1&nbsp;<a href="http://www.servocity.com/html/hs-6635hb_stan__hi-torque.html">HiTech HS-6635HB servo</a></li></ul><p>as well as the following components:</p><ul><li>1 1N4001 rectifier diode used on the ground pin of the 9V power supply </li><li>1 2N2222 transistor switching the power to the servo </li><li>1&nbsp;1N4001 rectifier diode&nbsp;connected to the base of the transistor </li><li>1 300 Ohm resistor connected in series with the base of the transistor </li><li>4 LEDs of different colors </li><li>4 ~220 Ohm resistors for the LEDs </li><li>1 momentary switch </li><li>1 100 Ohm resistor (to be used with the switch) </li><li>1 10K resistor (to be used with the switch) </li><li>1 9 volt / 1A power wall-wart power supply </li><li>1 generic proto board </li><li>straight and angled pin headers </li><li>1 barrel jack connector for the power supply </li></ul><p><strong>Simple Wiring Diagram</strong></p><p><img src="http://fabienroyer.files.wordpress.com/2011/02/wiring-diagram.png?w=300&amp;h=149" alt=""></p><p>&nbsp;</p><p>To further increase the life of the servo, I decided to control the power supply to the servo through a 2N2222A transistor. It works well because the servo doesn’t need to hold the water heater knob into place all the time: once positioned, the knob stays where it is and the servo no longer needs power to maintain its position.</p><p>The base of the transistor is connected to the ‘Servo Power Enable’ (pin 16 of the netduino mini) through a 300 Ohm resistor in series with a 1N4001 rectifier diode. The diode is there to eliminate 0.7 volts present on the pin even when it is turned off.</p><p>Here’s&nbsp;<a href="http://forums.netduino.com/index.php?/topic/1403-there-is-always-07-volts-on-digital-pins-even-when-theyre-not-active/">the thread on the netduino forums discussing the 0.7 volts issue</a>&nbsp;which seems specific to the netduino mini.</p><p>To be on the safe side, I also added a 1N4001 rectifier diode on pin 23 (power ground) of the netduino mini to prevent any potential damage to the micro-controller if the power were connected backwards. I did not see such protection on the&nbsp;<a href="http://netduino.com/netduinomini/schematic.pdf">schematics of the mini</a>.</p><p>Building the board:</p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/b-build-2of5.jpg"><img class="size-medium wp-image-228 aligncenter" title="B-Build-2of5" src="http://fabienroyer.files.wordpress.com/2011/02/b-build-2of5.jpg?w=200&amp;h=300" alt="" width="200" height="300"></a><a href="http://fabienroyer.files.wordpress.com/2011/02/b-build-3of5.jpg"><img class="size-medium wp-image-229 aligncenter" title="B-Build-3of5" src="http://fabienroyer.files.wordpress.com/2011/02/b-build-3of5.jpg?w=200&amp;h=300" alt="" width="200" height="300"></a></p><p>&nbsp;</p><p>The final board:</p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/c-whc-controller.jpg"><img class="size-medium wp-image-230 aligncenter" title="C-WHC-Controller" src="http://fabienroyer.files.wordpress.com/2011/02/c-whc-controller.jpg?w=300&amp;h=173" alt="" width="300" height="173"></a></p><p>&nbsp;</p><p><strong>Mechanical Parts</strong></p><ul><li>2 popsicle sticks </li><li>A spool of thin metal wire </li><li>A thin but sturdy brass rod </li><li>A section of rubber gasket long enough to fit around the circumference of the water heater knob. Make sure that the width of the rubber gasket doesn’t exceed the width of the knob’s hand-grip </li><li>An adjustable metal ring </li><li>Hand-craft a bracket the length of the popsicle stick from a thin strip of brass </li><li>10 zip ties </li><li>1 small wood board for mounting the servo </li></ul><p><strong>Mounting the servo on the water heater</strong></p><p>I chose to anchor the servo to the gas pipe of the water heater, using the section of the pipe to the left of the gas valve. To do so, I cut a piece of wood from left-over hardwood flooring material to fit the lower left area of the pipe. I drilled holes on the top and left sides of the board so that it could be secured to the gas pipe using zip ties. I also drilled 4 holes to secure the servo to the board with long thin screws and locking nuts.</p><p>&nbsp;</p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/c-whc-servo.jpg"><img class="size-medium wp-image-224 aligncenter" title="C-WHC-Servo" src="http://fabienroyer.files.wordpress.com/2011/02/c-whc-servo.jpg?w=300&amp;h=200" alt="" width="300" height="200"></a></p><p>&nbsp;</p><p><strong>Connecting the servo to the control knob</strong></p><ul><li>Drill two holes near the end of the popsicle sticks. </li><li>Make sure that the thin brass rod fits easily through the holes but doesn’t have wiggle room either. </li><li>Secure one of the popsicle sticks to the brass bracket with some tape then with the metal wire wrapped tightly around it. </li><li>Insert the brass bracket between the rubber gasket strip and the metal ring </li><li>Tighten the metal ring around the water heater knob. </li></ul><p>The final assembly should feel tight and strong while turning the knob.</p><p>&nbsp;</p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/c-whc-dial.jpg"><img class="aligncenter size-medium wp-image-225" title="C-WHC-Dial" src="http://fabienroyer.files.wordpress.com/2011/02/c-whc-dial.jpg?w=300&amp;h=200" alt="" width="300" height="200"></a></p><p>&nbsp;</p><p>To secure the other popsicle stick to the arm of the servo, drill a few holes into the stick, matching the holes in the servo’s arm. Then weave the thin metal wire through the holes, then wrap the metal wire tightly around&nbsp;the stick and the servo’s arm. The final assembly should also be tight and strong while turning the servo’s arm.</p><p>Connect the popsicle sticks together with the brass rod and secure it by bending it carefully around the ends of the sticks. It’s easier to do this while the servo’s arm is not attached to the servo.</p><p>Finally, re-attach the arm to the servo and test the assembly by moving the servo’s arm slowly.&nbsp;</p><p>The knob should turn in sync with the servo with ease:</p><p>&nbsp;</p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/c-whc-heater.jpg"><img class="aligncenter size-medium wp-image-226" title="C-WHC-Heater" src="http://fabienroyer.files.wordpress.com/2011/02/c-whc-heater.jpg?w=300&amp;h=200" alt="" width="300" height="200"></a></p><p>&nbsp;</p><p>&nbsp;</p><p><strong>Operation</strong></p><p>Connect a dumb-terminal to COM2 on the netduino mini (or to COM1 on the regular netduino).</p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/b-build-5of5.jpg"><img class="size-medium wp-image-232 aligncenter" title="B-Build-5of5" src="http://fabienroyer.files.wordpress.com/2011/02/b-build-5of5.jpg?w=300&amp;h=200" alt="" width="300" height="200"></a></p><p><a href="http://fabienroyer.files.wordpress.com/2011/02/b-build-4of5.jpg"><img class="size-medium wp-image-233 aligncenter" title="B-Build-4of5" src="http://fabienroyer.files.wordpress.com/2011/02/b-build-4of5.jpg?w=300&amp;h=200" alt="" width="300" height="200"></a></p><p>&nbsp;</p><p>Using the serial interface:</p><ul><li>Set the clock’s date and time and define a schedule when the heater should turn ON. </li><li>The schedule tracks 7 days, with 4 timeslots for each day. Each timeslot has a begin time defining when the heater should turn itself ON and an end time, defining when the heater should turn itself OFF. </li><li>Setting a timeslot to 0 resets the timeslot and the heater stays OFF. </li><li>Keep in mind that the heater timeslots and the clock expect to work on a 24 hour schedule. </li></ul><p>Sample output:</p><p><code><br>[02/19/2011 19:29:40]<br>Water Heater Controller v1.0</code></p><p><code>[02/19/2011 19:29:40] Initializing...<br>[02/19/2011 19:29:40] Loading schedule<br>[02/19/2011 19:29:40] Centering servo<br>[02/19/2011 19:29:41] Setting heater on high heat by default<br>[02/19/2011 19:29:51] Running...<br>-------------------------------------------------------------<br>Time: Saturday, 19 February 2011 19:29:51<br>Heater Schedule Today: Sat [8-21] [0-0] [0-0] [0-0]<br>Heater Status: ON [scheduled]</code></p><p><code>Main Menu:<br>1 : Show Schedule<br>2 : Set Schedule<br>3 : Set Clock<br>4 : Swith Heater ON / Resume Schedule<br>X : Shutdown</code></p><p><code>[02/19/2011 19:29:52] Heater state change<br>[02/19/2011 19:29:52] Setting heater on high<br>1<br>-------------------------------------------------------------<br>Heater Weekly Schedule:</code></p><p><code>Sun [8-21] [0-0] [0-0] [0-0]<br>Mon [6-9] [17-21] [0-0] [0-0]<br>Tue [6-9] [17-21] [0-0] [0-0]<br>Wed [6-9] [17-21] [0-0] [0-0]<br>Thu [6-9] [17-21] [0-0] [0-0]<br>Fri [6-9] [17-21] [0-0] [0-0]<br>Sat [8-21] [0-0] [0-0] [0-0]</code></p><p><strong>Meaning of the LEDs</strong></p><ul><li>High heat LED: ON indicates that the water heater is set to high heat.&nbsp; </li><li>Low heat LED: ON indicates that the water heater is set to low heat. </li><li>Servo Active LED: ON indicates that the servo is changing position. </li><li>High heat override LED: ON indicates that the push button was used to override the schedule. </li></ul><p><strong>Starting the water heater controller the first time</strong></p><p>Before you apply power to the board, make sure that the arm of the servo is centered (vertical position). This will ensure that the startup sequence is smooth. From there, the controller will slowly set the water heater knob on high heat before tracking to the schedule.</p><p>&nbsp;</p><p>Cheers,</p><p>-Fabien.</p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/FabienRoyer/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d2b430175afe457f833e9e9300268089">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Saving-energy-with-the-NET-Micro-Framework</comments>
      <itunes:summary> Our home is equipped with a relatively old gas heater, built in 1996. It still works great, has been serviced regularly since it was installed and there is no good reason to replace it yet. However, it isn’t as energy efficient as more recent models. The other aspect of this gas water heater is that it keeps the water hot 24/7, 365 days a year whether we need it or not. In my home, we generally only need hot water in the morning between 7 and 9 AM and in the evening, from 5 to 9 PM. On weekends, our schedule is a bit whacky and we need hot water from 8 AM to 9PM. So, 30 hours for week days &amp;#43; 26 hours for weekends, that’s 56 hours / week where hot water is actually needed, as opposed to 168 hours / week when the heater is just left alone. In order words, in our house, we only really need a third of the water heater energy that we normally consume. To make matters worse, the water heater was installed in the garage by the builder and it gets pretty cold during the winter time. Considering that&amp;nbsp;~25% of our heating bill goes into heating water, I felt compelled to stop this senseless waste. The idea that I came up with was to design a scheduler, configured to follow our weekly hot water usage pattern and capable of lowering the water heater temperature down to a minimum during off-hours. I wanted it to be cheap to build with easy-to-find parts and&amp;nbsp;very&amp;nbsp;reliable as my wife does not appreciate cold showers: I decided to use a&amp;nbsp;netduino-mini micro-controller, an AdaFruit&amp;nbsp;DS1307 real-time clock&amp;nbsp;and a servo to adjust the temperature of the water heater. Here’s what the end result looks like in action: Startup sequence&amp;nbsp;and&amp;nbsp;Manual override sequence The slow moving speed of the servo is intentional in the application in order to minimize wear and tear on the servo’s gears and the overall assembly. &amp;nbsp; Application OverviewEvery 60 seconds, the application checks the current date and time against a weekly schedule tracking daily time</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Saving-energy-with-the-NET-Micro-Framework</link>
      <pubDate>Thu, 10 Mar 2011 17:00:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Saving-energy-with-the-NET-Micro-Framework</guid>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/7639cda0-ccb3-4eac-a837-5944157e3852.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://files.channel9.msdn.com/thumbnail/90368aaa-dded-4c91-b92f-ce177faf184b.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Fabien Royer</dc:creator>
      <itunes:author>Fabien Royer</itunes:author>
      <slash:comments>12</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Saving-energy-with-the-NET-Micro-Framework/RSS</wfw:commentRss>
    </item>    
</channel>
</rss>