<?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 - Entries tagged with mods</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Tags/mods/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 - Entries tagged with mods</title>
      <link>http://channel9.msdn.com/Tags/mods</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/Tags/mods</link>
    <language>en</language>
    <pubDate>Fri, 24 May 2013 10:02:09 GMT</pubDate>
    <lastBuildDate>Fri, 24 May 2013 10:02:09 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Tron Disc with .NET Microframework</title>
      <description><![CDATA[<p><a href="http://harfordhackerspace.org">Harford Hackerspace</a> wanted to make our own Tron Identity Disc using the Netduino, allowing us to quickly load different versions of code to change the disc's functionality. 
&nbsp; David Powell, Gary W. Cygiel, Jeremy Ashinghurst, Paul King, Jason 
McMahon present a simple lightshow in this tutorial, developers can easily extend the code and hardware
 to produce an interactive game. </p>
<div><a href="http://www.youtube.com/watch?v=I_KGca_g96U" target="_new"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/video7ca300f0af91.jpg" alt=""></a></div>
<p>To get started, we purchased and retrofitted a Spin Master Tron Identity Disc replica, which kept us from having to create a new physical disk, and so sidestepped the most difficult aspect of the project.
</p>

<h2>Operation Specifications</h2>
<p>We decided that we wanted our version of the Tron Idenity Disc to have the following specifications:</p>
<p><b>Power</b></p>
<ul>
<li>Rechargeable lithium-ion battery </li><li>LED to indicate the Tron Identity Disc is being charged </li><li>An On/Off switch enabling the battery to disconnect from the Netduino to conserve power while the disc is being stored
</li></ul>
<p><b>Operation</b></p>
<ul>
<li>Scenario 1 - Power On<b></b>
<ul>
<li>All LEDs turn on so we can make sure they are all working<b></b> </li></ul>
</li><li>Scenario 2 – Animations<b></b>
<ul>
<li>Pressing a momentary button will cycle through LED animations<b></b> </li></ul>
</li><li>Scenario 3 – Charge Detection<b></b>
<ul>
<li>Placing the Tron Idenity Disc on or removing the Tron Identity Disc from a charging station will raise an event handler. Placing the disc on the charger will start a pulsating animation. Removing the disc will resume the previous animation.<b></b>
</li></ul>
</li></ul>
<p><b>Hardware</b></p>
<ul>
<li><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Deluxe</a><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Tron</a><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Identity</a><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Disc</a><u></u>
</li><li><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.netduino.com&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNFnCk2jHMrP3snNaRUoNADG8gXHBA">Netduino</a>
<u></u></li><li>Dremel with Cutoff Wheel<u></u> </li><li>Soldering Iron </li><li>Solder </li><li>Hot Glue Gun </li><li>Phillips Screw Driver </li><li>Wire Strippers </li><li>Heat Shrink </li><li><a href="http://www.sparkfun.com/products/341">Lithium-Ion Battery</a> (2x) </li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=CKN9924-ND">SPST On/Off Switch</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=P12216SCT-ND">SPST Momentary Switch</a>
</li><li><a href="http://www.sparkfun.com/products/8812">Prototype Board</a> </li><li><a href="http://www.newark.com/vcc-visual-communications-company/vaol-5gsby4/led-5mm-blue-7000mcd-470nm/dp/57P7133?Ntt=VAOL-5GSBY4">Blue LEDs</a> (33x)
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=MAX7219CNG%2B-ND">MAX7219</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=LM317TFS-ND">LM317T Adjustable Voltage Regulator</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=294-1108-ND">Heat sink for TO-220 devices</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=490-5401-ND">0.1uF capacitor</a> (2x)
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=PN2222AD26ZCT-ND">2222 Transistor</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=201UR102B-ND">1k Ohm potentiometer</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=P470BACT-ND">470 Ohm resistor, ¼ watt</a> (2x)
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=P10KBACT-ND">10k Ohm resistor, ¼ watt</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=P2.2KBATB-ND">2.2k Ohm resistor ¼ watt</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=PPC1.5W-1CT-ND">1.5 Ohm resistor, 1 watt</a>
</li><li><a href="http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=1N4001FSCT-ND">1N4001 Rectifier Diode</a>
</li></ul>
<h2>Tron Disc Light Ring</h2>
<p><b></b></p>
<p>The original <a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">
Deluxe</a><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Tron</a><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Identity</a><a href="http://www.google.com/url?q=http%3A%2F%2Fwww.toysrus.com%2Fproduct%2Findex.jsp%3FproductId%3D4068819&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGJ-4fHEkYe0QbsDCi5xzVEoIgQfg">Disc</a>
 contained six LED on the outer ring, which left much to be desired. Our modified disc includes 30 LEDs on the outer ring and two LEDs illuminating the inner arc.
</p>
<p>To get started, we opened the disc by removing its four Phillips head screws. Next, we removed all electronics including the wires, tilt sensor, LEDs, switch, speaker, and microcontroller board, taking care to not lose the plastic momentary button, since
 we later used it to switch between our animations. Then, we used a Dremel with a cutoff wheel to remove any unnecessary plastic in order to make room our own electronics. See Figure 1.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/Empty_Disc.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/Empty_Disc.jpg"><img title="Empty_Disc" border="0" alt="Empty_Disc" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/Empty_Disc_thumb.jpg" width="500" height="333"></a></p>
<p align="center"><strong>Figure 1: Removed Plastic with Dremel</strong></p>
<p>As shown in Figure 2, we used superglue to attach the narrow end of the momentary button to the plastic Tron ring. Then, using the Dremel, we cut a small L bracket from a scrap piece of acrylic and attached it with cyanoacrylate. We reinforced the L bracket
 using hot glue and applied a small amount of cyanoacrylate to the momentary switch and attached it to the L bracket. Consequently, the original plastic momentary button now activates our momentary switch.
</p>
<p>While we had the hot glue gun out, we also attached the SPST On/Off switch and the two inner ring LEDs.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/mounting_switch.jpg"><strong><img title="mounting_switch" border="0" alt="mounting_switch" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/mounting_switch_thumb.jpg" width="500" height="333"></strong></a></p>
<p align="center"><strong>Figure 2: Mounting Momentary Switch</strong></p>
<p>Next, we cut a circle from a piece of cardboard. Using a straight edge, we carefully marked the location of each LED to arrange an equally spaced circular pattern. Then, with a hobby razor knife, we cut notches in the cardboard at a slight angle to hold
 the LEDs. An additional benefit of the cardboard is it helps keep the anodes and cathodes from shorting out.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/clip_image006.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/clip_image006.jpg"><img title="clip_image006" border="0" alt="clip_image006" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/clip_image006_thumb.jpg" width="500" height="333"></a></p>
<p align="center"><strong>Figure 3: LED Nestled in Notched Cardboard</strong></p>
<p>Next, we connected all of the components together per the following schematic diagrams. The MAX7219 IC is capable of controlling 64 LEDs. However, we chose to use only 30 in order to simplify of wiring. The circuit is divided into five segments, each containing
 six LEDs. In each segment, all the cathodes are tied together and then tied to a single segment pin on the MAX7219 and the anodes are routed back to its digit pins. There is one digit for each LED in the segment and the segments share digit pins. The Netduino
 controls the logic level of the digit and segment pins using “bit-banged” I2C. All that said, the schematic is the best reference as to how the LEDs were wired.</p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/3.png"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/3.png"><img title="3" border="0" alt="3" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/3_thumb.png" width="500" height="212"></a></p>
<p align="center"><strong>Figure 4: Netduino and MAX7219 Schematic</strong></p>
<p><b></b></p>
<p><b></b></p>
<h2>Charging System</h2>
<p>The charging system is comprised of a charging circuit and a detection circuit. A lithium-ion battery inside the disc is charged from an external power source. The charging circuit, which was modified from a design by Scott Henion of<a href="http://www.google.com/url?q=http%3A%2F%2Fshdesigns.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGGePpOQjkuFZ45wutvAdxteBL_3w">SHDesigns</a><a href="http://www.google.com/url?q=http%3A%2F%2Fshdesigns.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGGePpOQjkuFZ45wutvAdxteBL_3w">.</a><a href="http://www.google.com/url?q=http%3A%2F%2Fshdesigns.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFQjCNGGePpOQjkuFZ45wutvAdxteBL_3w">org</a>,
 provides a method of safe charging. The detection circuit allows the Netduino to know when it's being charged.</p>
<h3>Charging Circuit</h3>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/1.png"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/1.png"><img title="1" border="0" alt="1" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/1_thumb.png" width="497" height="347"></a></p>
<p align="center"><strong>Figure 5: Charging Station Schematic</strong></p>
<p>The LM317 is an adjustable voltage regulator that may also be used as an adjustable constant-current source. In this case, it's used as a voltage regulator. The 470 ohm resistor forms a voltage divider with the 1k ohm potentiometer and the 2.2k ohm resistor
 to set the output voltage at 8.4V. Since lithium-ion batteries should be charged using constant current-constant voltage, the transistor and resistor form the current limiting in the circuit. When the charge current reaches a certain threshold, the resistor's
 voltage drop exceeds the turn-on voltage of the transistor and the transistor starts to conduct. That takes current away from the voltage divider, dropping the voltage until the current is below the threshold. In this way, the current is limited until the
 voltage limit is reached; then, the current slowly drops off at a constant voltage.</p>
<h3>Detection circuit</h3>
<p><strong></strong></p>
<p align="center"><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/Tron_Battery_Updated.jpg"><strong></strong></a><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/Tron_Battery_Updated.jpg"><img title="Tron_Battery_Updated" border="0" alt="Tron_Battery_Updated" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/Tron_Battery_Updated_thumb.jpg" width="500" height="251"></a></p>
<p align="center"><strong>Figure 6: Charge Detection Schematic</strong></p>
<p><b></b></p>
<p>The detection circuit works by applying a voltage to the disc whenever it is plugged in. When the disc is plugged in, 8.4V from the charger run through the 470 ohm resistor, then most of the current runs through the LED while a minimal amount runs through
 the 10k ohm resistor. The voltage to the Netduino is the voltage across the LED, equaling somewhere around 3V. When the charger is disconnected, however, the 10K ohm resistor pulls the voltage detection line to 0V. SW2 is a disconnect switch which feeds the
 main power to the Netduino. From there we use the Netduino's 5v power supply.</p>
<p>After all the connections were made we carefully placed all the wires and components inside the disc. We learned the hard way that you must pay extra attention since it's very easy to put a screw through one of your wires.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/tucking_components.jpg"><img title="tucking_components" border="0" alt="tucking_components" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/10104241/tucking_components_thumb.jpg" width="500" height="419"></a></p>
<p><b>Creating a driver for the MAX7219:</b></p>
<p>To create a driver for the MAX7219, we took a little information from the <a href="http://datasheets.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf">
data sheet</a>. First, we created a basic class structure and initialized some static defines for the command reference as well as a few
<a href="http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&amp;l=EN-US&amp;k=k%28MICROSOFT.SPOT.HARDWARE.OUTPUTPORT%29;k%28TargetFrameworkMoniker-%22.NETMICROFRAMEWORK%2cVERSION%3dV4.1%22%29;k%28DevLang-CSHARP%29&amp;rd=true">
OutputPort</a>'s to hold our pin's to <a href="http://en.wikipedia.org/wiki/Bit-banging">
bit-bang</a>. We bit-banged the protocol because the SPI implementation of the MAX7219 isn't 100% compliant with the Netduino's SPI Library:</p>
<pre class="csharpcode"><span class="kwrd">namespace</span> TronDisc
{
    <span class="kwrd">public</span> <span class="kwrd">class</span> max7219
    {
        <span class="rem">// Command reference</span>
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_noop           = 0x00;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit0         = 0x01;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit1         = 0x02;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit2         = 0x03;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit3         = 0x04;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit4         = 0x05;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit5         = 0x06;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit6         = 0x07;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_digit7         = 0x08;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_decodeMode     = 0x09;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_intensity      = 0x0a;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_scanLimit      = 0x0b;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_shutdown       = 0x0c;
        <span class="kwrd">public</span> <span class="kwrd">byte</span> max7219_reg_displayTest    = 0x0f;

        <span class="rem">// Pin ports for spi</span>
        <span class="kwrd">private</span> OutputPort loadPin;
        <span class="kwrd">private</span> OutputPort dataPin;
        <span class="kwrd">private</span> OutputPort clkPin;

        <span class="rem">// Constructor, pass pin definitions</span>
        <span class="kwrd">public</span> max7219( OutputPort in_dataPin,
                        OutputPort in_clockPin,
   OutputPort in_loadPin )
        {
            <span class="rem">// Assign local port pins to ports passed from constructor</span>
            dataPin = in_dataPin;
            clkPin = in_clockPin;
            loadPin = in_loadPin;
     }
     }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
 {font-size:small;
 color:black;
 font-family:consolas,"Courier New",courier,monospace;
 background-color:#ffffff}
.csharpcode 
 {margin:0em}
.csharpcode .rem
 {color:#008000}
.csharpcode .kwrd
 {color:#0000ff}
.csharpcode .str
 {color:#006080}
.csharpcode .op
 {color:#0000c0}
.csharpcode .preproc
 {color:#cc6633}
.csharpcode .asp
 {background-color:#ffff00}
.csharpcode .html
 {color:#800000}
.csharpcode .attr
 {color:#ff0000}
.csharpcode .alt
 {background-color:#f4f4f4;
 width:100%;
 margin:0em}
.csharpcode .lnum
 {color:#606060}
-->
</style>
<p>Next we added a method to our class to transmit a single byte to the MAX7219:</p>
<pre class="csharpcode"><span class="rem">// Transmits 1 byte over SPI, bitbang method</span>
<span class="kwrd">public</span> <span class="kwrd">void</span> putByte(<span class="kwrd">byte</span> data)
{
    <span class="kwrd">byte</span> i = 8;
    <span class="kwrd">int</span> mask;

    <span class="kwrd">while</span> (i &gt; 0)
    {
        mask = (1 &lt;&lt; i - 1);
        clkPin.Write(<span class="kwrd">false</span>);
        <span class="kwrd">if</span> (((<span class="kwrd">int</span>)data &amp; mask) == 0)
            dataPin.Write(<span class="kwrd">false</span>);
        <span class="kwrd">else</span>
            dataPin.Write(<span class="kwrd">true</span>);
        clkPin.Write(<span class="kwrd">true</span>);
        --i;
    }
}</pre>
<p>And finally, we added one more method that pulled our load pin low, transmitted the register and column bytes, and pulled load high again to latch the data:</p>
<pre class="csharpcode"><span class="rem">// Sends 1 Command / Data pair to a single driver chip</span>
<span class="kwrd">public</span> <span class="kwrd">void</span> maxSingle(<span class="kwrd">byte</span> reg, <span class="kwrd">byte</span> col)
{
    <span class="rem">// LOAD low</span>
    loadPin.Write(<span class="kwrd">false</span>);

    <span class="rem">// Transmit Register</span>
    putByte(reg);
    <span class="rem">// Transmit Column</span>
    putByte(col);

    <span class="rem">// LOAD high latches data sent</span>
    loadPin.Write(<span class="kwrd">true</span>);
}</pre>
<p>Complete with a function to send commands to the MAX via the maxSingle, we went back to our constructor and passed some initialization values after our pin assignments. maxSingle is so named because it only addresses one MAX7219, and since they are daisy-chainable,
 we can control multiple MAX7219s with little modification to our code:</p>
<pre class="csharpcode"><span class="rem">// Initialize MAX7219</span>
<span class="rem">// set scan limit</span>
maxSingle(max7219_reg_scanLimit, 0x07);
<span class="rem">// using an led matrix mode (not digits)</span>
maxSingle(max7219_reg_decodeMode, 0x00);
<span class="rem">// not in shutdown mode</span>
maxSingle(max7219_reg_shutdown, 0x01);
<span class="rem">// no display test</span>
maxSingle(max7219_reg_displayTest, 0x00);
<span class="rem">// set max intensity  (range 00-0f)</span>
maxSingle(max7219_reg_intensity, 0x0f);</pre>
<p><b>Using the driver:</b></p>
<p>To use the driver, we created a variable to hold the instance of our driver, created the actual OutputPort references to pins, and passed to our instanced MAX7219 driver. The pins we are using are D10, D11, D13:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> max7219 driver;

<span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Main()
{
    <span class="rem">// Define spi pins</span>
    OutputPort loadPin = <span class="kwrd">new</span> OutputPort(Pins.GPIO_PIN_D10, <span class="kwrd">false</span>);
    OutputPort dataPin = <span class="kwrd">new</span> OutputPort(Pins.GPIO_PIN_D11, <span class="kwrd">false</span>);
    OutputPort clkPin = <span class="kwrd">new</span> OutputPort(Pins.GPIO_PIN_D13, <span class="kwrd">false</span>);

    <span class="rem">// Instance of driver, passing pin assignments</span>
    driver = <span class="kwrd">new</span> max7219(dataPin, clkPin, loadPin);
}</pre>
<p>At this point, we used our driver by calling driver.maxSingle(reg, col) to light either a single LED or a group of LEDs depending on specifications.</p>
<h2><b>Animations</b></h2>
<p>We completed two different types of animations, one based off of an algorithm and one using frame-by-frame animation for more complex patterns.</p>
<p>Our first animation is my personal favorite, the pulsating animation, which uses pulses to raise and lower the brightness:</p>
<pre class="csharpcode"><span class="rem">// Main loop</span>
<span class="kwrd">while</span> (<span class="kwrd">true</span>)
{
   <span class="rem">// if direction is 1, we are going to fade down</span>
   <span class="kwrd">if</span> (dir == 1)
      cnt--;
   <span class="kwrd">else</span> <span class="rem">// otherwise fade up</span>
      cnt&#43;&#43;;

   <span class="rem">// if direction is fading down and we are at 0 (the bottom)</span>
   <span class="rem">// switch directions to fading up</span>
   <span class="kwrd">if</span> (dir == 1 &amp;&amp; cnt == 0)
      dir = 0;
   <span class="rem">// and if we are fading up (dir == 0) and we are at the max intensity</span>
   <span class="rem">// lets start fading down</span>
   <span class="kwrd">else</span> <span class="kwrd">if</span> (dir == 0 &amp;&amp; cnt == 15)
      dir = 1;

    <span class="rem">// loop through driver.MAX7219_reg_digit0-7 and make sure all led's</span>
    <span class="rem">// are on by passing 0xFF which is all 8 bits on per digit</span>
   <span class="kwrd">for</span> (j = 1; j &lt; 8; j&#43;&#43;)
      driver.maxSingle(j, 0xFF);

   <span class="rem">// Pass the cnt value to the intensity register</span>
   driver.maxSingle(driver.max7219_reg_intensity, (<span class="kwrd">byte</span>)(cnt &amp; 0x0f));

   <span class="rem">// Add a small delay between levels of intensity</span>
   Thread.Sleep(15);
}</pre>
<p>Wow, that looks great! Now we can create all kinds of animations using simple algorithms. To create more complex animations, however, a simpler method was needed. The disc is wired up around the ring using five digits of six LED segments. To simplify the
 math, we made a graphical ring of 30 LEDs, recorded each frame, and stored five characters per frame using six bits per character.</p>
<p>The creator is posted on the web at <a href="http://harfordhackerspace.org/ledwiz/tron/">
http://harfordhackerspace.org/ledwiz/tron/</a> and was created using HTML/Javascript and CSS. We won't get into the details of that code in this article, but feel free to use it to create as many animations as your Netduino will hold!</p>
<p>After creating an animation, click the ‘generate' button to get an output similar to the following:</p>
<pre class="csharpcode"><span class="kwrd">byte</span>[] animation = <span class="kwrd">new</span> <span class="kwrd">byte</span>[] {
  0x2,0x11,0x4,0x21,0x8,
  0x4,0x22,0x8,0x2,0x11,
  0x8,0x4,0x11,0x4,0x22
};</pre>
<p>Here you can see three frames (one line per frame) with five characters using six bits per character. To display the animation, keep track of which digit (0-5) is active as the register and pass the character as the column:</p>
<pre class="csharpcode"><span class="kwrd">int</span> i;

<span class="kwrd">for</span> (i = 0; i &lt; animation.Length; i&#43;&#43;)
{
    driver.maxSingle((<span class="kwrd">byte</span>)((i % 5) &#43; 1), animation[i]);
}</pre>
<p>It's a simple animation. To slow it down, add a <a href="http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&amp;l=EN-US&amp;k=k%28SYSTEM.THREADING.THREAD.SLEEP%29;k%28TargetFrameworkMoniker-%22.NETMICROFRAMEWORK%2cVERSION%3dV4.1%22%29;k%28DevLang-CSHARP%29&amp;rd=true">
Thread.sleep</a>(x) (x being the number of milliseconds between each command).</p>
<h2>Dealing with multiple frame by frame animations</h2>
<p>To create multi-frame animations, make a multi-dimensional array and modify the code to support multiple animations:</p>
<pre class="csharpcode"><span class="kwrd">byte</span> animation_num = 0;
<span class="kwrd">int</span> i;
<span class="kwrd">byte</span>[][] animations = <span class="kwrd">new</span> <span class="kwrd">byte</span>[][]
{
   <span class="kwrd">new</span> <span class="kwrd">byte</span>[]
   {
      0x2,0x11,0x4,0x21,0x8,
      0x4,0x22,0x8,0x2,0x11,
      0x8,0x4,0x11,0x4,0x22
   },
   <span class="kwrd">new</span> <span class="kwrd">byte</span>[]
   {
      0x1,0x10,0x2,0x8,0x2,
      0x3,0x18,0x6,0x2,0x8,
      0x7,0x3,0x18,0x1,0x8
   }
}
<span class="rem">// Main loop</span>
<span class="kwrd">while</span> (<span class="kwrd">true</span>)
{
   <span class="kwrd">for</span> (i = 0; i &lt; animations[animation_num].Length; i&#43;&#43;)
   {
      driver.maxSingle((<span class="kwrd">byte</span>)((i % 5) &#43; 1), animations[animation_num][i]);
   }
}</pre>
<p>Once it hits the main loop, it will keep playing the first animation (which is 0) until a change in the value of animation_num to 1 (then it will play the second animation).</p>
<p>A method is needed to read the button on the Disc and increment/loop the animation_num value. To do this, use the
<a href="http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&amp;l=EN-US&amp;k=k%28MICROSOFT.SPOT.HARDWARE.INTERRUPTPORT%29;k%28TargetFrameworkMoniker-%22.NETMICROFRAMEWORK%2cVERSION%3dV4.1%22%29;k%28DevLang-CSHARP%29&amp;rd=true">
InterruptPort</a> class.</p>
<p>First, add the InterruptPort code to the Main() function before the Main loop:</p>
<pre class="csharpcode"><span class="rem">// Tron Button to Change Annimations, pulls high</span>
InterruptPort changeBtn = 
   <span class="kwrd">new</span> InterruptPort(
      Pins.GPIO_PIN_D0, 
      <span class="kwrd">false</span>, 
      Port.ResistorMode.Disabled,
      Port.InterruptMode.InterruptEdgeHigh);
changeBtn.OnInterrupt &#43;= <span class="kwrd">new</span> NativeEventHandler(changeBtn_OnInterrupt);</pre>
<p>Then, add a method called changeBtn_OnInterrupt to the program:</p>
<pre class="csharpcode"><span class="rem">//Interrupt Handler for changeBtn to change annimations</span>
<span class="kwrd">static</span> <span class="kwrd">void</span> changeBtn_OnInterrupt(<span class="kwrd">uint</span> data1, <span class="kwrd">uint</span> data2, DateTime time)
{
    <span class="kwrd">if</span> (&#43;&#43;new_animation_num &gt; animation_total)
    {
        new_animation_num = 0;
    }

     <span class="rem">// reset intensity to max incase previous animation exits with </span>
     <span class="rem">// intensity less than max</span>
    driver.maxSingle(driver.max7219_reg_intensity, 0x0f);

    <span class="rem">// Print debug string</span>
    Debug.Print(<span class="str">&quot;Animation Num: &quot;</span>);
    Debug.Print(new_animation_num.ToString());
}</pre>
<p>Finally, to get it all working, add a switcher at the top of the loop, change the animation_num values to be public throughout the class, as well as static since the program is static:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Program
{
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">byte</span> new_animation_num = 0;
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">byte</span> animation_num = 0;
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">byte</span> animation_total = 2;

    <span class="rem">/* more goodness */</span>

    <span class="rem">// Main loop</span>
    <span class="kwrd">while</span> (<span class="kwrd">true</span>)
    {
        animation_num = new_animation_num;

        <span class="rem">// adding this to the top of our main loop</span>
    }
    <span class="rem">/* more goodness */</span>
}</pre>
<h2>Finishing touches</h2>
<p>To make it all work together, we mixed algorithmic animations by filling our animations array, hard-coded a few “if” statements to do algorithmic animations, as well as “else” statements for all the frame-based animations.&nbsp; We also added another InterruptHandler
 to both act like a button when the Disc is placed on the charging dock and change the animation to the pulse animation.&nbsp; Also, we tested the power by turning on all of the LEDs, waiting three seconds, and then proceeding.</p>
<h2>About</h2>
<p>Harford Hackerspace is a non-profit 501(C)(3) charitable organization set forth to create a place for people to collaborate on hardware and software projects. Members of the space have been meeting weekly since January 2009 to socialize, learn, and work
 on projects related to science and technology. In 2009 they built a <a href="http://harfordhackerspace.org/category/cnc/">
Computer Numerical Controller (CNC) Router</a> capable of precision cutting of wood, plastics, and aluminum. In August 2010 Harford Hackerspace hosted the first ever
<a href="http://harfordhackerspace.org/category/netduino/">Netduino class</a> with Secret Labs CTO Chris Walker. Most recently in November 2010 Harford Hackerspace won first place in the
<a href="http://www.baltimorehackathon.com">Baltimore Hackathon</a> with their <a href="http://harfordhackerspace.org/2010/11/haha-wins-first-place/">
RotoFoto Project.</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/mods/RSS&WT.dl=0&WT.entryid=Entry:RSSView:e40e14f6d92643b4be979e7600c6fbb8">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Tron-Disc-with-NET-Microframework</comments>
      <itunes:summary>Harford Hackerspace wanted to make our own Tron Identity Disc using the Netduino, allowing us to quickly load different versions of code to change the disc&#39;s functionality. 
&amp;nbsp; David Powell, Gary W. Cygiel, Jeremy Ashinghurst, Paul King, Jason 
McMahon present a simple lightshow in this tutorial, developers can easily extend the code and hardware
 to produce an interactive game.  

To get started, we purchased and retrofitted a Spin Master Tron Identity Disc replica, which kept us from having to create a new physical disk, and so sidestepped the most difficult aspect of the project.
 

Operation Specifications
We decided that we wanted our version of the Tron Idenity Disc to have the following specifications: 
Power 

Rechargeable lithium-ion battery LED to indicate the Tron Identity Disc is being charged An On/Off switch enabling the battery to disconnect from the Netduino to conserve power while the disc is being stored

Operation 

Scenario 1 - Power On

All LEDs turn on so we can make sure they are all working 
Scenario 2 – Animations

Pressing a momentary button will cycle through LED animations 
Scenario 3 – Charge Detection

Placing the Tron Idenity Disc on or removing the Tron Identity Disc from a charging station will raise an event handler. Placing the disc on the charger will start a pulsating animation. Removing the disc will resume the previous animation.


Hardware 

DeluxeTronIdentityDisc
Netduino
Dremel with Cutoff Wheel Soldering Iron Solder Hot Glue Gun Phillips Screw Driver Wire Strippers Heat Shrink Lithium-Ion Battery (2x) SPST On/Off Switch
SPST Momentary Switch
Prototype Board Blue LEDs (33x)
MAX7219
LM317T Adjustable Voltage Regulator
Heat sink for TO-220 devices
0.1uF capacitor (2x)
2222 Transistor
1k Ohm potentiometer
470 Ohm resistor, &#188; watt (2x)
10k Ohm resistor, &#188; watt
2.2k Ohm resistor &#188; watt
1.5 Ohm resistor, 1 watt
1N4001 Rectifier Diode

Tron Disc Light Ring
 
The original 
DeluxeTronIdentityDisc
 contained six LED on the outer r</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Tron-Disc-with-NET-Microframework</link>
      <pubDate>Mon, 13 Dec 2010 16:24:24 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Tron-Disc-with-NET-Microframework</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10104241_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/10104241_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Harford Hackerspace</dc:creator>
      <itunes:author>Harford Hackerspace</itunes:author>
      <slash:comments>9</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Tron-Disc-with-NET-Microframework/RSS</wfw:commentRss>
      <category>Hardware</category>
      <category>Electronics</category>
      <category>NETMF</category>
      <category>mods</category>
    </item>    
</channel>
</rss>