<?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</title>
	<atom:link href="http://www.gigamegablog.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gigamegablog.com</link>
	<description>Powered by GigaMegaWatts</description>
	<lastBuildDate>Mon, 13 Feb 2012 02:14:00 +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 Linux 101: Assigning a Static IP Address with Connman</title>
		<link>http://www.gigamegablog.com/2012/02/06/beaglebone-linux-101-assigning-a-static-ip-address-with-connman/</link>
		<comments>http://www.gigamegablog.com/2012/02/06/beaglebone-linux-101-assigning-a-static-ip-address-with-connman/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 00:10:43 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Beaglebone]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.gigamegablog.com/?p=1160</guid>
		<description><![CDATA[My article on configuring Angstrom Linux included instructions for setting a static IP address. Sometime after posting that article, I realized that the instructions work great unless you happen to reboot. Then, the settings reverted to the default of using &#8230; <a href="http://www.gigamegablog.com/2012/02/06/beaglebone-linux-101-assigning-a-static-ip-address-with-connman/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://www.gigamegablog.com/2012/01/29/beaglebone-linux-101-configuring-angstrom-linux/">article on configuring Angstrom Linux</a> included instructions for setting a static IP address. Sometime after posting that article, I realized that the instructions work great unless you happen to reboot. Then, the settings reverted to the default of using a DHCP server.</p>
<p>Ooops!</p>
<p>It turns out that this sleight-of-hand is the work, aptly enough, of a package named <a href="http://connman.net/">Connman</a>.</p>
<p>This newfangled connection manager is, in some ways, a good fit for the Beaglebone, since it was designed to run on memory-constrained embedded Linux systems. It was originally developed for use on 2 Linux platforms that have struggled, Meego and Moblin, but we won&#8217;t hold that against it.</p>
<p>However, Connman presents one big problem for Beaglebone users: it&#8217;s rather difficult to configure from the command line.</p>
<p>It doesn&#8217;t come with a command line configuration tool, but it does provide some well documented APIs that command line applications can use. As such, the best command line interface right now can be found in a package intended to test that the APIs are working correctly: <em>connman-tests</em>.</p>
<p>To install the package:</p>
<pre>opkg install connman-tests</pre>
<p>This will install a set of Python scripts in <em>/usr/lib/connman/test</em>.</p>
<p>To check your current configuration:</p>
<pre>cd /usr/lib/connman/test/
./get-services</pre>
<p>The output should look like the following:</p>
<pre>[ /net/connman/service/<strong>ethernet_405fc276b749_cable</strong> ]
 IPv6.Configuration = { Method=auto Privacy=disabled }
 AutoConnect = false
 Proxy.Configuration = { }
 Name = Wired
 Nameservers = [ 206.47.244.104 206.47.199.155 ]
 Provider = { }
 Favorite = true
 Domains.Configuration = [ ]
 State = online
 Proxy = { Method=direct }
 Nameservers.Configuration = [ ]
 LoginRequired = 0
 IPv6 = { }
 Domains = [ lan ]
 Ethernet = { Interface=eth0 MTU=1500 Method=auto 
Address=xx:xx:xx:xx:xx:xx }
 Security = [ ]
 IPv4.Configuration = { Method=dhcp }
 Type = ethernet
 Immutable = false
 IPv4 = { Netmask=255.255.255.0 Gateway=192.168.1.1 
Method=dhcp Address=192.168.1.161 }</pre>
<p>The important thing to note here is the service ID at the top of the output, in my case  <em>ethernet_405fc276b749_cable</em>.  (Dumb name for an ethernet cable, if you ask me.)</p>
<p>You can also get the DNS nameserver and gateway IP addresses from this output, if you don&#8217;t already know them.</p>
<p>To change the configuration, you use 2 other scripts, <em>set-ipv4-method</em> and <em>set-nameservers.</em></p>
<p>The syntax for set-ipv4-method is:</p>
<pre>./set-ipv4-method &lt;service&gt; [off|dhcp|manual &lt;address&gt; [netmask] [gateway]]</pre>
<p>The <em>service</em> parm is that long string that appears at the top of the output from the <em>get-services</em> script.</p>
<p>So, to set the Beaglebone to use a static IP address of 192.168.1.2, with a gateway of 192.168.1.1, I entered:</p>
<pre>./set-ipv4-method ethernet_405fc276b749_cable manual 
192.168.1.2 255.255.255.0 192.168.1.1</pre>
<p>To set the DNS nameservers, use <em>set-nameservers. </em> The syntax is:</p>
<pre>./set-nameservers &lt;service&gt; [nameserver*]</pre>
<p>In my case, I entered</p>
<pre>./set-nameservers ethernet_405fc276b749_cable 206.47.244.104 
206.47.199.155</pre>
<p>That&#8217;s it: after entering those 2 commands, you&#8217;ll be running with the new network settings, no reboot required. (Though, if you plan to blog about it, a reboot is definitely recommended!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2012/02/06/beaglebone-linux-101-assigning-a-static-ip-address-with-connman/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Beaglebone Linux 101: Configuring Angstrom Linux</title>
		<link>http://www.gigamegablog.com/2012/01/29/beaglebone-linux-101-configuring-angstrom-linux/</link>
		<comments>http://www.gigamegablog.com/2012/01/29/beaglebone-linux-101-configuring-angstrom-linux/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 00:01:46 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Beagleboard]]></category>
		<category><![CDATA[Beaglebone]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.gigamegablog.com/?p=1126</guid>
		<description><![CDATA[My previous two articles about the Beaglebone (here and  here) focused on using it as a development platform for handling Arduino-like tasks: interacting with digital, analog and serial devices. In this article I&#8217;m going to cover the basics of using &#8230; <a href="http://www.gigamegablog.com/2012/01/29/beaglebone-linux-101-configuring-angstrom-linux/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My previous two articles about the <a href="http://beagleboard.org/bone">Beaglebone</a> (<a href="http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/">here </a>and  <a href="http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/">here</a>) focused on using it as a development platform for handling Arduino-like tasks: interacting with digital, analog and serial devices.</p>
<p>In this article I&#8217;m going to cover the basics of using the Beaglebone in a different but complementary role: as a network-connected Linux computer.</p>
<p>If you&#8217;re not already familiar with Linux you might be tempted to ignore this aspect of the Beaglebone &#8212; once you&#8217;ve figured out how to copy programs onto the Beaglebone and run them,  you&#8217;re good to go.  However,  by doing some basic Linux configuration you can open up a lot of extra functionality, such as editing files on the Beaglebone directly from your desktop PC, or making the Beaglebone command line more user friendly.</p>
<p>I&#8217;m going to focus on the <a href="http://www.angstrom-distribution.org/">Angstrom Linux</a> distribution that is included in the microSD card packaged with each Beaglebone. Angstrom is not as widely used as other flavours of Linux, like Ubuntu or Fedora. This can be a frustrating to newcomers, since you&#8217;re less likely to figure out how to do things by Googling for the answer. However, Angstrom is well suited to a memory and storage-constrained platform like the Beaglebone, being bloat-free and able to squeeze out more performance from the ARM processor.</p>
<p>I should also mention off the top that I&#8217;m not going to show you how to run a spreadsheet, browser or any other GUI applications on the Beaglebone. That <em>is</em> possible, even without a cape that has a video port (by using VNC), but I think you&#8217;re likely to be disappointed. The Beaglebone&#8217;s memory and CPU constraints will cause a GUI system to be annoyingly slugglish . Think of it more as an Arduino on steroids, not a poor man&#8217;s PC.</p>
<h2>Configuring a terminal on Windows</h2>
<p>(Sorry Mac and Linux users &#8211; the first couple of sections are Windows-centric.)</p>
<p>Whether you connect to the Beaglebone via USB or over the network using SSH, the best terminal software to use on Windows is PuTTY.</p>
<p>You might be scared off after a glimpse of <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY&#8217;s plain Jane website</a> – it looks like a relic from the early days of the Internet. Trust me, though: PuTTY is the way to go. Unlike other Windows terminal programs, it &#8220;gets&#8221; Linux. It may not be the best all-around terminal program, but it’s the best Windows client for a Linux server.</p>
<p>PuTTY is bristling with options, but for the most part the default settings are fine.  When the Beaglebone is connected via USB, select Serial, fill in the COM port ID, and change the Speed to 115200.  When connecting over the network, select SSH and fill in the IP address.  You should also fill in a  name in the Saved Sessions textbox and click Save.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-55-51-PM.jpg"><img class="aligncenter size-full wp-image-1134" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-55-51-PM.jpg" alt="" width="461" height="446" /></a></p>
<p>With the default settings, you&#8217;ll find that some keys don&#8217;t work as expected.  For example, neither Home nor End will work when editing the command line.  To fix this, under Connection &#8211;&gt; Data, change the Terminal-type from the default of xterm to linux.</p>
<p>While you are in this window, you can also fill in a default username for logins. (Which, come to think of it, must be &#8220;root&#8221;, since you haven&#8217;t read the &#8220;Creating a user&#8221; section yet).</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-38-11-PM.jpg"><img class="aligncenter size-full wp-image-1133" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-38-11-PM.jpg" alt="" width="461" height="445" /></a></p>
<p>One other less-than-obvious thing about PuTTY is the way it handles copy-and-paste: Ctrl-C and Ctrl-V won&#8217;t work.  Instead, any text you highlight on the terminal is automatically copied to the Windows clipboard, and Shift-Insert is the shortcut for Paste.</p>
<h2>Transferring and editing files from Windows</h2>
<p>The other important piece of software you should install on Windows is something to  transfer files to the Beaglebone. If you aren&#8217;t yet comfortable with using Linux command line editors, then this tool is vital, since you are going to need to edit some files below.</p>
<p>For this, you&#8217;ll need to access the Beaglebone over the network (i.e. not a COM port), and use a Windows program called <a href="http://winscp.net/eng/index.php">WinSCP</a>.  The only default setting you&#8217;ll have to change is the File Protocol: the Angstrom demo image&#8217;s SSH server, Dropbear, doesn&#8217;t support SFTP.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-42-46-PM.jpg"><img class="aligncenter size-full wp-image-1132" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-42-46-PM.jpg" alt="" width="519" height="369" /></a></p>
<p>You can use WinSCP to transfer files back and forth between Windows and the Beaglebone but, more importantly, you can also use it to edit files directly on the Beaglebone, safely from the comfort of your Windows desktop.</p>
<p>I know, I know, eventually you&#8217;ll want to cut the Windows apronstrings and learn to Esc-Alt-whatever in a command line editor. But having GUI training wheels will save you a lot of frustration as you get started</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-51-46-PM.jpg"><img class="aligncenter size-full wp-image-1131" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-28-2012-9-51-46-PM.jpg" alt="" width="993" height="503" /></a></p>
<h2>Creating a user</h2>
<p>Angstrom Linux initially contains just a root user. I suspect a lot of people like it that way – root is God, so why bother running as a mere mortal instead? I would actually agree: since you&#8217;re almost certainly using it as a single user development platform, go crazy, have fun, be root.</p>
<p>However, if your Beaglebone is going to be accessible from a network, and especially if it&#8217;s going to be accessible over the Internet, disabling the root login is a wise security precaution: having to guess the user-ID makes the Beaglebone much harder to crack.</p>
<p>(Needless to say, if you aren’t going to disable root logins, then for-the-love-of-God give the root user-ID a password!)</p>
<p>My own approach is to login with my user-ID, then switch to root when needed (generally about 10 seconds after logging in, admittedly).</p>
<p>To create a new user-ID, johndoe:</p>
<pre><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">beaglebone:~#</span></span></span><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">useradd johndoe</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">beaglebone:~# passwd johndoe</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">Enter new UNIX password:</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">Retype new UNIX password:</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">passwd: password updated successfully</span></span></span></pre>
<p>To give the root user a password:</p>
<pre><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">beaglebone:~# passwd</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">Enter new UNIX password:</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">Retype new UNIX password:</span></span></span>
<span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">passwd: password updated successfully</span></span></span></pre>
<h2>Switching to root</h2>
<p>So you&#8217;ve logged in as an ordinary user, and have quickly discovered that you need to be root to actually do anything, including pretty much all of the steps below. To switch to root</p>
<pre>beaglebone:~$ su</pre>
<p>The password you enter is the root password, not the user&#8217;s. This ain&#8217;t Ubuntu, son.</p>
<p>If you find that you prefer Ubuntu&#8217;s way of doing things, you can install the sudo package:</p>
<pre>beaglebone:~# opkg install sudo</pre>
<p>I think this is well worth doing, if only for the comedy element.  <em>sudo</em> is the most uptight piece of software that I&#8217;ve come across.   The first time you use <em>sudo</em>, you&#8217;ll get a bossy warning:</p>
<pre>We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.</pre>
<p>After you enter your password, <em>sudo</em> will shriek and run off to tell on you:</p>
<pre>johndoe is not in the sudoers file.  This incident will be reported.</pre>
<p>To fix this, you don&#8217;t directly edit the /etc/sudoers file &#8212; oh no, that would be too easy.  Instead, you (logged in as root, of course) run <em>visudoer</em>, which forces you to grapple with the notorious vi editor.</p>
<p>If you haven&#8217;t lost your nerve yet, you can add your user-ID to the User Privilege section:</p>
<pre>##
## User privilege specification
##
root ALL=(ALL) ALL
johndoe ALL=(ALL) ALL</pre>
<p>I suspect that the creator of sudo would have a conniption if he saw you make such a crude change (the rules governing sudoer configuration are rather elaborate), but what do you have to lose: your actions have already been reported.</p>
<h2>Disabling root SSH login</h2>
<p>This step is optional, especially if your Beaglebone isn&#8217;t accessible from the Internet.  In fact, if you&#8217;re using WinSCP to edit system files then <em>don&#8217;t</em> disable the root login &#8211; you can&#8217;t switch to root from within WinSCP.</p>
<p>If you still want to do it, you can disable root login by specifying the &#8220;-w&#8221; command line parm when running the SSH server, <a href="http://matt.ucc.asn.au/dropbear/dropbear.html">Dropbear</a>.</p>
<p>Ordinarily, Dropbear configuration is done by setting options in file /etc/default/dropbear.  This used to work in Angstrom.  However, they&#8217;ve recently switched to launching Dropbear in a way that doesn&#8217;t use any configuration file.</p>
<p>As far as I know, the only way to change the dropbear configuration now is to edit the ExecStart line in a well-hidden file: /lib/systemd/system/dropbear@.service:</p>
<pre>beaglebone:/lib/systemd/system$ cat dropbear@.service
[Unit]
Description=SSH Per-Connection Server
Requires=dropbearkey.service
After=syslog.target dropbearkey.service
[Service]
ExecStart=-/usr/sbin/dropbear -i -r /etc/dropbear/dropbear_rsa_host_key -p 22<strong><span style="color: #000000;"> -w</span></strong>
ExecReload=/bin/kill -HUP $MAINPID
StandardInput=socket</pre>
<p>Note the &#8220;-w&#8221; at the end of the ExecStart line &#8211; I added that to disable the root login.</p>
<p>To restart Dropbear, you still reference the old (but ultimately unused) init.d script:</p>
<pre>/etc/init.d/dropbear restart</pre>
<h2>Changing the host name</h2>
<p>This is purely optional, unless you have multiple Beaglebones, but it&#8217;s an easy way to personalize things:</p>
<p>Edit /etc/hostname and change <em>beaglebone</em> to your new host name.</p>
<p>Then, edit /etc/hosts and make the same change there. Leave the rest of the file as is: it should look something like this when are done, with <em>yourhostname</em> being replaced with – yeah, you got it:</p>
<pre>cat /etc/hosts
127.0.0.1 localhost.localdomain localhost
127.0.0.1 yourhostname</pre>
<p>Your command line prompt won&#8217;t display your shiny new device name until you reboot:</p>
<pre>shutdown –r now</pre>
<h2>Using a static IP address</h2>
<p><em>Updated 2/6/12: The instructions in this section don&#8217;t work when using Connman to handle network connections (which is the default for Angstrom Linux on the Beaglebone) &#8212; it will revert to using DHCP after rebooting.  See <a href="http://www.gigamegablog.com/2012/02/06/beaglebone-linux-101-assigning-a-static-ip-address-with-connman/">Beaglebone Linux 101: Assigning a Static IP Address with Connman</a>)</em></p>
<p>This step is also optional, if you have a DHCP server and don&#8217;t mind using its choice of IP address. Unlike the Beagleboard XM, the Ethernet adapter on the Beaglebone always uses the same MAC address, which means that the IP address assigned by the DHCP server won&#8217;t change each time you boot.</p>
<p>Setting a static IP  address requires editing <em>/etc/network/interfaces</em>.  The default version of this file in the Angstrom demo image looks like this:</p>
<pre>beaglebone:~$ cat /etc/network/interfaces
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
# The loopback interface
auto lo
iface lo inet loopback
# Wireless interfaces
iface wlan0 inet dhcp
wireless_mode managed
wireless_essid any
wpa-driver wext
wpa-conf /etc/wpa_supplicant.conf
iface atml0 inet dhcp
# Wired or wireless interfaces
auto eth0
<strong>iface eth0 inet dhcp</strong>
iface eth1 inet dhcp
# Ethernet/RNDIS gadget (g_ether)
# ... or on host side, usbnet and random hwaddr
iface usb0 inet static
address 192.168.7.2
netmask 255.255.255.0
network 192.168.7.0
gateway 192.168.7.1
# Bluetooth networking
iface bnep0 inet dhcp</pre>
<p>You need to replace the &#8220;iface eth0 inet dhcp&#8221; line with hard-coded settings for your IP address, gateway, and DNS servers. (Oh, and you might want to do it while connected to the Beaglebone via the USB cable, rather than Ethernet, in case you mess things up).</p>
<p>Comment out the &#8221;iface eth0 inet dhcp&#8221; line and add new lines with the correct IP addresses in the address, gateway, and dns-nameservers address (don&#8217;t just copy mine &#8211; that&#8217;s cheating):</p>
<pre>#iface eth0 inet dhcp
iface eth0 inet static
<strong>address 192.168.1.2</strong>
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
<strong>gateway 192.168.1.1</strong>
<strong>dns-nameservers 192.168.1.1</strong></pre>
<p>To test your settings, cross your fingers and enter:</p>
<pre>/etc/init.d/networking restart</pre>
<p>Then check to see that you have the new IP address:</p>
<pre>ifconfig eth0</pre>
<p>and gateway…</p>
<pre>netstat –nr</pre>
<p>and DNS server:</p>
<pre> 
cat/etc/resolv.conf</pre>
<p>Ha, were you worried? Me neither!</p>
<h2>Setting the time zone</h2>
<p>You probably noticed shortly after connecting your Beaglebone to the Internet that it  automatically figured out the date and time, sort of: everything except the time zone.</p>
<p>The demo image includes a &#8220;cron&#8221; job that uses NTP to get the correct date and time. You can see this by entering:</p>
<pre>crontab -l
30 * * * * /usr/bin/ntpdate -b -s -u pool.ntp.org</pre>
<p>Every 30 minutes, it will run the ntpdate command to update the system date and time.</p>
<p>The system determines the time zone using a file called /etc/localtime. Don&#8217;t try editing this file – instead, you point it at the correct time zone under /usr/share/zoneinfo. To see what&#8217;s available:</p>
<pre> ls -lr /usr/share/zoneinfo/</pre>
<p>These files in the zoneinfo directory are installed by package tzdata.</p>
<p>Don&#8217;t feel bad if they don&#8217;t include your town – they missed mine too. However, you should be able to find your time zone, or another city in it. For me, I set the timezone by entering:</p>
<pre>rm /etc/localtime
ln -s /usr/share/zoneinfo/America/New_York /etc/localtime</pre>
<p>Note that &#8220;ln -s&#8221; creates a pointer to an existing file &#8211; make sure you get the parms in the right order.</p>
<p>Reboot to update the system time.</p>
<h2>Updating packages</h2>
<p>If you haven&#8217;t updated the Linux packages on your Beaglebone before, and you&#8217;re using one of the early Angstrom images (the original 11-16-11 image, or the 12-26-11 image) you&#8217;re in for a treat. A movie, perhaps, or dinner, or a long romantic walk on the moonlight. As long as it takes an hour or two, cause the first package update is sloooooow.</p>
<p>I don&#8217;t know why, but there has been a steady stream of package updates released since the Beaglebone came out. Usually, Angstrom is a &#8220;sleepier&#8221; distribution – just the occasional bug fix or security update. I&#8217;m guessing that package development for the Beaglebone is more active because the platform is new, and package updates will become less frequent over time.</p>
<p>The basics of updating packages is to remember 2 commands:</p>
<pre>Opkg update
Opkg upgrade</pre>
<p>The first updates your local copy of the list of available packages, and the second does the updating. It&#8217;s all automated – you shouldn&#8217;t see any prompts, so no need to stand around watching it go&#8230; and go &#8230;.</p>
<p>.. phew, done! After the first batch of updates, it&#8217;s a good idea to reboot.</p>
<p>After awhile, the &#8220;opkg upgrade&#8221; will begin to mutter complaints when it&#8217;s done – stuff like:</p>
<pre>Collected errors:
* check_data_file_clashes: Package shadow wants to install file /etc/login.defs
But that file is already provided by package * shadow-sysroot
* check_data_file_clashes: Package shadow wants to install file /etc/login.defs
But that file is already provided by package * shadow-sysroot</pre>
<p>Yada yada yada.  Whatever.</p>
<p>Honestly, you generally don&#8217;t have to do anything to fix the errors – as other packages get updated, the problems get fixed. If they don&#8217;t, there is always Google.</p>
<h2>Installing packages</h2>
<p>The demo image comes with a lot of software, but there are thousands of other packages available. To see everything that is out there, you can enter:</p>
<pre>opkg list</pre>
<p>That&#8217;s a lot of packages! If you have an idea of what you are looking for, use grep to filter the results:</p>
<pre>Opkg list | grep "python"</pre>
<p>To install the package</p>
<pre>Opkg install &lt;packagename&gt;</pre>
<p>If you can&#8217;t find what you want that way, try the online <a href="http://www.angstrom-distribution.org/repo/">Angstrom package browser</a>. It has a more convenient interface, and it&#8217;s possible that the package you&#8217;re looking for isn&#8217;t listed by opkg but can be found on the web site (in the dreaded &#8220;unstable&#8221; branch &#8211; scary!).</p>
<p>For example, my preferred command line editor is <a href="http://www.gnu.org/software/emacs/">Emacs</a>, but that doesn&#8217;t appear in the output of &#8220;opkg list&#8221;.  It is, however, <a href=" http://www.angstrom-distribution.org/repo/?pkgname=emacs">listed in the package browser</a>.</p>
<p>The &#8220;available versions&#8221; section lists 2 options:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-29-2012-3-33-26-PM.jpg"><img class="aligncenter size-full wp-image-1139" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-29-2012-3-33-26-PM.jpg" alt="" width="847" height="351" /></a></p>
<p>The 2 available versions are for the &#8220;Angstrom 2011.03&#8243; release, and the Beaglebone is running a more recent release, currently Angstrom 2012.01.  That&#8217;s why &#8220;opkg list&#8221; didn&#8217;t include emacs.</p>
<p>I don&#8217;t know why emacs isn&#8217;t made available in the new release &#8212; it could be lack of popularity, or a lower priority for conversion and testing, or a horrendous incompatibility with other packages.  However, since emacs is a user app that few other packages make use of, a horrendous incompatibility seems unlikely.  (And I&#8217;ve been running emacs on the Beaglebone for several weeks with no problems).</p>
<p>The Beaglebone is compatible with armv7a packages, so when that platform is available you should select it.  (Packages compiled for earlier versions of ARM processors will generally also run on the Beaglebone, but more slowly)</p>
<p>You can just click on the link to download it, and copy the package over via WinSCP, or use wget to download it directly to the Beaglebone:</p>
<pre> wget <a href="http://www.angstrom-distribution.org/feeds/unstable/ipk/glibc/armv7a/base/emacs_22.3-r1.6_armv7a.ipk">http://www.angstrom-distribution.org/feeds/unstable/ipk/glibc/armv7a/base/emacs_22.3-r1.6_armv7a.ipk</a></pre>
<p>To install it, just specify the filename instead of the package name:</p>
<pre>opkg install emacs_22.3-r1.6_armv7a.ipk</pre>
<p>You&#8217;ll likely find that it complains about a missing dependency file, liblockfile:</p>
<pre>Installing emacs (22.3-r1.6) to root...
Collected errors:
 * satisfy_dependencies_for: Cannot satisfy the following dependencies for emacs:
 * liblockfile (&gt;= 1.06) *
 * opkg_install_cmd: Cannot install package emacs.</pre>
<p>Yada yada yada.  Actually, this one we can fix.</p>
<p>The package browser web page for emacs, above, lists liblockfile as a dependency.  You can click on the link to <a href=" http://www.angstrom-distribution.org/repo/?pkgname=liblockfile">open up the liblockfile page </a>and download it from there, or enter the following to download the dependency and install both packages:</p>
<pre>wget http://www.angstrom-distribution.org/feeds/2011.03/ipk/glibc/armv7a/base/liblockfile_1.06-r1.6_armv7a.ipk
opkg install liblockfile_1.06-r1.6_armv7a.ipk emacs_22.3-r1.6_armv7a.ipk</pre>
<h2>Other useful opkg commands</h2>
<p>To remove a package</p>
<pre><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">opkg remove &lt;packagename&gt;</span></span></span></pre>
<p>To rip a package from the grasp of a protesting opkg (generally because you intend to replace the package with one that provides the same files):</p>
<pre lang="en-US"><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">opkg remove &lt;packagename&gt; --force-removal-of-dependent-packages</span></span></span></pre>
<p>To get more information about a package:</p>
<pre lang="en-US"><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">opkg info packagename</span></span></span></pre>
<p>To get a list of files that are installed by the package:</p>
<pre lang="en-US"><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">opkg files packagename</span></span></span></pre>
<p lang="fr-CA">(Which only works after you&#8217;ve already installed the package - so much for look before you leap!)</p>
<p lang="fr-CA">To find the package that installed a specific file:</p>
<pre lang="fr-CA">opkg search '&lt;path_to_file&gt;'</pre>
<p lang="fr-CA">e.g.</p>
<pre lang="fr-CA">opkg search '/bin/ps.procps'
procps - 3.2.8-r4</pre>
<p lang="fr-CA">The search function supports wildcards:</p>
<pre lang="fr-CA">opkg search '*bash*'</pre>
<h2>Automating package updates</h2>
<p>There are some people, who we&#8217;ll call &#8220;sissies&#8221;, who would argue that automating package updates is dangerous and irresponsible, since the updates might fail and you don&#8217;t want to leave your system in an unstable state.</p>
<p>Others, who we&#8217;ll call &#8220;real men&#8221;, think that the package update process is reliable enough that it rarely requires manual intervention. And, besides, you can always check the logs to detect any problems. It&#8217;s not like you&#8217;re going to forget to check the logs, right?</p>
<p>Personally, I&#8217;m a sissy. I&#8217;m also forgetful, so I&#8217;ve automated opkg anyway. Needless to say, I rarely bother to look at the output logs. (I know what I&#8217;ll find.. &#8220;Collected errors: yada yada yada&#8221;. Whatever.)</p>
<p>If you&#8217;re a real man, you can add a line to the crontab to automatically update your system.</p>
<p><em>[2/2/12: the following script was updated to add error handling]</em></p>
<p>First, create a script to run.  I use the following:</p>
<pre>#!/bin/sh
# runopkg.sh
# Update packages and append output to log file
/usr/bin/opkg update
# opkg update returns 0 if OK, 1 if error
if [ $? = 0 ]; then
    /usr/bin/opkg upgrade &amp;&gt;&gt; /var/log/opkgupgrade.log
    echo "opkg complete rc $?  $(date)" &gt;&gt; /var/log/opkgupgrade.log
else
    echo "ERROR: opkg update returned $?" &gt;&gt; /var/log/opkgupgrade.log
fi</pre>
<p>You can download this file from my site:</p>
<pre>beaglebone:~# wget http://www.gigamegablog.com/docs/runopkg.sh</pre>
<p>&#8230;make it executable&#8230;</p>
<pre>beaglebone:~# chmod u+x runopkg.sh</pre>
<p>&#8230;then add this script to the list of scheduled cron tasks:</p>
<pre>beaglebone:~# crontab -e
30 * * * * /usr/bin/ntpdate -b -s -u pool.ntp.org
33 3 * * * /home/root/runopkg.sh</pre>
<p>By default, the &#8220;crontab -e&#8221; command invokes the vi editor, which you&#8217;ll either love or hate.  Probably hate.</p>
<p>If you stored runopkg.sh in a directory other than the root home folder, be sure to enter the correct path in the crontab line.</p>
<p>The example above runs the update process every day at 3:33 am, and appends both the info and error messages to a log file. It checks the return code after running opkg update. Sometimes it fails to connect to one of the repositories, and it is safest not to do an upgrade with an incomplete list of updates.</p>
<h2>Customizing the command line</h2>
<p>Angstrom provides a standard Bash command line shell without any customizations: no <em>.profile</em> or <em>.bashrc</em> file.</p>
<p>Everybody&#8217;s got their own idea of how to make Bash more useful, but here are some common customizations to get you started.</p>
<p>First, create a file named .profile in  your home directory with the following contents:</p>
<pre># ~/.profile: executed by Bourne-compatible login shells.
if [ -f ~/.bashrc ]; then
 . ~/.bashrc
fi
# path set by /etc/profile
# export PATH
mesg n</pre>
<p>If you like, you can download this file directly from my site. Make sure you store it in your home folder .</p>
<pre>beaglebone:~# wget http://www.gigamegablog.com/docs/.profile</pre>
<p>This is an extremely plain .profile which mainly has one purpose: to activate the .bashrc file.</p>
<p>Next, create a file called .bashrc in your home directory with the following contents:</p>
<pre># ~/.bashrc: executed by bash(1) for non-login shells.
export PS1='\h:\w\$ '
umask 022
# You may uncomment the following lines if you want `ls' to be colorized:
export LS_OPTIONS='--color=auto'
# eval `dircolors`
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

# Some more alias to avoid making mistakes:
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# shell options
# autocorrect cd commands
shopt -s cdspell
# disable Ctrl-D to logout
set -o ignoreeof
# extended pattern matching
shopt -s extglob</pre>
<p>This file can be downloaded from my site &#8211; it should be stored in your home folder:</p>
<pre>beaglebone:~# wget http://www.gigamegablog.com/docs/.bashrc</pre>
<p>This does the following:</p>
<ul>
<li>shortens the command prompt to just your hostname and the current directory</li>
<li>changes the default permissions for new files you create so that they are writable by you, and just readable for everyone else</li>
<li>turns on colors for your &#8220;ls&#8221; output</li>
<li>creates a few shortcuts for common ls options (ll is the most useful, I think)</li>
<li>adds the &#8220;-i&#8221; parm to the copy, move and delete commands, which prompts you for confirmation when you are about to delete or overwrite a file</li>
<li>automatically fixes some typos in directory names</li>
<li>prevents Ctrl-D from dropping your session</li>
<li>enables <a href="http://www.gnu.org/software/bash/manual/bashref.html#Pattern-Matching">extra wildcards for matching files and directories</a></li>
</ul>
<p>By the way, when switching from a regular user to root using the su command, you need to include a hyphen to ensure that the root .profile and .bashrc are used:</p>
<pre>su -</pre>
<h2>Windows networking</h2>
<p>By now, you&#8217;re hopefully starting to look upon your Beaglebone with respect and admiration. You are also probably sick of WinSCP and/or command line editors. Why not welcome your Beaglebone into your Windows network and give it equal standing to your other PCs?</p>
<p>For this, you&#8217;ll need to install Samba.</p>
<pre>opkg install samba</pre>
<p>The correct configuration of Samba is actually quite complicated, or so I would assume since there is an <a href="http://oreilly.com/openbook/samba/book/index.html">entire book on the topic</a> . I haven’t actually read it, so instead I installed a browser-based configuration utility named Swat:</p>
<pre>opkg install xinetd swat</pre>
<p>The <span style="font-family: Georgia, serif; color: #333333;">xinetd utility is the standard way of invoking Swat and many other services that are accessed over the network.  It doesn&#8217;t start the service until it is accessed, which is quite helpful on a memory constrained platform like the Beaglebone.</span></p>
<p lang="en-US">The services are configured by entries in /etc/xinetd.conf or files in /etc/xinet.d, but unfortunately the Swat package currently doesn&#8217;t update either.  So, create a file at <em>/etc/xinetd.d/swat</em>, and paste the following into it:</p>
<pre lang="en-US">service swat
{
   disable = no
   port = 901
   socket_type = stream
   wait = no
   # only_from = localhost
   user = root
   server = /usr/sbin/swat
   log_on_failure += USERID
}</pre>
<p lang="en-US">Note that this configuration uses a port number of 901, allows access to other PCs on the network, and specifies that root is allowed to login.</p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">After changing the xinetd.conf file, you need to restart xinetd:</span></span></p>
<pre lang="en-US"><span style="color: #222222;"><span style="font-family: Courier, monospace;"><span style="font-size: small;">/etc/init.d/xinetd restart</span></span></span></pre>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">You should now be able to open the following address in a browser on another PC: <em>http://&lt;your-beaglebone-ipaddress&gt;:901</em></span></span></p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">Login as root at the prompt.</span></span></p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">The first thing you&#8217;ll want to do is add a user to Samba &#8212; Samba doesn&#8217;t automatically use the same user-IDs and passwords as Linux.  Ideally, you should add a user that has the same user-ID as a Linux user and Windows user, and the same password as the Windows user &#8211; you&#8217;ll have fewer problems with permissions that way.</span></span></p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">Go to the Swat password page and create a user. The interface isn&#8217;t terribly intuitive: fill in the user name and password in the Server Password Management area, then click then &#8220;Add New User&#8221; button.  You&#8217;ll get a subtle confirmation that the user was added, but it doesn&#8217;t display a list of users.</span></span></p>
<p lang="en-US"><img class="aligncenter" src="http://www.gigamegablog.com/wp-content/uploads/2010/12/swat.png" alt="" width="671" height="264" /></p>
<p lang="en-US">Next, click on Shares and add a share for your user&#8217;s home directory.</p>
<p lang="en-US">This step is advisable since, if there isn&#8217;t at least one share that your Windows user-ID is allowed to access, Samba/Windows will keep prompting for your user-ID and password.  If it&#8217;s the first time you are accessing a Samba share, you won&#8217;t know the cause of the problem: the user-ID, the password, or the share.  So, ensure you have access to <em>something</em> by explicitly sharing your user&#8217;s home directory.</p>
<p lang="en-US">The user interface on the Shares page isn&#8217;t very intuitive either: you need to fill in the textbox next to the Create Share button, then click the button</p>
<p lang="en-US"><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-29-2012-5-32-13-PM.jpg"><img class="aligncenter size-full wp-image-1143" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-29-2012-5-32-13-PM.jpg" alt="" width="431" height="351" /></a></p>
<p lang="en-US">Note that, by default, new shares are read-only and are <em>not</em> &#8220;available&#8221;. (Grrrr.)  So, you&#8217;ll need to manually change the &#8220;Available&#8221; setting and Read-only setting then click the Commit Changes button.</p>
<p lang="en-US">(When sharing directories other than your home directory, you may want to leave the Read-only setting on.  If your user-ID doesn&#8217;t have write permissions to the underlying Linux directory, don&#8217;t try to make it a writeable share.  It won&#8217;t work.)</p>
<p lang="en-US"><a href="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-29-2012-5-33-34-PM.jpg"><img class="aligncenter size-full wp-image-1142" title="" src="http://www.gigamegablog.com/wp-content/uploads/2012/01/1-29-2012-5-33-34-PM.jpg" alt="" width="608" height="799" /></a></p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">I’d also suggest you go to the Global page and change the workgroup to whatever your Windows PC uses &#8211; this makes your Beaglebone easily discovered by Windows.</span></span></p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">After saving your changes you shouldn&#8217;t have to manually restart Samba, since it continually scans for configuration changes.  However, I often find that a restart is necessary to get your changes to be recognized by Windows:</span></span></p>
<pre lang="en-US">/etc/init.d/samba restart</pre>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">Now, Windows Explorer should be able to see your Beaglebone in your network, with some shares underneath. </span></span></p>
<p lang="en-US"><span style="color: #333333;"><span style="font-family: Georgia, serif;">If you are prompted for a user-ID and password, use the one you entered into Swat’s password page.  If Windows prompts for a new user-ID and password when accessing a share or file, remember that the Linux permissions come into play &#8211; try changing the Linux  directory permissions to give write access to non-root users.</span></span></p>
<h2 lang="en-US">Wrapping Up</h2>
<p lang="en-US">There&#8217;s been some debate in the <a href="http://groups.google.com/group/beagleboard">Beagleboard Google Group</a> about whether it makes sense to have a separate group for the Beaglebone.</p>
<p lang="en-US">IMHO, no.  While the Beaglebone is quite different as an electronics hobbyist platform, it&#8217;s almost completely identical to the Beagleboard when it comes to Linux configuration.  All of the steps I covered in this article also apply to the Beagleboard.</p>
<p lang="en-US">So, when looking for Linux tips and solutions, don&#8217;t ignore postings targeted at the Beagleboard.</p>
<p lang="en-US">Furthermore, while Angstrom has its differences from other Linux distributions, the most commonly used software is the same or very similar.  Dropbear is largely the same as <a href="http://www.openssh.com/">OpenSSH</a>, Busybox is largely the same as the <a href="http://www.gnu.org/software/coreutils/">core GNU utilities</a>, and Angstrom Bash is <a href="http://www.gnu.org/software/bash/">Bash</a>.  Don&#8217;t be discouraged by the lack of documentation on Angstrom or some its utilities.  There&#8217;s a wealth of information out there on SSH, GNU and Bash, and you&#8217;ll find that most of it applies to Angstrom.</p>
<p lang="en-US">The stuff that doesn&#8217;t apply? Ignore it.  Wouldn&#8217;t you rather be coding than reading, anyway?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2012/01/29/beaglebone-linux-101-configuring-angstrom-linux/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<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><em><span style="color: #000000;">[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></em></p>
<p><span style="color: #000000;">This article is my second explaining the fundamentals of coding with the <a href="http://beagleboard.org/bone"><span style="color: #000000;">Beaglebone</span></a>. In the <a href="http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/"><span style="color: #000000;">first article</span></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.</span></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 />
<em><span style="color: #000000;">[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></em></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: #000000;"><em>Added Jan 25: Use Port 9 Pin 32 as your voltage source, if your analog sensor can work on 1.8V</em></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><em><span style="color: #000000;">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></em></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-pyserial. To install it:</p>
<pre>root@beaglebone:~# opkg install python-pyserial</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>22</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>17</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>2</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>BeagleBoard XM and Ubuntu 11.04 – The Big Dog Still Has a Burr in its Paw</title>
		<link>http://www.gigamegablog.com/2011/08/20/beagleboard-xm-and-ubuntu-11-04-%e2%80%93-the-big-dog-still-has-a-burr-in-its-paw/</link>
		<comments>http://www.gigamegablog.com/2011/08/20/beagleboard-xm-and-ubuntu-11-04-%e2%80%93-the-big-dog-still-has-a-burr-in-its-paw/#comments</comments>
		<pubDate>Sat, 20 Aug 2011 15:07:21 +0000</pubDate>
		<dc:creator>dwatts</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Beagleboard]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://gigamegatech.com/?p=958</guid>
		<description><![CDATA[As I wrote back in December, I switched from running Ubuntu 10.10 to Angstrom on my Beagleboard XM because I was unhappy with Ubuntu&#8217;s speed.  Some of Ubuntu&#8217;s code isn&#8217;t ready for the XM&#8217;s 1 gigahertz processor, so the processor &#8230; <a href="http://www.gigamegablog.com/2011/08/20/beagleboard-xm-and-ubuntu-11-04-%e2%80%93-the-big-dog-still-has-a-burr-in-its-paw/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As I wrote <a href="http://gigamegablog.com/2010/12/09/beagleboard-xm-and-angstrom-getting-the-big-dog-to-run-at-full-speed/">back in December</a>, I switched from running <a href="http://www.ubuntu.com/">Ubuntu </a>10.10 to <a href="http://www.angstrom-distribution.org/">Angstrom</a> on my <a href="http://beagleboard.org/hardware-xM">Beagleboard XM</a> because I was unhappy with Ubuntu&#8217;s speed.  Some of Ubuntu&#8217;s code isn&#8217;t ready for the XM&#8217;s 1 gigahertz processor, so the processor is automatically throttled back to 800 Mhz during Ubuntu&#8217;s bootup.  To make matters worse, Ubuntu&#8217;s code is compiled with cross-platform compatibility in mind, and therefore lacks some optimizations that would take advantage of the XM&#8217;s more advanced OMAP processor.</p>
<p style="text-align: center;"><a href="http://www.beagleboard.org"><img class="aligncenter size-full wp-image-467" src="http://www.gigamegablog.comhttp://www.gigamegablog.com/wp-content/uploads/2010/12/beagle-hd-logo.gif" alt="" width="301" height="53" /></a></p>
<p>I&#8217;ve been pretty happy with Angstrom – it has proven to be fast, stable and low maintenance.  When Ubuntu&#8217;s Natty Narwal release arrived in April, I didn’t jump at the chance to try it.  However, when I finally got around to checking it out, something in the <a href="https://wiki.ubuntu.com/ARM/NattyReleaseNotes">release notes</a> caught my eye:</p>
<p><em>OMAP3 CPUs don&#8217;t run at full speed by default. While we set the required mpurate cmdline parameter on our images, the values for the different OMAP3 CPUs are not always correct, to work around this you can edit the cmdline in /boot/boot.script and call &#8220;sudo flash-kernel&#8221;, the change will take effect on next reboot. This should only affect BeagleXM users</em></p>
<p>Ah, now you tell me!  It was all a misunderstanding – just a typo in the boot parameters.  Ubuntu baby, here I come. Nice knowing ya, Angstrom.</p>
<p>Alas, it was not to be.  Ubuntu 11.04 is no faster on the XM than Ubuntu 10.10 was.  The release notes actually refer to the fact that, by default, the processor is now throttled back to 600 Mhz (!), but you can change the boot parameters to lift it back to 800 Mhz.</p>
<p>However, Ubuntu does have some nice new features that Angstrom lacks, and I came across a couple of not-so-nice &#8220;features&#8221; that might trip up others who try out Ubuntu on the Beagleboard XM.  So, here&#8217;s the full story of getting Ubuntu 11.04 up and <del>running</del> loping.</p>
<h2>Preparing the Boot Image</h2>
<p>One of the new features in Ubuntu 11.04 is that the <a href="https://wiki.ubuntu.com/ARM/OMAP">official images from Canonical Inc</a>. include a version intended for &#8220;headless&#8221; configurations: where you intend to use the Beagleboard as a server with no monitor or keyboard.</p>
<p>Unlike other Linux images for the Beagleboard, Canonical&#8217;s images automatically run an installation program the first time you boot.  In Ubuntu 10.10 and earlier this install program required a physically connected monitor: now there is a text version that can be run in a serial terminal program like <a href="http://www.winputty.com/">WinPutty</a>.</p>
<p>An alternative (and the method I used when installing earlier Ubuntu releases) is <a href="http://elinux.org/BeagleBoardUbuntu#Demo_Image">Robert Nelson&#8217;s preconfigured &#8220;demo&#8221; Ubuntu image</a>.</p>
<p>A short digression… If I was going to install Ubuntu 11.04 again, I would actually go with Robert Nelson&#8217;s version over Canonical&#8217;s.  He updates the image quite often (and it now sports the shiny new version 3.0 Linux kernel – still no 1 Ghz support <img src='http://www.gigamegablog.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />   ).  Canonical&#8217;s image is now a few months out of date, and the first time you update the packages to their latest version you&#8217;ll get 100s of megabytes of data that take hours (no exaggeration) to install.</p>
<p>If you decide to use Robert Nelson&#8217;s image, then you can skip ahead to the &#8220;Getting on the Network&#8221; section.</p>
<p><a href="https://wiki.ubuntu.com/ARM/OMAPHeadlessInstall">Canonical&#8217;s instructions</a> for downloading their image and copying it to the microSD card are a little confusing, since you get directed to a download page that includes builds for all the processors they support.</p>
<p>The correct file for the Beagleboard (both XM and earlier) is this one: <a href="http://cdimage.ubuntu.com/releases/11.04/release/ubuntu-11.04-preinstalled-headless-armel+omap.img.gz">http://cdimage.ubuntu.com/releases/11.04/release/ubuntu-11.04-preinstalled-headless-armel+omap.img.gz</a>.  It&#8217;s a 204M file.</p>
<p>You&#8217;ll also need to download the updated kernel for the XM from  <a href="http://people.canonical.com/~tobin/natty/beagleXM-natty.tgz">http://people.canonical.com/~tobin/natty/beagleXM-natty.tgz</a></p>
<p>Windows users will probably need to find a way to use Linux in order to configure the microSD card. <a href="https://wiki.ubuntu.com/ARM/OmapNetbook"> Canonical&#8217;s  install instructions</a> for their oddly-named &#8221;Netbook&#8221; image – the one you would use if you have a monitor, mouse and keyboard connected to your Beagleboard – mentions that a Windows package like <a href="https://launchpad.net/win32-image-writer">Image Writer</a>  can be used to write the .img file to the microSD card.  True enough,  but then you&#8217;ll have to figure out how to mount the ext3 partition on the card to transfer over the kernel patch.  Personally, I used <a href="http://www.vmware.com/products/player/">VMPlayer</a> running the PC version of Ubuntu.</p>
<p>As usual, you&#8217;ll need to know what the device name of your card is before you start.  Generally, the best method is to run &#8220;dmesg&#8221; immediately after connecting the microSD card to the PC – the messages at the end of the output will identify the device name.  In my case, it was /dev/sde.</p>
<p>To copy the Ubuntu download to the microSD card:</p>
<pre>dwatts@ubuntu:~$ sudo umount /dev/sde?
dwatts@ubuntu:~$ gunzip -c ubuntu-11.04-preinstalled-headless-armel+omap.img.gz
 | sudo dd bs=4M of=/dev/sde
0+48794 records in
0+48794 records out
1675173888 bytes (1.7 GB) copied, 310.701 s, 5.4 MB/s
dwatts@ubuntu:/mnt/hgfs/download/Beagleboard$ sync</pre>
<p>You&#8217;ll also need to install the updated kernel for the XM, as described at the bottom of the <a href="https://wiki.ubuntu.com/ARM/OMAPHeadlessInstall">install instructions</a>.</p>
<p>The quickest way to mount the 2 partitions on the microSD card is to remove the card are reconnect it, Ubuntu &#8211; and most other OSes &#8212; will automatically mount them.  Otherwise:</p>
<pre>dwatts@ubuntu: sudo mkdir /media/boot
dwatts@ubuntu: sudo mkdir /media/ubuntu
dwatts@ubuntu: sudo mount –t vfat /dev/sde1 /media/boot
dwatts@ubuntu: sudo mount /dev/sde2 /media/ubuntu</pre>
<p>Then extract and copy over the 2 files.  Note that the 2<sup>nd</sup> file should be copied as root</p>
<pre>dwatts@ubuntu: tar -zxf beagleXM-natty.tgz
dwatts@ubuntu: cp uImage /media/boot
dwatts@ubuntu: sudo cp vmlinuz-2.6.38-8-omap /media/ubuntu/boot
dwatts@ubuntu: sync
dwatts@ubuntu: sudo umount /dev/sde?</pre>
<h2>Booting Ubuntu</h2>
<p>As mentioned earlier, the first boot will automatically launch an install program.  You can&#8217;t bypass it, and you can&#8217;t connect to the Beagleboard over a network until the installer completes.  So, if you don&#8217;t have a monitor physically connected to the Beagleboard, you&#8217;ll need to connect a PC to its serial port.</p>
<p>A USB-serial adapter should work well.  Mine is a generic brand that, when inserted into Windows, loads the common <a href="http://www.prolific.com.tw/eng/downloads.asp?id=31">&#8220;Prolific&#8221; driver</a>.</p>
<p>I used <a href="http://www.winputty.com/">WinPutty</a> as the serial terminal.</p>
<p>The serial settings are 115200 bps, N-8-1 with no Flow Control.  In order for the pseudo-graphics in the Canonical installer to appear correctly, you&#8217;ll need to change the character set from the default of Latin-1 to UTF8, as shown below:</p>
<p style="text-align: center;"><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-20-41-39.jpg"><img class="aligncenter size-full wp-image-975" title="WinPutty character set for Ubuntu installer" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-20-41-39.jpg" alt="" width="451" height="439" /></a></p>
<p>In its full glory, the install program looks like this.  The lovely magenta background is, as far as I know, a design choice, not a bug:</p>
<p style="text-align: center;"><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/20-08-2011-11-17-28-AM.jpg"><img class="aligncenter size-full wp-image-980" title="Ubuntu's character-based installer. Purdy, ain't it?" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/20-08-2011-11-17-28-AM.jpg" alt="" width="831" height="469" /></a></p>
<p>The installer lets you enter the a machine name, as well as your user-ID and password.  Beyond that, I selected the default on most menus.</p>
<p>In the screen that allows you to select software, shown above, I selected Basic Ubuntu Server, OpenSSH Server and Samba File Server.  Don&#8217;t go crazy with your software selections.  At this point your XM&#8217;s processor has been throttled down to an extra slow 600Mhz, so you don&#8217;t want to give the installer any more work than necessary.</p>
<h2>Fixing the Processor Speed</h2>
<p>After the install program runs and the Beagleboard XM is rebooted, the first thing you&#8217;ll want to do is fix the processor speed.  If you look at the processor info, you&#8217;ll see</p>
<pre>dwatts@bigdog:~$ cat /proc/cpuinfo
Processor        : ARMv7 Processor rev 2 (v7l)
BogoMIPS       : 471.61
Features          : swp half thumb fastmult vfp edsp neon vfpv3
CPU implementer      : 0x41
CPU architecture: 7
CPU variant    : 0x3
CPU part         : 0xc08
CPU revision   : 2
Hardware       : OMAP3 Beagle Board
Revision          : 0020
Serial              : 0000000000000000</pre>
<p>The BogoMIPS rating, a crude performance benchmark, is actually slightly lower than I get with an original (non-XM) Beagleboard.</p>
<p>To fix this you&#8217;ll need to change the mpurate setting from 1000 to 800 in /boot/boot.script, as marked in bold below.</p>
<pre>fatload mmc 0:1 0x80000000 uImage
fatload mmc 0:1 0x81600000 uInitrd
setenv bootargs ro elevator=noop vram=12M omapfb.mode=dvi:1280x720MR-16@60 _
  mpurate=<strong>800</strong> root=UUID=25210e81-e728-4a73-96ff-06df5c29216f fixrtc _
  quiet splash console=ttyO2,115200n8
bootm 0x80000000 0x81600000</pre>
<p>The not-terribly-user-friendly vi editor is good enough for this.  Just :</p>
<ul>
<li>launch vi (sudo vi /boot/boot.script)</li>
<li>cursor down to the beginning of the &#8220;1000&#8243; after &#8220;mpurate=&#8221;</li>
<li>press x twice to erase the 1 and the 0</li>
<li>press I once to enter insert mode</li>
<li>type 8</li>
<li>press Esc</li>
<li>Enter w</li>
<li>Enter q</li>
</ul>
<p>Crude, but effective.  If you mess up, you can exit vi at any time without saving by pressing Esc and entering q!.</p>
<p>After updating the file, enter</p>
<pre>dwatts@bigdog:~$ sudo flash-kernel
dwatts@bigdog:~$ sudo shutdown –r now</pre>
<p>After rebooting, the BogoMIPs score should be about 630, which is the same as with Ubuntu 10.10.</p>
<p>Unfortunately, based on this <a href="http://groups.google.com/group/beagleboard/browse_thread/thread/14796c8db9f69c77#">post by Robert Nelson in Beagleboard Google Groups</a>, it isn&#8217;t clear when (or if) Ubuntu is going to be able to run at 1 Ghz.</p>
<h2>Getting on the Network</h2>
<p>The default network configuration needs to handle the Beagleboard XM&#8217;s non-standard Ethernet device name of usb0.  The /etc/network/interfaces file should contain the 2 lines marked in bold below:</p>
<pre>dwatts@bigdog:~ cat :/etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
<strong>auto usb0</strong>
<strong>iface usb0 inet dhcp </strong></pre>
<p><strong> </strong>If they aren&#8217;t there, you&#8217;ll need to add them.  If you were traumatized by using the vi editor earlier, another approach to editing the file is :</p>
<pre>dwatts@bigdog:~ sudo –i
root@bigdog:~# echo auto usb0 &gt;&gt; /etc/network interfaces
root@bigdog:~# echo iface usb0 inet dhcp &gt;&gt;/etc/network interfaces</pre>
<p>Then activate the Ethernet port:</p>
<pre>root@bigdog:~# ifup usb0</pre>
<p>The Beagleboard XM&#8217;s Ethernet adapter uses a dynamic MAC address, so if you are using DHCP to assign the IP address (as the above configuration will do), the IP address will change each time it&#8217;s rebooted.  This can be rather frustrating if your Beagleboard is going to be used as a server.  You can change this by using the same settings as explained in <a href="http://gigamegablog.com/2010/12/26/beagleboard-xm-angstrom-next-steps-assigning-a-static-ip/">my blog post about Angstrom</a>– the interface file in Ubuntu has the same format as in Angstrom.  (A more advanced solution to the problem, which I haven&#8217;t tried, is to patch the kernel so that the same MAC address is used each time: <a href="http://www.electronsonradio.com/2011/07/angstrom-on-the-beagleboard-fixing-your-mac-address/">see this post on the Electrons on Radio blog</a>).</p>
<h2>Updating Ubuntu</h2>
<p>Now you get an opportunity to fully and completely appreciate how slowly the Ubuntu package updater runs on the Beagleboard XM.  You&#8217;ll need to download and install a few month&#8217;s (or more) worth of Ubuntu updates.</p>
<pre>root@bigdog:~# aptitude update
root@bigdog:~#: aptidude upgrade</pre>
<p>Unless you&#8217;re practicing to be a Buddhist monk, you&#8217;ll probably not want to sit and watch aptitude crawl along for the next couple of hours.</p>
<p>Speed issues aside, Ubuntu&#8217;s package installer software works the same on the Beagleboard as it does on a full PC.  Here are some of the more useful options (though you might end up using Webmin rather than the command line for this &#8212; see the Webmin section below):</p>
<p>To list the packages that are currently installed:</p>
<pre>root@bigdog:~#: dpkg --get-selections</pre>
<p>To find a package based on text in its name or description:</p>
<pre>root@bigdog:~#:  aptitude search &lt;text&gt;</pre>
<p>To get more info on a specific package</p>
<pre>root@bigdog:~#:  aptitude show &lt;packagename&gt;</pre>
<h2>Updating the Date and Time</h2>
<p>If you enter the  &#8221;date&#8221; command you&#8217;ll likely find that the date is correct, but the time is off by a few hours or more.  Ubuntu has already installed the NTP software needed to automatically set the time, but it needs to know where you live:</p>
<p>To display the current timezone:</p>
<pre>root@bigdog:~#:  cat /etc/timezone
America/North_Dakota/Center</pre>
<p>To change the timezone</p>
<pre>root@bigdog:~#: dpkg-reconfigure tzdata</pre>
<p>You&#8217;ll then see a pop-up dialog to guide you through the process.</p>
<p style="text-align: center;"><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-04-37.jpg"><img class="aligncenter size-full wp-image-971" title="Timezone configuration dialog" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-04-37.jpg" alt="" width="636" height="300" /></a></p>
<h2>WebMin</h2>
<p>After going through the indignity of manually hobbling your processor, then watching it take a couple of hours to slog through the software updates,  you might be wondering why any sane person would choose Ubuntu over Angstrom.  Here&#8217;s why: <a href="http://webmin.com/">Webmin</a>!</p>
<p>WebMin is the tops.  It&#8217;s the thing.  All the girls get up when it sings (yeah).</p>
<p>And Angstrom doesn’t have it.</p>
<p>Installing WebMin isn&#8217;t as easy as &#8220;aptitude install webmin&#8221;, but trust me: it&#8217;s worth it.  Full instructions are here: <a href="http://www.webmin.com/deb.html">http://www.webmin.com/deb.html</a>, but you should need just 2 or 3 commands:</p>
<pre>root@bigdog:~#: wget <a href="http://www.webmin.com/download/deb/webmin-current.deb">http://www.webmin.com/download/deb/webmin-current.deb</a>
root@bigdog:~#: dpkg –install webmin-current.deb</pre>
<p>Unless you&#8217;ve installed a bunch of Perl-specific packages, you&#8217;ll get a bunch of errors due to missing dependencies.  It looks messy, but it&#8217;s actually quite simple to fix:</p>
<pre>root@bigdog:~#: aptitude install perl libnet-ssleay-perl openssl _
  libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python</pre>
<p>Don&#8217;t worry if not all of those packages are missing.  Ubuntu&#8217;s updater might be slow, but it&#8217;s no dummy.  Not only will it sort out what&#8217;s needed, but it will automatically install webmin for you once all of the missing packages are there.</p>
<p>Once it&#8217;s installed, you can load Webmin in a brower from any PC at:</p>
<p><a href="https://%3Cipaddress%3E:10000/">https://&lt;ipaddress&gt;:10000</a></p>
<p>Note that Webmin will want to use secure protocol (https) by default, and your browser will mutter about missing security certificates as a result.  You can turn off the requirement for a secure connection within Webmin later.</p>
<p>Ordinarily, you should be able to login to Webmin using your own user-ID.  I couldn&#8217;t – no idea why, but something went wrong.  I had to login as root.</p>
<p>Wait, what? Login as root?  Impossible, you say!  Ubuntu won&#8217;t allow it.</p>
<p>Bah, Ubuntu and what army?  You just have to set a root password manually first:</p>
<pre>root@bigdog:~# passwd root
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully</pre>
<p>If you want to prevent Webmin from requiring an https connection, click the Webmin link in the upper left of the main Webmin menu, then Webmin Configuration, then SSL Encryption.  &#8220;Change the Enable SSL if available&#8221; setting to No:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-18-52.jpg"><img class="aligncenter size-large wp-image-961" title="Turning off https for Webmin" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-18-52-1024x510.jpg" alt="" width="640" height="318" /></a></p>
<p>Among the many Linux system administration tasks that Webmin makes a lot easier are:</p>
<p>1. Updating Ubuntu packages.  (Easier, but sadly not faster.)</p>
<p style="text-align: center;"><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-22-53.jpg"><img class="aligncenter size-large wp-image-962" title="Webmin Package Updater" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-22-53-1024x459.jpg" alt="" width="640" height="286" /></a></p>
<p>2. Viewing System Logs</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-25-41.jpg"><img class="aligncenter size-large wp-image-963" title="Webmin System Log Viewer" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-25-41-1024x457.jpg" alt="" width="640" height="285" /></a></p>
<p>3. Reading documentation and help files for packages.  Note that Webmin goes beyond man pages and puts together a list of all the documentation installed with the package.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-29-08.jpg"><img class="aligncenter size-large wp-image-964" title="Webmin Documentation Viewer" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-29-08-1024x546.jpg" alt="" width="640" height="341" /></a></p>
<p>4. Mounting drives, include shared folders on Windows PCs (after you&#8217;ve installed Samba and configured, as described below).  It will also handle updating fstab so that the drive is automatically mounted when the system is booted.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-31-48.jpg"><img class="aligncenter size-large wp-image-965" title="Mounting a drive with Webmin" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-31-48-1024x449.jpg" alt="" width="640" height="280" /></a></p>
<p>5. File management. Tucked away under the &#8220;Others&#8221; section of the left-hand menu is a Java-based File Manager.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-17-10.jpg"><img class="aligncenter size-large wp-image-972" title="Webmin File Explorer" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-17-10-1024x386.jpg" alt="" width="640" height="241" /></a></p>
<p>6. Software configuration.  The Servers menu in the lefthand pane contains custom modules for configuration some common software packages, such as SSH and Samba.</p>
<h2>SSH</h2>
<p>If you selected OpenSSH from the Ubuntu installer&#8217;s software menu, then the SSH is already up and running.  Otherwise, you can install it with:</p>
<pre>root@bigdog~#: aptitude install openssh-server</pre>
<p>Alternatively, you can use Webmin to locate and install a package, using the &#8220;Software Packages&#8221; menu:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/20-08-2011-11-57-29-AM.jpg"><img class="aligncenter size-full wp-image-984" title="Using Webmin to install SSH" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/20-08-2011-11-57-29-AM.jpg" alt="" width="878" height="405" /></a></p>
<p>The default settings will allow you to login using your Ubuntu user-ID and password.  The SSH server also supports file transfer using an SCP package like <a href="http://winscp.net/eng/index.php">WinSCP</a>.</p>
<p>If you intend to access your Beagleboard through the Internet, then you&#8217;ll probably want to replace password authentication with public key authentication.  To enable this:</p>
<p>1. Upload your public key to a file named ~/.ssh/authenticated_keys – you&#8217;ll probably have to create the ~/.ssh folder first.  You can use WinSCP to copy the file over, or WebMin&#8217;s file manager, which includes Edit and Upload functions.</p>
<p>2. Test that you can now login using your public key, rather than entering a password.  In WinPutty, you specify the location of your private key here:</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-23-07.jpg"><img class="aligncenter size-full wp-image-973" title="WinPutty private key configuration" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-23-07.jpg" alt="" width="450" height="440" /></a></p>
<p>3. In Webmin, select Servers in the lefthand pane, then select SSH Server. Set “Allow authentication by password” to No.  While you are there, set “Allow login by root” to No as a security precaution.  Return to the main SSH Server menu and click the Apply Changes button, which will restart the SSH server.</p>
<p style="text-align: center;"><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-51-04.jpg"><img class="aligncenter size-full wp-image-966" title="Using Webmin to configure SSH" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-17-51-04.jpg" alt="" width="1015" height="548" /></a></p>
<p>Incidentally, the SSH server&#8217;s default configuration will allow client-to-server port forwarding.  This allows you to access the web server and WebMin from a remote PC after connecting through SSH.  For example, the following settings in WinPutty allow you to connect with SSH and then securely access Webmin through a browser as <a href="http://localhost:10000/">http://localhost:10000</a>.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-54-02.jpg"><img class="aligncenter size-full wp-image-974" title="WinPutty settings for port forwarding" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-19-54-02.jpg" alt="" width="449" height="442" /></a></p>
<h2>Samba</h2>
<p>If you didn&#8217;t select &#8220;Samba File Server&#8221; from the Ubuntu installer&#8217;s  software menu, then you can install it using Webmin or by running</p>
<pre>root@bigdog:~# aptitude install samba</pre>
<p>Users are automatically added as Samba users, but their passwords aren’t.</p>
<p>You can configure Samba through Webmin  by selecting Samba Windows File Sharing under the Servers menu.  You need to click on “Edit Samba Users and Passwords”, then select “New password” and type in your password.  This is the password that Windows PCs will need to supply in order to access your Samba shares.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-18-04-04.jpg"><img class="aligncenter size-full wp-image-970" title="Setting Samba user password in Webmin" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/2011-08-17-18-04-04.jpg" alt="" width="777" height="382" /></a></p>
<p>To share a folder, click on “Create a new file share”.  Fill in the “Share name” and “Directory to share”.  If the directory already exists, set “Automatically create directory” to No.</p>
<p>By default, shares are read only.  To change that, click on the share name at the top of the window, then click on Security And Access Control.  Change “Writeable” to yes.</p>
<p><a href="http://www.gigamegablog.com/wp-content/uploads/2011/08/20-08-2011-12-10-40-PM.jpg"><img class="aligncenter size-large wp-image-986" title="Making a Samba shared directory writeable using Webmn" src="http://www.gigamegablog.com/wp-content/uploads/2011/08/20-08-2011-12-10-40-PM-1024x478.jpg" alt="" width="640" height="298" /></a></p>
<p>At the bottom of the window is a button to restart Samba and apply changes right away, but generally changes are automatically loaded by Samba without restarting.</p>
<h1>Wrapping Up</h1>
<p>Aside from Webmin, Ubuntu offers a few other advantages over Angstrom that you might want to consider:</p>
<ul>
<li>Its VNC server is much easier to configure than Angstrom&#8217;s.</li>
<li>If you are running VNC, or physically connected with a monitor, keyboard and mouse, Ubuntu offers some shiny new window managers that aren&#8217;t available on Angstrom, such as<a href="http://www.gnome.org/"> GNOME 3</a>  and Ubuntu&#8217;s own Unity2D desktop.</li>
<li>The <a href="http://www.google.com/chrome/">Google Chrome browser</a> (with support for extensions) and <a href="http://www.arduino.cc/">Arduino IDE </a>(running on Java) are among the applications that Ubuntu offers, and which aren&#8217;t available as packages for Angstrom.</li>
</ul>
<p>However, if you try running software like GNOME 3 and Chrome, you&#8217;ll find that they just serve to emphasize Ubuntu&#8217;s biggest weakness: they are just too slow to be usable for most tasks.</p>
<p>Ubuntu is, in my opinion, a solid choice for the Beagleboard XM when used as a server.  Background processes like Samba, the CUPS print server, and lighttpd web server run well &#8211; I haven&#8217;t noticed any response time annoyances there.  When combined with Webmin (which is also quite fast), it&#8217;s a relatively user friendly way to learn the basics of Linux system administration.</p>
<p>But, when you have the need for speed, <a href="http://www.angstrom-distribution.org/">Angstrom</a> is still way ahead of the pack.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gigamegablog.com/2011/08/20/beagleboard-xm-and-ubuntu-11-04-%e2%80%93-the-big-dog-still-has-a-burr-in-its-paw/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

