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

<channel>
	<title>GigaMegaBlog &#187; Programming</title>
	<atom:link href="http://www.gigamegablog.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gigamegablog.com</link>
	<description>Powered by GigaMegaWatts</description>
	<lastBuildDate>Sun, 05 Feb 2012 16:39:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Beaglebone Coding 101: Using the Serial and Analog Pins</title>
		<link>http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/</link>
		<comments>http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 02:20:57 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Beagleboard]]></category>
		<category><![CDATA[Beaglebone]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.gigamegablog.com/?p=1094</guid>
		<description><![CDATA[[Updated Jan 25: Correction! There is a 1.8V voltage source on the Beaglebone: Port 9 Pin 32.  Thanks to Koen Kooi for the info.  I've updated the text with this information] This article is my second explaining the fundamentals of &#8230; <a href="http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><span style="color: #0000ff;">[Updated Jan 25: Correction! There is a 1.8V voltage source on the Beaglebone: Port 9 Pin 32.  Thanks to Koen Kooi for the info.  I've updated the text with this information]</span></p>
<p>This article is my second explaining the fundamentals of coding with the <a href="http://beagleboard.org/bone">Beaglebone</a>. In the <a href="http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/">first article</a> I explained some of the mysteries of pin muxing, and gave an example of a very simple usage of a digital pin. This time, I’ll use an analog sensor and serial I/O (just O, actually), to create a time and temperature LCD display.</p>
<p>I have to admit that I’m far from an expert – I’m basically writing about this stuff as I figure it out.</p>
<p>The Beaglebone will hopefully prove to be a ground-breaking product, introducing a lot of electronics hobbyists to embedded Linux programming. Unfortunately, at this point there isn’t much in the way of embedded Linux development tools or tutorials that is geared to newcomers. This should change by the summer of 2012, as <a href="https://github.com/jadonk/bonescript">bonescript</a> expands and more Beaglebone-based projects pop up on blogs and sites like <a href="http://www.instructables.com">Instructables</a>. Until then, it will be one baby step at a time…</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/HPIM0986.jpg"><img class="aligncenter size-full wp-image-1098" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/HPIM0986.jpg" alt="" width="2304" height="1728" /></a></p>
<h2>Analog Input</h2>
<p>The first rule of analog input with the Beaglebone is:<br />
<span style="text-decoration: underline;"><span style="color: #ff0000; text-decoration: underline;">NOTE: Maximum voltage is 1.8V. Do not exceed this voltage. Voltage dividers</span></span><br />
<span style="text-decoration: underline;"><span style="color: #ff0000; text-decoration: underline;"> should be used for voltages higher than 1.8V.</span></span></p>
<p>So sayeth the Beaglebone System Reference Manual (Emphasis theirs. )</p>
<p>I haven’t experimented with what happens if you go above 1.8V, but since they’ve made the warning red and underlined, I’m pretty sure it would not go well.<br />
This limitation is a problem, since:</p>
<ul>
<li><del>There is no pin on the Beaglebone that provides a 1.8V source</del><br />
<span style="color: #0000ff;">[Correction Jan 25 - as pointed out in the comments, there is a pin that provides 1.8V, Port 9 pin 32 (labelled VDD_ADC in the Beaglebone System Reference Manual).    So you can ignore the stuff about voltage dividers and level converters below if you are using an analog sensor that can operate on 1.8V, like a potentiometer.]</span></li>
<li>Many analog sensors require a minimum voltage greater than 1.8V</li>
</ul>
<p>So, until someone has a better idea, voltage dividers will be an important part of any Beaglebone analog circuit.</p>
<p>The second most important thing to know about the Beaglebone’s analog input is that the software support seems to be a work-in-progress. The approach I’m taken is based on a <a href="http://dominion.thruhere.net/koen/cms/using-the-analog-pins-on-a-beaglebone">brief blog post</a> by one of the maintainers of the Beaglebone Angstrom demo images. His remarks would suggest that they have a better plan that is under development. As far as I know, the approach taken here is an Angstrom kernel modification that won’t work at all on a Ubuntu image with the vanilla Ubuntu kernel.</p>
<p>Back to the issue of 1.8 max voltage. You have a couple of options in your design:</p>
<ul>
<li><span style="color: #0000ff;">Added Jan 25: Use Port 9 Pin 32 as your voltage source, if your analog sensor can work on 1.8V</span></li>
<li>Use a couple of high precision resistors that can knock 3.3V or 5V down to exactly 1.8V</li>
<li>Use a couple of garden variety resistors to knock the voltage below 1.8V, then modify your software to adjust for the difference</li>
</ul>
<p>Being lazy, I’m going with the latter approach. Being very lazy, I’m not even bothering to hook up the resistors – as shown in the screenshot below, I’m using a tiny breakout board to do the work.</p>
<p>Specifically, this is a <a href="http://www.sparkfun.com/products/8745">Sparkfun Logic Level Converter &#8211; BOB-08745</a>. You’ll see this part recommended quite often in Beagleboard/Beaglebone circles, since it is an inexpensive solution that can handle a range of voltages, and supports 2-way conversion (necessary for I2C).</p>
<p>For the purpose of analog input I’m not using the board as intended &#8211; I&#8217;m taking advantage of a semi-documented hack. The RX pins on this board just use a voltage divider: the voltage going into the “HV” pins comes out as half the amount from the LV pins. The circuit for this, taken from the <a href="http://www.sparkfun.com/datasheets/BreakoutBoards/Level-Converter-v10.pdf">BOB-08745 schematic</a>, is shown below.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-6-23-53-PM.jpg"><img class="aligncenter size-full wp-image-1103" title="Voltage divider for analog input" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-6-23-53-PM.jpg" alt="" width="121" height="192" /></a></p>
<p>If you don’t have a BOB-08745, you can just use a couple of 10K resistors.</p>
<p>Before actually using this type of circuit, measure what voltage you get from the LV end of the voltage divider if the HV end is connected directly to 3.3V. If it isn’t below 1.8V, figure out what’s wrong before you hook it up to the Beaglebone. (Red and underlined, remember?) Don’t worry if the reading isn’t exactly 50% &#8211; we will calibrate the software to handle the variance.</p>
<p>The 2 analog sensors I’m using are a 10K potentiometer and an analog thermistor (temperature sensor), the <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en027103">Microchip MCP9700A</a>.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/Circuit.jpg"><img class="aligncenter size-full wp-image-1104" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/Circuit.jpg" alt="" width="2304" height="1728" /></a></p>
<p>As you can see from the photos, the connections are:</p>
<p>- Potentiometer and MCP9700A:</p>
<ul>
<li>Input pin to 3.3V (which connects to pins 3 or 4 of Port 9 on the Beaglebone),</li>
<li>Ground pin to ground (connects to pins 1 or 2 of Port 9 of the Beaglebone),</li>
<li>Output pin to one of the RXI pins on the Sparkfun level converter (or to the HV pin on the voltage divider circuit)</li>
<li><span style="color: #0000ff;">Added Jan 25: An alternative for the potentiometer is to connect the input pin to Port 9 Pin 32 (VDD_ADC)., and the output pin directly to the Beaglebone AIN0 pin (pin 39 on Port 9)</span></li>
</ul>
<p>- Sparkfun level converter:</p>
<ul>
<li>HV to 3.3V</li>
<li>HV GND and LV GND to Ground</li>
<li>LV RXO for the potentiometer to the Beaglebone AIN0 pin (pin 39 on Port 9, or the outside pin of the 4th row from the “bottom” &#8211; the end opposite the Ethernet port)</li>
<li>LV RXO for the MCP9700A to the Beaglebone AIN1 pin (pin 40 on Port 9, or the inside pin of the 4th row)</li>
</ul>
<p>Note that the LV pin on the level converter isn’t used, since we are just interested in the voltage divider.</p>
<p>The definitive guide to the Beaglebone pin connections is the System Reference Manual. For this project we are just using Port 9, so you can refer to the table below:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-3-38-57-PM.jpg"><img class="aligncenter size-full wp-image-1102" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-3-38-57-PM.jpg" alt="" width="782" height="801" /></a></p>
<h2>Testing Analog Input</h2>
<p>Remember all that stuff about pin muxing from the first article? You can forget about it for analog in.</p>
<p>As you can see by looking at Table 12 of the Beaglebone System Reference Manual (part of which is shown below), the mux table for all of the analog in pins (AIN1 to AIN6) is empty: the pins can only be used for analog in.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-7-09-16-PM.jpg"><img class="aligncenter size-full wp-image-1105" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-7-09-16-PM.jpg" alt="" width="768" height="215" /></a></p>
<p>There actually are entries for these pins in the file system, <em>/sys/kernel/debug/omap_mux</em>, but they have the correct setting by default, and as far as I can tell the Mode setting has no effect on the pins. (The Python code I wrote sets them anyway, but that’s admittedly more out of ignorance than caution.)</p>
<p>So, we can proceed directly to using the pins.</p>
<p>Let’s start with the potentiometer on analog 0 (pin 39 of Port 9). To get the current reading from the pot, enter the following (yes, it’s ain1 for analog 0 – go figure):</p>
<pre>root@beaglebone:~# cat /sys/devices/platform/tsc/ain1
 1807</pre>
<p>A number should be displayed. Turn the pot all the way up and repeat. You’ll see the maximum value.</p>
<p>For me, it’s 3779. Or 3775. Or 3776. It drifts around a little. Go figure.</p>
<p>The analog input pins on the Beaglebone are 12-bit, so the maximum possible value is 4096. This represents a value of 1.8V. At 3779, it’s reading 3779/4096 * 1.8V, or 1.66V, which is about what you would expect with a 10K/10K voltage divider with 3.3V input.</p>
<p>Now, check the MCP7200A thermometer on analog 1 (again, the analog index is off by 1, so it&#8217;s ain2):</p>
<pre>root@beaglebone:~# cat /sys/devices/platform/tsc/ain2
 826</pre>
<p>You should get a relatively low value: if it’s above 1000, either you are in hell or your thermistor isn&#8217;t hooked up correctly.</p>
<p>The formula for converting this reading to a temperature is:</p>
<p>(milliVolts – 500) / 10</p>
<p>The 826 reading I got is 826/4096 * 1.8V, or 362 mV.</p>
<p>Is it cold in here, or is it just me?</p>
<p>It’s just me. The voltage divider knocked the reading from the MCP7200A down by about half, or the actual reading is 362 * 2, or 724 mV. The temperature reading is therefore (724 – 500) / 10, or 22.4. (No, <em>that</em> isn&#8217;t cold, it’s just metric).</p>
<p>Actually, neither the MCP9700A nor this approach is very accurate. The <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en027103">MCP7200A’s datasheet</a> says it&#8217; typical accuracy is to within 1 degree C . There isn’t anything we can do to improve that, but we can make our calculation more accurate by allowing for slight variances of the resistors in our voltage divider.</p>
<p>To see what effect the voltage divider is having, temporarily hook the input to 3.3V instead of the MCP9700A’s output pin. Then check the value of /sys/devices/platform/tsc/ain2 again.</p>
<p>And again. And again.</p>
<p>I get 3765. And 3762. And 3759.</p>
<p>Given that each 10mV is a degree, that jumping about is a real problem. We’ll plug the average (call it 3762) into the code, then average a bunch of readings to get the temperature, approximately.</p>
<h2>Serial I/O</h2>
<p>The Beaglebone has 6 serial UARTs. One of those, UART0, is connected to the USB port, but that leaves us with 5 to play with. This is quite a step up from the Arduino’s single UART, or the <a href="http://www.netduino.com" target="_blank">Netduino</a>’s 2 UARTs.</p>
<p>All of these are 3.3V UARTs. This is a problem if you’re communicating with a 5V device, but only when receiving data. Some 3.3 microcontrollers, like the Netduino’s, have “5V tolerant” pins, so they can communicate directly with 5V serial devices. But, for the Beaglebone:</p>
<p><span style="text-decoration: underline;"><span style="color: #ff0000; text-decoration: underline;">NOTE: Do not connect 5V logic level signals to these pins or the board will be</span></span><br />
<span style="text-decoration: underline;"><span style="color: #ff0000; text-decoration: underline;"> damaged.</span></span></p>
<p>So sayeth the Beaglebone System Reference Manual.</p>
<p>I assume this means that connecting an UART RX pin directly to the TX pin of a 5V serial device is a bad idea. I did it for awhile, and my Beaglebone lived to tell the tale, but maybe I got lucky.</p>
<p>Were we receiving data from the Serial LCD, then a level converter would be required, like the Sparkfun BOB-08745 described earlier. (Actually a second level converter would be needed, since we would be going between 3.3Vand 5, not 3.3 and 1.8ish.)</p>
<p>However, it will be serial TX only for this project, and all 5V serial devices that I’ve come across handle 3.3V on the RX pin without problems.</p>
<p>In the demo Angstrom image, the pins are <em>not</em> enabled for UART by default. Yup, time for the black art of pin muxing again.</p>
<p>Working with UART1’s mux mode is relatively straightforward. UART1 is the Mode 0 usage for the pin, and as you may recall from <a href="http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/" target="_blank">my first article</a>, the pin name used in the file system are taken from the Mode 0 usage. To check the current settings:</p>
<pre>root@beaglebone:~# cat /sys/kernel/debug/omap_mux/uart1_rxd
 name: uart1_rxd.(null) (0x44e10980/0x980 = 0x0037), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7
 signals: uart1_rxd | mmc1_sdwp | d_can1_tx | NA | NA | NA | NA | NA

 root@beaglebone:~# cat /sys/kernel/debug/omap_mux/uart1_txd
 name: uart1_txd.(null) (0x44e10984/0x984 = 0x0037), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7
 signals: uart1_txd | mmc2_sdwp | d_can1_rx | NA | NA | NA | NA | NA</pre>
<p>As you can see, both are set to 0&#215;37 by default in the Angstrom demo image. This setting means they are in Mode 7 (as the 2nd line of the output confirms) and that the Receive feature is enabled for both pins.</p>
<p>Let’s briefly take a closer look at the meaning of these mux pins. In my last article I explained the Mode settings, but not the other bits. The full list of the bit settings can be found in Table 9-58 of the AM335x Technical Reference Manual &#8211; you can find a link to it <a href="http://processors.wiki.ti.com/index.php/Device:AM335x:Device_Evaluation">here</a>. I’ll save you the trouble of searching for the table in that 4500-page behemoth:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-7-19-44-PM.jpg"><img class="aligncenter size-full wp-image-1107" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-7-19-44-PM.jpg" alt="" width="624" height="352" /></a></p>
<p>The 2 UART pins currently have a mux setting of 0&#215;37, or 0011 0111. So:</p>
<ul>
<li>The slow slew rate is selected – this might concern me if I knew what it meant.</li>
<li>The Receiver is enabled – we want that for the RX pin, not so much for the TX pin</li>
<li>The pullup/pulldown is set to pullup – not a concern for serial communication</li>
<li>The pullup/pulldown is enabled</li>
<li>The 3 mode bits are all on, to indicate mode 7</li>
</ul>
<p>We want to set both pins to Mode 0, and we also want the receiver disabled on the TX pin:</p>
<pre>root@beaglebone:~# echo 20 &gt; /sys/kernel/debug/omap_mux/uart1_rxd

 root@beaglebone:~# cat /sys/kernel/debug/omap_mux/uart1_rxd
 name: uart1_rxd.uart1_rxd (0x44e10980/0x980 = 0x0020), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE0
 signals: uart1_rxd | mmc1_sdwp | d_can1_tx | NA | NA | NA | NA | NA

 root@beaglebone:~# echo 0 &gt; /sys/kernel/debug/omap_mux/uart1_txd

 root@beaglebone:~# cat /sys/kernel/debug/omap_mux/uart1_txd
 name: uart1_txd.uart1_txd (0x44e10984/0x984 = 0x0000), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE0
 signals: uart1_txd | mmc2_sdwp | d_can1_rx | NA | NA | NA | NA | NA</pre>
<p>Having said all that, I’m actually going to use UART2 for this project.</p>
<p>UART2 is a little trickier, since its pins have other names in the file system. Looking at Table 11 of the Beaglebone System Reference Manual, we see that UART2_TXD is pin 21, and UART2_RXD is pin 22. Table 12 (below) tells us that pin 21’s Mode 0 usage (and therefore the name used in the file system) is spi0_d0, and that UART2_RXD is the Mode 1 usage. For Pin 22, it’s spi0_sclk, and we also want to change it to Mode 1.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-7-21-55-PM.jpg"><img class="aligncenter size-full wp-image-1108" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-22-2012-7-21-55-PM.jpg" alt="" width="932" height="94" /></a></p>
<p>Here are the commands for checking the current settings, and changing the settings to use UART2:</p>
<pre>root@beaglebone:~# cat /sys/kernel/debug/omap_mux/spi0_d0
 name: spi0_d0.(null) (0x44e10954/0x954 = 0x0037), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7
 signals: spi0_d0 | NA | NA | NA | NA | NA | NA | NA

 root@beaglebone:~# echo 1 &gt; /sys/kernel/debug/omap_mux/spi0_d0

 root@beaglebone:~# cat /sys/kernel/debug/omap_mux/spi0_d0
 name: spi0_d0.(null) (0x44e10954/0x954 = 0x0001), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE1
 signals: spi0_d0 | NA | NA | NA | NA | NA | NA | NA

 root@beaglebone:~# cat /sys/kernel/debug/omap_mux/spi0_sclk
 name: spi0_sclk.(null) (0x44e10950/0x950 = 0x0037), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE7
 signals: spi0_sclk | NA | NA | NA | NA | NA | NA | NA

 root@beaglebone:~# echo 21 &gt; /sys/kernel/debug/omap_mux/spi0_sclk

 root@beaglebone:~# cat /sys/kernel/debug/omap_mux/spi0_sclk
 name: spi0_sclk.(null) (0x44e10950/0x950 = 0x0021), b NA, t NA
 mode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE1
 signals: spi0_sclk | NA | NA | NA | NA | NA | NA | NA</pre>
<h2>A Python Time and Temperature Display for the Beaglebone</h2>
<p>I’ve written some Python code to try out the analog and serial pins of the Beaglebone. It gets the temperature from the MCP9700A, and uses the potentiometer to set the backlight of the LCD.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/HPIM0988.jpg"><img class="aligncenter size-full wp-image-1099" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/HPIM0988.jpg" alt="" width="2304" height="1728" /></a></p>
<p>You can <a href="http://code.google.com/p/gigamega-micro/downloads/detail?name=serdisplay.py">download the Python program from my Google Code project page</a>: it&#8217;s just a single file, serdisplay.py.</p>
<p>From the Beaglebone command line, you can download the Python program as follows:</p>
<pre>root@beaglebone:~# wget http://gigamega-micro.googlecode.com/files/gpiotester.py</pre>
<p>I’ve tested the code with the<a href="http://www.sparkfun.com/products/10097"> Sparkfun Serial Enabled LCD Kit</a>, the <a href="http://www.sparkfun.com/products/258">Sparkfun Serial Enabled Backpack</a>. I’ve also coded support for Matrix Orbital serial LCDs, but haven’t tested that yet.</p>
<p>The code uses one Python library that isn’t included in the Angstrom demo image, python-serial. To install it:</p>
<pre>root@beaglebone:~# opkg install python-serial</pre>
<p>There is no configuration file or command line parameters yet, so any changes to the default settings (the Sparkfun Serial LCD Backpack and a 4-row 20-column LCD) should be made to the code near the top of the program:</p>
<pre># -------------- configurable settings ---------
# settings for UART1
 #DISPLAYPORT = '/dev/ttyO1'
 #RX_MUX = 'uart1_rxd'
 #TX_MUX = 'uart1_txd'
 #MUX_MODE = 0
# settings for UART2
 DISPLAYPORT = '/dev/ttyO2'
 RX_MUX = 'spi0_sclk'
 TX_MUX = 'spi0_d0'
 MUX_MODE = 1
# settings for Serial LCD
 DISPLAY_TYPE = 'SPARKFUN_KIT'
 #DISPLAY_TYPE = 'MATRIX_ORBITAL'
 #DISPLAY_TYPE = 'SPARKFUN'
# settings for analog voltage conversion
 MAX_ANALOG = 3762 # approx 4096 * (1.65/1.8), since voltage divider gives me max of 1.65
 # -- actual values of 3762 based on measurements
# settings for display updates
 TIME_UPDATE_INTERVAL = 1 # every second
 TIME_DISPLAY_ROW = 1
 TEMPERATURE_DISPLAY_ROW = 2
 LCD_NUM_ROWS = 4
 LCD_NUM_COLS = 20
# determines whether debug info is written to the console
 Debug = True
# ---------------------------------------------------------</pre>
<p>Then, just run the program as root:</p>
<pre>root@beaglebone:~# python serdisplay.py</pre>
<p>To stop the program, press Ctrl-Z to put it in the background, then kill the background job:</p>
<pre>root@beaglebone:~# kill %1</pre>
<p>If you want to keep the program running all the time, I’d recommend using the <a href="http://www.gnu.org/software/screen/">GNU Screen</a> utility:</p>
<pre>root@beaglebone:~# screen
&lt;Press enter when prompted&gt;
root@beaglebone:~# python serdisplay.py</pre>
<p>To return to the main command command prompt (leaving the Python program running in the background) press Ctrl-A D.  To go back to the Screen session at any time in the future:</p>
<pre>root@beaglebone:~# screen –r –d</pre>
<p>For troubleshooting, any error messages are written to serdisplay.log in the same directory as serdisplay.py.</p>
<h2>Programmer’s Show And Tell</h2>
<p>Since the focus of this article is the Beaglebone, not Python, I’ll just point out some Beaglebone-specific parts of the code.</p>
<p>The code which initializes the UART for the serial display is:</p>
<pre>DISPLAYPORT = '/dev/ttyO2'
 RX_MUX = 'spi0_sclk'
 TX_MUX = 'spi0_d0'
 MUX_MODE = 1
 BAUDRATE = 9600
 TIMEOUT = 3 # serial port timeout is 3 seconds - only used when reading from display
# MUX settings
 RECEIVE_ENABLE = 32
. . .
open('/sys/kernel/debug/omap_mux/' + RX_MUX, 'wb').write("%X" % (RECEIVE_ENABLE + MUX_MODE))
 # set the TX pin for Mode 0
 open('/sys/kernel/debug/omap_mux/' + TX_MUX, 'wb').write("%X" % MUX_MODE)
 serDisplay = serial.Serial(DISPLAYPORT, BAUDRATE, timeout=TIMEOUT)</pre>
<p>There are Linux character devices assigned to the BeagleBone UARTs: UART1 is /dev/ttyO1, UART2 is /dev/ttyO2, and so on.</p>
<p>From the point of view of the Python program, the Beaglebone’s UART behaves like any other serial port. The code I wrote would work unchanged (aside from the /dev name) when communicating with an XBee, or through a USB-based virtual COM port.</p>
<p>Analog input is a little more finicky. The code which reads the analog value is:</p>
<pre>def readAnalog(pinIndex):
 try:
    # add 1 to pin index to get analog pin sys filename
    reading = open("/sys/devices/platform/tsc/ain" + str(pinIndex + 1), "r").read()

    # sometimes string has trailing nulls - delete them
    val = int(re.sub(r'[^\d]+', '', reading))
    return val
 except:
    log.exception('Error in readAnalog')</pre>
<p>As indicated by the comments, I found that the value read through the file system was sometimes corrupted: it contained nulls, usually after the value, but occasionally imbedded within the value. I’m not sure if this is a Python-specific thing, or other code would also encounter the problem. In Python, you can strip out the null (and any other non-numeric) values using a regular expression:</p>
<pre>val = int(re.sub(r'[^\d]+', '', reading))</pre>
<p>From time to time, the attempt to read the analog value will throw an exception.  So, it&#8217;s best to use a try/except handler like the one above.</p>
<p>One other problem is that the analog value tends to jump around by about 5 points from one reading to the next, even when it should be constant (e.g. from the potentiometer). I adjusted for this by using an average reading for the temperature, and by ignoring potentiometer readings (i.e. LCD brightness settings) that are within 20 of the last setting.</p>
<p>Don’t forget that the analog value is from 0-4096 – 16 times more sensitive than on the Arduino &#8212;  so allow for a greater range of readings.</p>
<h2>Wrapping Up</h2>
<p>Based on my testing of the code in this project, I&#8217;ve found that the Beaglebone’s UARTs are quite reliable and pretty easy to use.  Serial communications should be a relatively easy and trouble-free addition to any Beaglebone project.</p>
<p>Analog in, on the other hand,  has room for improvement.</p>
<p>The approach I used for reading analog input in is good enough for things that don’t require precise accuracy, like the potentiometer or a light meter.  The readings returned by the MCP9700A thermistor are not as stable as they should be.</p>
<p>Fortunately, analog is not the only game in town when it comes to temperature readings, so I plan to experiment with some I2C sensors in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Beaglebone Coding 101: Blinking an LED</title>
		<link>http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/</link>
		<comments>http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 19:49:49 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Beagleboard]]></category>
		<category><![CDATA[Beaglebone]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.gigamegablog.com/?p=1079</guid>
		<description><![CDATA[[Updated Jan 22 - various improvements to the Python sample code at the end of the article] In November, Texas Instruments, Digi-Key and the other members of Beagleboard.org, the Beaglebone.  This is a simpler, more hobbyist-friendly little brother to the &#8230; <a href="http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>[Updated Jan 22 - various improvements to the Python sample code at the end of the article]</em></p>
<p>In November, <a href="http://www.ti.com">Texas Instruments</a>, <a href="http://www.digikey.com">Digi-Key</a> and the other members of <a href="http://beagleboard.org">Beagleboard.org</a>, the <a href="http://beagleboard.org/bone">Beaglebone</a>.  This is a simpler, more hobbyist-friendly little brother to the <a href="http://beagleboard.org/hardware">Beagleboard</a> (which I&#8217;ve written about in <a href="http://www.gigamegablog.com/tag/beagleboard/">past articles</a>).</p>
<p>Compared to the Beagleboards, the Beaglebone is considerably less expensive ($90), provides access to all of its pins, is pin-compatible with 3.3V sensors and devices (aside from analog in, which is still 1.8V), and provides a more friendly &#8220;out of the box&#8221; experience.  As with the Arduino, the only thing you need to get started is a USB cable.</p>
<p>As a developer, my most pleasant surprise with the Beaglebone was the inclusion of an entry-level IDE and scripting language: the <a href="http://c9.io/">Cloud9 IDE</a> configured to run <a href="http://nodejs.org/">node.js</a> and <a href="https://github.com/jadonk/bonescript">bonescript</a>.</p>
<p>With the Beagleboards, there was no &#8220;out of the box&#8221; IDE.  There were plenty of options for developing with the Beagleboard – Texas Instrument&#8217;s Code Composer Studio, Eclipse, or the command-line GCC tools being the most prominent – but all had a fairly steep learning curve just to do something basic, like blink an LED.</p>
<p>One of the most slippery patches on that learning curve is figuring out how to convince the Linux kernel to let your code access the pins.  It&#8217;s nowhere near as simple as Arduino&#8217;s &#8220;<em>digitalwrite(13, HIGH)</em>&#8221; – or, at least, it wasn&#8217;t until bonescript came along.  Although bonescript is still in its very early stages, there is enough meat on it to give the embedded Linux newbie a friendly introduction to coding.</p>
<h2>The Circuit</h2>
<p>The circuit is your garden-variety LED configuration:</p>
<ul>
<li>an LED</li>
<li>a resistor (680R or thereabouts) connected to the negative pin of the LED</li>
<li>a jumper from the positive pin of the LED to the digital pin</li>
<li>a jumper from the resistor to ground</li>
</ul>
<p>The Beaglebone actually has 65 GPIO pins to choose from, but we&#8217;ll go with the one used by the <em>blinkled.js</em> program that is included with bonescript.  This is Pin 3 on Header 8, referred to by the <a href="http://beagleboard.org/static/BONESRM_latest.pdf">Beaglebone System Reference Manual</a> as  GPIO1_6 on Expansion B, but known to Linux as gpmc_ad6.</p>
<p>Say what?</p>
<p>Well, the &#8220;Pin 3 on Header 8&#8243; part is simple enough. If you look at the Beaglebone, Port 8 is one of the 2 double-rows of female headers,  labeled P8 on the circuit board.  (In the figure below, taken from the System Reference Manual, Port 8 is labeled &#8220;Expansion B).</p>
<div class="img aligncenter size-full wp-image-1083" style="width:598px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-5-32-10-PM.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-5-32-10-PM.png" alt="Beaglebone, showing pin P8_3 and Ground" width="598" height="582" /></a>
	<div>Beaglebone, showing pin P8_3 and Ground</div>
</div>
<p>At either end of the headers you&#8217;ll find the rows marked 1 and 2, and 45 and 46.  So, Pin 3 is the 2<sup>nd</sup> row from the top, left column, as indicated in the figure.</p>
<p>The other names for the pin, along with the locations of the ground pins, can be found in the <a href="http://beagleboard.org/static/BONESRM_latest.pdf">System Reference Manual</a>.  If you look at Table 8 – &#8220;Expansion Header P8 Pinout&#8221; (a portion of which is shown below), you&#8217;ll find the pins labeled with their default usages in the Angstrom Linux demo image (the one that comes packaged with the beaglebone on a microSD card).</p>
<div class="img aligncenter size-full wp-image-1082" style="width:586px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-7-42-03-PM.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-7-42-03-PM.png" alt="Default pin settings in Anstrom Linux" width="586" height="227" /></a>
	<div>Default pin settings in Anstrom Linux</div>
</div>
<p>Clearly, Ground is the top row of Port 8, so that&#8217;s the last bit of information we need to know to hook up the circuit.  But we&#8217;ll need to understand that part about pins having &#8220;default usages&#8221; – more on that later.</p>
<h2>Cloud9 IDE and bonescript</h2>
<p>When you boot up the Beaglebone with the microSD card from the box, the Cloud9 IDE is automatically started.  Once you have an  IP address assigned to the Beaglebone (either through its Ethernet port connection or through USB networking), you can load the Cloud9 IDE on your PC browser at http:&lt;beaglebone address&gt;:3000</p>
<p>(I haven&#8217;t tried to use USB networking myself, but the procedure for doing so is explained in <a href="http://beagleboard.org/static/beaglebone/a3/README.htm">Getting started with your new BeagleBone</a>.)</p>
<p>The Cloud9 IDE interface is pretty intuitive.  You select a source code file in the left pane, edit it in a tab in the right pane, and select Debug or Run from the toolbar to execute the code.</p>
<div class="img aligncenter size-full wp-image-1080" style="width:607px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-8-43-35-PM.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-8-43-35-PM.png" alt="Cloud9 IDE" width="607" height="454" /></a>
	<div>Cloud9 IDE</div>
</div>
<p>If you are coming at this from the Arduino, you will notice 3 significant differences from the Arduino IDE:</p>
<ul>
<li>You don&#8217;t upload your code to the board.  The Beaglebone is more like a PC than an Arduino – the code is stored on its file system, and you just run it.</li>
<li>You can debug your code.  Not Arduino&#8217;s form of debugging – print statements to the console (though you can do that too) &#8212; but real debugging, as in breakpoints, watch variables, step-by-step execution.</li>
<li>The coding language is Javascript, not C.  Specifically, it&#8217;s <a href="http://nodejs.org/">node.js</a>, which is Javascript optimized for running on a server, rather than in a browser, by way of some extra libraries.  The &#8220;server&#8221; in this case is the little old Beaglebone.  As you might imagine, node.js is not the fastest environment for running code on the Beaglebone, but for LED blinking and many other types of prototyping, it&#8217;s fast enough.</li>
</ul>
<p>Despite the differences, Arduino coders should find the transition to Cloud9 and bonescript to be quite easy.  The blinkled.js code looks very much like Arduino code.  That&#8217;s no coincidence: the README for the bonescript project, which you can find on its github page <a href="https://github.com/jadonk/bonescript">here</a>,  says that the goal is &#8220;to have something that provides most of the Arduino functions and is generally usable by Summer 2012&#8243;.</p>
<pre><strong>var</strong> ledPin <strong>=</strong> bone.P8_3;
<strong>var</strong> ledPin2 <strong>=</strong> bone.USR3;

setup <strong>=</strong> <strong>function</strong>() {
    pinMode(ledPin, OUTPUT);
    pinMode(ledPin2, OUTPUT);
};

loop <strong>=</strong> <strong>function</strong>() {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
    delay(1000);
};</pre>
<p>This code from blinkled.js does the following:</p>
<ul>
<li>defines 2 pins, P8_3 (Port 8, pin 3) and USR3 (which is one of the built-in LEDS on the board, next to the Ethernet port)</li>
<li>sets these pins for Output</li>
<li>loops, turning these 2 LEDs on and off, once per second, ad infinitum</li>
</ul>
<p>If you&#8217;ve attached an LED to pin 3, and you run blinkled.js in Cloud9, you should find it blinking happily away. (There is a dropdown button next to the Run and Debug toolbar icons in Cloud9 to let you choose the file).</p>
<p>It&#8217;s that simple.</p>
<p>I lie.</p>
<p>There is actually considerable complexity behind the code which creates those 2 pin objects, <em>bone.P8_3</em> and <em>bone.USR3</em>.  The complicated code is in one of the 2 &#8220;library&#8221; files in the bonescript folder, <em>index.js</em>.</p>
<h2>Pins and Muxing</h2>
<p>Before we dive into the index.js code, let&#8217;s return to the <a href="http://beagleboard.org/static/BONESRM_latest.pdf">Beaglebone System Reference Manual</a>.  As you&#8217;ll recall, I earlier referred to the &#8220;default usage&#8221; on Port 8 Pin 3.  It has other usages, and the process of telling the board how you want to use that pin is called muxing (short for multiplexing).</p>
<p>The available usages of the pin, and all of the others on the Port 8, are listed in Tables 9 (the first part of which is shown below) and 10 of the System Reference Manual.  Each pin can have up to 8 uses, &#8220;mux mode&#8221; 0 through 7.  The default setting in the Angstrom Image is generally, but not always, mode 7.  Table 8 is the definitive guide to Angstrom&#8217;s default mux setting for each pin.</p>
<div class="img aligncenter size-full wp-image-1081" style="width:724px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-8-06-20-PM.png"><img src="http://www.gigamegablog.com/wp-content/uploads/2012/01/04-01-2012-8-06-20-PM.png" alt="Pin Mux settings from the System Reference Manual" width="724" height="228" /></a>
	<div>Pin Mux settings from the System Reference Manual</div>
</div>
<p>(Incidentally, other Linux distributions for the Beaglebone, such as Ubuntu, will have their own default mux settings.  The board doesn&#8217;t control the mux settings, the software does.  The developers of the Angstrom Linux image on the SD card selected their defaults to be the most commonly used ones by hobbyists, providing a good out-of-the-box experience.)</p>
<p>If you Google &#8220;Beagleboard mux&#8221;, you&#8217;ll find lots of pages explaining the various ways in which you can change the mux setting.  Many of them refer to U-Boot configuration and kernel modules, which are complicated and, fortunately, no longer necessary.  There has been a lot of work done recently at making the mux settings accessible to &#8220;userland&#8221; code by way of the Linux file system.  If you (or your code) wants to read or change the mux setting, it just needs to read or write to a file.</p>
<p>Great.  So which file?</p>
<p>This information used to be hard to come by, scattering amongst various forum and blog posts, or hidden inside code in U-Boot or the linux kernel.  However, if you&#8217;re learning to code with the Beaglebone, I think the best way to learn the mux file system is to look at how bonescript handles it.</p>
<h2>Muxing the bonescript way</h2>
<p>So, back to the Cloud9 IDE.  This time, open up the index.js file in the bonescript directory.  (Note that this part of bonescript is in active development and is likely to change by the time you read this, but the underlying file system will still be the same)</p>
<p>A little ways into the code (line 39 in the current release, bonescript 1.0-r10), you&#8217;ll find the following:</p>
<pre><strong>var</strong> gpio0 <strong>=</strong> 0;
<strong>var</strong> gpio1 <strong>=</strong> gpio0<strong>+</strong>32;
<strong>var</strong> gpio2 <strong>=</strong> gpio1<strong>+</strong>32;
<strong>var</strong> gpio3 <strong>=</strong> gpio2<strong>+</strong>32;

bone <strong>=</strong> exports.bone <strong>=</strong>
{
    P8_1<strong>:</strong> { name<strong>:</strong> "DGND" },
    P8_2<strong>:</strong> { name<strong>:</strong> "DGND" },
    P8_3<strong>:</strong> { name<strong>:</strong> "GPIO1_6", gpio<strong>:</strong> gpio1<strong>+</strong>6, mux<strong>:</strong> "gpmc_ad6" },
    P8_4<strong>:</strong> { name<strong>:</strong> "GPIO1_7", gpio<strong>:</strong> gpio1<strong>+</strong>7, mux<strong>:</strong> "gpmc_ad7" },
    P8_5<strong>:</strong> { name<strong>:</strong> "GPIO1_2", gpio<strong>:</strong> gpio1<strong>+</strong>2, mux<strong>:</strong> "gpmc_ad2" },
    P8_6<strong>:</strong> { name<strong>:</strong> "GPIO1_3", gpio<strong>:</strong> gpio1<strong>+</strong>3, mux<strong>:</strong> "gpmc_ad3" },
    P8_7<strong>:</strong> { name<strong>:</strong> "TIMER4", gpio<strong>:</strong> gpio2<strong>+</strong>2, mux<strong>:</strong> "gpmc_advn_ale" },
    P8_8<strong>:</strong> { name<strong>:</strong> "TIMER7", gpio<strong>:</strong> gpio2<strong>+</strong>3, mux<strong>:</strong> "gpmc_oen_ren" },
. . .
    USR0<strong>:</strong> { name<strong>:</strong> "USR0", gpio<strong>:</strong> gpio1<strong>+</strong>21, led<strong>:</strong> "usr0", mux<strong>:</strong> "gpmc_a5" },
    USR1<strong>:</strong> { name<strong>:</strong> "USR1", gpio<strong>:</strong> gpio1<strong>+</strong>22, led<strong>:</strong> "usr1", mux<strong>:</strong> "gpmc_a6" },
    USR2<strong>:</strong> { name<strong>:</strong> "USR2", gpio<strong>:</strong> gpio1<strong>+</strong>23, led<strong>:</strong> "usr2", mux<strong>:</strong> "gpmc_a7" },
    USR3<strong>:</strong> { name<strong>:</strong> "USR3", gpio<strong>:</strong> gpio1<strong>+</strong>24, led<strong>:</strong> "usr3", mux<strong>:</strong> "gpmc_a8" }</pre>
<p>This table contains 3 important pieces of information:</p>
<ol>
<li>the label that bonescript uses to identify the pins (P8_1, P8_2, etc)</li>
<li>the GPIO pin number (P8_3 is <em>gpio1+6</em>, or 38)</li>
<li>the mux label (P8_3 is <em>gpmc_ad6</em>)</li>
</ol>
<p>The GPIO pin number tells you the directory name you will use to read from or write to the pin.  The mux label tells you the filename you will use to read or write the mux setting.</p>
<p>Let&#8217;s start with the mux setting.  This is handled by some code just below the exports.bone table:</p>
<pre>if(pin.mux) {
 try {
    var muxfile = fs.openSync(
      "/sys/kernel/debug/omap_mux/" + pin.mux, "w"
      );
    fs.writeSync(muxfile, "7", null);
 } catch(ex3) {
    console.log("" + ex3);
    console.log("Unable to configure pinmux for: " + pin.name +
      " (" + pin.mux + ")");
. . .</pre>
<p>There is more to the error handling, but the important part is the reference to &#8220;<em>/sys/kernel/debug/omap_mux/</em>&#8221; + pin.mux.  This is the file used to read and write the mux setting.  In the case of Port 8 Pin 3, the full path is <em>/sys/kernel/debug/omap_mux/gpmc_ad6</em>.</p>
<p>This is the part that is newcomers to pin muxing often trip over: if you want to set a pin to be a GPIO pin, your code needs to reference a filename that appears to be intended for a different usage of the pin (gpmc_ad6).  The mux filename isn&#8217;t taken from its intended usage, it&#8217;s taken from its mode 0 usage.  The mode 0 usage for Port 8 Pin 3 is gpmc_ad6 – we know this from the table in the bonescript code, but the definitive reference for the Beaglebone pin mux modes are Tables 9 and 11 of the <a href="http://beagleboard.org/static/BONESRM_latest.pdf">Beaglebone System Reference Manual</a>.</p>
<p>Having opened the file (<em>fs.openSync</em>), the bonescript code writes a 7 to it (<em>fs.writeSync</em>).  This, as you probably guessed, sets the mux mode to 7, the GPIO mode for that pin.  The process of setting mux modes isn&#8217;t quite as simple as &#8220;write the  mode to a file&#8221;:  the mux mode setting also affects other aspects of the pin, such as whether it can be used for input.  The bonescript code shown above is actually correct only for setting pins to be GPIO Output pins.  The bonescript project will soon support other mux mode settings.</p>
<h2>Blinking LEDs the bonescript way</h2>
<p>Having set the pin to be in digital output mode, the next task is to set it high or low.  You&#8217;ll recall that this was handled in blinkled.js by calling a function called digitalWrite, same as the Arduino does.</p>
<p>The source code for digitalWrite can be found further down in index.js:</p>
<pre>digitalWrite <strong>=</strong> exports.digitalWrite <strong>=</strong> <strong>function</strong>(pin, value)
{
    fs.writeFileSync(gpio[pin.gpio].path, "" <strong>+</strong> value);
};</pre>
<p>OK, so it&#8217;s writing a value to a file, either HIGH (defined as 1) or LOW (0).  But which file?</p>
<p>The code to set that &#8220;path&#8221; property also in index.js, just below where the pin mux setting was done:</p>
<pre>try {
    try {
        fs.writeFileSync("/sys/class/gpio/export", "" + n);
    } catch(ex2) {
        // TODO: If the file is already exported, can we know who did
        // did it so that we aren't opening it twice?  In general, this
        // shouldn't be an error until we have some better resource
        // management.
        //console.log(ex2);
        //console.log("Unable to export gpio: " + n);
    }
    fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction",
        mode);
    gpio[n].path = "/sys/class/gpio/gpio" + n + "/value";
    return(true);
} catch(ex) {
    // Perhaps we couldn't open it because it was allocated as an LED
    if(pin.led) {
        fs.writeFileSync(
            "/sys/class/leds/beaglebone::" + pin.led + "/trigger",
            "gpio");
        if(mode == OUTPUT) {
            gpio[n].path =
                "/sys/class/leds/beaglebone::" + pin.led +
                "/brightness";
        } else {
            gpio[n].path =
                "/sys/class/leds/beaglebone::" + pin.led +
                "/gpio";
        }
        return(true);
    }
}</pre>
<p>The first thing it does is try to write to a file named &#8220;export&#8221;, specifically , &#8220;/sys/class/gpio/export&#8221;.  The value written is the GPIO pin number, which you&#8217;ll recall was specified in the table earlier in index.js.  For Port 8 Pin 3, it was defined as gpio1+6, or 38.</p>
<p>The export file is a funky weird-ass file: when you write a pin number to it, it (well, the kernel process which monitors that file) creates a directory and a bunch of files that provide interfaces for accessing the pin.  The directory is created at <em>/sys/class/gpio/export/gpioNN</em>. In the case of Port 8 Pin 3, that&#8217;s <em>/sys/class/gpio/export/gpio38</em>.</p>
<p>For the purpose of using a GPIO pin, the two most important files in the <em>gpioNN</em> directory are named <em>direction</em> and <em>value</em>.</p>
<p>The <em>direction</em> file determines whether the pin is going to be used for reading or writing.  As mentioned earlier, you can&#8217;t use a pin for reading without setting flipping a bit in the mux mode setting, so our only choice at this point is output.   The bonescript code writes the value &#8220;out&#8221; to the <em>direction</em> file (i.e. to <em>/sys/class/gpio/export/gpio38/direction</em>).</p>
<p>The code then saves the path to the <em>value</em> file (i.e. <em>/sys/class/gpio/export/gpio38/)</em> in the pin&#8217;s <em>path</em> property.  This, then, explains what the code in the digitalWrite function is doing:</p>
<pre>fs.writeFileSync(gpio[pin.gpio].path, "" <strong>+</strong> value);</pre>
<p>It writes a 1 to the value file (i.e. /sys/class/gpio/export/gpio38/value) to set the pin high (and the turn the LED on) and a 0 to set it low (and the LED off).</p>
<p>But wait, there&#8217;s more!</p>
<p>The bonescript code shown above also has an error handler.</p>
<p>Writing to the export file also tells the kernel that you intend to use that pin.  If the pin is already being used by something more important than your dinky userland application (i.e. the kernel or one of its pals), it will helpfully toss an error at you.</p>
<p>Generally, when your attempt to export a pin fails, you have no option but to go away and sulk.  Something is using that pin, and it might be a hardware driver that won&#8217;t be giving it up any time soon (such as the SD card socket, or an LCD).  There are ways of tracking down what&#8217;s using it, but I won&#8217;t cover them in this post.</p>
<p>One possibility is that the GPIO pin is being used by one of the built-in &#8220;user LEDs&#8221;, USR0 – USR3.  As you can see from the final entries in the bonescript mux table, those LEDs are connected to GPIOs 53-56.  So, the bonescript code checks to see if you&#8217;re trying to write to those GPIOs – if so, it assumes you want to access the user LEDs, and redirects you to their address.</p>
<p>These user LEDs are accessed through a different part of the file system than the GPIOs – technically, they are part of the Beaglebone board, not part of the CPU.  So, they are accessed through the <em>/sys/class/leds/beaglebone</em> directory, not <em>/sys/class/gpio</em>.</p>
<p>The Beagleboard (the &#8216;bone&#8217;s big brother) also has user LEDs, and they are accessed in basically the same way there, so you can find a good explanation of how to write to them in some of the articles written for the Beagleboard.  The command line interface is explained in <a href="http://elinux.org/EBC_Exercise_02_Flashing_an_LED">this article on eLinux</a>.  For C language code that interfaces to the user LEDs, see <a href="http://www.lvr.com/code/led_control.c">this sample</a> from Jan Axelson&#8217;s <a href="http://www.amazon.com/USB-Embedded-Hosts-Developers-Guide/dp/1931448248/ref=ntt_at_ep_dpt_3">USB Embedded Hosts: The Developer&#8217;s Guide</a>.  (This, by the way, is one of the few books currently available that specifically covers Beagleboard programming).</p>
<h2>Blinking LEDs the Python Way</h2>
<p>The directories and paths used by the bonescript code can also be used from other programming languages: pretty much anything that runs on Linux can read and write from the file system.</p>
<p>Here is my own humble contribution, a snippet of Python code which blinks the USR2, USR3 and Port 8 Pin 3 ten times.  It has the advantage of distilling the bonescript code down to the bare bones needed to access that particular pin.</p>
<p><em>[Updated Jan 22 - added support for User LEDs 2 and 3, handle case where pin already exported, and simplified  the file I/O syntax:]</em></p>
<pre class="brush: python; title: ; notranslate">
import time

# put Port 8 Pin 3 into mode 7 (GPIO)
open('/sys/kernel/debug/omap_mux/gpmc_ad6', 'wb').write(&quot;%X&quot; % 7)

try:
   # check to see if the pin is already exported
   open('/sys/class/gpio/gpio38/direction').read()
except:
   # it isn't, so export it
   print(&quot;exporting GPIO 38&quot;)
   open('/sys/class/gpio/export', 'w').write('38')

# set Port 8 Pin 3 for output
open('/sys/class/gpio/gpio38/direction', 'w').write('out')
# we will assume that USR1 and USR 2 are already configured as LEDs

for i in range(10):
   # turn on USR1 and external LED
   open('/sys/class/gpio/gpio38/value', 'w').write(&quot;1&quot;)
   open(&quot;/sys/devices/platform/leds-gpio/leds/beaglebone::usr1/brightness&quot;, 'w').write(&quot;1&quot;)
   # turn off USR2
   open(&quot;/sys/devices/platform/leds-gpio/leds/beaglebone::usr2/brightness&quot;, 'w').write(&quot;0&quot;)

   time.sleep(1)

   # turn off USR1 and external LED
   open('/sys/class/gpio/gpio38/value', 'w').write(&quot;0&quot;)
   open(&quot;/sys/devices/platform/leds-gpio/leds/beaglebone::usr1/brightness&quot;, 'w').write(&quot;0&quot;)
   # turn on USR2
   open(&quot;/sys/devices/platform/leds-gpio/leds/beaglebone::usr2/brightness&quot;, 'w').write(&quot;1&quot;)

   time.sleep(1)

# cleanup - remove GPIO38 folder from file system
open('/sys/class/gpio/unexport', 'w').write('38')
</pre>
<p> The Python code also demonstrates something that the bonescript code doesn&#8217;t handle.  To be a nice little userland app and clean up after yourself, you can write the GPIO pin number to /sys/class/gpio/unexport.  This doesn&#8217;t &#8220;release&#8221; the GPIO to other apps – you never had it locked for your exclusive use in the first place – so unexport&#8217;ing is just a convention to make the gpio file system is a little more manageable.</p>
<p>Since python is already installed on the Angstrom image, you can download the file and run it as follows:</p>
<pre>wget http://gigamega-micro.googlecode.com/files/gpiotester.py
python gpiotester.py</pre>
<h2>Wrapping Up</h2>
<p>If you think that&#8217;s a lot of work in order to blink an LED, you should have tried it a few years ago, when the Beagleboard was first released.</p>
<p>Back in the day, to do anything with a GPIO pin you pretty much had to be an embedded Linux guru, or beg for crumbs of knowledge from the guru&#8217;s table.  (Oh, and good luck getting your LED to light up on 1.8V.  You kids have it easy these days!)</p>
<p>The Beaglebone arrives at a time when the embedded Linux device market is growing by leaps and bounds, both in terms or hardware and development tools.  As a hobbyist (or a budding professional), this is a good time to hop on board the platform.</p>
<p>Incidentally, while the Beaglebone platform is geared for hobbyists and prototypers, the chip it uses is very much targeted at professionals.  The Texas Instruments Sitara AM3359 is a descendent of (and largely code compatible with) the storied OMAP chip family, which powers a lot of consumer gadgets: many of Nokia&#8217;s high-end smartphones like the E90, Motorola&#8217;s Droid line of Android smartphones, the Nook Color and the Kindle Fire.</p>
<p>If you can get to a root command line on one of those devices, you can probably set a GPIO high and low using the same code as above (and if you&#8217;re lucky, cause an inglorious crash).  How cool is that?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Nimbits Gadget Updated</title>
		<link>http://www.gigamegablog.com/2011/12/14/nimbits-gadget-updated/</link>
		<comments>http://www.gigamegablog.com/2011/12/14/nimbits-gadget-updated/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 00:13:54 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[nimbits]]></category>

		<guid isPermaLink="false">http://www.gigamegablog.com/?p=1072</guid>
		<description><![CDATA[I&#8217;ve added a couple of new settings to the Nimbits Google Gadget: graph width and gadget height.  I&#8217;ve updated the &#8220;Minding the Data Store&#8221; article with the details. Nimbits itself was recently updated to version 3.3, and the its web site &#8230; <a href="http://www.gigamegablog.com/2011/12/14/nimbits-gadget-updated/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve added a couple of new settings to the <a href="http://www.google.com/ig/directory?hl=en&amp;gl=us&amp;type=gadgets&amp;url=www.gigamegablog.com/gadgets/nimbits.xml">Nimbits Google Gadget</a>: graph width and gadget height.  I&#8217;ve updated the &#8220;<a href="http://www.gigamegablog.com/2011/05/21/a-nimbits-gadget-minding-the-data-store/">Minding the Data Store</a>&#8221; article with the details.<a href="http://www.gigamegablog.com/wp-content/uploads/2011/12/14-12-2011-7-10-18-PM.jpg"><img class="aligncenter size-full wp-image-1073" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/12/14-12-2011-7-10-18-PM.jpg" alt="" width="591" height="180" /></a></p>
<p><a href="http://www.nimbits.com/">Nimbits </a>itself was recently updated to version 3.3, and the <a href="http://www.nimbits.com/">its web site</a> has been reorganized to make all of the documentation easy to find.  If you are new to Nimbits, or haven&#8217;t seen it for a while, check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/12/14/nimbits-gadget-updated/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Pachube Gadget: Programmer&#8217;s Show and Tell</title>
		<link>http://www.gigamegablog.com/2011/11/23/a-pachube-gadget-programmers-show-and-tell/</link>
		<comments>http://www.gigamegablog.com/2011/11/23/a-pachube-gadget-programmers-show-and-tell/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 01:10:47 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pachube]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=1049</guid>
		<description><![CDATA[In my last post, I introduced a Google gadget that I wrote to display graphs of Pachube datastreams.  This gadget takes advantage of the Pachube API to add a few new features that I couldn&#8217;t find in other Pachube gadgets, &#8230; <a href="http://www.gigamegablog.com/2011/11/23/a-pachube-gadget-programmers-show-and-tell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://gigamegablog.com/2011/11/05/a-pachube-google-gadget-size-matters/">my last post</a>, I introduced <a href="http://www.google.com/ig/directory?type=gadgets&amp;url=www.gigamegablog.com/gadgets/gm-pachube.xml">a Google gadget</a> that I wrote to display graphs of <a href="http://www.pachube.com">Pachube</a> datastreams.  This gadget takes advantage of the Pachube API to add a few new features that I couldn&#8217;t find in other Pachube gadgets, like sizable graphs and support for local time zones.</p>
<p>In this article, I&#8217;d like to explore parts of the Javascript code in the gadget, and describe how they interface with the Pachube API.</p>
<h2>Viewing the Source Code</h2>
<p>As with any iGoogle Gadget, the source code can be viewed by clicking the &#8220;View source&#8221; link in the bottom right of the gadget&#8217;s iGoogle Gadget Directory page – <a href="http://www.google.com/ig/directory?type=gadgets&amp;url=www.gigamegablog.com/gadgets/gm-pachube.xml">my gadget&#8217;s page is here</a>.</p>
<p>However, this will only show you the XML definition for the gadget, since I&#8217;ve put the Javascript in a separate file.  My gadget has 2 different views defined in the XML file, normal and &#8220;canvas&#8221; (i.e. maximized), as you can see at the bottom of the XML file.  Using a separate Javascript file allows the 2 views to use the same code.  Here are direct links to the XML and Javascript files.</p>
<ul>
<li>XML: <a href="http://www.gigamegablog.com/gadgets/gm-pachube.xml">http://www.gigamegablog.com/gadgets/gm-pachube.xml</a></li>
<li>Javascript: <a href="http://www.gigamegablog.com/gadgets/gm-pachube.js">http://www.gigamegablog.com/gadgets/gm-pachube.js</a>.  (It&#8217;s OK to click on it.   Since this Javascript can&#8217;t execute outside of Google&#8217;s gadget container, your browser will just display the source code instead of running it.  Or, you can just right-click the link and save it as a file, you big baby. <img src='http://www.gigamegablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  )</li>
</ul>
<h2>The Pachube API</h2>
<p><a href="http://api.pachube.com/v2/">Pachube&#8217;s API documentation</a> is quite good overall, but it can be a little difficult to find the details for a particular feature.</p>
<p>The graphing API I&#8217;m using, for example, is in the &#8220;<a href="http://api.pachube.com/v2/#read-datastream-get-v2-feeds-feed-id-datastreams-datastream-id">Read datastream &#8211; GET  v2/feeds/&lt;feed_id&gt;/datastreams/&lt;datastream_id&gt;</a>&#8221; section.  It&#8217;s just barely there, actually – a passing reference to the all-important PNG parameter, along with a table of parameters you can pass to the API.  (A better way to learn the graphing API is to use Pachube&#8217;s Graph Builder – see the next section).</p>
<p>There are a lot of options for setting the time range of a graph, including some that my gadget doesn&#8217;t support, such as a specific end date.  These options are described in the &#8220;<a href="http://api.pachube.com/v2/#historical-queries">Historical Queries</a>&#8221; section tucked away at the end of that documentation page.</p>
<p>To get a list of datastreams in a feed, I use the &#8220;Read feed&#8221; API, described <a href="http://api.pachube.com/v2/#read-feed-get-v2-feeds-feed-id">here</a>.  As you can see from the JSON example in that section, this is a very handy API that returns a lot of information about the feed and each datastream.</p>
<p>An API key must be passed with most API calls, even when accessing Public feeds.     The <a href="http://api.pachube.com/#authentication">mechanism for passing the key</a> is described on a separate page, the <a href="http://api.pachube.com/">API Overview</a>.  That page also describes <a href="http://api.pachube.com/#time-zones">the timezone parameter</a>.  You&#8217;ll find more information on the API key and time zones later in this post.</p>
<h2>Pachube Graph Builder</h2>
<p>The best way to learn the API syntax for generating a graph is Pachube&#8217;s Graph Builder.  To display it, go to your Feed&#8217;s page on Pachube&#8217;s web site, then click on the gear icon in the lower right of the graph for a datastream, as shown below.</p>
<div class="img aligncenter size-full wp-image-1051" style="width:814px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/16-11-2011-7-14-24-PM.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/11/16-11-2011-7-14-24-PM.jpg" alt="Launching the Graph Builder" width="814" height="388" /></a>
	<div>Launching the Graph Builder</div>
</div>
<p>The Graph Builder page allows you to interactively try out various graph parameters, then copy a URL that calls the API to generate that graph.</p>
<div class="img aligncenter size-full wp-image-1052" style="width:917px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/16-11-2011-7-41-26-PM.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/11/16-11-2011-7-41-26-PM.jpg" alt="Pachube Graph Builder" width="917" height="600" /></a>
	<div>Pachube Graph Builder</div>
</div>
<h2>Pachube Graph API</h2>
<p>The URL that you&#8217;ll get from the Graph Builder will look something like this:</p>
<pre><a href="https://api.pachube.com/v2/feeds/37080/datastreams/JadePlant.png?width=500&amp;height=300&amp;colour=%238024f1&amp;duration=3hours&amp;title=Jade Plant Moisture&amp;show_axis_labels=true&amp;detailed_grid=true&amp;timezone=Eastern Time (US &amp;amp; Canada)">https://api.pachube.com/v2/feeds/37080/datastreams/JadePlant.png?</a>
   <a href="https://api.pachube.com/v2/feeds/37080/datastreams/JadePlant.png?width=500&amp;height=300&amp;colour=%238024f1&amp;duration=3hours&amp;title=Jade Plant Moisture&amp;show_axis_labels=true&amp;detailed_grid=true&amp;timezone=Eastern Time (US &amp;amp; Canada)"> width=500&amp;height=300&amp;colour=%238024f1&amp;duration=3hours </a>
   <a href="https://api.pachube.com/v2/feeds/37080/datastreams/JadePlant.png?width=500&amp;height=300&amp;colour=%238024f1&amp;duration=3hours&amp;title=Jade Plant Moisture&amp;show_axis_labels=true&amp;detailed_grid=true&amp;timezone=Eastern Time (US &amp;amp; Canada)">&amp;title=Jade Plant Moisture&amp;show_axis_labels=true &amp;detailed_grid=true</a>
   <a href="https://api.pachube.com/v2/feeds/37080/datastreams/JadePlant.png?width=500&amp;height=300&amp;colour=%238024f1&amp;duration=3hours&amp;title=Jade Plant Moisture&amp;show_axis_labels=true&amp;detailed_grid=true&amp;timezone=Eastern Time (US &amp;amp; Canada)">&amp;timezone=Eastern Time (US &amp;amp; Canada)</a></pre>
<p>All Pachube API URLs have the same basic layout, following the <a href="http://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> standard:</p>
<ul>
<li><em>https://api.pachube.com/v2</em> &#8211; All API URLs start with this.  (You can use the non-secure http:// prefix if your coding platform doesn&#8217;t support https, such as an Arduino.)<br />
The V2 refers to Version 2 of the API.  Version 1, which uses a different syntax, is &#8220;deprecated&#8221; (i.e. still supported, but use is discouraged).  Some of the examples you&#8217;ll find on the Web use the V1 API: if there is one /v2 in the URL, it&#8217;s a version 1 call.</li>
<li><em>feeds/37080</em>  - All API URLs for a specific feed will identify the feed # this way.</li>
<li><em>Datastreams/JadePlant.png</em> – All API URLs which deal with a specific datastream will identify it using its ID field (in this case, &#8220;JadePlant&#8221;).  The &#8220;.png&#8221; part is what tells the API that you want a graph.  If you replace that with &#8220;.xml&#8221;, you&#8217;ll get back XML data about your datastream instead.</li>
<li><em>?&lt;parms&gt;</em> – The parameters that follow the question mark are specific to the API call you are making.<br />
Pachube&#8217;s API is pretty easy-going about these parameters: if you pass ones that don&#8217;t apply to the API call, or even ones that don&#8217;t exist at all, the API will just ignore them.<br />
If you&#8217;re familiar with URLs, you might have noticed that the above URL example (copied from the Graph Builder) contains an invalid parameter: the &amp;timezone parameter contains spaces and an ampersand that need to be properly &#8220;escaped&#8221; when including in a URL.  The API doesn&#8217;t tell you this, it just ignores the timezone parameter.  (And, as a result, the X axis of the graph shows UTC times, the default, rather than EST times).</li>
</ul>
<h2>API Keys</h2>
<p>I have to admit that I don&#8217;t have a firm grasp on which APIs and feeds require authentication.  I&#8217;m tempted to just write &#8220;always pass an API key – it can&#8217;t hurt&#8221;.  But that&#8217;s way too simple for this blog, so here&#8217;s my best <span style="text-decoration: line-through;">guess</span> explanation of how it works…</p>
<p>If you tried pasting URLs from the Graph Builder into your browser, you probably noticed that no login was required, and no API key is being passed.  As far as I know, an API key is never required for a graph of a public datastream.</p>
<p>However, the other API used by the gadget, which retrieves a list of datastreams for a specified feed, does require authentication, even if the feed is public.  If you have a neglected browser from which you’ve never logged into Pachube (that blue E icon will probably do), try accessing  the following URL</p>
<pre><a title="http://api.pachube.com/v2/feeds/37080.json?timezone=Eastern%20Time%20%28US%20%26%20Canada%29" href="http://api.pachube.com/v2/feeds/37080.json?timezone=Eastern%20Time%20%28US%20%26%20Canada%29">http://api.pachube.com/v2/feeds/37080.json? </a>
   <a title="http://api.pachube.com/v2/feeds/37080.json?timezone=Eastern%20Time%20%28US%20%26%20Canada%29" href="http://api.pachube.com/v2/feeds/37080.json?timezone=Eastern%20Time%20%28US%20%26%20Canada%29">timezone=Eastern%20Time%20%28US%20%26%20Canada%29</a></pre>
<p>You should get a pop-up authentication prompt.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/23-11-2011-6-10-21-PM.jpg"><img class="aligncenter size-full wp-image-1054" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/23-11-2011-6-10-21-PM.jpg" alt="" width="327" height="353" /></a></p>
<p>Private feeds always require authentication, even for a graph.  For example, the following should definitely display an authentication prompt, unless you are a nefarious hacker.</p>
<pre><a href="http://api.pachube.com/v2/feeds/39460.json?timezone=Eastern%20Time%20%28US%20%26%20Canada%29">http://api.pachube.com/v2/feeds/39460.json? </a>
   <a href="http://api.pachube.com/v2/feeds/39460.json?timezone=Eastern%20Time%20%28US%20%26%20Canada%29">timezone=Eastern%20Time%20%28US%20%26%20Canada%29</a></pre>
<p>If your application were to try doing the same thing, it would get a &#8220;404 – Authentication Error&#8221;.  When trying to graph a private datastream without an API key, the application gets back a nice &#8220;Server error&#8221; graphic, instead</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/16-11-2011-8-33-21-PM.jpg"><img class="aligncenter size-full wp-image-1053" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/16-11-2011-8-33-21-PM.jpg" alt="" width="207" height="105" /></a></p>
<p>To avoid that, the code needs to pass an API key.  The gadget doesn&#8217;t ask you to fill in an API key of your own: instead, I&#8217;ve hard-coded one that has read access to public feeds, but update access to nothing (including my own feeds).</p>
<p>The key is passed in an HTML header field, <a href="http://api.pachube.com/#security-authentication">as specified in the Pachube API documentation</a>.  Various programming languages have various methods for setting the contents of the header field – the Google Gadgets approach<a href="http://code.google.com/apis/gadgets/docs/remote-content.html#Fetch_JSON"> is described in their documentation</a>, and shown below:</p>
<pre class="brush: jscript; title: ; notranslate">
var params = {};
params[gadgets.io.RequestParameters.HEADERS] = {
    &quot;X-PachubeApiKey&quot;: &quot;&lt;your API key&gt;&quot;
};
</pre>
<p>Incidentally, if you&#8217;re using the gadget to graph datastreams in a private feed, you might wonder how my API key has access to your private feed.  Relax, it doesn&#8217;t.  Through some kind of <em>under-the-covers-cached-browser-authentication-cookie-machination</em> (my words, not Pachube&#8217;s), the gadget is allowed to access your private feed on a browser in which you&#8217;ve previously logged into Pachube.  I’ve noticed intermittent “authentication failed” errors when using the gadget with my own private feed, presumably when my cached authentication expires (or the cookie-machinations go awry).</p>
<h2>Time Zones</h2>
<p>According to the <a href="http://api.pachube.com/#security-authentication">API documentation on time zones</a> :</p>
<p><em>There are two places where you can specify the time zone: in your user profile on the website and via a parameter in an API request.</em></p>
<p>I think the intention is that your user profile’s timezone setting is automatically used by the API unless overridden, but it currently doesn’t work that way for graphs.  Perhaps that&#8217;s a bug that will be fixed at some point, but for now you have to pass the <em>timezone</em> parameter to the graph API call, or the X axis will display UTC times.</p>
<p>I had originally planned to have a &#8220;UTC offset&#8221; field in the gadget settings, where you would fill in the # of hours difference between your time zone and UTC: for example, -5 for Eastern Standard Time.</p>
<p>However, when testing I noticed something odd: timezone=-5 gave me UTC minus 5 hours, as expected, but timezone=-4 gave me UTC minus 3 hours.</p>
<p>As described in <a href="http://community.pachube.com/node/821">this post in the Pachube Community forum</a>, if you set the timezone parameter to a numeric value, the API will select the first matching entry in Pachube&#8217;s (rather eclectic) <a href="http://api.pachube.com/#time-zones">list of geographic time zone settings</a>.</p>
<p>For example, timezone=-4 is the same as specifying &#8220;Atlantic Time (Canada), and timezone=-5 is the same as specifying &#8220;Bogota&#8221;.  Rather than being dependent on the local customs of Atlanteans and Bogatians, I gave in and included the full list of geographic timezones in the the gadget&#8217;s Edit Settings page.  (If you have no idea which one on those time zones you are in, ask Pachube, not me.)</p>
<div class="img aligncenter size-full wp-image-1055" style="width:338px;">
	<a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/23-11-2011-6-19-40-PM.jpg"><img src="http://www.gigamegablog.com/wp-content/uploads/2011/11/23-11-2011-6-19-40-PM.jpg" alt="Yes, Virginia, there is a Nuku'alofa" width="338" height="267" /></a>
	<div>Yes, Virginia, there is a Nuku'alofa</div>
</div>
<p>As shown in the Graph Builder section above , another tricky thing to consider when working with timezones is proper encoding of non-URL characters, like spaces and ampersands.  Javascript makes this easy: the gadget&#8217;s code for handling the conversion is simply:</p>
<pre class="brush: jscript; title: ; notranslate">
// replace And with &amp; (Google's Gadget API hates ampersands)
timeZone = timeZone.replace(&quot; and &quot;, &quot; &amp; &quot;);
// use escape function to encode spaces and ampersands in URL
urlSuffix = &quot;timezone=&quot; + escape(timeZone);
</pre>
<p>One last pothole to avoid: Google&#8217;s Gadget API seems to have a particular distaste for ampersands, however they’re encoded: the dropdown list of timezones wouldn&#8217;t display until I took them out.</p>
<h2>Getting the List of Datastreams in a Feed</h2>
<p>Pachube makes it easy to get the list of datastreams in a feed: just one API call returns a variety of properties, including the timestamp and value of the last datapoint received by each datastream.</p>
<p>The Javascript code for doing this is shown below, most of which is from the gadget’s getDatastreamStatus function:</p>
<pre class="brush: jscript; title: ; notranslate">
var urlPrefix = &quot;https://api.pachube.com/v2/&quot;;
var urlSuffix = &quot;timezone=&quot; + escape(timeZone);
var url = urlPrefix + &quot;feeds/&quot; + feedID + &quot;.json&quot; + &quot;?&quot; + urlSuffix;
var params = {};

params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
// NOTE - this API key has READ access only
params[gadgets.io.RequestParameters.HEADERS] = {
    &quot;X-PachubeApiKey&quot;: &quot;nBGUIT63Onke5-sfOoARTvKvkwl45b85wjz5PKDIZkc&quot;

// refresh data if longer than 5 minutes since last request
makeCachedRequest(url, getDatastreamsResponse, params, 300);
</pre>
<p>Yes, that’s an actual, genuine API key that I’ve published – my own, in fact.  As mentioned earlier, this one is defanged, limited to read-only access to public feeds.</p>
<p>The “.json” in the URL specifies that the data is to be returned in JSON format: other options are XML and CSV.  Your choice of format depends primarily on the coding platform you’re using.  Google’s Gadget API supports both XML and JSON, but I went with JSON because it is more light-weight (i.e. faster), a consideration if you’re working with a lot of datastreams.  The CSV option is intended for platforms that don’t support XML or JSON, such as an Arduino.</p>
<p>The code for <em>makeCachedRequest</em> is <a href="http://code.google.com/apis/gadgets/docs/remote-content.html#Cache">taken directly from Google’s API documentation</a>.  The code allows you to override Google’s default caching algorithm for gadget data, which retrieves updated data from the source (i.e. Pachube in this case) every 60 minutes, regardless of how often the user clicks the browser refresh button.  I’m overriding the interval to be every 5 minutes.</p>
<p>Note that the gadget doesn’t automatically update every 5 minutes: the update only occurs when the user first opens the web page containing the gadget, or clicks the refresh button, or when iGoogle refreshes the gadget.  (iGoogle refreshes each gadget once an hour, if the iGoogle page is in the foreground tab).  As far as I know, your gadget code has no way of forcing a refresh to occur.</p>
<p>The response to the API request is returned to the callback function passed as a parameter to makeCachedRequest, a simplified version of which is:</p>
<pre class="brush: jscript; title: ; notranslate">
function getDatastreamsResponse(obj)
{
  if (obj.data === null || typeof obj.data === &quot;undefined&quot;)
  {
    // something’s wrong – check the other obj properties, like obj.error and obj.rc
    . . .
  }

  jsonData = obj.data;

  if (!jsonData.datastreams)
  {
    displayErrorMsg(&quot;No datastreams found in feed&quot;);
    return;
  }

  datastreamList = jsonData.datastreams;
  feedTitle = jsonData.title;
  feedStatus = jsonData.status;
  feedDesc = jsonData.description;
</pre>
<p>The meat of the response is contained in the <em>.data</em> property of the parm passed to the callback function.  If that property is empty, then an error occurred.  Generally the error information is found in <em>obj.error</em> and/or <em>obj.rc</em>.  The former contains an error message as a raw JSON text string, and the latter contains one of the standard HTTP return codes <a href="http://api.pachube.com/#http-status-codes">as listed in Pachube’s documentation</a>.</p>
<p>The data object is bristling with useful information about the feed and datastream.  As shown in the code, I’m getting the feed’s title, status and description from there, as well as a list of datastreams, each of which is itself a JSON object with properties.  The screenshot below shows some of the other properties in this data object as seen in the Google Chrome Javascript console.  For a full list of all of the available properties, see the example in Pachube’s <a href="http://api.pachube.com/v2/#read-feed-get-v2-feeds-feed-id">Get Feeds documentation</a>.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/23-11-2011-6-23-54-PM.jpg"><img class="aligncenter size-full wp-image-1056" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/23-11-2011-6-23-54-PM.jpg" alt="" width="1002" height="355" /></a></p>
<h2>Getting the Datastream Graphs</h2>
<p>The Javascript which handles the calls to the Graph API, <em>displayGraphs()</em>, basically just pieces together the URL for the Graph API,  as explained in the &#8220;Pachube Graph API&#8221; section above.</p>
<p>There are a couple of issues handled here that I didn’t describe earlier.</p>
<p>Unbeknownst to the user (wouldn’t want to worry their pretty little heads, would we?), the code scales down the graph if necessary to fit within Pachube’s limit 300K pixels.</p>
<pre class="brush: jscript; title: ; notranslate">

var MAX_GRAPH_SIZE = 300000;  // Pachube's maximum graph size, in pixels
. . .
var defaultWidth = 320; // in normal gadget mode, 320 is the recommended width
if (graphHeight * graphWidth &gt; MAX_GRAPH_SIZE)
{
  // set to maximum size that will fit within Pachube's limit
  if (graphWidth &gt; defaultWidth)
  {
    graphWidth = defaultWidth;
  }

  graphHeight = Math.floor(MAX_GRAPH_SIZE / graphWidth);
}
</pre>
<p>This is done somewhat crudely, basically yanking the graph width back to 320 pixels, then yanking the height down as needed to fit within the 300K.</p>
<p>Also admittedly quite crude is the support for increasing the graph size when the gadget is maximized.</p>
<pre class="brush: jscript; title: ; notranslate">
// in canvas mode, double the graph size
if (gadgets.views.getCurrentView().getName() === &quot;CANVAS&quot;)
{
  graphHeight *= 2;
  graphWidth *= 2;
  defaultWidth *= 2;
}
</pre>
<p>I’m a little surprised that most gadgets ignore the maximized setting altogether, just displaying the same content in the same cramped size.  I think the problem is one of “discoverability”, to use a Googley term: the feature is disabled by default, and <a href="http://code.google.com/apis/gadgets/docs/ui.html#Dyn_Height">Google’s documentation on the feature</a> confusingly insists on referring to it as “canvas” mode.</p>
<p>As shown in the API documentation, enabling “canvas” mode is just a matter of pasting some boilerplate XML settings into your gadget, like so:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;Content type=&quot;html&quot; view=&quot;home&quot;&gt;
&lt;![CDATA[
 &lt;div id=&quot;content_div&quot;&gt;&lt;/div&gt;
. . .
&lt;script src=&quot;http://www.gigamegablog.com/gadgets/gm-pachube.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
]]&gt;
&lt;/Content&gt;
&lt;Content type=&quot;html&quot; view=&quot;canvas&quot;&gt;
&lt;![CDATA[
 &lt;div id=&quot;content_div&quot;&gt;&lt;/div&gt;
. . .
&lt;script src=&quot;http://www.gigamegablog.com/gadgets/gm-pachube.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
]]&gt;
&lt;/Content&gt;
</pre>
<p>Perhaps Google would prefer that your gadget take on an entirely new form when maximized, since the XML allows for a separate block of Javascript for canvas mode (the “content_div” section).  I wasn&#8217;t that ambitious, so instead I use a script tag to feed the same Javascript code into both the normal and canvas mode XML definitions, then changed the code to check which mode it’s in, as shown in the earlier code sample.</p>
<h2>Wrapping It Up</h2>
<p>If you&#8217;ve read the <a href="http://gigamegablog.com/2011/06/02/a-nimbits-gadget-programmer%e2%80%99s-show-and-tell/">Programmer’s Show and Tell for my Nimbits gadget</a>, you’ll notice that this time I’ve done much  less ranting about how frustrating Google’s Gadget API is to work with.  The API hasn’t changed, but once you know where the potholes are, the drive is a lot smoother. If you intend to write your own gadget I’d suggest you read my earlier rant/article first, since it points out a lot of those potholes.</p>
<p>I’m still dubious about the future of Google gadgets given Google’s newfound <a href="http://www.independent.co.uk/life-style/gadgets-and-tech/news/google-labs-closes-as-firm-focuses-on-making-money-from-its-greatest-hits-2318358.html?action=Popup">emphasis on monetization and focusing on core products</a>.   The iGoogle Developer Blog hasn’t had any new posts since a <a href="http://igoogledeveloper.blogspot.com/2011/05/more-new-features-for-gadget-dashboard.html">May post</a> asking “Did you know we are continuously adding new features” ?  (In fairness, they were referring to the Gadget Dashboard – they stopped adding new features to the gadget API long before May).</p>
<p>Methinks the best browser-based platform for making use of the Pachube API lies elsewhere, perhaps a Google App Engine project <a href="http://community.pachube.com/node/456">like this one</a>. .  The App Engine would give your code a lot more elbow room, and there is so much more to the Pachube API than what I’ve covered here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/11/23/a-pachube-gadget-programmers-show-and-tell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Pachube Google Gadget: Size Matters</title>
		<link>http://www.gigamegablog.com/2011/11/05/a-pachube-google-gadget-size-matters/</link>
		<comments>http://www.gigamegablog.com/2011/11/05/a-pachube-google-gadget-size-matters/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 22:34:14 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pachube]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=1034</guid>
		<description><![CDATA[As described in past articles, I use the Pachube online Database/Internet-Of-Things-Thingee to log data from Tweet-A-Watt and various other sensors. (It&#8217;s pronounced &#8220;Patch-bay&#8221;, apparently, but that won&#8217;t stop me from my thinking &#8220;Pa-Chew-Bee&#8221; every time I see the word. Feel &#8230; <a href="http://www.gigamegablog.com/2011/11/05/a-pachube-google-gadget-size-matters/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As described in <a href="http://gigamegablog.com/2011/03/10/tweet-a-watt-beyond-the-twitter/">past </a><a href="http://gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/">articles</a>, I use the <a href="http://www.pachube.com">Pachube</a> online Database/Internet-Of-Things-Thingee to log data from <a href="http://www.ladyada.net/make/tweetawatt/">Tweet-A-Watt</a> and various other sensors. (It&#8217;s pronounced &#8220;Patch-bay&#8221;, apparently, but that won&#8217;t stop me from my thinking &#8220;Pa-Chew-Bee&#8221; every time I see the word. Feel free to join me.)</p>
<p><a href="http://www.pachube.com"><img class="aligncenter size-full wp-image-1043" title="PachubeLogo" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/PachubeLogo.png" alt="" width="238" height="80" /></a></p>
<p>I like Pachube &#8212; it&#8217;s reliable, well-designed, well-documented, and very much open to hobbyists.  They <a href="http://blog.pachube.com/2011/01/bringing-down-barriers-pachube-service.html">recently did away with paid plans</a> and made all aspects of the site and service free, so I’d encourage you to give them a try. If you need help at getting your data into Pachube, see their <a href="http://api.pachube.com/quickstart/">Quick Start guide</a> and <a href="http://community.pachube.com/tutorials">Tutorials</a>. My article on <a href="http://gigamegablog.com/2011/03/10/tweet-a-watt-beyond-the-twitter/">connecting Tweet-A-Watt to Pachube</a> also contains some tips on getting started, and my article on the <a href="http://gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/">FEZ XBee Sensor</a> shows an easy way to post data to Pachube from Python.</p>
<p>Pachube&#8217;s site provides a page for each of your feeds, showing a graph of the last 24 hours of readings from each of your datastreams. That&#8217;s good if you remember to go look at it, but I&#8217;d prefer that my graphs come to me, via a gadget on my iGoogle home page.</p>
<p><a href="http://www.google.com/ig/directory?type=gadgets&amp;url=apps.pachube.com/google_gadget/gadget.xml">Pachube released a Google Gadget</a> some time ago, and I&#8217;ve been using it for some time. It works well, but there are a few extra features that I really wanted:<br />
- larger graphs, and the ability to resize the gadget container to see them<br />
- a time axis in local time, rather than UTC<br />
- the ability the set the timespan: 12 hours, 1 week, 1 month, etc.<br />
- a Maximized view that shows the graphs in humongous GigaMegaSize</p>
<p>So, I&#8217;ve created a Google Gadget which adds these features, plus a few more.</p>
<p>You can <a href="http://www.google.com/ig/directory?url=www.gigamegablog.com/gadgets/gm-pachube.xml">grab the gadget from the Google Gadgets directory</a>.</p>
<h1>Settings</h1>
<p>Here is a description of the various options available on the Edit Settings dialog.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/GadgetSettings.png"><img class="aligncenter size-full wp-image-1039" title="GadgetSettings" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/GadgetSettings.png" alt="" width="334" height="401" /></a></p>
<p><strong>Feed #</strong>: Numeric Pachube Feed ID</p>
<p><strong>Datastreams</strong>: To graph all datastreams in the feed, leave this field blank. Otherwise, enter the datastream ID and click the Add button. For example, to add the 2 datastreams below&#8230;</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/Datastreams.png"><img class="aligncenter size-full wp-image-1037" title="Datastreams" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/Datastreams.png" alt="" width="638" height="197" /></a></p>
<p>&#8230;type Cactus, click Add, type CatGrass, click Add. The field should then look like this:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/DatastreamsInputBox.png"><img class="aligncenter size-full wp-image-1038" title="DatastreamsInputBox" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/DatastreamsInputBox.png" alt="" width="309" height="91" /></a></p>
<p><strong>Time Span, Time Span Units</strong> – This determines what period of time will be graphed. As shown in the screenshot, the default is 24 hours. Time Span Units can be set to hours, days, weeks or months.</p>
<p><strong>Show Status</strong>. If true, each graph will be preceded by a line of text giving the Datastream ID, the last reading and the date and time it was received, as shown in this screenshot.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/GraphsDetailed.png"><img class="aligncenter size-full wp-image-1040" title="GraphsDetailed" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/GraphsDetailed.png" alt="" width="290" height="217" /></a></p>
<p><strong>Detailed Grid</strong>. If true, vertical and horizontal grid lines will be displayed, as in the 2 graphs above. If false, only a vertical grid separating each time span unit is displayed, as in the following (GigaMegaSized) graph.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/11/GraphWithoutStatus.png"><img class="aligncenter size-full wp-image-1041" title="GraphWithoutStatus" src="http://www.gigamegablog.com/wp-content/uploads/2011/11/GraphWithoutStatus.png" alt="" width="573" height="296" /></a></p>
<p><strong>Axis Labels</strong>: If true, numeric labels are added to the vertical and horizontal axis indicating the range of values. Note that, depending on the time span, these labels tend to overlap in a smaller graph (and I don&#8217;t have any control over the format of the labels). If false, the only labels are the minimum and maximum value of the vertical axis.</p>
<p><strong>Graph Width and Graph Height:</strong> Determines the size of each graph, in pixels. When the gadget is maximized, both sizes are automatically doubled. These values are required, and are initially set to a width of 280 and a height of 100.</p>
<p><strong>Gadget Height:</strong> Determines the height of the overall gadget, in pixels. If not specified, a default of 200 is used. (The gadget width can&#8217;t be set by the code, and varies depending on the browser type and the resolution of the monitor.)</p>
<p><strong>Time zone:</strong> Your local time zone. The default is UTC (aka Greenwich Mean Time). This setting affects the timestamp in the Status field, as well as the labels on the horizontal axis of the grid. The rather eclectic collection of names in the dropdown lists was Pachube’s idea, not mine. (Look <a href="http://api.pachube.com/#time-zones">here</a> if you don’t believe me!)</p>
<h1>Wrapping Up</h1>
<p>I&#8217;d welcome any bug reports or feature requests.</p>
<p>iGoogle’s Gadget framework does a lot of caching sleight-of-hand, so if you find that a change of settings doesn’t appear in the gadget, try refreshing the page. As for features , there are some things I can’t add because they aren’t supported by Pachube’s API yet (multiple datastreams in a graph, for example), but otherwise I’m open to suggestions.</p>
<p>For developers, I plan to write an article in the near future explaining the gadget&#8217;s use of the Pachube API.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/11/05/a-pachube-google-gadget-size-matters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FEZ XBee Sensor: Hat Trick</title>
		<link>http://www.gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/</link>
		<comments>http://www.gigamegablog.com/2011/10/29/fez-xbee-sensor-hat-trick/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 21:34:26 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[FEZ]]></category>
		<category><![CDATA[Netduino]]></category>
		<category><![CDATA[nimbits]]></category>
		<category><![CDATA[Pachube]]></category>
		<category><![CDATA[Python]]></category>

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

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

#if FEZ

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

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

#else

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

#endif

static string[] sensorIDs = new

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

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

. . .

try
{
	if (blnDisableLCD)
	{
		return;
	}

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

	. . .

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

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

RLP.Enable();

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

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

RLP.InitializeBSSRegion(elf_file);

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

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

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

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

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

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

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

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

logging.basicConfig(level=logging.DEBUG,

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

filename='SensorRelayError.log')

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

try:

    . . .

except:

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

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

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

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

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

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

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

def readConfigFile():

    #global config

    for line in open(CONFIGFILE):

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

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

            if len(parts) == 2:

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

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

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

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

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

		<guid isPermaLink="false">http://gigamegatech.com/?p=871</guid>
		<description><![CDATA[Updated June 4: I&#8217;ve corrected a couple of things, as marked in blue. Updated Dec 3: I made a small code change to fix the autoscale feature, as marked in green below. In my last post, I gave a user’s &#8230; <a href="http://www.gigamegablog.com/2011/06/02/a-nimbits-gadget-programmer%e2%80%99s-show-and-tell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><span style="color: #3366ff;"><em>Updated June 4: I&#8217;ve corrected a couple of things, as marked in blue. </em></span></p>
<p><span style="color: #008000;"><em>Updated Dec 3: I made a small code change to fix the autoscale feature, as marked in green below.</em></span></p>
<p>In my <a href="http://gigamegablog.com/2011/05/21/a-nimbits-gadget-minding-the-data-store/">last post</a>, I gave a user’s overview of a Google Gadget I wrote to display graphs from the <a href="http://www.nimbits.com">Nimbits</a> data logger.</p>
<p>This post is directed at developers. I’ll explain how the gadget interacts with the <a href="https://code.google.com/p/nimbits-server/wiki/RestApi">Nimbits API</a> and the <a href="http://code.google.com/apis/chart/">Google Charts API</a>, and give a few tips to those who are getting started with Gadget development.</p>
<p>Actually, my tips would only be useful to gadget noobies, since I’m a gadget noob myself. Fortunately, Google’s Gadget development framework is pretty easy to get started with. This is partly due to the abundance of sample code – you can examine the source code for any gadget by clicking the “View Source” link near the bottom right of the gadget’s page in the <a href="http://www.google.com/ig/directory?dpos=top&amp;root=%2Fig">Google Gadget directory</a>.</p>
<p>However, another reason why the Gadget framework is easy to learn is that there isn’t that much to it. The limitations can be frustrating, and it doesn’t seem like the framework is under active development by Google any longer.</p>
<p>That’s fine with me, though: the gadget is just the container, and the contents are supplied by the Nimbits and Google Charts APIs, both of which are very much moving forward.</p>
<h1>Viewing the Source Code</h1>
<p>If you click on the “View source” link for the <a href="http://www.google.com/ig/directory?url=www.gigamegablog.com/gadgets/nimbits.xml">Nimbits Gadget</a> , the first thing you’ll notice about the code is that there isn’t any. The link displays the Gadget’s XML definition. The JavaScript code is often embedded in the XML file (that’s actually what Google recommends for better performance), but I decided to put it in a separate .js file to avoid duplicating the code in &#8220;canvas&#8221; view.</p>
<p>So, the code is actually here: <a href="http://www.gigamegablog.com/gadgets/nimbits.js">http://www.gigamegablog.com/gadgets/nimbits.js</a>. (Yeah, I know your Mother told you not to run strange JavaScript, but if you click this link it will just display the code, not run it.)</p>
<p>Most of the JavaScript code is a series of functions that build up 2 calls to REST APIs:</p>
<ul>
<li>The <a href="https://code.google.com/p/nimbits-server/wiki/ChartApiService">Nimbits Chart API</a> to display the graph</li>
<li>The <a href="https://code.google.com/p/nimbits-server/wiki/CurrentValueService">Nimbits CurrentValue API</a>, to (optionally) return the Status line</li>
</ul>
<h1>The Nimbits Chart API</h1>
<p>A good introduction to the Chart API is <a href="http://nimbits.blogspot.com/2010/11/data-out-nimbits-integrates-into-google.html">Benjamin Sautner’s blog post</a>. . His post gives a couple of examples of calls to the Chart API, and the 2nd one is very similar to the one that I ended up using in the gadget:</p>
<p>&nbsp;</p>
<p>http://app.nimbits.com/service/chartapi?point=TempF&#038;email=bsautner@gmail.com&#038;cht=lc&#038;chs=200&#215;100&#038;chxt=x,y&#038;chxl=0:|Apr|May|June|1:||100+F</p>
<p>&nbsp;</p>
<p>If you aren’t familiar with REST APIs, then you might wonder why this looks like a URL. That’s the whole idea of REST: API calls are URLs with all of the parameters embedded in the URL string. Ideally, the URL’s parameters tells you (and, most importantly, the server) everything you need to know to handle the request, with no dependencies on previous requests, etc.</p>
<p>Authentication aside, if you and I paste a REST URL string into a browser, we should both get the exact same result. (And, for the purposes of this gadget, I basically tossed authentication aside – that’s why it only works with Public data points).</p>
<p>If you paste the above URL into a browser, you’ll get back a graph in a .png file. The Nimbits Charts API will always return a PNG. This makes it easy to use trial-and-error to experiment with the Charts API. Other Nimbits APIs, and most REST APIs in general, return XML – we’ll see an example of that in the CurrentValue API, below.</p>
<p>Before I get into the code I used in the gadget to build the chart…</p>
<h1>How To Build A Nimbits Gadget in 5 Minutes</h1>
<p>Mine took a little longer, actually, but displaying a Nimbits chart in a gadget is quite simple:</p>
<p>1. Open the <a href="http://code.google.com/apis/gadgets/docs/tools.html#GGE">Google Gadgets Editor</a>: basically a Notepad that saves files on one of Google’s servers.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/GGE.png"><img class="aligncenter size-full wp-image-889" title="GGE" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/GGE.png" alt="" width="764" height="461" /></a></p>
<p>Replace the “Hello, world!” line with</p>
<pre class="brush: jscript; title: ; notranslate">

&lt;img
src=&quot;http://app.nimbits.com/service/chartapi?point=TempF&amp;email=bsautner@gmail.com&amp;cht=lc&amp;chs=200x100&amp;chxt=x,y&amp;chxl=0:|Apr|May|June|1:||100+F&quot;
/&gt;
</pre>
<p>2.Click File, then Save. In the Save File dialog, change the filename from helloworld.xml to nimbits.xml. It should now look like this</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/GGE2.png"><img class="aligncenter size-full wp-image-890" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/GGE2.png" alt="" width="862" height="225" /></a></p>
<p>3.Click File, then Publish. The Gadget Editor will nag you about some of the things that are missing, but that’s OK because you’re only going to publish it to your own iGoogle page, not Vanity Fair. Click OK.</p>
<p>4.The “Publish Your Gadget” dialog will be displayed. Click on the “Add to my iGoogle page” option.</p>
<p>5.Another page is opened, with a big blue “Add Hello World! To iGoogle” button. Click it.</p>
<p>6.If all goes well, you should see a brand new gadget on your iGoogle page, as below.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/GGE_Hello_World.png"><img class="aligncenter size-full wp-image-891" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/GGE_Hello_World.png" alt="" width="316" height="200" /></a></p>
<p>If you jumped ahead and started changing the settings in the Gadget Editor to see what would happen then, hey, sorry about that whole nervous breakdown thing. I should have mentioned that Google automatically caches your gadget’s code, so your changes won’t be automatically applied to your iGoogle page. There is a way to turn that off – see the Caching section below.</p>
<p>Your shiny new gadget will faithfully report the temperature in Benjamin Sautner’s aquarium. But what if you actually wanted your gadget to display something else? That’s where the code comes in…</p>
<h1>Nimbits Chart API Options</h1>
<p>The code block below is taken from the displayChart() function of the gadget’s JavaScript. It builds an HTML <em>img </em>tag similar to the one you pasted into your gadget, but getting its parameters from variables instead.</p>
<p>The variables are loaded from settings in the User Preferences dialog. I won’t cover that code here, since <a href="http://code.google.com/apis/gadgets/docs/fundamentals.html#Datatypes">this section of Google’s Gadget Developer docs</a> tells you all you&#8217;ll need to know.</p>
<pre class="brush: jscript; title: ; notranslate">
html += '&lt;img src=http://' + serverName + '/service/chartapi?'
  + 'points=' + pointsParm;
html += '&amp;email=' + userEmail;
html +=  '&amp;chds=a&amp;cht=lc&amp;chco=' + colourParm + '&amp;chxt=y&amp;chf=bg,s,EFEFEF';
html += '&amp;chs=' + graphWidth + 'x' + graphHeight;
if (spanType == &quot;Hours&quot;)
{
	html += &quot;&amp;st=-&quot; + timeSpan + &quot;h&amp;et=now&quot;;
} else
{
	// # of readings
	html += &quot;&amp;count=&quot; + timeSpan;
}

 if (displayLegend)
{
	// display it at top listing all data points
	html += '&amp;chdl=' + legendParm + '&amp;chdlp=t';
}
var gridStyle = &quot;&amp;chg=&quot;;
if (displayGrid == &quot;Vertical&quot;)
{
   gridStyle += &quot;10,0,1,0&quot;;
} else if (displayGrid == &quot;Horiz&quot;)
{
	gridStyle += &quot;0,10,1,0&quot;;
} else if (displayGrid == &quot;Both&quot;)
{
	gridStyle += &quot;10,10,1,0&quot;;
} else
{
	// no grid
	gridStyle = &quot;&quot;;
}
</pre>
<p>Let’s break this block of code into parts</p>
<pre class="brush: jscript; title: ; notranslate">
html += '&lt;img src=http://' + serverName + '/service/chartapi?'
			  + 'points=' + pointsParm;
</pre>
<p>Every call to the Nimbits Charts API needs a server name and at least 1 DataPoint. If you want to include multiple Data Points, they must be comma-delimited. If your Data Point names include spaces, they must be replaced with plus signs (which is a Googly standard for handling spaces in URLs). For example, if there are 2 data points named “Plant Light” and “Home Meter 2”, then <em>pointsParm </em>is set to &#8220;Plant+Light,Home+Meter+2&#8243;.</p>
<pre class="brush: jscript; title: ; notranslate">
html += '&amp;email=' + userEmail;
</pre>
<p><span style="color: #3366ff;"><em>Unless the user has already been authenticated (logged into iGoogle isn&#8217;t enough), the e-mail address is a mandatory parameter for the Nimbits REST API calls</em>.</span> Surprisingly, there is no longer a way for a Gadget to automatically determine the user&#8217;s Gmail address.</p>
<pre class="brush: jscript; title: ; notranslate">
html += '&amp;chds=a&amp;cht=lc&amp;chco=' + colourParm + '&amp;chxt=y&amp;chf=bg,s,EFEFEF';
</pre>
<p><span style="color: #008000;"><del>Autoscale is a very useful setting – so useful that you can’t turn it off in my gadget.</del>  <em>Update Dec 3: Well, autoscale *</em>was*<em> a very useful feature, until it stopped working.  I&#8217;ve replaced it with the <a href="http://code.google.com/apis/chart/image/docs/data_formats.html#textformatautoscaling">Google Chart API&#8217;s &#8220;&amp;chds=a&#8221; parameter</a>, which appears to have the exact same effect.</em></span></p>
<p><em></em> It tells Google Charts to automatically scale and label the Y axis based on the value of the points you are graphing. Without it, the graph is always plotted on a scale of 1 to 100, regardless of the actual value of the data.</p>
<p>For example, here is a graph of 2 Data Points with very different scales: one for a relatively low-power set of devices (DuinoFarm) and one for a big fat PC.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/GraphWithAutoscale.png"><img class="aligncenter size-full wp-image-892" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/GraphWithAutoscale.png" alt="" width="321" height="204" /></a></p>
<p>Here is the same graph with autoscale turned off. The scale defaults to 1-100, and data points above 100 are cut off.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/GraphWithoutAutoscale.png"><img class="aligncenter size-full wp-image-893" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/GraphWithoutAutoscale.png" alt="" width="321" height="201" /></a></p>
<p>The &amp;cht parm is another mandatory one: it specifies the type of graph, with “lc” meaning line chart. Leave it out, and you’ll get the default “polar bear in a snowstorm” chart. There are a bunch of other types of graphs available, as shown in the <a href="http://code.google.com/apis/chart/image/docs/gallery/chart_gall.html">Google Chart Gallery</a>, but line charts are how I ride.</p>
<p>The &amp;chco parm specifies the colours to be used for the lines in the graph, assigned in the same order as the data points in the points parm. The values are <a href="http://www.devguru.com/technologies/html/quickref/color_chart.html">RGB hex codes</a>: for example &amp;chco=FF0000,00FF00, for red and green. Without this parm, everything is orange. (Well, Google being Google, probably whatever colour they feel like using that day. Today, it’s orange).</p>
<p>The &amp;chxt is another one that I always use: it provides the vertical scale. Without it, the graph looks like this:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/GraphWithoutScale.png"><img class="aligncenter size-full wp-image-894" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/GraphWithoutScale.png" alt="" width="321" height="203" /></a><br />
The last parm in this section, &amp;chf=bg,s,EFEFEF, is responsible for that lovely gray background you see in the screenshots.</p>
<pre class="brush: jscript; title: ; notranslate">
html += '&amp;chs=' + graphWidth + 'x' + graphHeight;
</pre>
<p>This one’s pretty self explanatory. The actual value used in the gadget looks something like &amp;chs=320&#215;200, with the 320 part being hard-coded. The Chart API is quite happy to serve up PNGs that are much larger than this, so if you are displaying a graph outside of a gadget container (such as the “canvas” view displayed when you maximize a gadget) then you can go crazy with megapixel monstrosities.</p>
<pre class="brush: jscript; title: ; notranslate">
if (spanType == &quot;Hours&quot;)
{
    html += &quot;&amp;st=-&quot; + timeSpan + &quot;h&amp;et=now&quot;;
} else
{
    // # of readings
    html += &quot;&amp;count=&quot; + timeSpan;
}
</pre>
<p>Unlike the last few parms, this one is a Nimbits API parm, not Google Charts. It tells Nimbits which set of data point values to pass along to Google Charts. I’m using a relative timespan, where the end point is always now, and the start point is whatever offset the user specifies in the Settings panel (in hours). <span style="color: #3366ff;"><em>The Nimbits API supports a lot of other formats for the start and end time parms, allowing you to chart any time period you like, as documented in <a href="http://code.google.com/p/nimbits-server/wiki/TimeSpan">the TimeSpan page of the Nimbits Wiki</a>, and a more flexible time span setting is definitely on the To Do list for this gadget</em>.</span></p>
<p>The remaining settings in the code are self-explanatory, controlling the legend and grid used in the graph.</p>
<p>The resulting <img alt="" /> tag is plopped into the gadget’s content area, where it gets magically replaced with a PNG of the actual graph. It really is magical, since the response received from REST APIs are usually not so easy to handle.</p>
<p>Which brings us to the Status line&#8230;</p>
<h1>The Nimbits CurrentValue API</h1>
<p>The Status line displays the data point name, its most recent value, and the date and time it was received. All of that information is returned by the Nimbits <a href="https://code.google.com/p/nimbits-server/wiki/CurrentValueService">CurrentValue API</a>. This API’s main purpose is to record new values, not return existing ones, but since it always returns the latest value it’s handy for seeing when the last data was received.</p>
<p>For example, try pasting the following URL into a browser</p>
<p><code></p>
<p>http://app.nimbits.com/service/currentvalue?point=HomeServer&#038;email=gigamegabot@gmail.com&#038;format=json</p>
<p></code></p>
<p>You’ll get back a series of tags and values that looks like this :<br />
<code><br />
{"id":7865660,"lat":0.0,"lng":0.0,"d":57.9303189764,"timestamp":"2011-03-15T00:15:03 +0000","pointFK":4405630,"note":""}<br />
</code><br />
This is in JSON format, which is a simplified variant of XML that is handy for Javascript code (and most other languages) to work with.</p>
<p>Unlike the graph, this return string isn’t something we can plop into the gadget’s HTML and display unaltered to the user. Instead, we need to process it with code. And that means that we have to invoke the REST API in a way that passes the result to a piece of code.</p>
<p>In the Google Gadgets framework, this is done by calling one of their APIs:<br />
<code><br />
gadgets.io.makeRequest(url, callback, params);<br />
</code><br />
The &#8220;callback&#8221; parameter is the name of the Javascript function that will receive the response, and the &#8220;params&#8221; parameter are primarily used to override Google’s caching algorithm, as explained later. I took the code that invokes makeRequest pretty much verbatim from <a href="http://code.google.com/apis/gadgets/docs/remote-content.html#Cache">Google’s documentation for calling REST APIs</a>.</p>
<p>The code which processes the data returned by the CurrentValue API is in the buildStatusString() function:</p>
<pre class="brush: jscript; title: ; notranslate">
if (obj.data == null || typeof obj.data == &quot;undefined&quot;)
{
	// something went wrong
	if (typeof obj.text == &quot;undefined&quot; || obj.text == null || obj.text == &quot;&quot;)
	{
		return obj.error;
	} else
	{
		return obj.text;
	}
}
jsondata = obj.data;

var alldata = &quot;&quot;;
for (var key in jsondata) {
	var value = jsondata[key];
	alldata += key + &quot;:&quot; + value + &quot;, &quot;;
 }
 var time1 = jsondata['timestamp'];
 var date1 = new Date(time1);
 // retrieve values as local time
 //var dateAndTime = date1.getMonth() + &quot;/&quot; + date1.getDate() + &quot; &quot; + date1.getHours() + &quot;:&quot; + date1.getMinutes();
 var monthNames = [ &quot;January&quot;, &quot;February&quot;, &quot;March&quot;, &quot;April&quot;, &quot;May&quot;, &quot;June&quot;,
	&quot;July&quot;, &quot;August&quot;, &quot;September&quot;, &quot;October&quot;, &quot;November&quot;, &quot;December&quot; ];
 var dateAndTime = monthNames[date1.getMonth()].substr(0,3) + &quot; &quot; + date1.getDate() + &quot;  &quot; + date1.toLocaleTimeString();

 var value1 = jsondata['d'];
 value1 = Math.round(100 * value1) / 100;

 return dateAndTime + ' -- ' + value1;
</pre>
<p>Admittedly, this code is anything but beautiful. It got real ugly real fast when I tried to grapple with API requests that fail.</p>
<p>The code starts off with an attempt to figure out if the response was data or an error message. The object returned from the REST API contains 3 properties. If all goes well, the only one that you have to worry about is .data. Otherwise, .error and/or .text may contain error messages.</p>
<p>JavaScript&#8217;s handling of null/undefined variables must make sense to someone, but not me!</p>
<p>If you got data, then JSON makes processing it quite easy. The tags that you saw displayed in the browser are keys to an array, so to retrieve the timestamp value you use code like this:</p>
<pre class="brush: jscript; title: ; notranslate">
var time1 = jsondata['timestamp'];
var date1 = new Date(time1);
</pre>
<p>The time1 variable is actually automatically handled as a date/time object by JavaScript, so why feed it into the Date function afterwards?</p>
<p>If you look at the value that is returned, it looks like this: &#8220;:&#8221;2011-03-15T00:15:03 +0000&#8243;. This is a UTC date and time string, so to make it more meaningful to the user you’ll want to convert it to their local time. In some languages, like Python, this conversion is a major pain.</p>
<p>JavaScript makes it easy: just feed that string into the Date function, and it automatically converts it to your local time when you access methods like date1.getDate() and toLocaleTimeString(). (Locale is different from local, by the way – toTimeString() also converts to the user’s local time.)</p>
<h1>Google Gadgets and Caching</h1>
<p>Google’s automatic caching of gadget code and data is something that trips up most first-time developers – it certainly got me.</p>
<p>Caching affects gadgets in 2 ways:</p>
<p>1. Gadget code is cached. So, if you change the code, then click refresh on the iGoogle page, an old copy of your code will still run, not the change you just made. This is a major performance benefit for users, but a major pain for developers.</p>
<p>Google feels your pain, sort of. They document this behavior, <a href="http://code.google.com/apis/gadgets/faq.html">way down at the bottom of the FAQ</a>, and offer a <a href="http://code.google.com/apis/gadgets/docs/legacy/tools.html#Dev_Gadget">“My Gadgets” gadget</a> that lets you disable this caching. The gadget has a tendency to flip from its initial state (it&#8217;s supposed to look like <a href="http://code.google.com/apis/gadgets/docs/legacy/basic.html#DevModStart">this screenshot in Google&#8217;s documentation</a>) to a minimalistic &#8220;Go to developer mode&#8221; link – I’m still not sure if that’s a bug or a feature – but &#8220;Going To Developer Mode&#8221; actually does disable the caching.</p>
<p>2. Remote data is cached. So, for example, calls to the Nimbits CurrentValue API are intercepted by the API framework, which returns the same data as you got last time. This is another performance boost, but at least Google has <a href="http://code.google.com/apis/gadgets/docs/remote-content.html#Cache">documented this one properly</a>.</p>
<p>The default behaviour is to cache any request that is within 60 minutes of the last time your gadget got data. You override this by passing an extra parameter in the call to the REST API – in my case, I set it to 5 minutes.</p>
<p>Note that this doesn’t mean your gadget will automatically update itself every 5 minutes – the update will only occur if the user refreshes the browser page, or if iGoogle automatically refreshes itself.</p>
<h1>Other Google Gadget Gotchas</h1>
<h2>Where to host your code?</h2>
<p>This is one of the first things you’ll have to decide, since you can’t test your code unless iGoogle can get to it through a web server. A good place to start is let Google host it – this is what happens if you enter your code into the <a href="http://code.google.com/apis/gadgets/docs/tools.html#GGE">Google Gadget Editor</a>. Google gives you 4M to play around with, and the GGE makes it easy to add the gadget to your iGoogle page while you are testing it.</p>
<p>Google’s Gadget framework isn’t picky though – your gadget just needs to be an .xml file with a URL.</p>
<p>The one hitch with hosting it outside of the Google Gadget Editor is how to add it to iGoogle without publishing it to the world. I find the most reliable method is the <a href="http://www.google.com/ig/directory?type=gadgets&amp;url=www.google.com/ig/modules/developer.xml">Gadget Directory page for Google’s “My Gadgets” gadget</a> . Not the gadget itself, whose “Add a gadget” feature inexplicably disappears, but the web page for the gadget, which has a convenient if equally inexplicable text box labeled “Add a gadget”. Works every time.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/MyGadgetsPage.png"><img class="aligncenter size-full wp-image-895" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/MyGadgetsPage.png" alt="" width="585" height="219" /></a></p>
<h2>Edit Settings: Google’s Playground</h2>
<p>As I discovered to my dismay after releasing the Nimbits gadget, you shouldn’t get too attached to the layout of your Edit Settings dialog. The layout is automatically generated by Google’s gadget framework, and you have no control over that layout.</p>
<p>Google can, and will, change that layout without warning or explanation. Other developers have experienced hidden settings that pop suddenly into view, and deleted settings that refuse to go away.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/EditSettings.png"><img class="aligncenter size-full wp-image-888" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/EditSettings.png" alt="" width="720" height="440" /></a></p>
<p>So, don’t go overboard with the options.</p>
<h2>Debugging your JavaScript</h2>
<p>For years and years, I heard web developers raving about Firefox’s <a href="http://getfirebug.com/">Firebug</a> plug-in without fully appreciating what they were raving about. Actually, I still don’t. But I can now say I’ve used it.</p>
<p>You’ll definitely need FireBug, or a JavaScript console of some sort ,when debugging your gadget. The console is used for catching errors in your JavaScript (it will report both the error and line number it occurred at), and for logging debug information using the JavaScript console.log() function.</p>
<p>I’ve left some console.log() calls in my gadget code because they are a handy way of seeing how the underlying REST API is being called. In the screenshot below, you can see the call being made to the Nimbits CurrentValue API, the JSON-formatted response a few lines later, and the call to the Nimbits Chart API at the bottom. (The console output also contains an error logged by an, ahem, “<a href="http://www.google.com/ig/directory?type=gadgets&amp;url=apps.pachube.com/google_gadget/gadget.xml">competing product</a>”. Just kidding – <a href="http://www.pachube.com">Pachube</a>’s great too, and I’m sure their request wasn’t <em>that</em> bad!)</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/06/JavaConsole.png"><img class="aligncenter size-full wp-image-896" title="" src="http://www.gigamegablog.com/wp-content/uploads/2011/06/JavaConsole.png" alt="" width="1001" height="206" /></a></p>
<p>Actually, FireBug’s functionality is so indispensible that Chrome and Internet Explorer have built similar features right into the browser. Having this built-in Javascript console leads to another common pitfall: don’t assume that a call to console.log() is going to work for other users, who might be running an older or non-mainstream browser. To ensure that console.log() won’t cause the script to fail, you can add the following to the JavaScript (I took the code from <a href="http://alvinabad.wordpress.com/2009/03/05/firebug-consolelogger/">Alvin Abad&#8217;s blog</a>.)</p>
<pre class="brush: jscript; title: ; notranslate">
if (typeof console == 'undefined') {
    var console = {};
    console.log = function(msg) {
        return;
    };
}
</pre>
<h1>Wrapping It Up</h1>
<p>As mentioned in the introduction to this article, I’m not terribly impressed with Google’s Gadget framework.</p>
<p>I like the fact that it’s a small set of tools with a relatively shallow learning curve. However, the simplicity of the framework becomes a weakness when you inevitably bump up against some limitation that has no apparent coding workaround.</p>
<p>The documentation is so-so, which is admittedly a notch above the average web development platform’s documentation.</p>
<p>As someone who has been a user of iGoogle on a daily basis for many years, I’m a little alarmed to see how the sausage is made. I can’t shake the feeling that Google has lost interest in moving the platform forward. There haven’t been any significant changes to the API or user interface in a couple of years, and they haven’t bothered to expand, or even clean up, their documentation.</p>
<p>Google Gadgets are a fun place to visit, but I wouldn’t want to make a living there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/06/02/a-nimbits-gadget-programmer%e2%80%99s-show-and-tell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netduino: A Little Help From Its Friends</title>
		<link>http://www.gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/</link>
		<comments>http://www.gigamegablog.com/2011/04/23/netduino-a-little-help-from-its-friends/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 17:52:02 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Netduino]]></category>

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

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

