<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>maniacbug</title>
	<atom:link href="http://maniacbug.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://maniacbug.wordpress.com</link>
	<description>AVR Microcontroller Projects</description>
	<lastBuildDate>Fri, 24 Feb 2012 08:55:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='maniacbug.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>maniacbug</title>
		<link>http://maniacbug.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://maniacbug.wordpress.com/osd.xml" title="maniacbug" />
	<atom:link rel='hub' href='http://maniacbug.wordpress.com/?pushpress=hub'/>
		<item>
		<title>FreeRTOS on Arduino</title>
		<link>http://maniacbug.wordpress.com/2012/01/31/freertos/</link>
		<comments>http://maniacbug.wordpress.com/2012/01/31/freertos/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 16:47:58 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=301</guid>
		<description><![CDATA[As I&#8217;ve started to dig into [FreeRTOS], I have found too few useful compilable examples on how to get started. The FreeRTOS tutorial is complicated and theoretical. It doesn&#8217;t leave you with any working running code. The Officially Supported demo &#8230; <a href="http://maniacbug.wordpress.com/2012/01/31/freertos/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=301&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="pingpair_freertos dataflow" href="http://www.flickr.com/photos/maniacbug/6535681051/"><img style="border:solid 2px #000000;" alt="pingpair_freertos dataflow" src="http://farm8.staticflickr.com/7145/6535681051_50dcb2cea0_z.jpg" /></a></h2>
<p>As I&#8217;ve started to dig into [<a href="http://www.freertos.org">FreeRTOS</a>], I have found too few useful compilable examples on how to get started.  The <a href="http://www.freertos.org/tutorial/index.html">FreeRTOS tutorial</a> is complicated and theoretical.  It doesn&#8217;t leave you with any working running code.  The <a href="http://www.FreeRTOS.org/RTOS_Demo_STM32_Primer_Ride.html">Officially Supported demo for STM32</a> works, but it&#8217;s way too complicated, and assumes you have lots of hardware.  Not a great way to get started.  Maple comes with a tragically simple  <a href="https://github.com/leaflabs/libmaple/blob/master/examples/freertos-blinky.cpp">freertos-blinky.cpp</a>, but all it does is show you how to blink the LED.  What&#8217;s next??  Fortunately, I came across a page of <a href="http://senstools.gforge.inria.fr/doku.php?id=os:freertos:examples">FreeRTOS examples for WSN430</a> that helped a lot.</p>
<p>In this blog post, I wanted to share my own experience with porting real code to FreeRTOS, which does something more useful than blink a light, but not something unfathomably complicated.  Along the way, this will explain how to exploit many of the features of FreeRTOS</p>
<p>Get the code from github: <a href="https://github.com/maniacbug/FreeRTOS">https://github.com/maniacbug/FreeRTOS</a></p>
<p><span id="more-301"></span><br />
<h2>Warming up: The easy examples</h2>
<p>My FreeRTOS port contains four simple examples, which serve as good warmups to understand FreeRTOS.  They are best approached in this order:</p>
<ol>
<li><strong>Blinky</strong>.  The usual suspect&#8230;  Blinks the LED, FreeRTOS style.  Obviously overkill for this simple case, but it should help show what&#8217;s going on.</li>
<li><strong>Twotasks</strong>.  Blinks the LED AND prints a message, both on separate timers.</li>
<li><strong>Buttonled</strong>.  Toggles the LED when you press and release a button on Pin 2.  Demonstrates one way to handle debouncing.</li>
<li><strong>Manybuttons</strong>.  Prints the state of many buttons when they change state.  Demonstrates how to use parameters for a task, using the same task handler for multiple buttons.</li>
</ol>
<h2>RF24 pingpair</h2>
<p>My final goal for this post is to port the very simple &#8216;pingpair&#8217; example from <a href="http://maniacbug.github.com/RF24/">RF24</a>.  This is the &#8216;hello world&#8217; of RF radios, sending a message back and forth between two radios.</p>
<h2>Tasks</h2>
<p>Let&#8217;s start by looking at the tasks.  These are the main worker bees of a FreeRTOS application:</p>
<ul>
<li><strong>vSendTask</strong>: Periodically sends a packet to the other unit</li>
<li><strong>vReceiveTask</strong>: Waits for incoming packets on the payload queue, and prints them out to the Serial.  Then prepares an ack packet for the next received packet.</li>
<li><strong>vStatusTask</strong>: Waits for status information on the status queue, and prints them out to the Serial</li>
<li><strong>vRadioSoftIrqTask</strong>: Handles the work of the radio interrupt.</li>
</ul>
<h2>Interrupt Handler</h2>
<p>The handling of interrupts is particularly interesting, using a &#8216;soft irq&#8217; to do  the real work.  The idea behind this is that the interrupt handler does the absolute minimum possible work in the handler itself.  In this case, all it does is wake up the vRadioSoftIrqTask, and return to regular processing.  The problem with doing a lot of work in the interrupt handler is that EVERYTHING is put on hold while it executes, without regard to whether there is something more important happening.  In the case of RF radio, receiving an incoming packet is important, but there is a 3-packet FIFO buffer, so we can wait a bit before processing them if something more important is happening.</p>
<h2>Semaphores</h2>
<ul>
<li><strong>xRadioIrqSemaphore</strong>: This is the mechanism that the radio irq uses to launch the softirq.  The vRadioSoftIrqTask simply waits forever on this semaphore, and the radio irq handler simply posts to this semaphone and exits.</li>
</ul>
<h2>Mutexes</h2>
<p>Mutexes are used to protect resources where we only want to have one task using them at a time.</p>
<ul>
<li><strong>xRadioMutex</strong>: All accesses to the radio are protected by this mutex, otherwise a high-priority task could interrupt a lower one who is currently using the radio for something else.</li>
<li><strong>xConsoleMutex</strong>: Ensures that two things don&#8217;t write to the serial console at once.  Currently, I wait on the mutex.  To avoid deadlocks, it may be better to just abort if it&#8217;s not free.  So far this has not been a problem.</li>
</ul>
<h2>Queues</h2>
<p>Queues are how we pass information between tasks.  Some tasks generate information, another task consumes it and does something with it.</p>
<ul>
<li><strong>xPayloadQueue</strong>: When the radio receives a frame, it places it into the Payload Queue.  This way the radio&#8217;s softirq can be decoupled from the application logic.  The radio fills the queue, and the application consumes it to do what it likes.</li>
<li><strong>xStatusQueue</strong>: Status messages are placed into this queue.</li>
</ul>
<h2>Porting Decisions</h2>
<p>When porting FreeRTOS, there are a few decisions to be made.  These are embodied in FreeRTOSConfig.h</p>
<ul>
<li><strong>Memory allocator</strong>.  I use heap_1.c, which is manages a static heap, and allows allocation only.  No memory is ever freed.  I think this is appropriate for a microcontroller with 2K SRAM.</li>
<li><strong>Heap size</strong>.  1500 bytes of heap seems to be the practical limit.</li>
<li><strong>Minimum stack size</strong>.  100 bytes of stack per task was the limit I found under experimentation, but 150 was better.  Most tasks that do anything will need to be created with a 150+ stack size.</li>
</ul>
<h2>FreeRTOS on Arduino Uno?</h2>
<p>FreeRTOS works great on 1284P and Maple.  After some heavy experimentation, I was able to get the pingpair sketch working on an Arduino Uno clone.  It turns out that a heap of 1300 and per-task stacks of 150 did the job.  In total, 380 bytes of SRAM remain free when the sketch is loaded.</p>
<p>The question is whether this is a good idea.  This is just a simple &#8216;hello world&#8217; for radios, 380 bytes doesn&#8217;t leave much for more complex application logic or more tasks.</p>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/301/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/301/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/301/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=301&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2012/01/31/freertos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7145/6535681051_50dcb2cea0_z.jpg" medium="image">
			<media:title type="html">pingpair_freertos dataflow</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Started with nRF24L01+ using a Protoshield</title>
		<link>http://maniacbug.wordpress.com/2012/01/29/getting-started-rf24-proto/</link>
		<comments>http://maniacbug.wordpress.com/2012/01/29/getting-started-rf24-proto/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 22:14:07 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[RF Radio]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=292</guid>
		<description><![CDATA[This post follows the Getting Started with nRF24L01+ on Arduino. If the resulting board from that is a little too rough around the edges, it can be built instead on a proper prototype shield for a few more dollars. Stuff &#8230; <a href="http://maniacbug.wordpress.com/2012/01/29/getting-started-rf24-proto/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=292&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="RF24 Getting Started ProtoShield" href="http://www.flickr.com/photos/maniacbug/6782821695/"><img style="border:solid 2px #000000;" alt="RF24 Getting Started ProtoShield" src="http://farm8.staticflickr.com/7033/6782821695_498347be25_z.jpg" /></a></h2>
<p>This post follows the <a href="http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/">Getting Started with nRF24L01+ on Arduino</a>.  If the resulting board from that is a little too rough around the edges, it can be built instead on a proper prototype shield for a few more dollars.</p>
<p><span id="more-292"></span><br />
<h2>Stuff we need</h2>
<h3>New Parts</h3>
<p>The changes from the original Getting Started board are that you need these parts instead of the corresponding parts from that post.</p>
<ul>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=19_21&amp;products_id=194">Bare PCB Arduino ProtoShield</a> $3.00</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_12&amp;products_id=208">Arduino Stackable Header Kit</a> $0.90</li>
</ul>
<h3>Same Parts</h3>
<p>You still need these&#8230;</p>
<ul>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=7&amp;products_id=53">2.4G Wireless nRF24L01+ Module</a> $4.00</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_12&amp;products_id=390">2.54mm 2x4Pin Female Header (5Pcs)</a> $1.50</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_11&amp;products_id=136">Solder cable &#8211; 7cm (10pcs)</a> $0.50 (Or get some wire at Home Depot and cut it yourself)</li>
</ul>
<h2>Building it</h2>
<p>Follow the instructions in the <a href="http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/">Getting Started with nRF24L01+ on Arduino</a>.  The protoshield doesn&#8217;t have labels on the grid, so you can use the photos for reference.</p>
<h2>Using it</h2>
<p>The stackable headers are handy because you can stack another sheild atop it.  However, the radio is a little too high for that.  You have a couple options:</p>
<ul>
<li>Skip the 2&#215;4 header and solder the module directly to the shield.</li>
<li>Add a second set of stackable headers, so the shield atop this one is up a bit higher still.</li>
</ul>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/292/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=292&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2012/01/29/getting-started-rf24-proto/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7033/6782821695_498347be25_z.jpg" medium="image">
			<media:title type="html">RF24 Getting Started ProtoShield</media:title>
		</media:content>
	</item>
		<item>
		<title>Control and Monitor Arduino Over the Web Using ENC28J60</title>
		<link>http://maniacbug.wordpress.com/2012/01/28/webserver/</link>
		<comments>http://maniacbug.wordpress.com/2012/01/28/webserver/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 05:02:32 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Ethernet]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=283</guid>
		<description><![CDATA[The NanodeUIP web server provides a mobile-optimized web page to control and monitor your Ethernet-connected Arduino. All you need is an Arduino and an ENC28J60-based Ethernet shield, or get a Nanode which combines the two together. The home page shows &#8230; <a href="http://maniacbug.wordpress.com/2012/01/28/webserver/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=283&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="NanodeUIP Webserver Screens" href="http://www.flickr.com/photos/maniacbug/6774605587/"><img style="border:solid 2px #000000;" alt="NanodeUIP Webserver Screens" src="http://farm8.staticflickr.com/7142/6774605587_af9f0cec58_z.jpg" /></a></h2>
<p>The NanodeUIP web server provides a mobile-optimized web page to control and monitor your Ethernet-connected Arduino.  All you need is an Arduino and an ENC28J60-based Ethernet shield, or get a Nanode which combines the two together.</p>
<p>The home page shows the three functions the webserver can handle:</p>
<ul>
<li>Monitor Buttons</li>
<li>Control Lights</li>
<li>Monitor Sensors</li>
</ul>
<p><span id="more-283"></span><br />
<h3>Buttons</h3>
<p>The &#8216;Buttons&#8217; page shows the current state, HIGH or LOW, of a pre-defined set of digital input pins.  See &#8216;Configuring&#8217; below for details on how to change which pins are reported and what they&#8217;re labeled.</p>
<p>Press the &#8216;Refresh&#8217; button to update the current state.</p>
<h3>Lights</h3>
<p>The &#8216;Lights&#8217; page allows control of a pre-defined set of digital output pins.  While they&#8217;re called lights, they could really control anything like a motor or camera or anything the Arduino can do.</p>
<h3>Sensors</h3>
<p>The &#8216;Sensors&#8217; page shows the current value of a pre-defined set of analog input pins.  Press the &#8216;Refresh&#8217; button to update the current state.</p>
<h2>jQuery Mobile</h2>
<p>The UI relies on <a href="http://jquerymobile.com/">jQuery Mobile</a> for a pretty interface that&#8217;s optimized for a mobile phone.  All the CSS and JavaScript files are hosted by jQuery, so the Arduino web server just needs to point the browser at the right place to go get them.  The extra markup doubles the size of the HTML, but there is still plenty of flash memory to spare.</p>
<h2>NanodeUIP</h2>
<p><a href="https://github.com/maniacbug/NanodeUIP">NanodeUIP</a> is an Arduino-compatible library for ENC28J60-based Ethernet hardware, like Nanode and EtherShield.  It&#8217;s based on <a href="http://www.sics.se/~adam/old-uip/">uIP</a>, a mature, stable, well-documented TCP/IP stack.  The library was originally created by Stephen Early based on Adam Dunkels&#8217; uIP and Guido Socher&#8217;s enc28j60 driver.  My fork adds numerous examples, including this one.  </p>
<h2>Getting it</h2>
<p>This web server is included in my NanodeUIP fork as an example, see <a href="https://github.com/maniacbug/NanodeUIP/tree/master/examples/webserver">examples/webserver</a>.</p>
<p>Using a Nanode, you can upload this sketch straight away to your unit and all is well.  You can watch the boot-up messages in the serial monitor, and this will tell you what IP address it used.  Load up that IP address in your browser, touch &#8220;Lights&#8221;, and toggle the &#8220;Red Light&#8221; switch.  You should see the Nanode LED turning on and off as you do it.</p>
<p>The default buttons are on pins 2,3 and 4.  Try connecting those to ground and refreshing the &#8216;Buttons&#8217;.  The default sensors are on analog 0 and 1, so likewise try connecting those to ground or VCC and refresh to see the values change.</p>
<h2>Using on EtherShield</h2>
<p>For an EtherShield, it&#8217;s almost as easy.  There is a line right at the top of the sketch you&#8217;ll want to un-comment.  After modification, the first line of code says this:</p>
<div style="background-color:#7d170d;padding:5px;"><code>#define ETHERSHIELD // uncomment to run on EtherShield<br /></code></div>
<p>For a regular EtherShield, with the chip select pin on #10, that is all you need to change.  If you&#8217;ve got something custom with a special CS pin, change the networking bringup section in setup().  Change the &#8216;SS&#8217; in this line to the pin you need.</p>
<div style="background-color:#7d170d;padding:5px;"><code>uip.init(macaddr,SS);<br /></code></div>
<h2>Configuration</h2>
<p>The main thing a person needs to change in order to make the web server useful  is to describe the pins which need monitoring and control.  This is done in the webserver.ino file.  Look for the &#8220;Pin Descriptions&#8221; section.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Comment">/*</span><span class="Comment">************************************************************************</span><span class="Comment">*/</span><br /><span class="Comment">/*</span><span class="Comment">*</span><br /><span class="Comment"> * @defgroup pins Pin Descriptions </span><br /><span class="Comment"> *</span><br /><span class="Comment"> * The main purpose of this app is to control or monitor a set of pins</span><br /><span class="Comment"> * from a web server.&nbsp;&nbsp;This sections defines which pins are controlled</span><br /><span class="Comment"> * and what they are called.</span><br /><span class="Comment"> *</span><br /><span class="Comment"> * @{</span><br /><span class="Comment"> </span><span class="Comment">*/</span><br /></code></div>
<p>The first code block lists the human-readable labels of all the pins.  What do you want to call them?  Each label needs its own line here, because it must individually be placed into program (flash) memory.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Comment">/*</span><span class="Comment">*</span><br /><span class="Comment"> * Easy-to-remember names of pins used in this sketch</span><br /><span class="Comment"> </span><span class="Comment">*/</span><br /><span class="Type">const</span> <span class="Type">char</span> led_red_str[] PROGMEM = <span class="Constant">&quot;Red Light&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> led_yellow_str[] PROGMEM = <span class="Constant">&quot;Yellow Light&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> led_green_str[] PROGMEM = <span class="Constant">&quot;Green Light&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> button_a_str[] PROGMEM = <span class="Constant">&quot;Button A&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> button_b_str[] PROGMEM = <span class="Constant">&quot;Button B&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> button_c_str[] PROGMEM = <span class="Constant">&quot;Button C&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> analog_0_str[] PROGMEM = <span class="Constant">&quot;Analog 0&quot;</span>;<br /><span class="Type">const</span> <span class="Type">char</span> analog_1_str[] PROGMEM = <span class="Constant">&quot;Analog 1&quot;</span>;<br /></code></div>
<p>The following block defines which digital output pins are controllable through the &#8216;Lights&#8217; page.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Comment">/*</span><span class="Comment">*</span><br /><span class="Comment"> * Lights controlled by the web server</span><br /><span class="Comment"> </span><span class="Comment">*/</span><br /><span class="Type">const</span> pin_def_t lights[] PROGMEM =<br />{<br />&nbsp;&nbsp;{ led_red_str, led_red },<br />&nbsp;&nbsp;{ led_yellow_str, led_yellow },<br />&nbsp;&nbsp;{ led_green_str, led_green },<br />&nbsp;&nbsp;{ <span class="Constant">0</span>,<span class="Constant">0</span> } <span class="Comment">// terminator</span><br />};<br /></code></div>
<p>The following block defines which digital input pins are monitored on the &#8216;Buttons&#8217; page.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Comment">/*</span><span class="Comment">*</span><br /><span class="Comment"> * Buttons monitored by the web server</span><br /><span class="Comment"> </span><span class="Comment">*/</span><br /><span class="Type">const</span> pin_def_t buttons[] PROGMEM =<br />{<br />&nbsp;&nbsp;{ button_a_str, button_a },<br />&nbsp;&nbsp;{ button_b_str, button_b },<br />&nbsp;&nbsp;{ button_c_str, button_c },<br />&nbsp;&nbsp;{ <span class="Constant">0</span>,<span class="Constant">0</span> } <span class="Comment">// terminator</span><br />};<br /></code></div>
<p>The following block defines which analog input pins are monitored on the &#8216;Sensors&#8217; page.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Comment">/*</span><span class="Comment">*</span><br /><span class="Comment"> * Sensors monitored by the web server</span><br /><span class="Comment"> </span><span class="Comment">*/</span><br /><span class="Type">const</span> pin_def_t sensors[] PROGMEM =<br />{<br />&nbsp;&nbsp;{ analog_0_str, <span class="Constant">0</span> },<br />&nbsp;&nbsp;{ analog_1_str, <span class="Constant">1</span> },<br />&nbsp;&nbsp;{ <span class="Constant">0</span>,<span class="Constant">0</span> } <span class="Comment">// terminator</span><br />};<br /></code></div>
<p>Finally, the following function is called at startup to set the pins to the right input/output direction, and to register the pins with the CGI handler.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Comment">/*</span><span class="Comment">*</span><br /><span class="Comment"> * Ensure the pins are set correctly, and register them with the</span><br /><span class="Comment"> * web server.</span><br /><span class="Comment"> </span><span class="Comment">*/</span><br /><span class="Type">void</span> setup_pins()<br />{<br />&nbsp;&nbsp;<span class="Comment">// led's are outputs</span><br />&nbsp;&nbsp;pinMode(led_red,OUTPUT);<br />&nbsp;&nbsp;pinMode(led_yellow,OUTPUT);<br />&nbsp;&nbsp;pinMode(led_green,OUTPUT);<br />&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// buttons are inputs</span><br />&nbsp;&nbsp;pinMode(button_a,INPUT);<br />&nbsp;&nbsp;digitalWrite(button_a,HIGH);<br />&nbsp;&nbsp;pinMode(button_b,INPUT);<br />&nbsp;&nbsp;digitalWrite(button_b,HIGH);<br />&nbsp;&nbsp;pinMode(button_c,INPUT);<br />&nbsp;&nbsp;digitalWrite(button_c,HIGH);<br />&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Tell the CGI which pins we care about</span><br />&nbsp;&nbsp;cgi_register(buttons,lights,sensors);<br />}<br /><span class="Comment">/*</span><span class="Comment">* @} </span><span class="Comment">*/</span><br /></code></div>
<h2>Flash Filesystem</h2>
<p>The web server builds a simple file system in program memory (flash), so it can serve those files back out to clients who request them.  It is not necessary to modify the files on the flash filesystem under normal use.  For more advanced use, it&#8217;s interesting to look under the covers.  For a good explanation of what&#8217;s involved, let&#8217;s take a look at the Makefile in the fs directory.</p>
<p>The purpose of the Makefile is to create three files in the root directory.  fs.cpp will contain the files themselves, transalated into C arrays so they can be processed by the compiler.  files.h lists those files out, so they can be referenced by dir.h which works as a directory listing of files.</p>
<div style="background-color:#7d170d;padding:5px;"><code>OUTDIR = ..<br />ALLFILES = $(OUTDIR)/fs.cpp $(OUTDIR)/files.h $(OUTDIR)/dir.h<br />all: $(ALLFILES)<br /></code></div>
<p>The INFILES are the files from disk which will be compiled into the flash filesystem.</p>
<div style="background-color:#7d170d;padding:5px;"><code>INFILES = $(wildcard *.html) $(wildcard *.shtml) $(wildcard *.txt) $(wildcard *.js)<br /></code></div>
<p>The first step is to run <a href="http://linux.about.com/library/cmd/blcmdl1_xxd.htm">xxd</a> on all the input files, turning them into C files.  These C files are collected in the xxd directory.  They are run through an awk script to put them into program memory.</p>
<div style="background-color:#7d170d;padding:5px;"><code>XXDDIR = xxd<br />XXDFILES = $(addprefix $(XXDDIR)/, $(addsuffix .cpp, $(INFILES)))<br />$(XXDDIR)/%.cpp : %<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xxd -i $&lt; | gawk -f ../xxd.awk &gt; $@<br /></code></div>
<p>Next, the files are scanned into a directory structure using another pair of awk scripts.  dir.h contains entries for each file, telling us the name of each file, where it&#8217;s located in memory, and how large it is.</p>
<div style="background-color:#7d170d;padding:5px;"><code>$(OUTDIR)/files.h : $(XXDFILES)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gawk -f ../files.awk $^ &gt; $@<br />&nbsp;<br />$(OUTDIR)/dir.h : $(XXDFILES)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gawk -f ../dir.awk $^ &gt; $@<br /></code></div>
<p>Finally, all the C files are collapsed into a single CPP file, and copied up to the sketch folder.</p>
<div style="background-color:#7d170d;padding:5px;"><code>$(OUTDIR)/fs.cpp : $(XXDFILES)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cat $(XXDFILES) &gt; $@<br /></code></div>
<h2>Common Gateway Interface (CGI)</h2>
<p>CGI is the old-time term for web pages generated by code.  This harkens back to a day when it was something new, because people actually hand-wrote HTML pages.  Sounds shocking now! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>uIP differentiates between three sources of HTML:</p>
<ul>
<li>HTML files (served by the httpd_fs file system)</li>
<li>Server-generated HTML files (also served by the file system, but processed for special commands)</li>
<li>Scripts (created by the httpd_cgi subsystem)</li>
</ul>
<p>A file with an .html extention will simply be written straight out to the client when it&#8217;s requested.</p>
<p>An .shtml file is an html file with special handling.  From an SHTML file, you can include other files, or run scripts.</p>
<p>A script causes one of the registered CGI handlers in httpd_cgi to be called.  This is what&#8217;s used to generate the dynamic portion of the HTML result, including the current state of pins, and of course selecting which pins to display at all.</p>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/283/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=283&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2012/01/28/webserver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7142/6774605587_af9f0cec58_z.jpg" medium="image">
			<media:title type="html">NanodeUIP Webserver Screens</media:title>
		</media:content>
	</item>
		<item>
		<title>Nordic FOB and nRF24L01+</title>
		<link>http://maniacbug.wordpress.com/2012/01/08/nordic-fob/</link>
		<comments>http://maniacbug.wordpress.com/2012/01/08/nordic-fob/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 16:12:35 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[RF Radio]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=271</guid>
		<description><![CDATA[Sparkfun sells a nifty little gadget to control your project remotely using nRF24L01+ radios. It&#8217;s a small key fob with 5 buttons, which transmits codes when you press each button. Today we&#8217;re going to explore how to receive those signals &#8230; <a href="http://maniacbug.wordpress.com/2012/01/08/nordic-fob/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=271&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="Nordic FOB and nRF24L01+" href="http://www.flickr.com/photos/maniacbug/6645514331/"><img style="border:solid 2px #000000;" src="http://farm8.staticflickr.com/7159/6645514331_38eb2bdeaa_z.jpg" alt="Nordic FOB and nRF24L01+" /></a></h2>
<p>Sparkfun sells a nifty little gadget to control your project remotely using nRF24L01+ radios. It&#8217;s a small key fob with 5 buttons, which transmits codes when you press each button. Today we&#8217;re going to explore how to receive those signals using the <a href="http://maniacbug.github.com/RF24/index.html">RF24</a> library. This is all thanks to Kirk Mower who sent me these units for Christmas. Thanks, Kirk! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<span id="more-271"></span></p>
<h2>Parts</h2>
<table>
<tbody>
<tr style="background-color:#eeeeee;color:red;">
<td style="padding:0 10px;"><strong> Qty </strong></td>
<td style="padding:0 10px;"><strong> Vendor# </strong></td>
<td style="padding:0 10px;"><strong> Description </strong></td>
<td style="padding:0 10px;"><strong> Price </strong></td>
</tr>
<tr>
<td style="padding:0 10px;">1</td>
<td style="padding:0 10px;"><a href="http://www.sparkfun.com/products/8602">WRL-08602</a></td>
<td style="padding:0 10px;">Nordic FOB</td>
<td style="padding:0 10px;">$24.95</td>
</tr>
<tr>
<td style="padding:0 10px;">1</td>
<td style="padding:0 10px;"><a href="http://www.sparkfun.com/products/691">WRL-00691</a></td>
<td style="padding:0 10px;">Transceiver nRF24L01+ Module with Chip Antenna</td>
<td style="padding:0 10px;">$19.95</td>
</tr>
</tbody>
</table>
<h2>Connections</h2>
<h2 style="text-align:center;padding:3px;"><a title="Sparkfun nRF24L01+ module connections" href="http://www.flickr.com/photos/maniacbug/6645514819/"><img style="border:solid 2px #000000;" src="http://farm8.staticflickr.com/7028/6645514819_5f4225dbf8.jpg" alt="Sparkfun nRF24L01+ module connections" /></a></h2>
<p>Connecting the Sparkfun transceiver unit to an Arduino using a breadboard is easier than with the <a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=7&amp;products_id=53">typical modules</a>. Does that make it worth $20 over $4? You&#8217;ll have to decide that. To connect it, we can follow the guidance on my previous post, <a href="http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/">Getting Started with nRF24L01+ on Arduino</a>. Wiring it this way means we can use all the <a href="http://maniacbug.github.com/RF24/examples.html">RF24 examples</a>, which are set up to use these pins by default.</p>
<table>
<tbody>
<tr style="background-color:#eeeeee;color:red;">
<td style="padding:0 10px;"><strong> Radio </strong></td>
<td style="padding:0 10px;"><strong> Arduino </strong></td>
</tr>
<tr>
<td style="padding:0 10px;">GND</td>
<td style="padding:0 10px;">GND</td>
</tr>
<tr>
<td style="padding:0 10px;">VCC</td>
<td style="padding:0 10px;">3V3</td>
</tr>
<tr>
<td style="padding:0 10px;">CE</td>
<td style="padding:0 10px;">9</td>
</tr>
<tr>
<td style="padding:0 10px;">CSN</td>
<td style="padding:0 10px;">10</td>
</tr>
<tr>
<td style="padding:0 10px;">SCK</td>
<td style="padding:0 10px;">13</td>
</tr>
<tr>
<td style="padding:0 10px;">MOSI</td>
<td style="padding:0 10px;">11</td>
</tr>
<tr>
<td style="padding:0 10px;">MISO</td>
<td style="padding:0 10px;">12</td>
</tr>
</tbody>
</table>
<h2>Sketch</h2>
<p>This is now an example for the RF24 library, <a href="http://maniacbug.github.com/RF24/nordic_fob_8pde-example.html">nordic_fob.pde</a>.</p>
<p>Setting up the radio is simply a matter of matching the radio parameters on the receiver with those of the transmitter. We can refer to the <a href="http://www.sparkfun.com/datasheets/Wireless/Nordic/Nordic-FOB.zip">device firmware</a> for the transmitter settings.</p>
<div style="background-color:#7d170d;padding:5px;"><code>  radio.begin();<br />
radio.setChannel(<span class="Constant">2</span>);<br />
radio.setPayloadSize(<span class="Constant">4</span>);<br />
radio.setAutoAck(<span class="Boolean">false</span>);<br />
radio.setCRCLength(RF24_CRC_8);<br />
radio.openReadingPipe(<span class="Constant">1</span>,<span class="Constant">0xE7E7E7E7E7LL</span>);<br />
</code></div>
<p>The payload sent by the transmitter is 4 bytes long. The first is one byte containing the current state of the buttons. The low 5 bits correspond with each button, and the bit is 1 when the button is up and 0 when pressed. Bytes 2 &amp; 3 are a 16-bit sequence number I call the &#8216;id&#8217;. Every time the unit sends a packet, the sequence number is increased by 1. The 4th byte is not used. So this is what our payload looks like:</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Type">struct</span> payload_t<br />
{<br />
<span class="Type">uint8_t</span> buttons;<br />
<span class="Type">uint16_t</span> id;<br />
<span class="Type">uint8_t</span> empty;<br />
};<br />
</code></div>
<p>The main loop simply listens for packets, and dumps out the results, translating the button bits into words so it&#8217;s easier to read.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Type">void</span> loop(<span class="Type">void</span>)<br />
{<br />
<span class="Comment">//</span><br />
<span class="Comment">// Receive each packet, dump it out</span><br />
<span class="Comment">//</span></p>
<p><span class="Comment">// if there is data ready</span><br />
<span class="Statement">if</span> ( radio.available() )<br />
{<br />
<span class="Comment">// Get the packet from the radio</span><br />
payload_t payload;<br />
radio.read( &amp;payload, <span class="Statement">sizeof</span>(payload) );</p>
<p><span class="Comment">// Print the ID of this message.  Note that the message</span><br />
<span class="Comment">// is sent 'big-endian', so we have to flip it.</span><br />
printf(<span class="String">"#</span><span class="Special">%05u</span><span class="String"> Buttons "</span>,flip_endian(payload.id));</p>
<p><span class="Comment">// Print the name of each button </span><br />
<span class="Type">int</span> i = num_buttons;<br />
<span class="Statement">while</span> (i--)<br />
{<br />
<span class="Statement">if</span> ( ! ( payload.buttons &amp; _BV(i) ) )<br />
{<br />
printf(<span class="String">"</span><span class="Special">%s</span><span class="String"> "</span>,button_names[i]);<br />
}<br />
}</p>
<p><span class="Comment">// If no buttons, print None</span><br />
<span class="Statement">if</span> ( payload.buttons == _BV(num_buttons) - <span class="Constant">1</span> )<br />
printf(<span class="String">"None"</span>);</p>
<p>printf(<span class="String">"</span><span class="Special">\r\n</span><span class="String">"</span>);<br />
}<br />
}<br />
</code></div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/271/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/271/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/271/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/271/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/271/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/271/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/271/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/271/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=271&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2012/01/08/nordic-fob/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7159/6645514331_38eb2bdeaa_z.jpg" medium="image">
			<media:title type="html">Nordic FOB and nRF24L01+</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7028/6645514819_5f4225dbf8.jpg" medium="image">
			<media:title type="html">Sparkfun nRF24L01+ module connections</media:title>
		</media:content>
	</item>
		<item>
		<title>Arduino on Ice: Internet Radio via Shoutcast</title>
		<link>http://maniacbug.wordpress.com/2011/12/30/arduino-on-ice-internet-radio-via-shoutcast/</link>
		<comments>http://maniacbug.wordpress.com/2011/12/30/arduino-on-ice-internet-radio-via-shoutcast/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 15:53:06 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Ethernet]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=264</guid>
		<description><![CDATA[I&#8217;ve seen plenty Internet Radio examples out there on various platforms, but none on Arduino. Is 2K memory just too little to stream radio effectively? Thought it was time to find out. Turns out it&#8217;s no problem at all. Using &#8230; <a href="http://maniacbug.wordpress.com/2011/12/30/arduino-on-ice-internet-radio-via-shoutcast/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=264&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="Nanode streaming Internet Radio (close-up)" href="http://www.flickr.com/photos/maniacbug/6600655547/"><img style="border:solid 2px #000000;" alt="Nanode streaming Internet Radio (close-up)" src="http://farm8.staticflickr.com/7165/6600655547_3b6f91af24_z.jpg" /></a></h2>
<p>I&#8217;ve seen plenty Internet Radio examples out there on various platforms, but none on Arduino.  Is 2K memory just too little to stream radio effectively?  Thought it was time to find out.  Turns out it&#8217;s no problem at all.  Using uIP on ENC28J60 for networking and VS1053 for playback, a stock ATmega328p-based Arduino can stream Internet Radio no problem with plenty RAM to spare.</p>
<p>The example sketch discussed here is something of a &#8220;Hello, world.&#8221; of Internet Radio.  It starts up, connects to a single hard-coded stream, and plays it forever.  This makes it simple!  Plug and listen.  For this example, I&#8217;ll use the stream from <a href="http://www.c895.org/">www.c895.org</a>, &#8220;Seattle&#8217;s Hottest Music&#8221; <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-264"></span><br />
<h2>Hardware</h2>
<p>The easiest way to combine Arduino and ENC28J60-based Ethernet is the <a href="http://maniacbug.wordpress.com/2011/08/07/nanode/">Nanode</a>.  Alternately, you could use an Arduino Uno with an inexpensive (non-official) <a href="http://www.nuelectronics.com/estore/index.php?main_page=product_info&amp;cPath=1&amp;products_id=4">EtherShield</a>.   I&#8217;ve also hooked this up with my own <a href="http://maniacbug.wordpress.com/2011/04/03/arduino-clone-v1-2/">Custom Arduino</a> board with a <a href="http://maniacbug.wordpress.com/2011/07/10/arduino-ethernet-using-enc28j60/"> Custom ENC28J60-based Ethernet</a> board.  It&#8217;s all the same.  The Nanode is the easiest, though.</p>
<p>For the player, I use the <a href="http://www.mdfly.com/index.php?main_page=product_info&amp;cPath=9_53&amp;products_id=396">Breakout board for VS1053 MP3 and MIDI</a> available from MDFly.com for $25.  They are for sale elsewhere on the web too, so anything that breaks out the primary control lines will do the job.</p>
<p>Total off the shelf cost, $65. $40 for a Nanode, $25 for the player module.</p>
<h2>Software</h2>
<h3>EtherBright Library, based on avr-uip</h3>
<p>Get the <a href="https://github.com/maniacbug/EtherBright">EtherBright</a> library, and put it in your sketchbook libraries. The key to making this project work was finding a small, memory-efficient TCP/IP stack in software that&#8217;s mature and well-tested.  For the longest time, I thought such a thing did not exist.  Then I found <a href="http://en.wikipedia.org/wiki/UIP_%28micro_IP%29">uIP</a>, which is part of the <a href="http://www.contiki-os.org">Contiki OS</a>.  More importantly, I found the <a href="http://code.google.com/p/avr-uip/">avr-uip</a> port which extracts uIP out of Contiki, and pairs it with the ENC28J60 driver.  Even with all of its restrictions and compromises, it was able to download files from the web at 180kbytes/sec with only a 500-byte packet buffer.  That&#8217;s plenty fast enough to keep up with a 128kbits/sec Icecast stream with plenty of time left over for dealing with network hiccups.</p>
<p>Unfortunately, avr-uip is not packaged to work with the Arduino IDE, so I extracted a few key pieces, and repackaged it as the EtherBright library.  From avr-uip, it contains:</p>
<ul>
<li>TCP/IP stack (&#8216;uip&#8217; directory)</li>
<li>ENC28J60 drivers (&#8216;drivers/enc28j60&#8242; and &#8216;drivers/interfaces&#8217;)</li>
<li>Webclient applet.  Basic logic for making HTTP requests and parsing the response.  Minor changes from the avr-uip project, to use PROGMEM for string storage and to support the ICY protocol.</li>
</ul>
<h3>VS1053 Library</h3>
<p>Get the <a href="https://github.com/maniacbug/VS1053">VS1053</a> library.  For the player, I just followed the code in <a href="http://www.vsdsp-forum.com/phpbb/viewtopic.php?f=11&amp;t=65&amp;p=308#p308">this thread</a> on the VLSI forum, and cleaned it up a bit into a nice library.</p>
<h3>IcyArduino Sketch</h3>
<p>Get the <a href="https://github.com/maniacbug/IcyArduino">IcyArduino</a> sketch, and put it in your sketchbook.</p>
<h2>Connections</h2>
<p>Hooking up the hardware is easy, especially with Nanode.  The VS1053 unit is attached to the secondary connector outside the digital pins.  This table details the setup I&#8217;ve used here.  It is straightforward to modify it for other EtherShield setups.  Do be aware that the Nanode uses pin 8 for SPI chip select, so I&#8217;m using pin 10 for the VS1033 chip select.  Other shields use pin 10 for the Ethernet, so you&#8217;d have to hook up the VS1053 to a different pin and change the software.</p>
<table>
<tr style="background-color:#EEEEEE;color:red;">
<td style="padding:0 10px;"> <strong>  Nanode </strong> </td>
<td style="padding:0 10px;"> <strong>  Wire </strong> </td>
<td style="padding:0 10px;"> <strong>  VS1053 </strong> </td>
</tr>
<tr>
<td style="padding:0 10px;"> 5V </td>
<td style="padding:0 10px;"> brown </td>
<td style="padding:0 10px;"> 5V</td>
</tr>
<tr>
<td style="padding:0 10px;"> 0V </td>
<td style="padding:0 10px;"> red </td>
<td style="padding:0 10px;"> GND</td>
</tr>
<tr>
<td style="padding:0 10px;"> 13 SCK </td>
<td style="padding:0 10px;"> green </td>
<td style="padding:0 10px;"> SCLK </td>
</tr>
<tr>
<td style="padding:0 10px;"> 12 MISO </td>
<td style="padding:0 10px;"> orange </td>
<td style="padding:0 10px;"> SO </td>
</tr>
<tr>
<td style="padding:0 10px;"> 11 MOSI </td>
<td style="padding:0 10px;"> yellow </td>
<td style="padding:0 10px;"> SI </td>
</tr>
<tr>
<td style="padding:0 10px;"> 10 SS </td>
<td style="padding:0 10px;"> blue </td>
<td style="padding:0 10px;"> XCS</td>
</tr>
<tr>
<td style="padding:0 10px;"> INT </td>
<td style="padding:0 10px;"> &#8211; </td>
<td style="padding:0 10px;"> &#8211; </td>
</tr>
<tr>
<td style="padding:0 10px;"> 3V3 </td>
<td style="padding:0 10px;"> &#8211; </td>
<td style="padding:0 10px;"> -</td>
</tr>
<tr>
<td style="padding:0 10px;"> 7 MAC </td>
<td style="padding:0 10px;"> white </td>
<td style="padding:0 10px;"> XDCS </td>
</tr>
<tr>
<td style="padding:0 10px;"> 6 LED </td>
<td style="padding:0 10px;"> &#8211; </td>
<td style="padding:0 10px;"> -</td>
</tr>
<tr>
<td style="padding:0 10px;"> 5 </td>
<td style="padding:0 10px;"> purple </td>
<td style="padding:0 10px;"> XRESET</td>
</tr>
<tr>
<td style="padding:0 10px;"> 4 </td>
<td style="padding:0 10px;"> grey </td>
<td style="padding:0 10px;"> DREQ </td>
</tr>
</table>
<h2>IcyArduino explained</h2>
<p>Now let&#8217;s take a tour through IcyArduino.ino.</p>
<h3>setup</h3>
<p>First, we initialize serial and printf, then print out some information so we know that all is well sofar.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span class="Type">void</span> setup(<span class="Type">void</span>)<br />{<br />&nbsp;&nbsp;<span class="Comment">// Bring up serial and print some hello text</span><br />&nbsp;&nbsp;Serial.begin(<span class="Constant">57600</span>);<br />&nbsp;&nbsp;printf_begin();<br />&nbsp;&nbsp;printf_P(PSTR(<span class="Constant">__FILE__</span> <span class="String">&quot;</span><span class="Special">\r\n</span><span class="String">&quot;</span>));<br />&nbsp;&nbsp;printf_P(PSTR(<span class="String">&quot;Free memory = </span><span class="Special">%u</span><span class="String"> bytes</span><span class="Special">\r\n</span><span class="String">&quot;</span>),SP-(__brkval?(<span class="Type">uint16_t</span>)__brkval:(<span class="Type">uint16_t</span>)&amp;__heap_start));<br /></code></div>
<p>Second, we bring up the three layers of uIP, first the chip driver, then the uIP stack, then the webclient applet.  Note that this sketch uses static IP addresses for simplicity.</p>
<div style="background-color:#7d170d;padding:5px;"><code>&nbsp;&nbsp;<span class="Comment">// Bring up ENC28J60 driver</span><br />&nbsp;&nbsp;network_prepare_MAC(mac.addr);<br />&nbsp;&nbsp;network_init();<br />&nbsp;&nbsp;enc28j60Write(ECOCON, <span class="Constant">1</span> &amp; <span class="Constant">0x7</span>);	<span class="Comment">//Get a 25MHz signal from enc28j60</span><br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Bring up uIP</span><br />&nbsp;&nbsp;uip_init();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Setup MAC address</span><br />&nbsp;&nbsp;uip_setethaddr(mac);<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Setup our IP, gateway, and netmask -- all statically</span><br />&nbsp;&nbsp;uip_ipaddr_t ipaddr;<br />&nbsp;&nbsp;uip_ipaddr(ipaddr, <span class="Constant">192</span>,<span class="Constant">168</span>,<span class="Constant">1</span>,<span class="Constant">55</span>);<br />&nbsp;&nbsp;uip_sethostaddr(ipaddr);<br />&nbsp;&nbsp;uip_ipaddr(ipaddr, <span class="Constant">192</span>,<span class="Constant">168</span>,<span class="Constant">1</span>,<span class="Constant">1</span>);<br />&nbsp;&nbsp;uip_setdraddr(ipaddr);<br />&nbsp;&nbsp;uip_ipaddr(ipaddr, <span class="Constant">255</span>,<span class="Constant">255</span>,<span class="Constant">255</span>,<span class="Constant">0</span>);<br />&nbsp;&nbsp;uip_setnetmask(ipaddr);<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Bring up the webclient applet</span><br />&nbsp;&nbsp;webclient_init();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Now that everything is set up, start periodic timers for uIP</span><br />&nbsp;&nbsp;timer_set(&amp;periodic_timer, CLOCK_SECOND / <span class="Constant">2</span>);<br />&nbsp;&nbsp;timer_set(&amp;arp_timer, CLOCK_SECOND * <span class="Constant">10</span>);<br /></code></div>
<p>Finally, once uIP is up, we can finish up by starting the player and connect to our stream.</p>
<div style="background-color:#7d170d;padding:5px;"><code>&nbsp;&nbsp;<span class="Comment">// Bring up the MP3 player</span><br />&nbsp;&nbsp;player.begin();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span class="Comment">// Launch a connection to our stream</span><br />&nbsp;&nbsp;connect();<br />}<br /></code></div>
<h3>loop</h3>
<p>The loop() is a stock uIP main loop, which is looking for new packets and handing them off to uIP correctly.  The one thing I added is some reconnection logic to the arp timer.  This fires every 10 seconds, which I thought was a good time to reconnect if we&#8217;ve lost the connection.  Also, commented out by default, is a troubleshooting mechanism to print uIP statistics.  This is a good thing to turn on if things aren&#8217;t working right.</p>
<div style="background-color:#7d170d;padding:5px;"><code>&nbsp;&nbsp;&nbsp;&nbsp;if(timer_expired(&amp;arp_timer))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer_reset(&amp;arp_timer);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uip_arp_timer();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Uncomment to get a periodic dump of stats.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//dump_uip_stats();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Also use this timer to reconnect if we've lost connection<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!connected)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connect();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /></code></div>
<h3>callbacks</h3>
<p>This section contains the pre-defined callbacks which the webclient applet will use to signal changes.</p>
<p>The datahandler is called by the webclient applet when there is data to handle.  This simply passes it off to the driver to be played, plus captures some statistics about the transfer.</p>
<div style="background-color:#7d170d;padding:5px;"><code>void webclient_datahandler(char *data, u16_t len)<br />{<br />&nbsp;&nbsp;Serial.print('.');<br />&nbsp;<br />&nbsp;&nbsp;if ( ! started_at )<br />&nbsp;&nbsp;&nbsp;&nbsp;started_at = millis();<br />&nbsp;<br />&nbsp;&nbsp;size_received += len;<br />&nbsp;<br />&nbsp;&nbsp;player.playChunk(reinterpret_cast&lt;uint8_t*&gt;(data),len);<br />&nbsp;<br />&nbsp;&nbsp;if (!data)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Serial.println();<br />&nbsp;&nbsp;&nbsp;&nbsp;printf_P(PSTR(&quot;%lu: DONE. Received %lu bytes in %lu msec.\r\n&quot;),millis(),size_received,millis()-started_at);<br />&nbsp;&nbsp;}<br />}<br /></code></div>
<p>The rest of the file simply deals with the start and stop conditions, setting the current status as appropriate and printing status messages.</p>
<div style="background-color:#7d170d;padding:5px;"><code>void webclient_connected(void)<br />{<br />&nbsp;&nbsp;uip_log_P(PSTR(&quot;webclient_connected&quot;));<br />&nbsp;&nbsp;player.startSong();<br />&nbsp;&nbsp;connected = true;<br />}<br />&nbsp;&nbsp;<br />void webclient_timedout(void)<br />{<br />&nbsp;&nbsp;uip_log_P(PSTR(&quot;TIMEOUT.&nbsp;&nbsp;Reconnecting within 10s.\r\n&quot;));<br />&nbsp;&nbsp;player.stopSong();<br />&nbsp;&nbsp;connected = false;<br />}<br />&nbsp;&nbsp;<br />void webclient_aborted(void)<br />{<br />&nbsp;&nbsp;uip_log_P(PSTR(&quot;ABORTED.&nbsp;&nbsp;Reconnecting within 10s.\r\n&quot;));<br />&nbsp;&nbsp;player.stopSong();<br />&nbsp;&nbsp;connected = false;<br />}<br />&nbsp;&nbsp;<br />void webclient_closed(void)<br />{<br />&nbsp;&nbsp;uip_log_P(PSTR(&quot;webclient_closed\r\n&quot;));<br />&nbsp;&nbsp;player.stopSong();<br />&nbsp;&nbsp;connected = false;<br />}<br /></code></div>
<h3>Nanode For the Win</h3>
<p>This project will work fine using a generic Arduino clone of any sort and nearly any ENC28J60-based Ethernet module or shield.  But it&#8217;s best on Nanode for a few reasons:</p>
<ul>
<li>Nanode has a <a href="http://wiki.london.hackspace.org.uk/view/Project:Nanode/docs">secondary pinout</a> that is much more rational than Arduino.  All of the VS1053 wires can plug in neatly and securely into a single 12-pin connector attached to the side of the board.</li>
<li>Nanode has a its own MAC address.  So rather than making up a MAC and hoping it doesn&#8217;t conflict with anyone else&#8217;s out there, we know we have a proper address.</li>
<li>Nanode has a LED that doesn&#8217;t conflict with SCK, so we can actually use it on a project that relies on SPI.  Can&#8217;t do that with the stock Arduino LED.</li>
</ul>
<h2 style="text-align:center;padding:3px;"><a title="Some cool things about Nanode" href="http://www.flickr.com/photos/maniacbug/6600813841/"><img style="border:solid 2px #000000;" alt="Some cool things about Nanode" src="http://farm8.staticflickr.com/7017/6600813841_aff4a6dbea.jpg" /></a></h2>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/264/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=264&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2011/12/30/arduino-on-ice-internet-radio-via-shoutcast/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7165/6600655547_3b6f91af24_z.jpg" medium="image">
			<media:title type="html">Nanode streaming Internet Radio (close-up)</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7017/6600813841_aff4a6dbea.jpg" medium="image">
			<media:title type="html">Some cool things about Nanode</media:title>
		</media:content>
	</item>
		<item>
		<title>nRF24L01+ Running on Maple</title>
		<link>http://maniacbug.wordpress.com/2011/12/14/nrf24l01-running-on-maple-3/</link>
		<comments>http://maniacbug.wordpress.com/2011/12/14/nrf24l01-running-on-maple-3/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 02:56:48 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Maple]]></category>
		<category><![CDATA[RF Radio]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=249</guid>
		<description><![CDATA[Last weekend, I got a Maple Native board from Leaf Labs. This is a somewhat-Arduino-compatible board running a STM Cortex-M3 processor with 512k flash and 1M of external RAM. I figure it will ease the wait for the Arduino Due. &#8230; <a href="http://maniacbug.wordpress.com/2011/12/14/nrf24l01-running-on-maple-3/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=249&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="nRF24L01+ connected to Leaf Labs Maple Native" href="http://www.flickr.com/photos/maniacbug/6489477865/"><img style="border:solid 2px #000000;" alt="nRF24L01+ connected to Leaf Labs Maple Native" src="http://farm8.staticflickr.com/7012/6489477865_b56edb629b_z.jpg" /></a></h2>
<p>Last weekend, I got a <a href="http://leaflabs.com/store/#Maple-Native">Maple Native</a> board from Leaf Labs.  This is a somewhat-Arduino-compatible board running a STM Cortex-M3 processor with 512k flash and 1M of external RAM.  I figure it will ease the wait for the Arduino Due.</p>
<p>So my first task is to port <a href="http://maniacbug.github.com/RF24/">RF24</a>, my Driver for nRF24L01(+) 2.4GHz Wireless Transceiver library.  This library makes it easy to use dirt-cheap <a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;products_id=53">nRF24L01+ modules</a> for radio communication.</p>
<p><span id="more-249"></span>
<p>It turns out the port was dead simple.  So now Maple users can enjoy the benefits of $4 RF Radios.</p>
<h2>The Hardware</h2>
<p>In the picture above, I re-used the board introduced earlier in my <a href="http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/">Getting Started with nRF24L01+ on Arduino</a> post.  Happily, the pins are in the same order on the Arduino as the Maple, so the same board fits neatly onto the Maple Native, albeit oriented backwards.  Then, wires are needed to connect VCC and GND over to the module.  All of the other power (red &amp; black) wires on the green board are extraneous on Maple.</p>
<h2>The Example</h2>
<p>Check out the specific example for Maple, <a href="https://github.com/maniacbug/RF24/blob/master/examples/pingpair_maple/pingpair_maple.pde">pingpair_maple</a>.  </p>
<p>Put the same sketch on two units.  On one of the boards, tie pin #10 to ground.  On the other, leave it floating.  This mechanism identifies one of the units as the sender, and the other as the receiver.  Power them both up, and watch the debug spew tell the tale.</p>
<div style="background-color:#7d170d;padding:5px;"><code>Now sending 90...ok...Got response 90, round-trip delay: 28<br />Now sending 1122...ok...Got response 1122, round-trip delay: 26<br />Now sending 2152...ok...Got response 2152, round-trip delay: 27<br />Now sending 3182...ok...Got response 3182, round-trip delay: 29<br />Now sending 4214...ok...Got response 4214, round-trip delay: 27<br />Now sending 5244...ok...Got response 5244, round-trip delay: 29<br />Now sending 6277...ok...Got response 6277, round-trip delay: 26<br />Now sending 7307...ok...Got response 7307, round-trip delay: 26<br />Now sending 8337...ok...Got response 8337, round-trip delay: 29<br />Now sending 9369...ok...Got response 9369, round-trip delay: 27<br />Now sending 10399...ok...Got response 10399, round-trip delay: 29<br />Now sending 11431...ok...Got response 11431, round-trip delay: 27<br />Now sending 12462...ok...Got response 12462, round-trip delay: 28<br /></code></div>
<p>As I only have one Maple, I tested it using a Maple and one of my <a href="http://maniacbug.wordpress.com/2011/10/19/sensor-node/">Wireless Sensor Nodes</a></p>
<h2>The Changes</h2>
<p>Mainly what was needed was to re-arrange the Arduino-specific header files into their own header, and add some compatibility glue.</p>
<h3>rf24_config.h</h3>
<div style="background-color:#7d170d;padding:5px;"><code>#ifndef __RF24_CONFIG_H__<br />#define __RF24_CONFIG_H__<br />&nbsp;<br />#if ARDUINO &lt; 100<br />#include &lt;WProgram.h&gt;<br />#else<br />#include &lt;Arduino.h&gt;<br />#endif<br />&nbsp;<br />#include &lt;stddef.h&gt;<br />&nbsp;<br />// Stuff that is normally provided by Arduino<br />#ifndef ARDUINO<br />#include &lt;stdint.h&gt;<br />#include &lt;stdio.h&gt;<br />#include &lt;string.h&gt;<br />extern HardwareSPI SPI;<br />#define _BV(x) (1&lt;&lt;(x))<br />#endif<br />&nbsp;<br />#undef SERIAL_DEBUG<br />#ifdef SERIAL_DEBUG<br />#define IF_SERIAL_DEBUG(x) ({x;})<br />#else<br />#define IF_SERIAL_DEBUG(x)<br />#endif<br />&nbsp;<br />// Avoid spurious warnings<br />#if ! defined( NATIVE ) &amp;&amp; defined( ARDUINO )<br />#undef PROGMEM<br />#define PROGMEM __attribute__(( section(".progmem.data") ))<br />#undef PSTR<br />#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &amp;__c[0];}))<br />#endif<br />&nbsp;<br />// Progmem is Arduino-specific<br />#ifdef ARDUINO<br />#include &lt;avr/pgmspace.h&gt;<br />#define PRIPSTR "%S"<br />#else<br />typedef char const prog_char;<br />typedef uint16_t prog_uint16_t;<br />#define PSTR(x) (x)<br />#define printf_P printf<br />#define strlen_P strlen<br />#define PROGMEM<br />#define pgm_read_word(p) (*(p))<br />#define PRIPSTR "%s"<br />#endif<br />&nbsp;<br />#endif // __RF24_CONFIG_H__<br /></code></div>
<h3>SPI Configiration</h3>
<p>Needed to avoid setting SPI parameters in the Arduino fashion.  Fortunately, the defaults for Maple HardwareSPI were correct for this radio, so no SPI configuration was needed whatsoever.</p>
<div style="background-color:#7d170d;padding:5px;"><code>void RF24::csn(int mode)<br />{<br />#ifdef ARDUINO<br />  SPI.setBitOrder(MSBFIRST);<br />  SPI.setDataMode(SPI_MODE0);<br />  SPI.setClockDivider(SPI_CLOCK_DIV4);<br />#endif<br />  digitalWrite(csn_pin,mode);<br />}<br /></code></div>
<h3>pingpair_maple.pde</h3>
<p>The example needed a little tuning:</p>
<div style="background-color:#7d170d;padding:5px;"><code>//<br />// Maple specific setup. Other than this section, the sketch is the same on Maple as on<br />// Arduino<br />//<br />&nbsp;<br />#ifdef MAPLE_IDE<br />&nbsp;<br />// External startup function<br />extern void board_start(const char* program_name);<br />&nbsp;<br />// Use SPI #2.<br />HardwareSPI SPI(2);<br />&nbsp;<br />#else<br />#define board_startup printf<br />#define toggleLED(x) (x)<br />#endif<br /></code></div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/249/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/249/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/249/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=249&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2011/12/14/nrf24l01-running-on-maple-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7012/6489477865_b56edb629b_z.jpg" medium="image">
			<media:title type="html">nRF24L01+ connected to Leaf Labs Maple Native</media:title>
		</media:content>
	</item>
		<item>
		<title>Arduino on ATmega1284P</title>
		<link>http://maniacbug.wordpress.com/2011/11/27/arduino-on-atmega1284p-4/</link>
		<comments>http://maniacbug.wordpress.com/2011/11/27/arduino-on-atmega1284p-4/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 20:45:11 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=240</guid>
		<description><![CDATA[Sooner or later, the Arduino starts to feel a little claustrophobic. Your sketches start running out of memory, so you need more RAM. You want to talk serial to another peripheral (like an RFID Module) AND watch the action in &#8230; <a href="http://maniacbug.wordpress.com/2011/11/27/arduino-on-atmega1284p-4/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=240&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="ATmega1284P on a breadboard" href="http://www.flickr.com/photos/maniacbug/6381016739/"><img style="border:solid 2px #000000;" src="http://farm7.staticflickr.com/6114/6381016739_f43b4d5ef9_z.jpg" alt="ATmega1284P on a breadboard" /></a></h2>
<p>Sooner or later, the Arduino starts to feel a little claustrophobic. Your sketches start running out of memory, so you need more RAM. You want to talk serial to another peripheral (like an <a href="http://maniacbug.wordpress.com/2011/10/09/125khz-rfid-module-rdm630/">RFID Module</a>) AND watch the action in the Serial Monitor at the same time, so you need more UARTS. You want to use SPI and control a motor and read a few sensors, and pretty soon you&#8217;re out of pins, so you need more I/O pins. You&#8217;re logging data, and running out of 1k EEPROM fast, so a bit more EEPROM would sure be handy.</p>
<p>The obvious solution to this problem is an <a href="http://www.mouser.com/ProductDetail/Arduino/A000047/?qs=sGAEpiMZZMs0PWRNvpRp0BuldInrlO5S">Arduino Mega 2560</a>. Oh yeah, this thing is powerful! 54 pins! 4 UARTS! 8k RAM! You add it to your cart, and then realize it&#8217;s almost $50.</p>
<p>Now maybe you&#8217;re wondering, isn&#8217;t there anything in-between that might be a bit less cash? Indeed there is, it&#8217;s call the ATmega1284P and today I&#8217;m going to explore getting Arduino to run on it, on a breadboard.</p>
<p><span id="more-240"></span></p>
<h2>Comparison</h2>
<p>Here&#8217;s a quick breakdown of three chips&#8230; The 328P powers the Uno, the 2560P powers the Mega 2560, and the 1284P is the &#8216;Goldilocks&#8217; chip, nestled right in the middle&#8211;EXCEPT for RAM. It has an abundance of RAM (16k!) which is important because RAM is typically the resource you run out of the quickest.</p>
<table>
<tbody>
<tr style="background-color:#eeeeee;color:red;">
<td style="padding:0 10px;"><strong> Feature </strong></td>
<td style="padding:0 10px;"><strong> 328P </strong></td>
<td style="padding:0 10px;"><strong> 1284P </strong></td>
<td style="padding:0 10px;"><strong> 2560P </strong></td>
</tr>
<tr>
<td style="padding:0 10px;">Price</td>
<td style="padding:0 10px;">$2.99</td>
<td style="padding:0 10px;">$4.66</td>
<td style="padding:0 10px;">$11.28</td>
</tr>
<tr>
<td style="padding:0 10px;">RAM</td>
<td style="padding:0 10px;">2k</td>
<td style="padding:0 10px;">16k</td>
<td style="padding:0 10px;">8k</td>
</tr>
<tr>
<td style="padding:0 10px;">Flash</td>
<td style="padding:0 10px;">32k</td>
<td style="padding:0 10px;">128k</td>
<td style="padding:0 10px;">256k</td>
</tr>
<tr>
<td style="padding:0 10px;">EEPROM</td>
<td style="padding:0 10px;">1k</td>
<td style="padding:0 10px;">4k</td>
<td style="padding:0 10px;">4k</td>
</tr>
<tr>
<td style="padding:0 10px;">UART</td>
<td style="padding:0 10px;">1</td>
<td style="padding:0 10px;">2</td>
<td style="padding:0 10px;">4</td>
</tr>
<tr>
<td style="padding:0 10px;">IO Pins</td>
<td style="padding:0 10px;">23</td>
<td style="padding:0 10px;">32</td>
<td style="padding:0 10px;">86</td>
</tr>
<tr>
<td style="padding:0 10px;">Interrupts</td>
<td style="padding:0 10px;">2</td>
<td style="padding:0 10px;">3</td>
<td style="padding:0 10px;">8</td>
</tr>
<tr>
<td style="padding:0 10px;">Analog Inputs</td>
<td style="padding:0 10px;">6</td>
<td style="padding:0 10px;">8</td>
<td style="padding:0 10px;">16</td>
</tr>
</tbody>
</table>
<h2>Background Reading</h2>
<p>I&#8217;m going to build an Arduino ATmega1284P circuit on a breadboard, burn a bootloader, and upload sketches to it, all using the Arduino 1.0 IDE. This will all go better if you have done it once first with a regular ATmega328P. Doing these things on that chip is well-documented, and easy to get support on the forums if something goes wrong.</p>
<p>So first, read up and practice up on a 328P with help from these handy pages on the Arduino Wiki:</p>
<ul>
<li><a href="http://www.arduino.cc/en/Main/Standalone">Building Arduino on a Breadboard</a></li>
<li><a href="http://arduino.cc/en/Tutorial/ArduinoISP">Arduino ISP Tutorial</a></li>
</ul>
<h2>Building the Circuit</h2>
<h2 style="text-align:center;padding:3px;"><a title="ATmega1284P on a Breadboard.sch" href="http://www.flickr.com/photos/maniacbug/6413368937/"><img style="border:solid 2px #000000;" src="http://farm8.staticflickr.com/7009/6413368937_48cacb7410.jpg" alt="ATmega1284P on a Breadboard.sch" /></a></h2>
<p>There are three sections to the circuit show above. (Click on the image for a higher-resolution).</p>
<ul>
<li>Power/Timing. I&#8217;m using a 16MHz crystal and 22pF caps for timing and a 0.1uF cap for power.</li>
<li>FTDI. I use a Sparkfun FTDI breakout to program everything, so I&#8217;ve set this breadboard up with a connector for that mechanism.</li>
<li>Arduino ISP. To burn the bootloader using Arduino as ISP, six connections are needed from the Arduino. The from/to pins are indicated on the schematic.</li>
</ul>
<p>For another view, check out this forum thread: <a href="http://arduino.cc/forum/index.php/topic,64612.0.html">Using the 1284p/664p (IDE, bread board and boot loaders)</a></p>
<h2>Get the Software</h2>
<p>The Arduino makes it easy to support a new &#8216;Hardware Platform&#8217;. The files you need are hosted on github, the <a href="https://github.com/maniacbug/mighty-1284p">Mighty 1284P Platform for Arduino</a>.</p>
<p>WARNING this ONLY WORKS on Arduino 1.0. It would be possible to back-port to 0022, but seems unneeded now that 1.0 is nearing final release.</p>
<p>To install it&#8230;</p>
<ol>
<li>Download the <a href="https://github.com/maniacbug/mighty-1284p/zipball/master">ZIP File</a></li>
<li>Unzip it a folder called &#8216;hardware&#8217; off your sketches directory, e.g. /Users/maniacbug/Source/Arduino/hardware/mighty-1284p</li>
<li>Restart the IDE</li>
<li>Select Tools &gt; Boards &gt; Mighty 1284P</li>
</ol>
<h2>Burn a Bootloader</h2>
<p>Once you have the Mighty 1284P platform set up, burning a bootloader is trivial. Follow the Arduino ISP instructions. You first burn the &#8220;Arduino ISP&#8221; sketch onto a regular Ardunio. Then change the &#8220;Boards&#8221; setting to the Mighty 1284P, hook up the &#8216;Arduino&#8217; connections in the schematic above, choose &#8220;Tools &gt; Programmer &gt; Arduino as ISP&#8221; from the IDE, and then &#8220;Tools &gt; Burn bootloader.&#8221;</p>
<p>To verify that it worked, move the LED to pin 1, and power cycle the breadboard. When the bootloader starts it flashes pin 1.</p>
<h2>Upload a Sketch</h2>
<p>Uploading a sketch is trivial now that the platform is set up and bootloader is in place. Try the &#8216;Blink&#8217; example first, but change the LED pin to &#8217;1&#8242; in the sketch. (Of course, move the LED back to the right pin, which is pin 2 on the MCU).</p>
<h2>Understanding Pin Mappings</h2>
<p>When you refer to a &#8220;pin&#8221; in the Arduino environment, e.g. &#8220;digitalWrite(13,HIGH)&#8221;, the system maps that pin onto a MCU pin. There is definitely no standard pin mapping for 1284P, many people have published their own. I chose a mapping that makes sense for the breadboard, where the digital pins start at MCU pin 1, and simply go around the chip counter-clockwise.</p>
<div style="background-color:#7d170d;padding:5px;"><code>                      +---\/---+<br />
(D 0) PB0 1|        |40 PA0 (AI 0 / D24)<br />
(D 1) PB1 2|        |39 PA1 (AI 1 / D25)<br />
INT2 (D 2) PB2 3|        |38 PA2 (AI 2 / D26)<br />
PWM (D 3) PB3 4|        |37 PA3 (AI 3 / D27)<br />
PWM/SS (D 4) PB4 5|        |36 PA4 (AI 4 / D28)<br />
MOSI (D 5) PB5 6|        |35 PA5 (AI 5 / D29)<br />
PWM/MISO (D 6) PB6 7|        |34 PA6 (AI 6 / D30)<br />
PWM/SCK (D 7) PB7 8|        |33 PA7 (AI 7 / D31)<br />
RST 9|        |32 AREF<br />
VCC 10|        |31 GND<br />
GND 11|        |30 AVCC<br />
XTAL2 12|        |29 PC7 (D 23)<br />
XTAL1 13|        |28 PC6 (D 22)<br />
RX0 (D 8 )PD0 14|        |27 PC5 (D 21) TDI<br />
TX0 (D 9) PD1 15|        |26 PC4 (D 20) TDO<br />
RX1/INT0 (D 10) PD2 16|        |25 PC3 (D 19) TMS<br />
TX1/INT1 (D 11) PD3 17|        |24 PC2 (D 18) TCK<br />
PWM (D 12) PD4 18|        |23 PC1 (D 17) SDA<br />
PWM (D 13) PD5 19|        |22 PC0 (D 16) SCL<br />
PWM (D 14) PD6 20|        |21 PD7 (D 15) PWM<br />
+--------+<br />
</code></div>
<h2>Alternatives</h2>
<p>There are a handful of folks who have built a fully-functional board with 1284P. These are all worth checking out to see if one meets your needs. Still, I think there is a gap to be filled for a cheap 1284P-based Arduino with minimal add-ons.</p>
<ul>
<li><a href="http://sanguino.cc/">Sanguino</a>. The classic. Uses ATmega644 which is real close to the 1284, but the core is not maintained beyond Arduino 0017.</li>
<li><a href="http://www.crossroadsfencing.com/BobuinoRev17/">Bobuino</a>. Capable, fully-featured board, with SD, RTC, USB, and more. You pay $80 for all those features&#8211;which is great if you need it all, but it&#8217;s too expensive if you just need a bit more power for your projects.  In my view, you might as well get a Mega 2560.  My other complaint is the lack of coherent software distribution. The (hidden) <a href="http://www.crossroadsfencing.com/BobuinoRev17/Bobuino_directions.doc">directions</a> expect users to cobble together a system from various places, and then includes a (hidden) <a href="http://www.crossroadsfencing.com/BobuinoRev17/Bobuino17.zip">package of files</a> which is not under source control. And worse, no source for the bootloader.</li>
<li><a href="http://www.brewtroller.com/">Brewtroller</a> <a href="http://code.google.com/p/brewtroller/downloads/detail?name=Sanguino1284P.zip">Sanguino1284P.zip</a>. Looks like the most complete distribution. Not ported to 1.0 yet. Uses the backwards analog pin mappings from avr-developers. Designed for specialized use (brewing control).</li>
<li><a href="http://blog.stevemarple.co.uk/2011/08/introducing-calunium-arduino-clone.html">Calunium</a> <a href="http://www.flickr.com/photos/stevemarple/sets/72157627418450430/">Photos</a> <a href="https://github.com/stevemarple/Calunium">on Github</a>. Ported to 1.0. Uses a rather custom pin arrangement. No bootloader. Still, looks like the best bet overall.</li>
<li><a href="http://bahbots.com/">BahBots Controller</a>. See <a href="http://bahbots.com/forum/viewtopic.php?f=5&amp;t=10">Setting up support for the BahBots controller in Arduino</a>. I couldn&#8217;t find the bootloader, it runs at 20MHz (I want 16MHz). Again, requires you to cobble together a core using the avr-developers core.</li>
</ul>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/240/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=240&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2011/11/27/arduino-on-atmega1284p-4/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm7.staticflickr.com/6114/6381016739_f43b4d5ef9_z.jpg" medium="image">
			<media:title type="html">ATmega1284P on a breadboard</media:title>
		</media:content>

		<media:content url="http://farm8.staticflickr.com/7009/6413368937_48cacb7410.jpg" medium="image">
			<media:title type="html">ATmega1284P on a Breadboard.sch</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Started with nRF24L01+ on Arduino</title>
		<link>http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/</link>
		<comments>http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 05:05:46 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[RF Radio]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=229</guid>
		<description><![CDATA[Nordic&#8217;s nRF24L01+ 2.4GHz RF radios are a great way to communicate wirelessly between Arduino&#8217;s. They&#8217;re cheap, and powerful. Unfortunately, they can be a little daunting to beginners to get started. Today, I want to make it easy for total beginners &#8230; <a href="http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=229&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="RF24 Getting Started - Finished Product" href="http://www.flickr.com/photos/maniacbug/6307669179/"><img style="border:solid 2px #000000;" alt="RF24 Getting Started - Finished Product" src="http://farm7.static.flickr.com/6044/6307669179_a8d19298a6_z.jpg" /></a></h2>
<p>Nordic&#8217;s nRF24L01+ 2.4GHz RF radios are a great way to communicate wirelessly between Arduino&#8217;s.  They&#8217;re cheap, and powerful.  Unfortunately, they can be a little daunting to beginners to get started.  Today, I want to make it easy for total beginners to get up and running on nRF24L01+ radios quickly and easily.</p>
<h2>Stuff we need</h2>
<p>First, we have to go shopping.  A great place to start is the iTeadStudio store.  Here&#8217;s what you need.  Obviously, you&#8217;ll want to buy two of the radios and protoboards because what good is a radio that can only talk to itself?</p>
<ul>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=7&amp;products_id=53">2.4G Wireless nRF24L01+ Module</a> $4.00</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_12&amp;products_id=390">2.54mm 2x4Pin Female Header (5Pcs)</a> $1.50</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_12&amp;products_id=228">2.54mm 40Pin Male Header (5 Psc)</a> $1.50</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_13&amp;products_id=418">Double Side ProtoBoard 5cm * 7cm</a> $0.99</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=10_11&amp;products_id=136">Solder cable &#8211; 7cm (10pcs)</a> $0.50 (Or get some wire at Home Depot and cut it yourself)</li>
</ul>
<p>Reasonable substitutes for this stuff can also be found at Sparkfun if you like spending a lot more money.  Also the radios are at <a href="http://www.mdfly.com/index.php?main_page=product_info&amp;cPath=8_52&amp;products_id=81">MDfly.com</a>.</p>
<p><span id="more-229"></span><br />
<h2>Preparation</h2>
<p>We only need one of the 2&#215;4 pin female headers.  Cut off two chunks of the male headers, lengths of 6 and 8 pins.  Cut wires to about 2inches in length.  If you use the 7cm wires from iTeadStudio, it&#8217;s OK, you&#8217;ll just have a little extra wire in the way.</p>
<p>Here&#8217;s what it looks like all ready to go.  Click on the picture for a closer view.  In this picture, I am using a pair of 4-pin female headers instead of a 2&#215;4 female header.  I also cut an extra green wire I decided not to use in this tutorial.</p>
<h2 style="text-align:center;padding:3px;"><a title="RF24 Getting Started - Parts" href="http://www.flickr.com/photos/maniacbug/6307668499/"><img style="border:solid 2px #000000;" alt="RF24 Getting Started - Parts" src="http://farm7.static.flickr.com/6120/6307668499_60a7325e9d.jpg" /></a></h2>
<h2>Solder it up</h2>
<ul>
<li>The 8-pin male header goes in position C09-16.</li>
<li>The 6-pin male header goes in position V13-18.</li>
<li>The 2&#215;4-pin male header goes in position K16-N15.</li>
<li>The wires are connected as follows:</li>
</ul>
<table>
<tr style="background-color:#EEEEEE;color:red;">
<td style="padding:0 10px;"> <strong>  Line </strong> </td>
<td style="padding:0 10px;"> <strong>  From Arduino Pin </strong> </td>
<td style="padding:0 10px;"> <strong>  From Grid Position </strong> </td>
<td style="padding:0 10px;"> <strong>  To Radio Pin </strong> </td>
<td style="padding:0 10px;"> <strong>  To Grid Position </strong> </td>
</tr>
<tr>
<td style="padding:0 10px;"> GND </td>
<td style="padding:0 10px;"> GND </td>
<td style="padding:0 10px;"> U17 </td>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> N17</td>
</tr>
<tr>
<td style="padding:0 10px;"> 3V3 </td>
<td style="padding:0 10px;"> 3V3 </td>
<td style="padding:0 10px;"> U14 </td>
<td style="padding:0 10px;"> 2 </td>
<td style="padding:0 10px;"> N14</td>
</tr>
<tr>
<td style="padding:0 10px;"> CE </td>
<td style="padding:0 10px;"> 9 </td>
<td style="padding:0 10px;"> D15 </td>
<td style="padding:0 10px;"> 3 </td>
<td style="padding:0 10px;"> M17</td>
</tr>
<tr>
<td style="padding:0 10px;"> CSN </td>
<td style="padding:0 10px;"> 10 </td>
<td style="padding:0 10px;"> D14 </td>
<td style="padding:0 10px;"> 4 </td>
<td style="padding:0 10px;"> M14</td>
</tr>
<tr>
<td style="padding:0 10px;"> SCK </td>
<td style="padding:0 10px;"> 13 </td>
<td style="padding:0 10px;"> D11 </td>
<td style="padding:0 10px;"> 5 </td>
<td style="padding:0 10px;"> L17</td>
</tr>
<tr>
<td style="padding:0 10px;"> MOSI </td>
<td style="padding:0 10px;"> 11 </td>
<td style="padding:0 10px;"> D13 </td>
<td style="padding:0 10px;"> 6 </td>
<td style="padding:0 10px;"> L14</td>
</tr>
<tr>
<td style="padding:0 10px;"> MISO </td>
<td style="padding:0 10px;"> 12 </td>
<td style="padding:0 10px;"> D12 </td>
<td style="padding:0 10px;"> 7 </td>
<td style="padding:0 10px;"> K16</td>
</tr>
</table>
<p>Here&#8217;s what it looks like with all the wires in place, up close and personal.  Again, click through for even bigger images.</p>
<h2 style="text-align:center;padding:3px;"><a title="RF24 Getting Started - Connections Close-up" href="http://www.flickr.com/photos/maniacbug/6308190888/"><img style="border:solid 2px #000000;" alt="RF24 Getting Started - Connections Close-up" src="http://farm7.static.flickr.com/6037/6308190888_9f2f3c2562.jpg" /></a></h2>
<h2>Software</h2>
<p>Get the <a href="http://maniacbug.github.com/RF24/">RF24</a> library from github.  There is ample documentation at that link, as well as a pointer to the downloads page.  Unzip the archive in to your &#8216;libraries&#8217; folder under your sketch folder (mine is in /home/users/maniacbug/Source/Arduino/libraries), and restart the Arduino IDE.</p>
<p>From the File menu, select &#8220;Examples&#8221;, then &#8220;RF24&#8243;, and finally &#8220;GettingStarted&#8221;.  This will load up the GettingStarted example.  It looks something like this.  Take a look at the <a href="http://maniacbug.github.com/RF24/GettingStarted_8pde-example.html">GettingStarted example</a> in the documentation for all the details.</p>
<div style="background-color:#7d170d;padding:5px;"><code><span style="color:#7E7E7E;">/**</span><br /><span style="color:#7E7E7E;">&nbsp;*&nbsp;Example&nbsp;for&nbsp;Getting&nbsp;Started&nbsp;with&nbsp;nRF24L01+&nbsp;radios.&nbsp;</span><br /><span style="color:#7E7E7E;">&nbsp;*</span><br /><span style="color:#7E7E7E;">&nbsp;*&nbsp;This&nbsp;is&nbsp;an&nbsp;example&nbsp;of&nbsp;how&nbsp;to&nbsp;use&nbsp;the&nbsp;RF24&nbsp;class.&nbsp;&nbsp;Write&nbsp;this&nbsp;sketch&nbsp;to&nbsp;two&nbsp;</span><br /><span style="color:#7E7E7E;">&nbsp;*&nbsp;different&nbsp;nodes.&nbsp;&nbsp;Put&nbsp;one&nbsp;of&nbsp;the&nbsp;nodes&nbsp;into&nbsp;'transmit'&nbsp;mode&nbsp;by&nbsp;connecting&nbsp;</span><br /><span style="color:#7E7E7E;">&nbsp;*&nbsp;with&nbsp;the&nbsp;serial&nbsp;monitor&nbsp;and&nbsp;sending&nbsp;a&nbsp;'T'.&nbsp;&nbsp;The&nbsp;ping&nbsp;node&nbsp;sends&nbsp;the&nbsp;current&nbsp;</span><br /><span style="color:#7E7E7E;">&nbsp;*&nbsp;time&nbsp;to&nbsp;the&nbsp;pong&nbsp;node,&nbsp;which&nbsp;responds&nbsp;by&nbsp;sending&nbsp;the&nbsp;value&nbsp;back.&nbsp;&nbsp;The&nbsp;ping&nbsp;</span><br /><span style="color:#7E7E7E;">&nbsp;*&nbsp;node&nbsp;can&nbsp;then&nbsp;see&nbsp;how&nbsp;long&nbsp;the&nbsp;whole&nbsp;cycle&nbsp;took.</span><br /><span style="color:#7E7E7E;">&nbsp;*/</span><br />&nbsp;<br />#include&nbsp;&lt;<span style="color:#CC6600;">SPI</span>.h&gt;<br />#include&nbsp;<span style="color:#006699;">"nRF24L01.h"</span><br />#include&nbsp;<span style="color:#006699;">"RF24.h"</span><br />#include&nbsp;<span style="color:#006699;">"printf.h"</span><br />&nbsp;<br /><span style="color:#7E7E7E;">//</span><br /><span style="color:#7E7E7E;">//&nbsp;Hardware&nbsp;configuration</span><br /><span style="color:#7E7E7E;">//</span><br />&nbsp;<br /><span style="color:#7E7E7E;">//&nbsp;Set&nbsp;up&nbsp;nRF24L01&nbsp;radio&nbsp;on&nbsp;SPI&nbsp;bus&nbsp;plus&nbsp;pins&nbsp;9&nbsp;&amp;&nbsp;10&nbsp;</span><br />&nbsp;<br />RF24&nbsp;radio(9,10);<br /></code></div>
<p>Upload the sketch, start the serial monitor, set the speed to 57600, and you should see this:</p>
<div style="background-color:#7d170d;padding:5px;"><code>RF24/examples/GettingStarted/<br />ROLE: Pong back<br />STATUS		 = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0<br />RX_ADDR_P0-1	 = 0xf0f0f0f0d2 0xf0f0f0f0e1<br />RX_ADDR_P2-5	 = 0xc3 0xc4 0xc5 0xc6<br />TX_ADDR		 = 0xf0f0f0f0d2<br />RX_PW_P0-6	 = 0x08 0x08 0x00 0x00 0x00 0x00<br />EN_AA		 = 0x3f<br />EN_RXADDR	 = 0x03<br />RF_CH		 = 0x4c<br />RF_SETUP	 = 0x07<br />CONFIG		 = 0x0f<br />DYNPD/FEATURE	 = 0x00 0x00<br />Data Rate	 = 1MBPS<br />Model		 = nRF24L01<br />CRC Length	 = 16 bits<br />PA Power	 = PA_HIGH<br /></code></div>
<p>Instead, if you see a lot of zeroes everywhere, something is wrong with your connections.  Double check them all again!  In the course of making this tutorial, I even switched two of the wires myself and had to re-solder them.  If you hooked everything else up right, you will see numbers just like those above.</p>
<h2>Make another one</h2>
<p>Ok, do it all again, making another protoboard shield, on top of another Arduino, so our first unit has something to talk to.</p>
<p>Start the second unit up, just like above, and launch the serial monitor at 57600.  Press the &#8216;T&#8217; key once the debugging text has printed successfully.  That will put this unit into Transmit mode, which sends a ping out to the other unit.  Make sure the other unit is still running, so this one has something to talk to!</p>
<p>Soon you will see the happy chatter of the radios doing their thing:</p>
<div style="background-color:#7d170d;padding:5px;"><code>Now sending 90...ok...Got response 90, round-trip delay: 28<br />Now sending 1122...ok...Got response 1122, round-trip delay: 26<br />Now sending 2152...ok...Got response 2152, round-trip delay: 27<br />Now sending 3182...ok...Got response 3182, round-trip delay: 29<br />Now sending 4214...ok...Got response 4214, round-trip delay: 27<br />Now sending 5244...ok...Got response 5244, round-trip delay: 29<br />Now sending 6277...ok...Got response 6277, round-trip delay: 26<br />Now sending 7307...ok...Got response 7307, round-trip delay: 26<br />Now sending 8337...ok...Got response 8337, round-trip delay: 29<br />Now sending 9369...ok...Got response 9369, round-trip delay: 27<br />Now sending 10399...ok...Got response 10399, round-trip delay: 29<br />Now sending 11431...ok...Got response 11431, round-trip delay: 27<br />Now sending 12462...ok...Got response 12462, round-trip delay: 28<br /></code></div>
<h2>From here&#8230;</h2>
<p>The examples directory in the RF24 library has all sorts of different things you can try.  If you&#8217;re feeling adventurous, you can even hook up the IRQ pin from pin 8 on the radio to pin 2 on the Arduino (that was what the extra green wire was for in my &#8216;parts&#8217; picture).</p>
<p>Instead of the ghetto-style ProtoBoard setup, you could step it up a notch and use a <a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=17&amp;products_id=197">Arduino ProtoShield Kit</a>.  See the more recent post, <a href="http://maniacbug.wordpress.com/2012/01/29/getting-started-rf24-proto/">Getting Started with nRF24L01+ using a Protoshield</a></p>
<p>In a future post, I&#8217;ll put up a simple PCB you could use instead of all the soldering.  It&#8217;ll be a little smaller, too.</p>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/229/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/229/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/229/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=229&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6044/6307669179_a8d19298a6_z.jpg" medium="image">
			<media:title type="html">RF24 Getting Started - Finished Product</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6120/6307668499_60a7325e9d.jpg" medium="image">
			<media:title type="html">RF24 Getting Started - Parts</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6037/6308190888_9f2f3c2562.jpg" medium="image">
			<media:title type="html">RF24 Getting Started - Connections Close-up</media:title>
		</media:content>
	</item>
		<item>
		<title>Low-Power Wireless Sensor Node</title>
		<link>http://maniacbug.wordpress.com/2011/10/19/sensor-node/</link>
		<comments>http://maniacbug.wordpress.com/2011/10/19/sensor-node/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 21:13:35 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[RF Radio]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=225</guid>
		<description><![CDATA[My goal today is to create a sensor node which can be used in a wireless sensor network, to capture environmental information and send it back to the base. My main goals are for the nodes to: Be cheap, and &#8230; <a href="http://maniacbug.wordpress.com/2011/10/19/sensor-node/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=225&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="RF Duinode V3 (2V4)" href="http://www.flickr.com/photos/maniacbug/6224308836/"><img style="border:solid 2px #000000;" alt="RF Duinode V3 (2V4)" src="http://farm7.static.flickr.com/6097/6224308836_b9b3b421a3_z.jpg" /></a></h2>
<p>My goal today is to create a sensor node which can be used in a wireless sensor network, to capture environmental information and send it back to the base.  My main goals are for the nodes to: Be cheap, and last for a year.</p>
<p>How cheap and how low-power can we go?  In the end, I got down under $12 for a very capable Arduino-compatible node with a 2.4GHz radio running ~2.6V that should last a year and a half on 2 AA&#8217;s, or 5 months on a coin cell.</p>
<p><span id="more-225"></span><br />
<h2>Adventures in Low Power</h2>
<p>Previously, I ran a small test network of these nodes using 3.3V regulated power.  After doing that, I realized it&#8217;s possible to run on even less power and with an even cheaper BOM by ditching the regulator entirely.  Two AA cells will range from 2.4 to 2.9V.  An Atmega328P MCU and the nRF24L01+ radio will both operate just fine in that range.</p>
<p>To enable this, I needed to create a new &#8216;board&#8217; in the Arduino IDE.  This board has two changes from the stock Duemilanove:</p>
<ul>
<li>Set the correct fuses for the &#8216;Brown-Out Detector&#8217; (BOD).  The Arduino IDE as-shipped sets the BOD to 2.7V, so the chip won&#8217;t even power up with 2x AA&#8217;s.</li>
<li>Run the chip at 8MHz clock rate.  That is exactly the edge of the specified clock rate curve for 2.4V, the low end of my voltage range.</li>
</ul>
<p>Here&#8217;s what my entry to the boards.txt file looks like exactly:</p>
<div style="background-color:#7d170d;padding:5px;"><code>lopower.name=Arduino Ultru Low-Power (&lt;2.4V, 8 MHz) w/ ATmega328<br />&nbsp;<br />lopower.upload.protocol=stk500<br />lopower.upload.maximum_size=30720<br />lopower.upload.speed=57600<br />&nbsp;<br />lopower.bootloader.low_fuses=0xFF<br />lopower.bootloader.high_fuses=0xDA<br />lopower.bootloader.extended_fuses=0x06<br />lopower.bootloader.path=atmega<br />lopower.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex<br />lopower.bootloader.unlock_bits=0x3F<br />lopower.bootloader.lock_bits=0x0F<br />&nbsp;<br />lopower.build.mcu=atmega328p<br />lopower.build.f_cpu=8000000L<br />lopower.build.core=arduino<br /></code></div>
<h2>Power Experimentation</h2>
<p>Now it&#8217;s time to measure and estimate power.  Our usage pattern will be the MCU and radio powered down as low as they can go most of the time.  Then they wake once every minute or two, transmit, and then go back to sleep.</p>
<p>These are the specific questions I needed to answer, so I ran experiments for each:</p>
<ul>
<li>How much power is consumed when sleeping?</li>
<li>How much power is consumed when awake and transmitting?</li>
<li>How long will it be sleeping each cycle? </li>
<li>How long will it be awake each cycle?</li>
<li>How much capacity is really available from the batteries?</li>
</ul>
<h3>Current Consumption</h3>
<p>To measure current, we need a multimeter capable of doing so.  I use a <a href="http://www.amazon.com/gp/product/B000EX0AE4">Extech EX330 Autoranging Mini Multimeter</a>, but many cheaper meters have current-measuring features.  Look for an &#8220;mA&#8221; setting.  The methodology here is to insert the multimeter inline into the circuit at the point we want to know the current flow.  That is, the current flows THROUGH the meter on its way from the battery to the load.  To keep things simple, it&#8217;s a good idea to use the actual battery being tested as the current source, rather than some external bench power.</p>
<p>There are two current measurements needed here, one while sleeping and the other while operating.  So I created simple test sketches that did each.  One just puts everything to sleep (MCU and radio), the other transmits constantly to a working receiver.  Simply measure the current from the meter during both tests.</p>
<p>Actually for the &#8216;transmitting&#8217; test, I am using the &#8220;endless sending&#8221; test.  This is consuming 13.57mA reliably.</p>
<p>For &#8216;sleeping&#8217;, I am getting strange results.  With the radio removed, and the voltage measurement circuit removed, the meter still reports 395 uA.  But on mA mode, it reports 0.14mA.  Argh!  Also, adding the radio in doesn&#8217;t seem to matter much.  Adding back in the voltage measurement, I hover up at 410 uA.</p>
<h3>Duration / Duty Cycle</h3>
<p>How long between wake-ups is defined by the application.  For now, I am waking once a minute, but that is likely much more frequently than needed to effectively measure temperature.</p>
<p>To measure how long it stays awake, I used the same &#8220;endless sending&#8221; test as for capacity.  I have the system endlessly send readings without actually ever sleeping.  Every 30 seconds, the receiver posts a reading to the database.  By counting the number of readings elapsed between each saved reading, I can see how long it takes to measure and send a reading.  In my tests, there were reliably 1128 readings every 30 seconds, for an awake duration of 27ms.</p>
<h3>Capacity</h3>
<p>The one true test for this is to take a fully-charged battery, and burn it to the ground.  Because consumption varies with current draw, it&#8217;s important to run the test at the correct amount of draw.  It seemed like the logical choice was to use the &#8216;constant transmitting&#8217; sketch which I used above to measure draw, and leave it on as long as it takes.  Two AA batteries lasted over a week!  So 156 hours @ 13.57mA tells us these &#8217;2300mAh&#8217; batteries actually gave about 2110mAh.</p>
<p>Just for fun, I had the sender transmit its voltage level, so I could graph the progress.</p>
<h2 style="text-align:center;padding:3px;"><a title="Capacity Test - 2AA @ 13mA" href="http://www.flickr.com/photos/maniacbug/6224740147/"><img style="border:solid 2px #000000;" alt="Capacity Test - 2AA @ 13mA" src="http://farm7.static.flickr.com/6108/6224740147_cd59d6791a.jpg" /></a></h2>
<p>In the end, I decided to go with a 3V coin cell battery, CR2450, rated at 540mAh.  This is a big trade-off.  With the coin cell, the units are much smaller and easier to place.  They are also a few dollars cheaper.  But I&#8217;ll only get 5 months, and the batteries are not rechargeable.</p>
<h2>Power Calculations</h2>
<p>Armed with these results, we can estimate how long the node will really last.  I have a handy spreadsheet I use for these calculations.  The results for this test are pasted below, but the same calculations can work for anything sleep/wake setup.  we plug in the answers to the five questions above, and out comes the answer we want to know: How long will it operate?</p>
<table>
<tr>
<td style="padding:0 10px;"> &#8216;<strong>Inputs </strong>&#8216;</td>
</tr>
<tr>
<td style="padding:0 10px;">Sleep Consumption</td>
<td style="padding:0 10px;"> 0.14 </td>
<td style="padding:0 10px;">mA </td>
</tr>
<tr>
<td style="padding:0 10px;">Operating Consumption</td>
<td style="padding:0 10px;"> 13.57 </td>
<td style="padding:0 10px;">mA </td>
</tr>
<tr>
<td style="padding:0 10px;">Sleep Duration</td>
<td style="padding:0 10px;"> 60 </td>
<td style="padding:0 10px;">s </td>
</tr>
<tr>
<td style="padding:0 10px;">Operating Duration</td>
<td style="padding:0 10px;"> 0.027 </td>
<td style="padding:0 10px;">s </td>
</tr>
<tr>
<td style="padding:0 10px;">Capacity</td>
<td style="padding:0 10px;"> 2035.5 </td>
<td style="padding:0 10px;">mAh </td>
</tr>
<tr>
<td style="padding:0 10px;"> </td>
<td style="padding:0 10px;">  </td>
<td style="padding:0 10px;" /></tr>
<tr>
<td style="padding:0 10px;"> &#8216;<strong>Per sleep cycle </strong>&#8216;</td>
</tr>
<tr>
<td style="padding:0 10px;">Capacity Used Sleeping</td>
<td style="padding:0 10px;"> 8.4 </td>
<td style="padding:0 10px;">=Sleep_Consumption * Sleep_Duration</td>
</tr>
<tr>
<td style="padding:0 10px;">Capacity Used Operating</td>
<td style="padding:0 10px;"> 0.36639 </td>
<td style="padding:0 10px;">=Operating_Consumption * Operating_Duration</td>
</tr>
<tr>
<td style="padding:0 10px;">Total Capacity Used mAs</td>
<td style="padding:0 10px;"> 8.76639 </td>
<td style="padding:0 10px;">=Operating_Consumption * Operating_Duration + Sleep_Consumption * Sleep_Duration</td>
</tr>
<tr>
<td style="padding:0 10px;">Total Capacity Used</td>
<td style="padding:0 10px;"> 0.00243510833333333 </td>
<td style="padding:0 10px;">=Total_Capacity_Used_mAs/3600 </td>
</tr>
<tr>
<td style="padding:0 10px;"> </td>
<td style="padding:0 10px;">  </td>
<td style="padding:0 10px;" /></tr>
<tr>
<td style="padding:0 10px;"> &#8216;<strong>Results </strong>&#8216;</td>
</tr>
<tr>
<td style="padding:0 10px;">Time Available cycles</td>
<td style="padding:0 10px;"> 835897.102456085 </td>
<td style="padding:0 10px;">=Capacity / Total_Capacity_Used</td>
</tr>
<tr>
<td style="padding:0 10px;">Time Available hours</td>
<td style="padding:0 10px;"> 13931.6183742681 </td>
<td style="padding:0 10px;">=Time_Available_cycles / (3600/Sleep_Duration)</td>
</tr>
<tr>
<td style="padding:0 10px;">Time Available days</td>
<td style="padding:0 10px;"> 580.484098927837 </td>
<td style="padding:0 10px;">=Time_Available_hours / 24</td>
</tr>
<tr>
<td style="padding:0 10px;">Time Available months</td>
<td style="padding:0 10px;"> 19.3494699642612 </td>
<td style="padding:0 10px;">=Time_Available_days / 30</td>
</tr>
</table>
<p>This file is available on Box.net: <a href="http://www.box.net/shared/g6f998mhpxa1yxihm9ta">Power Calculations.ods</a> <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">CC BY-NC-SA</a></p>
<h2>Sensors</h2>
<p>What shall we measure, and how?</p>
<h3>Temperature</h3>
<p>The &#8220;hello world&#8221; of wireless sensor networks is temperature.  I figure it&#8217;s always interesting to know what the temperature is, so now I can find out what the temperature is in 25 unique points within the house <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   My weapon of choice is a Microchip MCP9700.  There are many options.  This one seemed simple and cheap.</p>
<p>To drive it, I created a simple MCP9700 library.  It supports both the &#8217;00 and &#8217;01 variants, maintains a calibrated error value, and handles the average of multiple readings.  Soon to be available on github!</p>
<h3>Battery Voltage</h3>
<p>It&#8217;s useful to know the battery voltage, from which we can infer the remaining battery capacity.  So the nodes collect and transmit their battery voltage with every sample.</p>
<p>These nodes use the internal 1.1V reference voltage, so the battery voltage has to be divided down before it can be sampled.  For this, I use a simple voltage divider circuit with 1M and 470k resistors.  The resistors are chosen to have very high impedance so they don&#8217;t draw a ton of current.  As a consequence, a capacitor is needed.  (Not sure why exactly, but it was suggested on the Arduino forum, and definitely solved the problem of poor readings.)</p>
<p>Here is a very simple schematic of the voltage divider at work:</p>
<h2 style="text-align:center;padding:3px;"><a title="Battery Voltage Measurement.sch" href="http://www.flickr.com/photos/maniacbug/6046166167/"><img style="border:solid 2px #000000;" alt="Battery Voltage Measurement.sch" src="http://farm7.static.flickr.com/6080/6046166167_fb49f479d2.jpg" /></a></h2>
<h3>Others to Come</h3>
<p>To future-proof this node just a little, I included an expansion port.  This exposes 4 unused pins (2 digital, 2 analog) and the SPI bus.  It will allow me to add additional sensors in the future without having to re-spin the board.  For details, see my post on the <a href="http://maniacbug.wordpress.com/2011/04/03/arduino-box-header-platform-2/">Arduino Box Header Platform</a>; this is &#8220;Port B&#8221;.</p>
<h2>Software</h2>
<p>These nodes are running my <a href="https://github.com/maniacbug/RF24Network">RF24Network</a> stack.  Built on my <a href="https://github.com/maniacbug/RF24">RF24</a> radio driver, the network layer provides node addressing and routing to build a tree topology out of the nRF24L01+ radios.</p>
<p>The temperature reading &amp; sending code on the client is really simple.  It is also using my MCP9700 library for the temp sensor and my Sleep library for putting the node to sleep and waking at the right interval.</p>
<div style="background-color:#7d170d;padding:5px;"><code>&nbsp;&nbsp;// If there's a reading ready, send it.<br />&nbsp;&nbsp;if ( temp_sensor &amp;&amp; temp_sensor-&gt;available() )<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;// Take a reading<br />&nbsp;&nbsp;&nbsp;&nbsp;message.temp = temp_sensor-&gt;read();<br />&nbsp;&nbsp;&nbsp;&nbsp;if ( voltage_sensor )<br />&nbsp;&nbsp;&nbsp;&nbsp;  message.voltage = voltage_sensor-&gt;read();<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;// Send it to the base<br />&nbsp;&nbsp;&nbsp;&nbsp;RF24NetworkHeader header(/*to node*/ base_node,/*message type*/ 'T');<br />&nbsp;&nbsp;&nbsp;&nbsp;network.write(header,&amp;message,sizeof(message));<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;// Leaf nodes sleep<br />&nbsp;&nbsp;&nbsp;&nbsp;if ( is_leaf()  )<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Power down the radio.  Note that the radio will get powered back up<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// on the next write() call.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;radio.powerDown();<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Sleep the MCU.  The watchdog timer will awaken in a short while, and<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// continue execution here.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep.go();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br /></code></div>
<p>The receiving node and SQL storage infrastructure will be the topics of future blog posts.</p>
<h2>Bill of Materials</h2>
<p>Pricing for all of these parts is in quantity 25, which is about how many I want to have operating at once.  All part ##&#8217;s are from <a href="http://www.mouser.com">Mouser</a>.</p>
<table>
<tr style="background-color:#EEEEEE;color:red;">
<td style="padding:0 10px;"> <strong>  Qty </strong> </td>
<td style="padding:0 10px;"> <strong>  Vendor# </strong> </td>
<td style="padding:0 10px;"> <strong>  Description </strong> </td>
<td style="padding:0 10px;"> <strong>  Price </strong> </td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 556-ATMEGA328P-PU  </td>
<td style="padding:0 10px;"> Atmel Microcontrollers (MCU) 32KB In-system Flash 20MHz 1.8V-5.5V </td>
<td style="padding:0 10px;"> $3.05</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 614-CR2450N.IB  </td>
<td style="padding:0 10px;"> Renata Coin Cell Battery 3V 24.5 x 5.0mm 540mAh  </td>
<td style="padding:0 10px;"> $1.10</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 122-00224-GR  </td>
<td style="padding:0 10px;"> Eagle Plastic Devices Battery Holders, Snaps &amp; Contacts 24.5MM THRUHOLE BLK  </td>
<td style="padding:0 10px;"> $0.65</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 611-OS102011MS2QN1  </td>
<td style="padding:0 10px;"> C&amp;K Components Slide Switches SPDT On-On  </td>
<td style="padding:0 10px;"> $0.32</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 571-1-390261-9  </td>
<td style="padding:0 10px;"> TE Connectivity IC &amp; Component Sockets 28P ECONOMY TIN SKT  </td>
<td style="padding:0 10px;"> $0.30</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 774-ATS080B  </td>
<td style="padding:0 10px;"> CTS Electronic Components Crystals 8.0MHz 18pF Fund. -20C +70C  </td>
<td style="padding:0 10px;"> $0.29</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 579-MCP9700A-E/TO  </td>
<td style="padding:0 10px;"> Microchip Board Mount Temperature Sensors Lin Active Therm  </td>
<td style="padding:0 10px;"> $0.26</td>
</tr>
<tr>
<td style="padding:0 10px;"> 2 </td>
<td style="padding:0 10px;"> 140-50N2-220J-RC  </td>
<td style="padding:0 10px;"> Xicon Ceramic Disc Capacitors 50V 22pF NPO 5% Tol  </td>
<td style="padding:0 10px;"> $0.08</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 642-MJTP1230  </td>
<td style="padding:0 10px;"> Apem Tactile &amp; Jog Switches 6mm TACTILE SW  </td>
<td style="padding:0 10px;"> $0.06</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 604-WP132XYD  </td>
<td style="padding:0 10px;"> 	Kingbright Standard LED &#8211; Through Hole YELLOW DIFFUSED  </td>
<td style="padding:0 10px;"> $0.06</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 604-WP132XGD  </td>
<td style="padding:0 10px;"> 	Kingbright Standard LED &#8211; Through Hole GREEN DIFFUSED  </td>
<td style="padding:0 10px;"> $0.07</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 604-WP7104HD  </td>
<td style="padding:0 10px;"> Kingbright Standard LED &#8211; Through Hole RED DIFFUSED  </td>
<td style="padding:0 10px;"> $0.06</td>
</tr>
<tr>
<td style="padding:0 10px;"> 4 </td>
<td style="padding:0 10px;"> 594-K104M15X7RF53L2 </td>
<td style="padding:0 10px;">  Vishay Multilayer Ceramic Capacitors (MLCC) &#8211; Leaded 0.1uF 50volts 20% X7R 2.5mm LS  </td>
<td style="padding:0 10px;"> $0.04</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 660-MF1/4DCT52R1004F </td>
<td style="padding:0 10px;">  KOA Speer Metal Film Resistors &#8211; Through Hole 1/4W 1M ohm 1%  </td>
<td style="padding:0 10px;"> $0.05</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 660-MF1/4DC4703F </td>
<td style="padding:0 10px;">  KOA Speer Metal Film Resistors &#8211; Through Hole 470K 1% 100PPM </td>
<td style="padding:0 10px;"> $0.05</td>
</tr>
<tr>
<td style="padding:0 10px;"> 1 </td>
<td style="padding:0 10px;"> 660-MF1/4DC1002F </td>
<td style="padding:0 10px;"> KOA Speer Metal Film Resistors &#8211; Through Hole 10K 1% 100PPM </td>
<td style="padding:0 10px;"> $0.06</td>
</tr>
<tr>
<td style="padding:0 10px;"> 3 </td>
<td style="padding:0 10px;"> 660-MF1/4DC3300F </td>
<td style="padding:0 10px;"> KOA Speer Metal Film Resistors &#8211; Through Hole 330ohm 1% 100PPM </td>
<td style="padding:0 10px;"> $0.06</td>
</tr>
</table>
<p>The radio unit is from iTeadStudio, <a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=7&amp;products_id=53">2.4G Wireless nRF24L01+ Module</a> for $4.00.</p>
<p>Cost breakdown:BOM $6.69, Radio $4, Board $1, Total $11.69</p>
<h2>Schematic</h2>
<p>Eagle file is on box.net: <a href="http://www.box.net/shared/0mrr1x78ds8ofembz2dp">RF Duinode V3.sch</a>  <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">CC BY-NC-SA</a></p>
<h2 style="text-align:center;padding:3px;"><a title="RF Duinode V3.sch" href="http://www.flickr.com/photos/maniacbug/6224857389/"><img style="border:solid 2px #000000;" alt="RF Duinode V3.sch" src="http://farm7.static.flickr.com/6236/6224857389_63634bd0e5.jpg" /></a></h2>
<h2>Circuit Board</h2>
<p>Eagle file is on box.net: <a href="http://www.box.net/shared/4zu25ffnq0r4626ikdni">RF Duinode V3.brd</a>  <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">CC BY-NC-SA</a></p>
<h2 style="text-align:center;padding:3px;"><a title="RF Duinode V3-laen" href="http://www.flickr.com/photos/maniacbug/6225376286/"><img style="border:solid 2px #000000;" alt="RF Duinode V3-laen" src="http://farm7.static.flickr.com/6218/6225376286_f57938f8c2.jpg" /></a></h2>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/225/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/225/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/225/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=225&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2011/10/19/sensor-node/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6097/6224308836_b9b3b421a3_z.jpg" medium="image">
			<media:title type="html">RF Duinode V3 (2V4)</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6108/6224740147_cd59d6791a.jpg" medium="image">
			<media:title type="html">Capacity Test - 2AA @ 13mA</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6080/6046166167_fb49f479d2.jpg" medium="image">
			<media:title type="html">Battery Voltage Measurement.sch</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6236/6224857389_63634bd0e5.jpg" medium="image">
			<media:title type="html">RF Duinode V3.sch</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6218/6225376286_f57938f8c2.jpg" medium="image">
			<media:title type="html">RF Duinode V3-laen</media:title>
		</media:content>
	</item>
		<item>
		<title>125Khz RFID Module RDM630</title>
		<link>http://maniacbug.wordpress.com/2011/10/09/125khz-rfid-module-rdm630/</link>
		<comments>http://maniacbug.wordpress.com/2011/10/09/125khz-rfid-module-rdm630/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 18:51:25 +0000</pubDate>
		<dc:creator>maniacbug</dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://maniacbug.wordpress.com/?p=221</guid>
		<description><![CDATA[Parts I picked these up with my last iTeadStudio order to experiment with: 125Khz RFID module RDM630 &#8211; UART $11.00 EM4100 125khz RFID Key Tag $0.50 Connections Connecting to the Arduino is brain-dead simple. Note that I am not connecting &#8230; <a href="http://maniacbug.wordpress.com/2011/10/09/125khz-rfid-module-rdm630/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=221&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h2 style="text-align:center;padding:3px;"><a title="RFID Test Photo" href="http://www.flickr.com/photos/maniacbug/6224279352/"><img style="border:solid 2px #000000;" alt="RFID Test Photo" src="http://farm7.static.flickr.com/6157/6224279352_efb8be9ff2_z.jpg" /></a></h2>
<h2>Parts</h2>
<p>I picked these up with my last iTeadStudio order to experiment with:</p>
<ul>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=16&amp;products_id=6">125Khz RFID module RDM630 &#8211; UART</a> $11.00</li>
<li><a href="http://iteadstudio.com/store/index.php?main_page=product_info&amp;cPath=16&amp;products_id=10">EM4100 125khz RFID Key Tag</a> $0.50</li>
</ul>
<h2>Connections</h2>
<p>Connecting to the Arduino is brain-dead simple.  Note that I am not connecting the module to the Arduino&#8217;s RX/TX pins, because I want to leave that open for the Serial Monitor.</p>
<table>
<tr style="background-color:#EEEEEE;color:red;">
<td style="padding:0 10px;"> <strong>  Arduino </strong> </td>
<td style="padding:0 10px;"> <strong>  RFID </strong> </td>
</tr>
<tr>
<td style="padding:0 10px;"> 2 </td>
<td style="padding:0 10px;"> LED</td>
</tr>
<tr>
<td style="padding:0 10px;"> 6 </td>
<td style="padding:0 10px;"> TX</td>
</tr>
<tr>
<td style="padding:0 10px;"> +5V </td>
<td style="padding:0 10px;"> +5V</td>
</tr>
<tr>
<td style="padding:0 10px;"> GND </td>
<td style="padding:0 10px;"> GND</td>
</tr>
</table>
<p><span id="more-221"></span><br />
<h2>Reading the ID</h2>
<p>My approach in software is to use the SoftwareSerial library.  The advantage is that the hardware serial (UART) is free for communication with the host PC.  The disadvantage is that the software serial is a lot more finicky.</p>
<p>Fortunately, the module holds the LED pin low while sending data.  So what I&#8217;ve done is connected that pin to Arduino pin #2, and then I wait for an falling edge on interrupt 0.  Once I have that, I know to expect exactly 14 bytes at 9600 baud from the module&#8217;s TX pin.</p>
<p>For convenience, I also put this code up as a gist: <a href="https://gist.github.com/1273929">rfid_simple.pde</a>.</p>
<div style="background-color:#7d170d;padding:5px;"><code>#include&nbsp;&lt;<span style="color:#CC6600;">SoftwareSerial</span>.h&gt;<br />&nbsp;<br /><span style="color:#7E7E7E;">//&nbsp;Pin&nbsp;definitions</span><br />const&nbsp;<span style="color:#CC6600;">int</span> rfid_irq = 0;<br />const&nbsp;<span style="color:#CC6600;">int</span> rfid_tx_pin = 6;<br />const&nbsp;<span style="color:#CC6600;">int</span> rfid_rx_pin = 7;<br />&nbsp;<br /><span style="color:#7E7E7E;">//&nbsp;For&nbsp;communication&nbsp;with&nbsp;RFID&nbsp;module</span><br /><span style="color:#CC6600;">SoftwareSerial</span> rfid(rfid_tx_pin, rfid_rx_pin);<br />&nbsp;<br /><span style="color:#7E7E7E;">//&nbsp;Indicates&nbsp;that&nbsp;a&nbsp;reading&nbsp;is&nbsp;now&nbsp;ready&nbsp;for&nbsp;processing</span><br />volatile&nbsp;bool&nbsp;ready&nbsp;=&nbsp;<span style="color:#CC6600;">false</span>;<br />&nbsp;<br /><span style="color:#7E7E7E;">//&nbsp;Buffer&nbsp;to&nbsp;contain&nbsp;the&nbsp;reading&nbsp;from&nbsp;the&nbsp;module</span><br />uint8_t&nbsp;buffer[14];<br />uint8_t*&nbsp;buffer_at;<br />uint8_t*&nbsp;buffer_end&nbsp;=&nbsp;buffer&nbsp;+&nbsp;sizeof(buffer);<br />&nbsp;<br /><span style="color:#CC6600;">void</span> rfid_read(<span style="color:#CC6600;">void</span>);<br />&nbsp;<br /><span style="color:#CC6600;">void</span> <span style="color:#CC6600;"><b>setup</b></span>(<span style="color:#CC6600;">void</span>)<br />{<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Open serial connection to host PC to view output</span><br />&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">begin</span>(57600);<br />&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">println</span>(<span style="color:#006699;">"rfid_simple"</span>);<br />&nbsp;<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Open software serial connection to RFID module</span><br />&nbsp;&nbsp;<span style="color:#CC6600;">pinMode</span>(rfid_tx_pin,<span style="color:#006699;">INPUT</span>);<br />&nbsp;&nbsp;rfid.<span style="color:#CC6600;">begin</span>(9600);<br />&nbsp;<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Listen for interrupt from RFID module</span><br />&nbsp;&nbsp;<span style="color:#CC6600;">attachInterrupt</span>(rfid_irq,rfid_read,<span style="color:#006699;">FALLING</span>);<br />}<br />&nbsp;<br /><span style="color:#CC6600;">void</span> <span style="color:#CC6600;"><b>loop</b></span>(<span style="color:#CC6600;">void</span>)<br />{<br />&nbsp;&nbsp;<span style="color:#CC6600;">if</span> ( ready )<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;ready&nbsp;=&nbsp;<span style="color:#CC6600;">false</span>;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Print the buffer</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">print</span>(<span style="color:#006699;">"Reading: "</span>);<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;uint8_t*&nbsp;bp&nbsp;=&nbsp;buffer;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;">while</span> ( bp &lt; buffer_end )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">print</span>(*bp++);<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">println</span>();<br />&nbsp;&nbsp;}<br />}<br />&nbsp;<br /><span style="color:#CC6600;">void</span> rfid_read(<span style="color:#CC6600;">void</span>)<br />{<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Read characters into the buffer until it is full</span><br />&nbsp;&nbsp;buffer_at&nbsp;=&nbsp;buffer;<br />&nbsp;&nbsp;<span style="color:#CC6600;">while</span> ( buffer_at &lt; buffer_end )<br />&nbsp;&nbsp;&nbsp;&nbsp;*buffer_at++&nbsp;=&nbsp;rfid.<span style="color:#CC6600;">read</span>();<br />&nbsp;<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Signal that the buffer has data ready</span><br />&nbsp;&nbsp;ready&nbsp;=&nbsp;<span style="color:#CC6600;">true</span>;<br />}<br /></code></div>
<h2>Processing the ID</h2>
<p>The data from the tag needs to be processed a bit in order to be useful.  Running the rfid_simple sketch above, and swiping the key I have, gives this result:</p>
<div style="background-color:#7d170d;padding:5px;"><code>rfid_simple<br />Reading: �3D009F49608B�<br /></code></div>
<p>The key says &#8220;0010439008&#8243; on it, hardly the same.  What we have to do is convert the characters to bytes, and take only the middle 4 bytes.  That will yield 0x009F4960, which is exactly 10439008.  Yay.  The first byte appears to be garbage, and the last byte is a checksum.</p>
<p>We can use the checksum to make sure everything came across the wire properly.  We can simply XOR each of the 5 bytes together, and compare with the checksum byte, e.g.  ( ( ( ( 0x3D ^ 0&#215;00) ^ 0x9F) ^ 0&#215;49) ^ 0&#215;60) == 0x8B.</p>
<p>So the final version of the RFID reader will read in the garbage byte at the start, and read in the checksum, calculate a checksum, and compare the two.  I needed to put the chars-to-byte conversion into its own function because it&#8217;s used in different places now.</p>
<p>Below are the changes from the above version.  The code for this one is also up as a gist: <a href="http://gist.github.com/1273970">rfid_decimal.pde</a></p>
<div style="background-color:#7d170d;padding:5px;"><code><span style="color:#CC6600;">void</span> <span style="color:#CC6600;"><b>loop</b></span>(<span style="color:#CC6600;">void</span>)<br />{<br />&nbsp;&nbsp;<span style="color:#CC6600;">if</span> ( ready )<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Convert the buffer into a 32-bit value</span><br />&nbsp;&nbsp;&nbsp;&nbsp;uint32_t&nbsp;result&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Skip the preamble</span><br />&nbsp;&nbsp;&nbsp;&nbsp;++buffer_at;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Accumulate the checksum, starting with the first value</span><br />&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;checksum&nbsp;=&nbsp;rfid_get_next();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// We are looking for 4 more values</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;">int</span> i = 4;    <br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;">while</span>(i--)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Grab the next value</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;value&nbsp;=&nbsp;rfid_get_next();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Add it into the result</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;&lt;&lt;=&nbsp;8;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;|=&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Xor it into the checksum</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checksum&nbsp;^=&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Pull out the checksum from the data</span><br />&nbsp;&nbsp;&nbsp;&nbsp;uint8_t&nbsp;data_checksum&nbsp;=&nbsp;rfid_get_next();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Print the result</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">print</span>(<span style="color:#006699;">"Reading: "</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">print</span>(result);<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;">if</span> ( checksum == data_checksum )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">println</span>(<span style="color:#006699;">" OK"</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;"><b>Serial</b></span>.<span style="color:#CC6600;">println</span>(<span style="color:#006699;">" CHECKSUM FAILED"</span>);<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// We're done processing, so there is no current value    </span><br />&nbsp;&nbsp;&nbsp;&nbsp;ready&nbsp;=&nbsp;<span style="color:#CC6600;">false</span>;<br />&nbsp;&nbsp;}<br />}<br />&nbsp;<br /><span style="color:#7E7E7E;">//&nbsp;Convert&nbsp;the&nbsp;next&nbsp;two&nbsp;chars&nbsp;in&nbsp;the&nbsp;stream&nbsp;into&nbsp;a&nbsp;byte&nbsp;and</span><br /><span style="color:#7E7E7E;">//&nbsp;return&nbsp;that</span><br />uint8_t&nbsp;rfid_get_next(<span style="color:#CC6600;">void</span>)<br />{<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// sscanf needs a 2-byte space to put the result but we</span><br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// only need one byte.</span><br />&nbsp;&nbsp;uint16_t&nbsp;result;<br />&nbsp;<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Working space to assemble each byte</span><br />&nbsp;&nbsp;<span style="color:#CC6600;">static</span> <span style="color:#CC6600;">char</span> byte_chars[3];<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Pull out one byte from this position in the stream</span><br />&nbsp;&nbsp;snprintf(byte_chars,3,<span style="color:#006699;">"%c%c"</span>,buffer_at[0],buffer_at[1]);<br />&nbsp;&nbsp;sscanf(byte_chars,<span style="color:#006699;">"%x"</span>,&amp;result);<br />&nbsp;&nbsp;buffer_at&nbsp;+=&nbsp;2;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;<span style="color:#CC6600;">return</span> static_cast&lt;uint8_t&gt;(result);<br />}<br />&nbsp;<br /><span style="color:#CC6600;">void</span> rfid_read(<span style="color:#CC6600;">void</span>)<br />{<br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// Only read in values if there is not already a value waiting to be</span><br />&nbsp;&nbsp;<span style="color:#7E7E7E;">// processed</span><br />&nbsp;&nbsp;<span style="color:#CC6600;">if</span> ( ! ready )<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Read characters into the buffer until it is full</span><br />&nbsp;&nbsp;&nbsp;&nbsp;buffer_at&nbsp;=&nbsp;buffer;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#CC6600;">while</span> ( buffer_at &lt; buffer_end )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*buffer_at++&nbsp;=&nbsp;rfid.<span style="color:#CC6600;">read</span>();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Reset buffer pointer so it's easy to read out</span><br />&nbsp;&nbsp;&nbsp;&nbsp;buffer_at&nbsp;=&nbsp;buffer;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#7E7E7E;">// Signal that the buffer has data ready</span><br />&nbsp;&nbsp;&nbsp;&nbsp;ready&nbsp;=&nbsp;<span style="color:#CC6600;">true</span>;<br />&nbsp;&nbsp;}<br />}<br /></code></div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maniacbug.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maniacbug.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/maniacbug.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/maniacbug.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maniacbug.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maniacbug.wordpress.com/221/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maniacbug.wordpress.com/221/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maniacbug.wordpress.com/221/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maniacbug.wordpress.com&amp;blog=20445345&amp;post=221&amp;subd=maniacbug&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://maniacbug.wordpress.com/2011/10/09/125khz-rfid-module-rdm630/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/007a1c3bc57c42e31f0468dc8e8b84ff?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">maniacbug</media:title>
		</media:content>

		<media:content url="http://farm7.static.flickr.com/6157/6224279352_efb8be9ff2_z.jpg" medium="image">
			<media:title type="html">RFID Test Photo</media:title>
		</media:content>
	</item>
	</channel>
</rss>
