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

<channel>
	<title>brownsofa.org</title>
	<atom:link href="http://brownsofa.org/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://brownsofa.org/blog</link>
	<description>treading a well-worn path to somewhere different</description>
	<lastBuildDate>Tue, 15 May 2012 03:23:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Getting Started with Amazon AWS Command Line Basics</title>
		<link>http://brownsofa.org/blog/archives/346</link>
		<comments>http://brownsofa.org/blog/archives/346#comments</comments>
		<pubDate>Tue, 15 May 2012 03:10:55 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[aws]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://brownsofa.org/blog/?p=346</guid>
		<description><![CDATA[I didn&#8217;t even realize there&#8217;s a set of command line tools for working with Amazon&#8217;s Web Services.  It only took a few mins to get started, but it wasn&#8217;t immediately apparent what needed to happen. I&#8217;m using OSX Lion.  If you&#8217;re using another *nix this is all fairly easy to translate. I have no idea [...]]]></description>
			<content:encoded><![CDATA[<p>I didn&#8217;t even realize there&#8217;s a set of command line tools for working with Amazon&#8217;s Web Services.  It only took a few mins to get started, but it wasn&#8217;t immediately apparent what needed to happen.</p>
<p><em>I&#8217;m using OSX Lion.  If you&#8217;re using another *nix this is all fairly easy to translate. I have no idea how this could be Windows-ified&#8230;</em></p>
<h2>Download and Install</h2>
<p>I downloaded the tools as a zip archive from <a href="http://aws.amazon.com/developertools/351">http://aws.amazon.com/developertools/351</a>.  I like to keep this kind of package within a <code>~/local</code> folder, so:</p>
<pre>mkdir ~/local
cd Downloads
unzip ec2-api-tools.zip
mv ec2-api-tools-1.5.3.1 ~/local</pre>
<p>To make upgrades easier, create a symlink to that directory:</p>
<pre>cd ~/local
ln -s ec2-api-tools-1.5.3.1 ec2-api-tools</pre>
<h2>Security</h2>
<p>You need your username and password to get into the AWS web interface.  You&#8217;ll still need to authenticate with the command line tools, but you have a more convenient mechanism to do this &#8211; X.509 keys.</p>
<p>Log into the AWS web page, and go to <strong>My Account</strong> &gt; <strong>Security Credentials</strong>.  Go to the <strong>X.509 Certificates</strong> tab and hit <strong>Create A New Certificate</strong>.  Download the private key and the certificate and save them somewhere safe &#8211; since it already has appropriate permissions and contains keys, I save mine to <code>~/.ssh/pk.pem</code> and <code>~/.ssh/cert.pem</code> respectively.</p>
<h2>Configure</h2>
<p>The tools require you to set <code>JAVA_HOME</code> and <code>EC2_HOME</code> environment variables, and there are a couple of other variables that will save you a whole lot of typing. Add the following to the end your <code>~/.bash_profile</code>:</p>
<pre>export PATH=$HOME/local/ec2-api-tools/bin:$PATH
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
export EC2_HOME=$HOME/local/ec2-api-tools
export EC2_PRIVATE_KEY=~/.ssh/pk_ec2.pem
export EC2_CERT=~/.ssh/cert_ec2.pem
export EC2_URL=https://ec2.us-west-1.amazonaws.com</pre>
<p>Be careful with the last of these.  I host my instances in the US-West-1 region &#8211; you will likely need to figure out which URL to put here based on the region your instances or volumes are at.  If you have machines in multiple regions, use the <code>--region</code> switch in the commands instead.</p>
<p>Source the file to have the changes take effect:</p>
<pre>. ~/.bash_profile</pre>
<p>and carry on.</p>
<h2>Run</h2>
<p>Now, it&#8217;s easy.  For example, run <code>ec2-describe-instances</code> &#8211; it should show you a list of all your EC2 instances, and a whole bunch of info about them.  I leave it to you to work out the other 280-odd commands.  Looks like you can do pretty much do any operation to manage EC2 instances, images, volumes, networking, snapshots, &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://brownsofa.org/blog/archives/346/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building NodeJS on OS X 10.5.8</title>
		<link>http://brownsofa.org/blog/archives/334</link>
		<comments>http://brownsofa.org/blog/archives/334#comments</comments>
		<pubDate>Thu, 26 May 2011 03:58:44 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://brownsofa.org/blog/?p=334</guid>
		<description><![CDATA[It seems that I borked xcode, did something bad with my libssl, or just that my system&#8217;s too out of date to trivially install, homebrew or build NodeJS. I really want to install Node, so here&#8217;s what I just did. I started off downloading and extracting the latest NodeJS source tarball (0.4.2 at time of [...]]]></description>
			<content:encoded><![CDATA[<p>It seems that I borked xcode, did something bad with my libssl, or just that my system&#8217;s too out of date to trivially <a href="http://sites.google.com/site/nodejsmacosx/">install</a>, <a href="http://shapeshed.com/journal/setting-up-nodejs-and-npm-on-mac-osx/">homebrew</a> or <a href="http://www.devpatch.com/2010/02/installing-node-js-on-os-x-10-6/">build</a> <a href="http://nodejs.org/">NodeJS</a>.  I really want to install Node, so here&#8217;s what I just did.</p>
<p>I started off downloading and extracting the latest NodeJS source tarball (0.4.2 at time of writing).  After attempting to configure and build, I was getting some complaints out of make:</p>
<p>I was getting some complaints out of <code>make</code>:</p>
<pre>../src/node_crypto.cc: In function ‘void node::crypto::InitCrypto(v8::Handle<v8::Object>)’:
../src/node_crypto.cc:2917: error: ‘SSL_COMP_get_compression_methods’ was not declared in this scope
Waf: Leaving directory `/Users/Ian/node-latest-install/build'
Build failed:  -> task failed (err #1):
	{task: cxx node_crypto.cc -> node_crypto_4.o}</pre>
<p>After a helpful tweek from <a href="http://twitter.com/#!/tonymilne">@tonymilne</a> I looked at the output of <code>./configure</code> slightly more closely: whilst it reported it found <code>header openssl/crypto.h</code>, it said that <code>openssl</code> was not found.</p>
<p>Getting an updated version of OpenSSL was pretty easy with homebrew:</p>
<pre>brew create http://www.openssl.org/source/openssl-0.9.8r.tar.gz
brew install openssl</pre>
<p>It didn&#8217;t quite fully install though.  It told me &#8220;This formula is keg-only, so it was not symlinked into /usr/local&#8221;, and that</p>
<pre>If you build your own software and it requires this formula, you'll need
to add its lib &amp; include paths to your build variables:

  LDFLAGS: -L/usr/local/Cellar/openssl/0.9.8r/lib
  CPPFLAGS: -I/usr/local/Cellar/openssl/0.9.8r/include</pre>
<p>Turns out that similar but different problems were solved by <a href="http://canonical.org/~kragen/compiling-node-on-macos.html">setting options</a> with configure, and running <code>./configure --help</code> in the folder with the NodeJS source shows some pertinent options.  I tried</p>
<pre>./configure --prefix=~/local --openssl-includes=/usr/local/Cellar/openssl/0.9.8r/include  --openssl-libpath=/usr/local/Cellar/openssl/0.9.8r/lib</pre>
<p>and it seems like it was successful &#8211; <code>node --vars</code> includes <code>-DHAVESSL=1</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://brownsofa.org/blog/archives/334/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Compleat ATtiny13 LED Flasher: Part 3 &#8211; Low Power Mode</title>
		<link>http://brownsofa.org/blog/archives/261</link>
		<comments>http://brownsofa.org/blog/archives/261#comments</comments>
		<pubDate>Mon, 10 Jan 2011 06:36:28 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[microprocessors]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://brownsofa.org/blog/?p=261</guid>
		<description><![CDATA[This is the final part of three in attempting to explain how to make the ATtiny13 flash a LED. Part 1: Setup, Hardware and A Basic Solution Part 2: Using timer interrupts Part 3: Low power mode In previous posts we&#8217;ve looked at creating a simple LED flasher circuit for the ATtiny, a first-pass program [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the final part of three in attempting to explain how to make the ATtiny13 flash a LED.<br />
</em></p>
<ul>
<li><em> Part 1: <a href="http://brownsofa.org/blog/archives/191">Setup, Hardware and A Basic Solution</a></em></li>
<li><em> Part 2: <a href="http://brownsofa.org/blog/archives/215">Using timer interrupts</a></em></li>
<li><em><strong> Part 3: Low power mode</strong></em></li>
</ul>
<p>In previous posts we&#8217;ve looked at creating a simple LED flasher circuit for the ATtiny, a first-pass program for the ATtiny using delays, and a second-pass implementation exploiting timer overflows resulting in a simpler program.  In this article I will explore the power saving modes on the ATtiny13 as an example of how to minimize the power consumption of your circuit.  If your ATTtiny13-, ATtiny80-, or even ATmega-based circuit relies on battery power you will be able to significantly improve the battery life by using the chips&#8217; power saving modes.</p>
<p>In this article we will be using the same circuit developed in the <a href="http://brownsofa.org/blog/archives/191">previous</a> <a href="http://brownsofa.org/blog/archives/215">posts</a>:</p>
<p style="text-align: center;"><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/LED-Flasher-Circuit.png"><img class="size-medium wp-image-217 alignnone" title="ATTiny13 LED Flasher Circuit" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/LED-Flasher-Circuit-300x152.png" alt="" width="300" height="152" /></a><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/board.jpg"><img class="size-medium wp-image-192 alignnone" title="ATTiny LED flasher circuit" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/board-300x225.jpg" alt="" width="300" height="225" /></a></p>
<h2><span id="more-261"></span>Overview</h2>
<p>Looking at the first page of the <a href="http://www.atmel.com/dyn/resources/prod_documents/doc8126.pdf">datasheet</a> you see it lists &#8220;Low Power Idle, ADC Noise Reduction, and Power-down Modes&#8221;.  Also looking at the <a href="http://www.nongnu.org/avr-libc/user-manual/modules.html">modules list</a> in the avr-libc documentation there&#8217;s an entry for &#8220;<a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html">&lt;avr/sleep.h&gt;: Power Management and Sleep Modes</a>&#8220;.  Starting with example code from the latter, putting the device to sleep doesn&#8217;t look very hard:</p>
<pre class="brush:cpp">#include &lt;avr/sleep.h&gt;

    ...
      set_sleep_mode(&lt;mode&gt;);
      sleep_mode();</pre>
<p>Then immediately following is this note: &#8220;[...] unless your purpose is to completely lock the CPU (until a  hardware reset), interrupts need to be enabled before going to sleep.&#8221;</p>
<p>So here are my questions: What are the sleep modes and what do they do?  What interrupt vector(s) are available and how do I enable them?</p>
<p>In the datasheet, §7 covers the sleep modes.  Right at the top, Table 7-1 summarizes which clocks and oscillators are active, and how the device can be awaken from each of the three supported sleep modes.  Looking at §7.1.1-3, the lowest power consumption sleep mode looks like &#8220;Power Down Mode&#8221; (no surprise), and once in that state it can be awoken by an external interrupt (i.e. a level change on a pin) or through the Watchdog Timer.</p>
<p>Looking at §8.4, the Watchdog timer (WDT) is a separately clocked counter/timer system, capable of generating interrupts which we can use to bring the device out of the Power Down sleep mode.  §8.5.2 details the WDT&#8217;s register, and in particular Table 8-2 lists how to alter the length of the WDT&#8217;s time period.</p>
<h2>Implementation</h2>
<p>We&#8217;ve sen that there&#8217;s a way to put the device to sleep, and a way to periodically wake it up.  Last time our LED flasher toggled its LED state each time a timer-based interrupt was generated.  Let&#8217;s do the same thing, except put the device to sleep once the LED state has been toggled.  Hopefully this will reduce the power consumption overall, but mainly during the &#8220;off&#8221; part of the cycle.</p>
<p>Our last implementation using Timer/Counter0 looked like this:</p>
<pre class="brush:cpp">#include &lt;avr/interrupt.h&gt;

volatile int timer_overflow_count = 0;

ISR(TIM0_OVF_vect) {
   if (++timer_overflow_count &gt; 5) {   // a timer overflow occurs 4.6 times per second
      // Toggle Port B pin 4 output state
      PORTB ^= 1&lt;&lt;PB4;
      timer_overflow_count = 0;
   }
}

int main(void) {
   // Set up Port B pin 4 mode to output
    DDRB = 1&lt;&lt;DDB4;

   // prescale timer to 1/1024th the clock rate
   TCCR0B |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);

   // enable timer overflow interrupt
   TIMSK0 |=1&lt;&lt;TOIE0;
   sei();

   while(1) {
      // let ISR handle the LED forever
   }
}</pre>
<p>We need to adjust the timer setup and interrupt we&#8217;re using, and add the power mode change.  Working on the timer part first, we remove all references to Timer0, and replace them with set up for the WDT.  Having read through §8.5.2 it&#8217;s clear that operating the WDT is very similar to Timer/Counter0.  Setting the <code>WDTIE</code> bit enables WDT interrupts, and combinations of <code>WDP3</code>, <code>WDP2</code>, <code>WDP1</code>, and <code>WDP0</code> adjust the prescaling and thus the WDT&#8217;s period.  Looking at Table 8-2, setting <code>WDP2</code> and <code>WDP0</code> gives a 0.5s timer period.</p>
<p>To wrap up replacing the older timer code, we also need to change the interrupt vector we&#8217;re using.  The <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html">documentation for interrupt.h</a> shows that this is called <code>WDT_vect</code>.</p>
<p>Finally, because we can prescale the timer this low, we can also dispense with our old overflow counter.</p>
<pre class="brush:cpp">#include &lt;avr/interrupt.h&gt;

ISR(WDT_vect) {
   // Toggle Port B pin 4 output state
   PORTB ^= 1&lt;&lt;PB4;
}

int main(void) {
   // Set up Port B pin 4 mode to output
    DDRB = 1&lt;&lt;DDB4;

   // prescale timer to 0.5s
   WDTCR |= (1&lt;&lt;WDP2) | (1&lt;&lt;WDP0);

   // Enable watchdog timer interrupts
   WDTCR |= (1&lt;&lt;WDTIE);

   sei(); // Enable global interrupts 

   for (;;) {
      // Waiting for interrupt...
   }
}</pre>
<p>If you set up the circuit and program this into the ATtiny13, the LED should flash on and off with a period of ~1 second, as you would expect.  It might be interesting top find out what kind of power savings the sleep modes might give us, so before we add the sleep code let&#8217;s measure current drain right now.  To make measurements a little easier slow down the flash rate by setting the prescaler to 4 seconds &#8211; <code>WDTCR |= (1&lt;&lt;WDP3);</code> &#8211; then set your multimeter to measure current and put in the main power loop somewhere.  For me the most convenient way was to break the connection between VCC on the ISP breakout and pin 8 on the ATtiny, and insert the ammeter there.  I measured 50mA on the mark (whilst the LED was on), and 2.3mA on the space.</p>
<p>To put the device to sleep, the <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html">documentation for sleep.h</a> states that</p>
<pre class="brush:cpp">set_sleep_mode(&lt;mode&gt;);
sleep_mode();</pre>
<p>is all there is to it. But what parameter do we pass to <code>set_sleep_mode</code> to enable Power Down Mode?  Since it&#8217;s not in this page of the documentation, if you take a look at the <a href="http://www.nongnu.org/avr-libc/user-manual/sleep_8h_source.html">code for the header file itself</a>, at line 253 there&#8217;s a #define for <code>SLEEP_MODE_PWR_DOWN</code> that&#8217;s applicable to ATtiny13s.</p>
<p>We have already set up the WDT to wake the device from sleep when it raises an interrupt, so as soon as the interrupt handler is complete it is safe to go back to sleep.  Working this in, our code now looks like:</p>
<pre class="brush:cpp">#include &lt;avr/interrupt.h&gt;
#include &lt;avr/sleep.h&gt;

ISR(WDT_vect) {
   // Toggle Port B pin 4 output state
   PORTB ^= 1&lt;&lt;PB4;
}

int main(void) {
   // Set up Port B pin 4 mode to output
    DDRB = 1&lt;&lt;DDB4;

   // temporarily prescale timer to 4s so we can measure current
   WDTCR |= (1&lt;&lt;WDP3); // (1&lt;&lt;WDP2) | (1&lt;&lt;WDP0);

   // Enable watchdog timer interrupts
   WDTCR |= (1&lt;&lt;WDTIE);

   sei(); // Enable global interrupts 

   // Use the Power Down sleep mode
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);

   for (;;) {
      sleep_mode();   // go to sleep and wait for interrupt...
   }
}</pre>
<p>Plugging in the ammeter again shows 47mA on the mark and 7µA on the space.  These readings (and the previous set) are definitely within range of the typical DC characteristics shown in Table 18-1 in the datasheet.  If you were using a CR1632 lithium coin cell rated at 125mAh, using the power down mode might increase battery life from 2.4h to 2.6h.  Ok, that&#8217;s not fantastic but the huge majority of electron juice is used by the LED.  If your circuit was a little more complex and had longer periods of inactivity, using the power down saves you a lot of power.  If our LED were on for 1/10th of the time it were off, the battery duration change goes from an increase of 8% with the sleep code to an increase of <strong>55%</strong>, which seems well worth it to me.</p>
<h2>More Reading</h2>
<p>For more ways to reduce power consumption, read §7.4 in the datasheet.</p>
<p><a href="http://jumptuck.wordpress.com">Jumptuck&#8217;s</a> <a href="http://jumptuck.wordpress.com/2008/11/13/led-menorah-powered-by-avr-tiny13/">LED Menorah</a> is a real-world example of using the sleep modes to reduce power consumption &#8211; in that case it&#8217;s to reduce power whilst the device is &#8220;off&#8221;.</p>
<p>Go back to <a href="http://brownsofa.org/blog/archives/191">part 1</a> or <a href="http://brownsofa.org/blog/archives/215">part 2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://brownsofa.org/blog/archives/261/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The Compleat ATtiny13 LED Flasher: Part 2 &#8211; Using Timer Interrupts</title>
		<link>http://brownsofa.org/blog/archives/215</link>
		<comments>http://brownsofa.org/blog/archives/215#comments</comments>
		<pubDate>Wed, 05 Jan 2011 06:27:48 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[microprocessors]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[ATtiny13]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brownsofa.org/blog/?p=215</guid>
		<description><![CDATA[This is the second part of three in attempting to explain how to make the ATtiny13 flash a LED. Part 1: Setup, Hardware and A Basic Solution Part 2: Using timer interrupts Part 3: Low power mode Post-Pre-script: If you find this post useful, happen to try out the code, or have any other views [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the second part of three in attempting to explain how to make the ATtiny13 flash a LED.</em></p>
<ul>
<li><em>Part 1: <a href="http://brownsofa.org/blog/archives/191">Setup, Hardware and A Basic Solution</a></em></li>
<li><em><strong>Part 2: Using timer interrupts</strong></em></li>
<li><em>Part 3: <a href="http://brownsofa.org/blog/archives/261">Low power mode</a></em></li>
</ul>
<p><em><del>Post-</del>Pre-script: If you find this post useful, happen to try out the code, or have any other views or criticisms, please leave a comment.  I&#8217;d love to hear what you think.<br />
- Ian</em></p>
<p>So last time around, we made a LED flash.  Of course there are other, more elegant ways to do it.  In this post I&#8217;ll explore interrupts, and specifically the timer overflow interrupt.  For this I&#8217;ll use the same circuit setup from the first article.  If you&#8217;re reading this one independently, here&#8217;s a circuit diagram:</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/LED-Flasher-Circuit.png"><img class="aligncenter size-medium wp-image-217" title="ATTiny13 LED Flasher Circuit" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/LED-Flasher-Circuit-300x152.png" alt="" width="300" height="152" /></a></p>
<h2><span id="more-215"></span>Interrupts</h2>
<p>The structure of programs for these microcontrollers often takes a standard form:</p>
<pre class="brush:cpp">#include &lt;headers&gt;

int main() {
   set_up_routine();

   while (1) {
      do_something_interesting();
   }
   return 1;
}</pre>
<p>So once the code&#8217;s on the device, after power-up it enters <code>main()</code>, runs whatever setup you want to do, then begins running in an infinite loop doing whatever it is you want the tiny guy to do.</p>
<p>In this model, say you want to get input from devices, you must <em>poll</em> them &#8211; that is, every so often your program must go out of its way to figure out whether an input pin has changed from high to low, or some other measurement.  Now this can cause problems.   For example:</p>
<pre class="brush:cpp">#include &lt;headers&gt;

int isSwitchPressed();      // returns 1 if switch is currently pressed down, 0 otherwise

int main() {
   set_up_routine();

   while (1) {
      if (isSwitchPressed()) {
         do_something_that_takes_a_long_time();
      }
   }
   return 1;
}</pre>
<p>Let&#8217;s say that our interesting thing was to play a fancy little light sequence on a LED.  You press the switch, the LED does its thing (or whatever else is in <code>do_something_that_takes_a_long_time</code>), that function returns and again we&#8217;re waiting for the switch to be pressed.  This is all well and good.  If the switch is not pressed, the function returns false, the <code>if</code>&#8216;s body is not evaluated, the <code>while</code> loop ends and restarts, and the code tests whether the switch is pressed.</p>
<p>But here&#8217;s the rub.  Consider:</p>
<pre class="brush:cpp">#include &lt;headers&gt;

int isSwitchPressed();      // returns 1 if switch is currently pressed down, 0 otherwise

int main() {
   set_up_routine();

   while (1) {
      if (isSwitchPressed()) {
         do_something_that_takes_a_long_time();
      } else {
         do_something_else_that_takes_a_long_time();
      }
   }
   return 1;
}</pre>
<p>If the switch is not pressed, <code>do_something_else_that_takes_a_long_time()</code> is executed.  If you push the switch during the time this function is executing, nothing will happen.  The microcontroller will not register that the switch was pressed, and you lose that event happening.</p>
<p>So what if you want a button press during <code>do_something_else_that_takes_a_long_time()</code> to run the regular <code>do_something_that_takes_a_long_time()</code> code?  You could start testing the switch state in <code>do_something_else_that_takes_a_long_time</code>.  No, just kidding.  That would suck.</p>
<p>This is where <em>interrupts</em> come into play.  They do what you might expect them to do &#8211; they interrupt the normal code execution.  Interrupts can be triggered by different types of events.  In the example above you may recognize that a hardware-based interrupt might come to the rescue.  Interrupts can also be generated by the microcontroller&#8217;s own internal systems, or by your code itself.  These are called <em>interrupt vectors</em>.  A list of the interrupt vectors for the ATtiny13 is listed in §9.1 in the <a href="http://www.atmel.com/dyn/resources/prod_documents/doc8126.pdf">ATtiny13 datasheet</a> (p. 45).</p>
<p>When an interrupt happens, your way to instruct the µc to do something is through an interrupt handler, aka interrupt service routine, aka ISR.  It looks just like a regular function, but you don&#8217;t call it directly from your code; it gets executed whenever an interrupt occurs.  Once your ISR has completed execution, the program counter jumps back to right where it left of from in your <code>main()</code> loop (or wherever it was when the interrupt was raised) and carries on running.</p>
<p>More pseudocode:</p>
<pre class="brush:cpp">#include &lt;headers&gt;

ISR(interrupt_vector_caused_by_switch_press) {
   do_something_that_takes_a_long_time();
}

int main() {
   set_up_routine();

   while (1) {
      do_something_else_that_takes_a_long_time();
   }
   return 1;
}</pre>
<p>So if the button is pressed, and interrupt is raised and our ISR is called.  No matter where the program counter is when you press the button, <code>do_something_that_takes_a_long_time()</code> will get called within a few clock cycles.  If you haven&#8217;t pressed the button then all that gets executed is <code>do_something_else_that_takes_a_long_time()</code>.</p>
<p>OK, you get it, enough theory and pseudocode.  Moving on&#8230;</p>
<p><em>A word of warning: interrupts give you ways to do all kinds of weird things.  Check out <a href="http://www.societyofrobots.com/member_tutorials/node/207">this</a> and <a href="http://greatengineering.net/Embedded-System-Engineering/Implementation/Interrupt-Race-Conditions.html">this</a> for just a hint of the perils that await you!</em></p>
<h2>Implementing Interrupts on ATtiny13 with AVR Libc</h2>
<p><em>There&#8217;s more than one way to skin a cat.  My preferred method is using the <a href="http://www.nongnu.org/avr-libc/user-manual/index.html">AVR Libc</a> code, and the avr-gcc C compiler toolchain, and that&#8217;s exclusively what I&#8217;ll focus on. </em></p>
<p>I&#8217;m getting down to brass tacks and jumping around the <a href="http://www.atmel.com/dyn/resources/prod_documents/doc8126.pdf">datasheet</a> a bit here.</p>
<p>The ATtiny13 datasheet §9.1 lists the <em>Timer/Counter Overflow</em> interrupt vector.  Then reading §11.7.1, you learn that in its normal mode, the counter counts upwards, and once it gets to the &#8220;top&#8221; (there&#8217;s only so many bits allocated to store the counter value) it resets back to zero and the <code>TOV0</code> bit is set.  §11.9.6 says that if you enable the Timer/Counter0 Overflow Interrupt by setting the <code>TOIE0</code> bit to 1 in the <code>TIMSK0</code> register and interrupts are enabled (&#8220;the I-bit in the Status Register is set&#8221;), whenever the <code>TOV0</code> bit is set, the interrupt will be raised.</p>
<p>The timer is what we&#8217;re using to generate our interrupts.  It&#8217;s an 8-bit register, incremented once per clock tick (unless prescaled &#8211; see later).  Since it&#8217;s only an 8-bit register its maximum value is 255, therefore once every 256 clock cycles the timer reaches its maximum value and resets back to zero.  If we set up the device properly, when this occurs the Timer/Counter0 Overflow Interrupt will be generated, and we can write a ISR to respond to this interrupt, and flash our timer.</p>
<p>&#8220;256 clock cycles?&#8221; I hear you ask.  &#8221;That&#8217;s not very long.&#8221;  We could add a counter variable and toggle the LED once the counter reaches a certain number of overflows.  That might work.  The clock runs at around 9.6MHz by default (§6.2.2) and is shipped with the clock freqeuncy divided by 8 (§6.4.2), therefore the 8-bit timer register will overflow ~4688 times per second.  Using an 8-bit variable to count those would itself overflow 18 times per second, so we&#8217;d need to use a 16-bit variable instead.  That gets us into the human timescale, but 65536/4688 gives us a maximum flash time of ~13 seconds.  It might work, but there&#8217;s a yet more elegant way&#8230;</p>
<p>An alternative is to prescale the timer.  This has the effect of using 1 of every <em>n</em> clock ticks to increment the timer counter (§12.1).   You can choose from a number of slowdown factors, all of them are powers of two, and all are listed in the datasheet in §11.9.2, table 11-9.  The slowest rate we can make the timer increment is at 1/1024th the rate of the main system clock (by setting <code>CS02</code> and <code>CS00</code> bits to 1 in the <code>TCCR0B</code> register).</p>
<p>If prescaling by x1024, the timer register gets incremented at 1.2MHz/1024, i.e. ~1172 times per second, and thus overflows 4.6 times per second.  We could use an 8-bit variable to count the overflows and get a maximum of just under 56 seconds for that one little <code>uint</code>.  Sounds better to me.</p>
<p>Here&#8217;s a little pseudocode to encapsulate this so far:</p>
<pre class="brush:cpp">ISR(timer_overflow_vector) {
   if (timer_overflow_count &gt; 5) {   // a timer overflow occurs 4.6 times per second
      toggle_led();
      reset_timer_overflow_count();
   }
}

main() {
   initialize_io_port();
   prescale_timer();
   enable_timer_overflow_interrupt();

   while(1) {
      // let ISR handle the LED forever
   }
}</pre>
<p>Some of this is gravy, so let&#8217;s fill those in with more realistic code:</p>
<pre class="brush:cpp">volatile int timer_overflow_count = 0;

ISR(timer_overflow_vector) {      // TODO
   if (++timer_overflow_count &gt; 5) {   // a timer overflow occurs 4.6 times per second
      // Toggle Port B pin 4 output state
      PORTB ^= 1&lt;&lt;PB4;
      timer_overflow_count = 0;
   }
}

int main(void) {
   // Set up Port B pin 4 mode to output
    DDRB = 1&lt;&lt;DDB4;

   prescale_timer();   // TODO
   enable_timer_overflow_interrupt();   // TODO

   while(1) {
      // let ISR handle the LED forever
   }
}</pre>
<p>A little insight from <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html">avr-libc</a> helps with the interrupts.  By including <code>avr/interrupt.h</code>, the ATtiny13&#8242;s Timer/Counter0 Overflow is exposed through the <code>TIM0_OVF_vect</code> interrupt vector.  Thus:</p>
<pre class="brush:cpp">#include &lt;avr/interrupt.h&gt;

volatile int timer_overflow_count = 0;

ISR(TIM0_OVF_vect) {
   if (++timer_overflow_count &gt; 5) {   // a timer overflow occurs 4.6 times per second
      // Toggle Port B pin 4 output state
      PORTB ^= 1&lt;&lt;PB4;
      timer_overflow_count = 0;
   }
}

int main(void) {
   // Set up Port B pin 4 mode to output
    DDRB = 1&lt;&lt;DDB4;

   prescale_timer();   // TODO
   enable_timer_overflow_interrupt();   // TODO

   while(1) {
      // let ISR handle the LED forever
   }
}</pre>
<p>Prescaling the timer is straightforward and straight from the datasheet: <code>TCCR0B |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00)</code>.  Setting up the timer overflow interrupt was also defined in the datasheet: <code>TIMSK0 |=1&lt;&lt;TOIE0</code>, and the <code>sei</code> instruction has a helpful <code>sei()</code> macro defined in <code>avr/interrupt.h</code>.  Consolidating for our final code:</p>
<pre class="brush:cpp">#include &lt;avr/interrupt.h&gt;

volatile int timer_overflow_count = 0;

ISR(TIM0_OVF_vect) {
   if (++timer_overflow_count &gt; 5) {   // a timer overflow occurs 4.6 times per second
      // Toggle Port B pin 4 output state
      PORTB ^= 1&lt;&lt;PB4;
      timer_overflow_count = 0;
   }
}

int main(void) {
   // Set up Port B pin 4 mode to output
    DDRB = 1&lt;&lt;DDB4;

   // prescale timer to 1/1024th the clock rate
   TCCR0B |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);

   // enable timer overflow interrupt
   TIMSK0 |=1&lt;&lt;TOIE0;
   sei();

   while(1) {
      // let ISR handle the LED forever
   }
}</pre>
<p><strong>References/Acknowledgements: </strong>I have to point out the complete awesomeness and of Dean&#8217;s <a href="http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;file=viewtopic&amp;t=89843&amp;start=0&amp;postdays=0&amp;postorder=asc&amp;highlight=">Newbie&#8217;s Guide to AVR Interrupts</a> on <a href="http://www.avrfreaks.net/">http://www.avrfreaks.net</a>.  It&#8217;s awesome.   If you want a great explanation of interrupts, go there and read his tut.</p>
<p>Continue reading <a href="http://brownsofa.org/blog/archives/261">part 3</a> to see how to use these techniques plus sleep modes to save battery power, or review the <a href="http://brownsofa.org/blog/archives/191">previous section</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://brownsofa.org/blog/archives/215/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Compleat ATtiny13 LED Flasher: Part 1 &#8211; Setup, Hardware and A Basic Solution</title>
		<link>http://brownsofa.org/blog/archives/191</link>
		<comments>http://brownsofa.org/blog/archives/191#comments</comments>
		<pubDate>Sun, 02 Jan 2011 05:17:17 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[microprocessors]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[ATtiny13]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[led matrix]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brownsofa.org/blog/?p=191</guid>
		<description><![CDATA[This is the first part of three in attempting to explain how to make the ATtiny13 flash a LED. Part 1: Setup, Hardware and A Basic Solution Part 2: Using Timer Interrupts Part 3: Low Power Mode If you&#8217;re used to the user-friendliness of Arduino, getting started with bare bones AVRs can be hard work. [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the first part of three in attempting to explain how to make the ATtiny13 flash a LED. </em></p>
<ul>
<li><em><strong>Part 1: Setup, Hardware and A  Basic Solution</strong></em></li>
<li><em>Part 2: <a href="http://brownsofa.org/blog/archives/215">Using Timer Interrupts</a></em></li>
<li><em>Part 3: <a href="http://brownsofa.org/blog/archives/261">Low Power Mode</a></em></li>
</ul>
<p>If you&#8217;re used to the user-friendliness of Arduino, getting started with bare bones AVRs can be hard work.  I&#8217;d like to try to go slowly through the early steps and point out some of the information sources I used.</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/board.jpg"><img class="alignleft size-thumbnail wp-image-192" title="ATTiny LED flasher circuit" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/board-150x150.jpg" alt="" width="150" height="150" /></a>First, start at the end: here&#8217;s the final circuit.  It has an ATtiny13, an LED and current-limiting resistor, a few wires, the programmer interface, and that&#8217;s about it.  All it does is flash the LED on and off (very much like the classic 555 timer astable multivibrator but with the advantage of no passive components required).  That&#8217;s it.  Not much to it.</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/photo.jpg"><img class="alignright size-thumbnail wp-image-193" title="Circuit diagram" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/photo-150x150.jpg" alt="" width="150" height="150" /></a>Also, here&#8217;s a quick sketch of a circuit diagram too &#8211; the inputs all come directly from the ISP interface from the programmer.</p>
<p>Ok, that&#8217;s the end result.  Next: how to get there:</p>
<ol>
<li>Prerequisites (hardware and software)</li>
<li>Build the circuit</li>
<li>Write code</li>
<li>Upload to microprocessor</li>
</ol>
<h2><span id="more-191"></span></h2>
<p><strong>Prerequisites</strong></p>
<p>You need a programmer (e.g. <a href="http://www.sparkfun.com/products/9231">Pocket Programmer</a>, Adafruit&#8217;s <a href="http://www.adafruit.com/index.php?main_page=product_info&amp;products_id=46">USBtinyISP</a>, any number <a href="http://www.pololu.com/catalog/product/1300">of</a> <a href="http://hackaday.com/2010/05/15/minimalist-avr-programmer-is-just-fab/">others</a>, or even <a href="http://electronics.stackexchange.com/questions/33/arduino-as-avr-programmer">use</a> your <a href="http://hackaday.com/2009/07/15/avr-isp-programming-via-arduino/">arduino</a>),  a way to interface your programmer to your computer (a USB cable would be normal), and a way to interface your programmer to the ATtiny (ISP headers are normal, and here&#8217;s a <a href="http://electronics.stackexchange.com/questions/33/arduino-as-avr-programmer/71#71">picture of the pinout </a>of the 6-pin header).</p>
<p>Software-wise, there are also myriad choices.  There are different solutions for <a href="http://www.google.com/search?q=program+avr+with+windows">Windows</a>, <a href="http://www.google.com/search?q=program+avr+with+mac">Mac </a>and <a href="http://www.google.com/search?q=program+avr+with+linux">Linux</a>.  I&#8217;ve only tried a couple of Windows options to date.</p>
<p>Since there are so many options, I&#8217;d recommend finding a set of hardware and software that matches your existing equipment and budget that has a decent amount of documentation for troubleshooting.  If you can&#8217;t find much out about how to get programmer X working on your computer, try another programmer.</p>
<p>There are more detailed instructions about my tool chain for compiling and programming the chip in the <a href="http://brownsofa.org/blog/archives/50">dice post</a>.  I&#8217;m using a <a href="http://www.sparkfun.com/products/9231">Pocket Programmer</a>, and <a href="http://winavr.sourceforge.net/">WinAVR</a>.</p>
<p><strong>Build</strong><br />
Plug the microprocessor into your breadboard.  There&#8217;s a notch or a dot at one end of the package to indicate the top, or the position of pin 1 (pointed to in the photo).  Pay attention to which way round the chip is!  The rest of the pins are numbered counter-clockwise from pin 1.</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/1.jpg"><img class="size-thumbnail wp-image-195 alignnone" title="Pin 1 on ATTiny13" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/1-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>If you have a nice <a href="http://www.sparkfun.com/products/8508">breakout board</a> for your ISP connector, plug it into the breadboard, and start working from that.  Otherwise, refer to the <a href="http://electronics.stackexchange.com/questions/33/arduino-as-avr-programmer/71#71">pinout </a>for the ISP and plug wires directly into the socket.</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/2.jpg"><img class="size-thumbnail wp-image-196 alignnone" title="Programmer" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/2-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Connect each of the signals from the programmer to your ATtiny &#8211; each of MISO, MOSI, SCK, GND, VCC and RESET.  Look at the <a href="http://www.atmel.com/dyn/resources/prod_documents/doc8126.pdf">datasheet for the ATtiny13</a>to see the pinout  (page 2).</p>
<p>(I have a printout of tinkerlog.com&#8217;s <a href="http://tinkerlog.com/2009/06/18/microcontroller-cheat-sheet/">microcontroller cheat sheet</a> on my desk.  It has pinouts of most common ATtiny and ATmega chips, and ISP headers, and I&#8217;m constantly referring to it.)</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/3.jpg"><img class="size-thumbnail wp-image-197 alignnone" title="Connect MISO and MOSI" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/3-150x150.jpg" alt="" width="150" height="150" /></a><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/4.jpg"><img class="size-thumbnail wp-image-198 alignnone" title="Connect SCK and VCC" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/4-150x150.jpg" alt="" width="150" height="150" /></a><em><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/5.jpg"><img class="size-thumbnail wp-image-200 alignnone" title="Connect GND and RESET" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/5-150x150.jpg" alt="" width="150" height="150" /></a></em></p>
<p>I want to source current for the LED from the ATtiny, and sink it to ground, so connect a supply line on the edge of the breadboard to GND from the ISP.</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/6.jpg"><img class="size-thumbnail wp-image-201 alignnone" title="Connect ground rail" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/6-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Connect the long lead of the LED to pin 3 of the ATtiny.   Connect the short pin to an empty row.  Into that row, connect the resistor (100 or 200 ohms should be fine) and then finally connect the other leg of the resistor to the ground channel.</p>
<p><a href="http://brownsofa.org/blog/wp-content/uploads/2011/01/7.jpg"><img class="size-thumbnail wp-image-202 alignnone" title="Connect LED and resistor" src="http://brownsofa.org/blog/wp-content/uploads/2011/01/7-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p><strong>Write the code</strong></p>
<p>Paste this into your code editor:</p>
<pre class="brush:cpp">/*
 * ATtiny13 LED Flasher
 * File: main.c
 */

#include &lt;stdlib.h&gt;
#include &lt;util/delay.h&gt;

int main(void)
{
	const int msecsDelayPost = 100;

	// Set up Port B pin 4 mode to output
	DDRB = 1&lt;&lt;DDB4;

	// Set up Port B data to be all low
	PORTB = 0;	

	while (1) {
		// Toggle Port B pin 4 output state
		PORTB ^= 1&lt;&lt;PB4;

		// Pause a little while
		_delay_ms (msecsDelayPost);
	}

	return 0;
}</pre>
<p>Simple enough.  Save the file as main.c, generate or customize a makefile, and at a command prompt type <code>make all</code>.  You should see something like the following:</p>
<pre class="brush:plain">D:\Projects\AVR&gt;make all

-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Size before:
AVR Memory Usage
----------------
Device: attiny13

Program:      64 bytes (6.3% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)

Compiling C: main.c
avr-gcc -c -mmcu=attiny13 -I. -gdwarf-2 -DF_CPU=1200000UL -Os -funsigned-char -f
unsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ad
hlns=./main.lst  -std=gnu99 -MMD -MP -MF .dep/main.o.d main.c -o main.o

Linking: main.elf
avr-gcc -mmcu=attiny13 -I. -gdwarf-2 -DF_CPU=1200000UL -Os -funsigned-char -funs
igned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhln
s=main.o  -std=gnu99 -MMD -MP -MF .dep/main.elf.d main.o --output main.elf -Wl,-
Map=main.map,--cref     -lm

Creating load file for Flash: main.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature main.elf main.hex

Creating load file for EEPROM: main.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
        --change-section-lma .eeprom=0 --no-change-warnings -O ihex main.elf mai
n.eep || exit 0

Creating Extended Listing: main.lss
avr-objdump -h -S -z main.elf &gt; main.lss

Creating Symbol Table: main.sym
avr-nm -n main.elf &gt; main.sym

Size after:
AVR Memory Usage
----------------
Device: attiny13

Program:      64 bytes (6.3% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)

-------- end --------

D:\Projects\AVR&gt;</pre>
<p><strong>Upload to microprocessor</strong></p>
<p>Now the easy bit: plug the programmer into your computer, and type <code>make program </code>at the command prompt.  With any luck, you will see something like</p>
<pre class="brush:plain">D:\Projects\AVR&gt;make program
avrdude -p attiny13 -P usb     -c usbtiny    -U flash:w:main.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.34s

avrdude: Device signature = 0x1e9007
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: input file main.hex auto detected as Intel Hex
avrdude: writing flash (64 bytes):

Writing | ################################################## | 100% 0.27s

avrdude: 64 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex auto detected as Intel Hex
avrdude: input file main.hex contains 64 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.05s

avrdude: verifying ...
avrdude: 64 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

D:\Projects\AVR&gt;</pre>
<p>&#8230;and the LED should start flashing!</p>
<p>Continue reading <a href="http://brownsofa.org/blog/archives/215">part 2</a> to see how to achieve the same results by using timer interrupts.</p>
]]></content:encoded>
			<wfw:commentRss>http://brownsofa.org/blog/archives/191/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

