<?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>Principia Labs &#187; arduino</title>
	<atom:link href="http://principialabs.com/tag/arduino/feed/" rel="self" type="application/rss+xml" />
	<link>http://principialabs.com</link>
	<description>design, build, test, iterate.</description>
	<lastBuildDate>Sun, 28 Mar 2010 16:38:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Building Boarduino</title>
		<link>http://principialabs.com/building-boarduino/</link>
		<comments>http://principialabs.com/building-boarduino/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 18:05:33 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[adafruit]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://principialabs.com/?p=90</guid>
		<description><![CDATA[I recently soldered up a Boarduino from Adafruit Industries. Boarduino is simply an Arduino clone with a smaller form factor, designed to plug directly into a breadboard rather than giving you the female headers of the original. I thought I&#8217;d post a few photos of the process. I really like the idea of the Boarduino, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently soldered up a Boarduino from <a href="http://adafruit.com/">Adafruit Industries</a>.  Boarduino is simply an <a href="http://arduino.cc/">Arduino</a> clone with a smaller form factor, designed to plug directly into a breadboard rather than giving you the female headers of the original.  I thought I&#8217;d post a few photos of the process.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2422080500/" title="Adafruit Boarduino by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2181/2422080500_cb4a1f1114.jpg" width="500" height="375" alt="Adafruit Boarduino" /></a>
</div>

<p>I really like the idea of the Boarduino, because I found I was doing almost all of my prototyping on a  breadboard, and it seemed like I was always trying to figure out new and different <a href="/wp-content/uploads/arduino-breadboard.jpg">ways to anchor</a> the big Arduino down.</p>

<p><span id="more-53"></span></p>

<p>To get the size down, Boarduino makes a couple of design changes, most notably the elimination of the female headers on the top of the board, in exchange for the male headers on the bottom, which then plug directly into a breadboard, rather than having a rat&#8217;s nest of jumper wires running from the Arduino to the board.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2422080506/" title="Arduino NG and Boarduino by aerocapture, on Flickr"><img src="http://farm4.static.flickr.com/3281/2422080506_c9b9240048.jpg" width="500" height="375" alt="Arduino NG and Boarduino" /></a>
</div>

<p>Boarduino also eliminates the USB port and the associated USB chip, much like the <a href="http://www.arduino.cc/en/Main/ArduinoBoardMini">Arduino Mini</a>.  Instead, to program the board you need either a <a href="http://www.adafruit.com/index.php?main_page=product_info&amp;cPath=19&amp;products_id=70">USB-TTL cable</a>, which plugs into the six-pin header at the end of the board, or an FTDI breakout board like the <a href="http://www.arduino.cc/en/Main/MiniUSB">MiniUSB</a>.</p>

<p>Both the Arduino Mini and Boarduino are designed to plug into a breadboard.  The main difference between the two is that the Mini uses a permanently-soldered surface-mount chip, whereas the Boarduino uses a 28-pin socket and <acronym title="Dual Inline Package">DIP</acronym> chip, so if you blow one, you just spend six bucks and <a href="http://www.adafruit.com/index.php?main_page=product_info&amp;cPath=19&amp;products_id=56">pop in a new one</a>, rather than buying a whole new Mini.  In addition, the Arduino Mini lacks Boarduino&#8217;s 9V barrel jack and voltage regulator, so you have to design that circuit yourself.  Plus, the Boarduino is simply cooler because you get to <em>build</em> it yourself!</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2419682593/" title="The Lab by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2115/2419682593_16886f4944.jpg" width="500" height="375" alt="The Lab" /></a>
</div>

<p>The first step is getting your work area all set up, as shown in the image above.  (The WES51 really ties the room together does it not?)</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2419680469/" title="Boarduino Solder Joints by aerocapture, on Flickr"><img src="http://farm4.static.flickr.com/3192/2419680469_b485dbd90d.jpg" width="500" height="367" alt="Boarduino Solder Joints" /></a>
</div>

<p>Check out the great solder joints done by the WES51.  I used a small, stiff watercolor paintbrush and isopropyl alcohol to clean the rosin flux off the board and joints after soldering, leaving a nice, clean-looking board.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2420495394/" title="&amp;quot;Yeah, it lights up.&amp;quot; by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2105/2420495394_d46d4d5b67.jpg" width="500" height="391" alt="&amp;quot;Yeah, it lights up.&amp;quot;" /></a>
</div>

<p style="text-align: center;">Power supply finished and tested, in this case with the USB-TTL cable.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2422030032/" title="16 MHz Ceramic Oscillator by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2348/2422030032_925ddeac79.jpg" width="500" height="375" alt="16 MHz Ceramic Oscillator" /></a>
</div>

<p style="text-align: center;">Note that the Boarduino uses a 16MHz <i>ceramic</i> oscillator rather than a crystal.  This is slightly less accurate, but only on a nanosecond scale, and not relevant for most projects.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2422030058/" title="Time for the Socket by aerocapture, on Flickr"><img src="http://farm4.static.flickr.com/3234/2422030058_0a1ba4bf0c.jpg" width="500" height="375" alt="Time for the Socket" /></a>
</div>

<p style="text-align: center;">Ready to install the 28-pin socket.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2421249267/" title="Headers Soldered by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2256/2421249267_499b9889c4.jpg" width="500" height="375" alt="Headers Soldered" /></a>
</div>

<p style="text-align: center;">Socket and headers soldered in.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2421249271/" title="The ATmega168 Microcontroller by aerocapture, on Flickr"><img src="http://farm4.static.flickr.com/3148/2421249271_a1ebf0eede.jpg" width="500" height="375" alt="The ATmega168 Microcontroller" /></a>
</div>

<p style="text-align: center;">Behold the AVR ATmega168 microcontroller.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2421249275/" title="Inserting the ATmega168 by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2239/2421249275_b7e2d6d7dc.jpg" width="500" height="375" alt="Inserting the ATmega168" /></a>
</div>

<p style="text-align: center;">Inserting the ATmega168.</p>

<div style="text-align: center;">
<a href="http://www.flickr.com/photos/aerocapture/2422080494/" title="Power and USB FTDI Applied by aerocapture, on Flickr"><img src="http://farm3.static.flickr.com/2260/2422080494_28c0b47a92.jpg" width="500" height="375" alt="Power and USB FTDI Applied" /></a>
</div>

<p style="text-align: center;">Boarduino completed, powered up and ready to go.</p>

<p>Can&#8217;t get enough of those close-up solder pix?  Check out <a href="http://flickr.com/photos/aerocapture/tags/boarduino/">the rest of my Boarduino photos</a> on Flickr.</p>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/building-boarduino/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Arduino-Python 4-Axis Servo Control</title>
		<link>http://principialabs.com/arduino-python-4-axis-servo-control/</link>
		<comments>http://principialabs.com/arduino-python-4-axis-servo-control/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 18:46:29 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[servo]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://principialabs.com/?p=69</guid>
		<description><![CDATA[Although the Arduino platform is ideal for standalone applications, it really comes to life when interfaced with a PC. Connect Arduino to a personal computer and you instantly add a ton of versatility and processing power to your project. This tutorial will describe how to use Arduino to control a bank of four independent RC [...]]]></description>
			<content:encoded><![CDATA[<div class="video">
<embed src="http://blip.tv/play/wkew8g0C" type="application/x-shockwave-flash" width="380" height="310" allowscriptaccess="always" allowfullscreen="true"></embed>
</div>

<p>Although the <a href="http://arduino.cc/">Arduino</a> platform is ideal for standalone applications, it really comes to life when interfaced with a PC.  Connect Arduino to a personal computer and you instantly add a ton of versatility and processing power to your project.</p>

<p>This tutorial will describe how to use Arduino to control a bank of four independent RC servos with your PC (or Mac, or *nix Box), using a USB cable and a modular Arduino-Python software stack.</p>

<p>The following discussion builds upon concepts presented in two previous articles, &#8220;<a href="/arduino-serial-servo-control/">Arduino Serial Servo Control</a>&#8221; and &#8220;<a href="/joystick-control-of-a-servo/">Joystick Control of a Servo</a>.&#8221;  As always, comments, critiques, or suggestions for improving or adapting this code are welcome and appreciated.</p>

<h4>Project Outline</h4>

<p>The primary goal for this project was to create a software stack that allows simple and flexible control of multiple servos from any type of Python script.</p>

<p>The solution has two basic components: (1) an Arduino sketch that waits for serial input from a connected PC, then moves each servo to its commanded position, and; (2) a Python module on the PC that opens the serial connection and formats the data packets expected by the Arduino.</p>

<p>Any other Python program written to sit on <em>top</em> of these two layers need not worry about the messy details of serial communication, but rather can just say something like, &#8220;Move servo #2 to 90 degrees.&#8221;  Or, more precisely:</p>

<pre><code>servo.move(2,90)
</code></pre>

<p>Easy, right?  Let&#8217;s get started.</p>

<p><span id="more-51"></span></p>

<h2>Part I:  Smoke, Mirrors, and Hand-Waving</h2>

<p>If you just want to get things up and running quickly, start here.  These instructions will get your servos connected and obeying every whim of your PC in no time.</p>

<h4>Hardware Setup</h4>

<p>Hardware for this project consists of an Arduino module, four <a href="http://www.horizonhobby.com/Products/Default.aspx?ProdID=JSP20050">JR Sport ST47</a> standard servos, and a breadboard to create the circuit.</p>

<p>The servos each have three wires: Ground (brown), Power (red) and Control (yellow).  Each of the Control wires will connect to a different digital pin on the Arduino board (pins 2 through 5 in our setup), and <em>all</em> of the Power and Ground wires will need to connect somehow to the 5V and Gnd pins.</p>

<div style="text-align:center;"><a href='http://principialabs.com/wp-content/uploads/arduino-breadboard.jpg'><img src="http://principialabs.com/wp-content/uploads/arduino-breadboard.thumbnail.jpg" alt="" title="Breadboard: click to enlarge" /></a></div>

<p>The simplest way to accomplish this is to create a &#8220;bus&#8221; bar along one of the breadboard&#8217;s edges, as shown in the photo above. Simply route the Arduino&#8217;s 5V and Gnd to a convenient area on the breadboard, and connect all the servos.</p>

<h4>Required Software: The Lower Layers</h4>

<p>To get the effects seen in the video above, you&#8217;ll need at least the following two programs.  Although this code is designed to control four servos, it also works as-is with <em>fewer</em> servos, and &#8212; with a few modifications &#8212; as many as twelve (or 48 with the <a href="http://arduino.cc/en/Main/ArduinoBoardMega">Arduino Mega</a>!).</p>

<p><strong>Download the code:</strong></p>

<div style="padding-left:20px;">

<p><del><b>MultipleServos.pde</b>: This is the Arduino sketch.  Copy and paste this code into your Arduino software and upload it to the board.</del></p>

<p><a href='http://principialabs.com/wp-content/uploads/MultipleSerialServoControl.pde'><b> MultipleSerialServoControl.pde</b></a>: [Updated 12/23/09] This is the NEW Arduino sketch, which uses the Arduino <a href="http://arduino.cc/en/Reference/Servo">Servo library</a> to make alterations <i>much</i> simpler.  You can control up to 12 servos using this code (with modifications) and most Arduino boards, or <i>up to 48 servos</i> using an Arduino Mega!  (See the code comments for specific details.)  This code should also solve most of the servo &#8220;jitter&#8221; issues mentioned in the comments below.  Copy and paste this code into your Arduino software and upload it to the board.  (Requires <a href="http://www.arduino.cc/en/Main/Software">Arduino 0017</a> or greater.)</p>

<p><a href='http://principialabs.com/wp-content/uploads/servo.py'><b>servo.py</b></a>: This is the Python module which talks directly to the above Arduino sketch.  This script requires the <a href="http://sourceforge.net/projects/pyserial/">pyserial</a> module, available from Sourceforge. Save this script on your PC wherever you like, just be sure to name it &#8220;servo.py&#8221;.</p>

</div>

<div class="help">
<b>New to Python?</b> Welcome!  Python is a versatile and fun language to learn, and it&#8217;s used by just about everyone, from newbies to NASA!  Check out the <a href="http://wiki.python.org/moin/BeginnersGuide">Beginner&#8217;s Guide</a>  to get your bearings, or get the full skinny at <a href="http://python.org/">python.org</a>.
</div>

<p><strong>Customize the code:</strong></p>

<p>Depending on your computer system and Arduino hardware setup, you may need to make a few modifications to the code.</p>

<p><strong>Arduino:</strong> In the &#8220;MultipleSerialServoContro&#8221; sketch, take note of the following variables and make adjustments as necessary for your setup.  See &#8220;<a href="/arduino-serial-servo-control/">Arduino Serial Servo Control</a>&#8221; for more details regarding the <code>minPulse</code> and <code>maxPulse</code> variables.  (If you&#8217;ve got standard RC servos attached to pins 2-5, you probably won&#8217;t have to change anything.)</p>

<pre><code>// Common servo setup values
int minPulse = 600;   // minimum servo position, us (microseconds)
int maxPulse = 2400;  // maximum servo position, us

// Attach each Servo object to a digital pin
servo1.attach(2, minPulse, maxPulse);
servo2.attach(3, minPulse, maxPulse);
servo3.attach(4, minPulse, maxPulse);
servo4.attach(5, minPulse, maxPulse);
</code></pre>

<p><strong>Python:</strong>  In the &#8220;servo.py&#8221; script, you&#8217;ll most likely need to change the value of the <code>usbport</code> variable, which tells Python how to find your Arduino (On Windows, it&#8217;ll be something like &#8216;COM5&#8242;. On a Mac, &#8216;/dev/tty.usbserial-xxxxx&#8217;.  On Linux, &#8216;/dev/ttyUSB0&#8242;.).  Try running <code>ls /dev/tty*</code> from a Mac or Linux terminal for a list of available ports.  [ToDo: Modify the script to make this step unnecessary.]</p>

<p><strong>Test the code:</strong></p>

<p>Once your hardware is set up and the software is installed, you can test the system&#8217;s basic functionality from the <a href="http://programming-crash-course.com/the_python_interactive_interpreter">Python interactive interpreter</a>, like so:</p>

<pre><code>~/path/to/servo.py$ python
&gt;&gt;&gt; import servo
&gt;&gt;&gt; servo.move(2,150)
</code></pre>

<p>The <code>servo.move()</code> method takes two arguments, both integers.  The first is the servo number you wish to move, 1-4 (or whatever).  The second is the commanded angular position of the servo horn, from 0-180 degrees.  So, if you want to move Servo #3 fully clockwise (180 degrees), you&#8217;ll type <code>servo.move(3,180)</code>.  Cake, baby!</p>

<h4>Optional Software: From Totally Geek to Totally Chic</h4>

<p>The following scripts are designed to leverage the functionality of the <code>servo.move()</code> method for simple and readable code.  Make sure these files reside in the same directory as &#8220;servo.py&#8221;.</p>

<ul style="list-style-type: none; padding-left: 20px;">

<li><a href='http://principialabs.com/wp-content/uploads/servodance.py'><b>servodance.py</b></a>:  A cascading effect that feels like watching a quarter spiral down one of those funnel-shaped wishing wells.</li><br />

<li><a href='http://principialabs.com/wp-content/uploads/servorandom.py'><b>servorandom.py</b></a>: The final servo sequence seen in the video, with individual servos moving to random positions and then waving &#8220;goodbye&#8221; in unison.</li><br />

<li><a href='http://principialabs.com/wp-content/uploads/servomarch.py'><b>servomarch.py</b></a>:  This one&#8217;s not in the video, but it&#8217;s a fun script to test individual and simultaneous movement of multiple servos.  Just set the number of servos to march (default is 4), and send them off!</li><br />

<li><a href='http://principialabs.com/wp-content/uploads/multijoystick.py'><b>multijoystick.py</b></a>: Allows joystick control of four servos, with each joystick axis controlling a single servo.  This script is the most complex, so try getting the first three working, then graduate to this one &#8212; it&#8217;s easier to troubleshoot problems that way.  <br/>[Note: This script also requires installation of the <a href="http://www.pygame.org/">pygame</a> module.]</li>

</ul>

<p>With any luck, you should now have everything up and running just like in the video!</p>

<h4>NEW: Adding Servos</h4>

<p><p>[Updated 12/23/09] If you&#8217;re using the <a href='http://principialabs.com/wp-content/uploads/MultipleSerialServoControl.pde'>new Arduino sketch</a>, you can easily add servos to your project by making a few simple additions to the code.  The beauty of this system is that <code>servo.py</code> can remain unchanged, and all of the higher-level Python scripts just need simple alterations to include whatever number of servos you decide to add.  This segment will outline how to change the Arduino sketch; changes to the Python scripts will be up to you!</p>

<p>There are three places in the <code>MultipleSerialServoControl</code> sketch where you&#8217;ll need to make additions, if you want to control more than four servos.  Each section of the code contains the comment &#8220;TO ADD SERVOS:&#8221; followed by a suggestion on what to add.  </p>

<p>First, add a Servo object for each additional servo:</p>

<pre name="code" class="arduino:nocontrols">
// Create a Servo object for each servo
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
// TO ADD SERVOS:
//   Servo servo5;
//   etc...
</pre>

<p>Second, assign a digital pin to each additional servo:</p>

<pre name="code" class="arduino:nocontrols">
  // Attach each Servo object to a digital pin
  servo1.attach(2, minPulse, maxPulse);
  servo2.attach(3, minPulse, maxPulse);
  servo3.attach(4, minPulse, maxPulse);
  servo4.attach(5, minPulse, maxPulse);
  // TO ADD SERVOS:
  //   servo5.attach(YOUR_PIN, minPulse, maxPulse);
  //   etc...
</pre>

<p>Third, create a new switch case for each additional servo:</p>

<pre name="code" class="arduino:nocontrols">
      // Assign new position to appropriate servo
      switch (servo) {
        case 1:
          servo1.write(pos);    // move servo1 to 'pos'
          break;
        case 2:
          servo2.write(pos);
          break;
        case 3:
          servo3.write(pos);
          break;
        case 4:
          servo4.write(pos);
          break;
   // TO ADD SERVOS:
   //     case 5:
   //       servo5.write(pos);
   //       break;
   // etc...
      }
</pre>

<p>After making changes, be sure to click the &#8220;Verify&#8221; button on your Arduino software to make sure there are no errors, then upload it to the board.  Test your changes by calling the <code>servo.move()</code> method from the Python interpreter.  That&#8217;s it!</p>

<div style="border-top:1px solid #ddd;margin:40px 140px;">
</div>

<h2>Part II:  Getting Down to Brass Tacks</h2>

<p>Next, let’s take a look under the hood to see how it all works.  If you&#8217;re the type that just wants to get things working and damn the details, <strong>STOP HERE</strong>.  Otherwise, continue on, and I&#8217;ll do my best to explain how the code &#8220;do what it do.&#8221;</p>

<h4>The Problem Set</h4>

<p>Asynchronous serial communication is not perfect.  Sometimes there are errors,  dropped packets, confusion.  Sometimes the mail does <em>not</em> get through.  In both of the previous two serial/servo projects, the Arduino expected only one byte from the PC, and in both cases that byte represented a commanded servo position &#8212; and nothing more.  If a byte was missed or skipped, it wasn&#8217;t a big deal, another one was sure to come along, and it was impossible to misinterpret.</p>

<p>This project presents a couple of new challenges.  First, we are controlling more than one servo, so the Arduino needs more than one command element for each move.  As we&#8217;ve seen above, it needs to know (at least) <em>which</em> servo to move, and <em>how much</em> to move it.  Secondly, we have the problem of communication.  This time, we&#8217;re sending <em>two</em> command elements for each move (servo number &amp; position), and these elements are clearly <em>not</em> interchangable. That is, if we want to send <code>servo.move(4,90)</code>, we need to make sure that Arduino knows that the &#8217;4&#8242; means &#8220;Servo #4&#8243; and the &#8217;90&#8242; means &#8220;90 degrees.&#8221;</p>

<p>Tom Igoe&#8217;s article, &#8220;<a href="http://www.tigoe.net/pcomp/code/serial-communication/interpreting-serial-data-bytes">Interpreting Serial Data</a>,&#8221; contains an excellent discussion of some of the problems involved in serial communication, and lists several issues that need to be addressed in every project, namely:</p>

<blockquote>
  <ol>
  <li>How many bytes am I sending? Am I receiving the same number?</li>
  <li>Did I get the bytes in the right order?</li>
  <li>Are my bytes part of a larger variable?</li>
  <li>Is my data getting garbled in transit?</li>
  </ol>
</blockquote>

<p>The Arduino&#8217;s <code>Serial.read()</code> function reads one byte of data at a time from its <em>serial buffer</em>.  Think of the serial buffer as a mailbox.  It&#8217;s a small (128 bytes) area of memory where incoming serial messages are stashed until the Arduino is ready to read them.  Every character we send from the PC to Arduino is one byte.  So, while we could send the Arduino something very unambiguous like, &#8220;Yeah, hi, Arduino, it&#8217;s the Linux Box again.  What&#8217;s happening?  If you could go ahead and move Servo #4 to the 90-degree position, that would be great.  Thaaanks,&#8221; (163 bytes) it&#8217;s obviously better if we can come up with something a little more terse.</p>

<p>However, as we&#8217;ve seen, if we just send over the characters &#8217;4&#8242;, &#8217;9&#8242;, and &#8217;0&#8242; &#8212; remember, each character is a byte &#8212; the Arduino might get confused.  This problem is amplified when more commands start stacking up in the buffer.  Let&#8217;s say now we command <code>servo.move(2,180)</code> and <code>servo.move(3,120)</code>.  Now the buffer should hold {4,9,0,2,1,8,0,3,1,2,0}, except&#8211;OOPS!&#8211;one of the bytes got dropped along the way, so now it holds {4,9,0,2,1,8,3,1,2,0}.  &#8220;Wait, which servo did you want me to move?&#8221;  You can clearly see a problem developing.</p>

<h4>Solution: Data Packets and Start Bytes</h4>

<p>Luckily, part of the solution is handled in the way Arduino communicates.  Arduino uses <a href="http://en.wikipedia.org/wiki/ASCII">ASCII</a> encoding to represent alphanumeric characters.  Each character sent over the wire is converted to the binary equivalent of a decimal value from 0 to 255.  [See this <a href="http://www.arduino.cc/en/Reference/ASCIIchart">conversion chart</a> for specifics.]</p>

<p>So, for example, if we send over the character &#8216;A&#8217;, Arduino recognizes this as its decimal value, &#8217;65&#8242;.  We won&#8217;t get too deep into this concept except to say that the implementation is <em>great</em> for our application, because as long as the values we&#8217;re sending are less than 255, they&#8217;ll fit neatly into one byte.  Since the largest value we send is 180, we only have to send two bytes per command.</p>

<p>Now, if you&#8217;ve looked at the ASCII conversion chart, you&#8217;ll recognize that doing this every time you want to send a command would be a real pain.  Also, trying to teach Python this chart would take up a lot of unnecessary code.  Thankfully, this problem is already solved for us with Python&#8217;s <code>chr()</code> function.  Wrap any decimal value from 0-255 in <code>chr()</code>, and you get back its ASCII equivalent.  A few examples:</p>

<pre><code>~$ python
&gt;&gt;&gt; chr(65)
'A'
&gt;&gt;&gt; chr(110)
'n'
&gt;&gt;&gt; chr(13)
'r'
&gt;&gt;&gt; chr(9)
't'
</code></pre>

<p>You get the idea, but notice that ASCII doesn&#8217;t just represent letters and numbers, but also symbols and other &#8220;control&#8221; or &#8220;non-printing&#8221; characters like line-feeds, returns, and tabs.</p>

<p>So, now if we want to send <code>servo.move(4,90)</code>, we only need <em>two</em> bytes, the ASCII equivalents of &#8217;4&#8242; and &#8217;90&#8242;, represented in Python as <code>chr(4)</code> and <code>chr(90)</code>, and interpreted by the Arduino sketch as, once again, simply &#8217;4&#8242; and &#8217;90&#8242;.  Easy!  [Seriously, if your brain explodes at this point, or you're bleeding from the ears, it's understandable.  I don't like it any more than you do, but stick with me, it'll all work out neatly in the end.]</p>

<p><strong>Packets, Headers, and Payloads</strong></p>

<p>Okay, great, now instead of just digits in Arduino&#8217;s serial buffer, we have meaningful values.  Part of the problem is solved, but we still haven&#8217;t addressed the issue of dropped or missing bytes.  That is, how will the Arduino know that a &#8217;4&#8242; is &#8220;Servo #4&#8243; and not &#8220;4 degrees&#8221; when pulling values out of a crowded buffer like {4,90,2,180,3,0,1,110} ?</p>

<p>The answer is <a href="http://computer.howstuffworks.com/question525.htm">data packets</a>.  Very simply, instead of just sending a long string of numbers to Arduino, we&#8217;ll send a very specific ordered message, a <em>packet</em> of values, that is intended to be read and interpreted <strong>as a whole</strong> and <strong>in order</strong>, or else discarded completely.</p>

<p>Now, the structure of a packet can be as simple or as complex as we need it to be, as you might have noticed if you followed that last link.  But all we really need is some means of ensuring that Arduino doesn&#8217;t confuse one value for another.</p>

<p>Essentially, our Python script needs to tell Arduino three things:</p>

<ol>
<li>Here comes a new servo command.</li>
<li>Servo number to move.</li>
<li>Commanded servo position.</li>
</ol>

<p>We&#8217;ve already been sending the last two elements, the servo number and position.  Here, we&#8217;re adding a third element, which we&#8217;ll call the <em>header</em> or the <em>start byte</em>.  Our header, like the rest of the data in our packet, will be just one byte long, and contain no real information other than the conceptual message, &#8220;I am a header.&#8221;</p>

<p>The <em>order</em> of this message is important.  Every packet sent over the wire, or read from the serial buffer, will now have the following format:</p>

<pre><code>(Header, Servo Number, Servo Position)
</code></pre>

<p>or, more tersely:</p>

<pre><code>(startbyte, servo, angle)
</code></pre>

<p>What to use as a startbyte?  Well, we&#8217;re only using the values from 0-180 as either our Servo Number or Servo Postion.  Any value from 181 to 255 would be unique.  We&#8217;ll use &#8217;255&#8242; just to make it obvious.  So, every packet will now look something like one of the following:</p>

<pre><code>(255, 1, 90)
(255, 2, 180)
(255, 3, 0)
</code></pre>

<p>And the Arduino&#8217;s serial buffer would look something like:</p>

<pre><code>{255,1,90,255,2,180,255,3,0}
</code></pre>

<p>Now, instead of reading byte after byte and hoping for the best, Arduino will <em>wait</em> until a minimum of three bytes arrive in the buffer, and then read the first byte to determine whether or not it is, in fact, a header (255).  If it&#8217;s not, Arduino skips that value, and moves on to the next byte without touching the servos.  When it finally sees a header, Arduino continues reading the next two bytes, in order, and assigning them to the Servo Number and the Servo Position, respectively.  If either of <em>those</em> two values is &#8217;255&#8242;, Arduino assumes something is wrong, and skips everything until it reads a new header.</p>

<p><strong>Side Note:  Authoritarian Flow Control</strong></p>

<p>&#8220;Now just a minute!&#8221; you&#8217;re saying.  &#8220;If that is the case, then <em>some</em> of the commands Python sends to the Arduino will be totally ignored!&#8221;  And you&#8217;re right.  This method of serial flow control is definitely one-way, with no error-checking.  Other methods, such as &#8220;call-and-response&#8221; or &#8220;<a href="http://itp.nyu.edu/physcomp/Labs/Serial">handshaking</a>&#8221; are much better at ensuring accuracy, since there&#8217;s a back-and-forth arrangement that can call for data to be re-sent in the event of dropped packets.  But the two-way protocol this method requires is <em>much</em> slower.</p>

<p>We have to make an engineering decision.  In our application, which is more important, accuracy or quick response?  It depends on exactly how you are using the servos, but if you consider say, a joystick-controlled robot or RC vehicle application, then clearly an immediate response and quick visual feedback is preferable to perfect accuracy.  If you command &#8220;turn right&#8221; with a joystick, and your vehicle doesn&#8217;t respond appropriately, you&#8217;ll just instinctively add more right stick input.</p>

<p>Perfect accuracy is not required.</p>

<h4>Writing the Code</h4>

<p>Very briefly, let&#8217;s look at how the above concepts are implemented in both the Python and Arduino software.</p>

<p><strong>Python Implementation</strong></p>

<p>Whenever we call the <code>servo.move()</code> method, the Python script <code>servo.py</code> handles the serial communication details using the <code>pyserial</code> module, and formats the arguments into the data packet outlined above.  The bare-bones version looks like this:</p>

<pre name="code" class="python:nocontrols">
#!/usr/bin/env python

import serial
usbport = '/dev/ttyUSB0'
ser = serial.Serial(usbport, 9600, timeout=1)

def move(servo, angle):
    if (0 <= angle <= 180):
        ser.write(chr(255))
        ser.write(chr(servo))
        ser.write(chr(angle))
    else:
        pass
</pre>

<p><strong>Arduino Implementation</strong></p>

<p>Arduino opens its own serial connection, waits for at least three bytes to fill the buffer, then starts reading:</p>

<pre name="code" class="arduino:nocontrols">
/** MultipleSerialServoControl.pde (bare bones) **/

void setup() {
  // Open the serial connection, 9600 baud
  Serial.begin(9600);
} 

void loop() 
{ 
  // Wait for serial input (min 3 bytes in buffer)
  if (Serial.available() > 2) {
    // Read the first byte
    startbyte = Serial.read();
    // If it's really the startbyte (255) ...
    if (startbyte == 255) {
      // ... then get the next two bytes
      for (i=0;i<2;i++) {
        userInput[i] = Serial.read();
      }
      // First byte = servo to move?
      servo = userInput[0];
      // Second byte = which position?
      pos = userInput[1];
      // Packet error checking and recovery
      if (pos == 255) { servo = 255; }
</pre>

<p>If Arduino gets a complete packet with header, servo, and angle values, it assigns the new position to the appropriate servo.  If the value of <code>servo</code> is not between 1 and 4 (or whatever maximum number of servos you specify), the loop exits without assigning any new values.  That's it!  The Arduino Servo library really makes servo control easy and painless.</p>

<pre name="code" class="arduino:nocontrols:firstline[26]">
      // Assign new position to appropriate servo
      switch (servo) {
        case 1:
          servo1.write(pos);    // move servo1 to 'pos'
          break;
        case 2:
          servo2.write(pos);
          break;
        case 3:
          servo3.write(pos);
          break;
        case 4:
          servo4.write(pos);
          break;
    }
  }
</pre>

<h4>Whew! We're Done.</h4>

<p>Well, if you've made it this far, congratulations: you're totally insane.  I hope the above dissertation helps at least one person better grasp these concepts, since it took me across many web pages and into several late nights to find the answers.  Good luck!</p>

<h4>References</h4>

<ol>
<li>Tom Igoe, <em><a href="http://www.oreilly.com/catalog/9780596510510/">Making Things Talk: Practical Methods for Connecting Physical Objects</a></em></li>
<li>Tom Igoe, "<a href="http://www.tigoe.net/pcomp/serial.shtml">Serial Communication</a>"</li>
<li>Tom Igoe, "<a href="http://www.tigoe.net/pcomp/serialdata.shtml">Interpreting Serial Data</a>"</li>
<li>Society of Robots, "<a href="http://www.societyofrobots.com/actuators_servos.shtml">Actuators and Servos</a>"</li>
<li>ITP Physical Computing, "<a href="http://itp.nyu.edu/physcomp/Labs/Servo">Servo Lab</a>"</li>
<li>ITP Physical Computing, "<a href="http://itp.nyu.edu/physcomp/Labs/Serial">Serial Lab</a>"</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/arduino-python-4-axis-servo-control/feed/</wfw:commentRss>
		<slash:comments>92</slash:comments>
		</item>
		<item>
		<title>Joystick Control of a Servo</title>
		<link>http://principialabs.com/joystick-control-of-a-servo/</link>
		<comments>http://principialabs.com/joystick-control-of-a-servo/#comments</comments>
		<pubDate>Thu, 27 Dec 2007 18:46:11 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[servo]]></category>

		<guid isPermaLink="false">http://principialabs.com/joystick-control-of-a-servo/</guid>
		<description><![CDATA[UPDATE: Please read Arduino-Python 4-Axis Servo Control for the most current anddetailed information on using a USB joystick to control one or more RC servos. Inspired by Armadillo Aerospace and their laptop-controlled Pixel rocket, I decided to figure out how to use an Arduino module to achieve wireless remote control of a flight vehicle. Along [...]]]></description>
			<content:encoded><![CDATA[<div class="help" style="margin: 10px 6px 24px 6px; text-align: center;"><strong>UPDATE:</strong>  Please read <a href="http://principialabs.com/arduino-python-4-axis-servo-control/">Arduino-Python 4-Axis Servo Control</a> for the most current and<br />detailed information on using a USB joystick to control one or more RC servos.</div>

<div class="video">
<embed src="http://blip.tv/play/wkeilE8A" type="application/x-shockwave-flash" width="380" height="300" allowscriptaccess="always" allowfullscreen="true"></embed>
</div>

<p>Inspired by Armadillo Aerospace and their laptop-controlled <a href="http://media.armadilloaerospace.com/wallpapers/PixelFlightWallpaper1.jpg">Pixel rocket</a>, I decided to figure out how to use an Arduino module to achieve wireless remote control of a flight vehicle.</p>

<p>Along the path to development, an achievable intermediate goal would be something like a wireless RC rover with a video camera, monitored and controlled with a laptop and joystick on a WiFi network.</p>

<p>Step one in the process is simple joystick control of a servo over a USB connection.  This project builds upon the process documented in &#8220;<a href="/arduino-serial-servo-control">Arduino Serial Servo Control</a>.&#8221;  I welcome any comments or suggestions for improving or adapting this code.</p>

<p><span id="more-43"></span></p>

<p><strong>Hardware</strong></p>

<p>The hardware setup is very simple, and is described in detail in the serial-servo article.  The <a href="http://www.google.com/products?q=jr+sport+st47+standard+servo">JR Sport ST47 standard servo</a> is wired directly to Arduino&#8217;s 5V power and ground, and the servo&#8217;s control wire is connected to Digital pin #2.  The Arduino module is connected to a PC (running Linux in our case) with a USB cable, and a standard USB joystick is also connected.</p>

<p><strong>Software</strong></p>

<p>The simple two-layer software stack includes a Python script for interpreting inputs from the joystick, and the Arduino sketch to await serial inputs from the Python script and pulse the servo.</p>

<p>Let&#8217;s start with the Python script.  This code lives on the PC, and requires the <a href="http://pyserial.sourceforge.net/">pyserial</a> and <a href="http://www.pygame.org/">pygame</a> modules to be installed, along with (obviously) Python&#8217;s standard library.  The <code>pygame</code> module is primarily designed for graphics game creation, but it has a set of very straightforward methods for interpreting joysticks and other non-standard input devices.  The <code>pyserial</code> module simply allows us to open a serial connection to the Arduino over a USB port.</p>

<p>The primary purpose of the Python script is to read and report on joystick inputs.  A gaming joystick may have six different axes and a multitude of buttons.  This script will sense inputs from each axis, and (if enabled) print the values of the stick positions.</p>

<p>Each joystick axis reports a range of decimal values between -1.0 and 1.0, with zero being the center position.  This script converts those values (from the X-axis) into round numbers between zero and 180 and assigns that value as a servo position.  Since the servo can travel through 180 degrees, each servo position value increments the servo horn by one degree, with the center at 90 degrees.  The integers 0-180 are then converted to ASCII characters and sent over the serial connection to the Arduino.</p>

<pre name="code" class="python">
#!/usr/bin/env python
#
# joystick-servo.py
#
# created 19 December 2007
# copyleft 2007 Brian D. Wendt
# http://principialabs.com/
#
# code adapted from:
# http://svn.lee.org/swarm/trunk/mothernode/python/multijoy.py
#
# NOTE: This script requires the following Python modules:
#  pyserial - http://pyserial.sourceforge.net/
#  pygame   - http://www.pygame.org/
# Win32 users may also need:
#  pywin32  - http://sourceforge.net/projects/pywin32/
#

import serial
import pygame

# allow multiple joysticks
joy = []

# Arduino USB port address (try "COM5" on Win32)
usbport = "/dev/ttyUSB0"

# define usb serial connection to Arduino
ser = serial.Serial(usbport, 9600)

# handle joystick event
def handleJoyEvent(e):
    if e.type == pygame.JOYAXISMOTION:
        axis = "unknown"
        if (e.dict['axis'] == 0):
            axis = "X"

        if (e.dict['axis'] == 1):
            axis = "Y"

        if (e.dict['axis'] == 2):
            axis = "Throttle"

        if (e.dict['axis'] == 3):
            axis = "Z"

        if (axis != "unknown"):
            str = "Axis: %s; Value: %f" % (axis, e.dict['value'])
            # uncomment to debug
            #output(str, e.dict['joy'])

            # Arduino joystick-servo hack
            if (axis == "X"):
                pos = e.dict['value']
                # convert joystick position to servo increment, 0-180
                move = round(pos * 90, 0)
                if (move < 0):
                    servo = int(90 - abs(move))
                else:
                    servo = int(move + 90)
                # convert position to ASCII character
                servoPosition = chr(servo)
                # and send to Arduino over serial connection
                ser.write(servoPosition)
                # uncomment to debug
                #print servo, servoPosition

    elif e.type == pygame.JOYBUTTONDOWN:
        str = "Button: %d" % (e.dict['button'])
        # uncomment to debug
        #output(str, e.dict['joy'])
        # Button 0 (trigger) to quit
        if (e.dict['button'] == 0):
            print "Bye!\n"
            ser.close()
            quit()
    else:
        pass

# print the joystick position
def output(line, stick):
    print "Joystick: %d; %s" % (stick, line)

# wait for joystick input
def joystickControl():
    while True:
        e = pygame.event.wait()
        if (e.type == pygame.JOYAXISMOTION or e.type == pygame.JOYBUTTONDOWN):
            handleJoyEvent(e)

# main method
def main():
    # initialize pygame
    pygame.joystick.init()
    pygame.display.init()
    if not pygame.joystick.get_count():
        print "\nPlease connect a joystick and run again.\n"
        quit()
    print "\n%d joystick(s) detected." % pygame.joystick.get_count()
    for i in range(pygame.joystick.get_count()):
        myjoy = pygame.joystick.Joystick(i)
        myjoy.init()
        joy.append(myjoy)
        print "Joystick %d: " % (i) + joy[i].get_name()
    print "Depress trigger (button 0) to quit.\n"

    # run joystick listener loop
    joystickControl()

# allow use as a module or standalone script
if __name__ == "__main__":
    main()
</pre>

<p>Now for the Arduino sketch.  This code merely waits for serial input from the PC, does a little math on the decimal values of the transmitted ASCII characters, then pulses the servo to the corresponding position.  If no new serial input is received from the PC (i.e., the joystick is not moved), then the Arduino will maintain the last known position of the servo horn with an identical pulsewidth every 20ms.  As always, the minPulse and maxPulse values should be tweaked to work with your particular servo model.</p>

<pre name="code" class="arduino">
/*
 * JoystickSerialServo
 * --------------
 * Servo control with a PC and Joystick
 *
 * Created 19 December 2007
 * copyleft 2007 Brian D. Wendt
 * http://principialabs.com/
 *
 * Adapted from code by Tom Igoe
 * http://itp.nyu.edu/physcomp/Labs/Servo
 */

/** Adjust these values for your servo and setup, if necessary **/
int servoPin     =  2;    // control pin for servo motor
int minPulse     =  600;  // minimum servo position
int maxPulse     =  2400; // maximum servo position
int refreshTime  =  20;   // time (ms) between pulses (50Hz)

/** The Arduino will calculate these values for you **/
int centerServo;         // center servo position
int pulseWidth;          // servo pulse width
int servoPosition;       // commanded servo position, 0-180 degrees
int pulseRange;          // max pulse - min pulse
long lastPulse   = 0;    // recorded time (ms) of the last pulse


void setup() {
  pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin
  pulseRange  = maxPulse - minPulse;
  centerServo = maxPulse - ((pulseRange)/2);
  pulseWidth  = centerServo;   // Give the servo a starting point (or it floats)
  Serial.begin(9600);
}

void loop() {
  // wait for serial input
  if (Serial.available() > 0) {
    // read the incoming byte:
    servoPosition = Serial.read();

    // compute pulseWidth from servoPosition
    pulseWidth = minPulse + (servoPosition * (pulseRange/180));

    // stop servo pulse at min and max
    if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }
    if (pulseWidth < minPulse) { pulseWidth = minPulse; }

    // debug
    //Serial.println(servoPosition);
  }

  // pulse the servo every 20 ms (refreshTime) with current pulseWidth
  // this will hold the servo's position if unchanged, or move it if changed
  if (millis() - lastPulse >= refreshTime) {
    digitalWrite(servoPin, HIGH);   // start the pulse
    delayMicroseconds(pulseWidth);  // pulse width
    digitalWrite(servoPin, LOW);    // stop the pulse
    lastPulse = millis();           // save the time of the last pulse
  }
}
</pre>

<p>This may not be the most elegant solution to the joystick servo control problem, but it does serve as a nice "Hello Servo" project, to let you see what's going on at the lower levels of input and output.</p>

<p>The next step in the process is to remove the USB cable to the Arduino, and control the servo by sending serial data over a WiFi or <a href="http://en.wikipedia.org/wiki/ZigBee">ZigBee</a> network.  Also, for a real remote robotics project, the code will need to be modified so that each joystick axis controls a separate servo, e.g. pitch, roll, yaw, and throttle.  Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/joystick-control-of-a-servo/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Arduino Serial Servo Control</title>
		<link>http://principialabs.com/arduino-serial-servo-control/</link>
		<comments>http://principialabs.com/arduino-serial-servo-control/#comments</comments>
		<pubDate>Sun, 09 Dec 2007 18:33:24 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[servo]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://principialabs.com/arduino-serial-servo-control-2/</guid>
		<description><![CDATA[One of the cool features of the Arduino platform is its ability to talk to other electronic devices using standard protocols. The big draw of physical computing, in my opinion, is the power it gives you to affect a limitless range of real-world objects with your PC, rather than just boring old monitors and printers. [...]]]></description>
			<content:encoded><![CDATA[<div class="video">
<embed src="http://blip.tv/play/wkeg4hMA" type="application/x-shockwave-flash" width="380" height="300" allowscriptaccess="always" allowfullscreen="true"></embed>
</div>

<p>One of the cool features of the Arduino platform is its ability to talk to other electronic devices using standard protocols.  The big draw of physical computing, in my opinion, is the power it gives you to affect a limitless range of real-world objects with your PC, rather than just boring old monitors and printers.</p>

<p>This short tutorial will demonstrate one way to use Arduino to control a servo motor with a PC, using a USB cable and the Arduino&#8217;s serial library.  It will in no way attempt to be an introduction to asynchronous serial communication, since such topics are <a href="http://www.tigoe.net/pcomp/serial.shtml">better addressed elsewhere</a>.</p>

<p>RC servos are comprised of a DC motor mechanically linked to a potentiometer. <a href="http://principialabs.com/arduino-pulse-width-modulation">Pulse-width modulation</a> (PWM) signals sent to the servo are translated into position commands by electronics inside the servo. When the servo is commanded to rotate, the DC motor is powered until the potentiometer reaches the value corresponding to the commanded position.</p>

<p><span id="more-41"></span></p>

<p>A standard RC servo has three wires: Ground (black or brown), Power (red) and Control (orange, yellow or white) and will move based on pulses sent over the control wire.  The control pulses set the angle of the servo horn. The servo expects a pulse every 20 ms in order to gain correct information about the angle. The pulse width maps directly to the servo angle.  Most servos will rotate 180&deg;, and expect pulse widths between 1-2 ms or so.</p>

<div style="text-align: center;">
<img src="/files/servo-pwm.jpg" alt="Servo Control with PWM" /><br /><small>Image credit: <a href="http://www.societyofrobots.com/actuators_servos.shtml#control" alt="">Society of Robots</a></small>
</div>

<p>This project uses a <a href="http://www.horizonhobby.com/Products/Default.aspx?ProdID=JSP20050">JR Sport ST47 Standard servo</a>, which accepts an input voltage between 4.8 and 6 volts &#8212; perfect for the Arduino&#8217;s 5V output pin.  Connect the servo&#8217;s brown and red wires to the Arduino&#8217;s Gnd and 5V POWER pins, respectively (colored orange in the diagram below), and connect the servo&#8217;s orange control wire to the Arduino&#8217;s digital pin #2 (on the green row in the diagram).</p>

<div style="text-align: center;">
<img src="/files/arduino_board.png" alt="Arduino Diagram" /><br /><small>Image credit: <a href="http://www.arduino.cc/en/Guide/Board" alt="">Arduino.cc</a></small>
</div>

<p>Using the Arduino IDE, upload the following code to the board, which will allow you to control the position of the servo over a serial connection.  Pay particular attention to the variables <code>minPulse</code> and <code>maxPulse</code>, as these define the min and max pulse widths for your servo.  As mentioned earlier, most servos expect a pulse width between 1-2 ms, however, a range of 0.5 ms to 2.5 ms (500-2500&mu;s) may be required, depending on your servo.  Experiment as necessary.</p>

<pre name="code" class="arduino">
/*
 * NewSerialServo
 * --------------
 * Servo control from the Serial port
 *
 * Alteration of the control interface to use < and > keys
 * to slew the servo horn left and right.  Works best with
 * the Linux/Mac terminal "screen" program.
 *
 * Created 10 December 2007
 * copyleft 2007 Brian D. Wendt
 * http://principialabs.com/
 *
 * Adapted from code by Tom Igoe
 * http://itp.nyu.edu/physcomp/Labs/Servo
 */

/** Adjust these values for your servo and setup, if necessary **/
int servoPin     =  2;    // control pin for servo motor
int minPulse     =  600;  // minimum servo position
int maxPulse     =  2400; // maximum servo position
int turnRate     =  100;  // servo turn rate increment (larger value, faster rate)
int refreshTime  =  20;   // time (ms) between pulses (50Hz)

/** The Arduino will calculate these values for you **/
int centerServo;         // center servo position
int pulseWidth;          // servo pulse width
int moveServo;           // raw user input
long lastPulse   = 0;    // recorded time (ms) of the last pulse


void setup() {
  pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin
  centerServo = maxPulse - ((maxPulse - minPulse)/2);
  pulseWidth = centerServo;   // Give the servo a starting point (or it floats)
  Serial.begin(9600);
  Serial.println("      Arduino Serial Servo Control");
  Serial.println("Press < or > to move, spacebar to center");
  Serial.println();
}

void loop() {
  // wait for serial input
  if (Serial.available() > 0) {
    // read the incoming byte:
    moveServo = Serial.read();

    // ASCII '<' is 44, ASCII '>' is 46 (comma and period, really)
    if (moveServo == 44) { pulseWidth = pulseWidth - turnRate; }
    if (moveServo == 46) { pulseWidth = pulseWidth + turnRate; }
    if (moveServo == 32) { pulseWidth = centerServo; }

    // stop servo pulse at min and max
    if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }
    if (pulseWidth < minPulse) { pulseWidth = minPulse; }

    // print pulseWidth back to the Serial Monitor (uncomment to debug)
    // Serial.print("Pulse Width: ");
    // Serial.print(pulseWidth);
    // Serial.println("us");   // microseconds
  }

  // pulse the servo every 20 ms (refreshTime) with current pulseWidth
  // this will hold the servo's position if unchanged, or move it if changed
  if (millis() - lastPulse >= refreshTime) {
    digitalWrite(servoPin, HIGH);   // start the pulse
    delayMicroseconds(pulseWidth);  // pulse width
    digitalWrite(servoPin, LOW);    // stop the pulse
    lastPulse = millis();           // save the time of the last pulse
  }
}

</pre>

<p>Once you&#8217;ve got the code uploaded, you&#8217;re ready to go!  You can send and receive serial data using the Arudino IDE&#8217;s Serial Monitor, or you can use a Linux terminal (as in the video) with the <code>screen</code> command, like so:</p>

<pre>
screen /dev/ttyUSB0 9600
</pre>

<p>The first element of the <code>screen</code> command specifies the USB port, and the second the serial baud rate (9600).  You may need to run <code>ls /dev/tty*</code> to find the correct USB port on your machine.</p>

<p>The theory behind this project can be extended to include a graphical user interface on the PC to control the servo motor, and maybe even the addition of an Ethernet connection for networked control.</p>

<p><strong>Update:</strong>  (10 Dec 2007)  <em>I wasn&#8217;t happy with the &#8220;Enter Servo Position (0-9):&#8221; interface shown in the video, so I revamped the code to allow left/right movements using the &lt; and > keys.  This new sketch is the one that is currently displayed here.  <a href="http://todbot.com/blog/spookyarduino/">Tod E. Kurt</a> already has a good implementation of the 0-9 angular-position concept if you prefer it.</em></p>

<div class="new"><b>New:</b> <em>Check out the <a href="/arduino-python-4-axis-servo-control/">Arduino-Python 4-Axis Servo Control</a> tutorial</em></div>

<p><strong>References</strong></p>

<ol>
<li>Wikipedia, &#8220;<a href="http://en.wikipedia.org/wiki/Servomechanism">Servomechanism</a>&#8220;</li>
<li>Society of Robots, &#8220;<a href="http://www.societyofrobots.com/actuators_servos.shtml">Actuators and Servos</a>&#8220;</li>
<li>ITP Physical Computing, &#8220;<a href="http://itp.nyu.edu/physcomp/Labs/Servo">Servo Lab</a>&#8220;</li>
<li>ITP Physical Computing, &#8220;<a href="http://itp.nyu.edu/physcomp/Labs/Serial">Serial Lab</a>&#8220;</li>
<li>Tom Igoe, &#8220;<a href="http://www.tigoe.net/pcomp/serial.shtml">Serial Communication</a>&#8220;</li>
<li>Tom Igoe, &#8220;<a href="http://www.tigoe.net/pcomp/serialdata.shtml">More on Serial Communication</a>&#8220;</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/arduino-serial-servo-control/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Arduino Pulse Width Modulation</title>
		<link>http://principialabs.com/arduino-pulse-width-modulation/</link>
		<comments>http://principialabs.com/arduino-pulse-width-modulation/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 18:31:10 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[pwm]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://principialabs.com/arduino-pulse-width-modulation/</guid>
		<description><![CDATA[The digital pins on the Arduino board can be set (with code) to output either HIGH (5V) or LOW (0V) &#8212; essentially ON or OFF. This is great for applications like blinking LEDs or activating relays. But what if we wanted an output voltage somewhere in between 0V and 5V? This might be useful in [...]]]></description>
			<content:encoded><![CDATA[<div class="video">
<embed src="http://blip.tv/play/wkegzGEA" type="application/x-shockwave-flash" width="380" height="300" allowscriptaccess="always" allowfullscreen="true"></embed>
</div>

<p>The digital pins on the Arduino board can be set (with code) to output either HIGH (5V) or LOW (0V) &#8212; essentially ON or OFF.  This is great for applications like blinking LEDs or activating relays.</p>

<p>But what if we wanted an output voltage somewhere <em>in between</em> 0V and 5V?  This might be useful in applications like controlling the speed of a DC motor, or &#8220;dimming&#8221; an LED.</p>

<p>Well, the digital pins cannot directly produce an analog voltage; as we&#8217;ve said, they&#8217;re either HIGH or LOW.  But it turns out we can <em>simulate</em> these &#8220;in-between&#8221; voltages using a technique called Pulse Width Modulation, or PWM.</p>

<p><span id="more-40"></span></p>

<p>First off, <em>don&#8217;t panic</em>.  PWM sounds complicated, but as we&#8217;ll see, the concept is very simple, and the implementation is even easier, especially on the Arduino.</p>

<p>Let&#8217;s say we want to make an LED shine with half of its normal intensity when supplied with 5 volts.  Since we can&#8217;t use the Arduino&#8217;s digital pins to <em>directly</em> supply 2.5V, we&#8217;ll &#8220;pulse&#8221; the output pin on and off &#8212; really fast.  You may have noticed this effect when you played with the Arduino&#8217;s &#8220;Blink&#8221; sketch.  If you blink an LED fast enough &#8212; that is, if the delay between blinks is <em>short enough</em> &#8212; the LED will appear to be lit continuously, but just a little bit dimmer than it was originally.</p>

<p>It&#8217;s easy to visualize this concept using the graphs below.  When you plot voltage over time, you can see that the pin is pulsing between HIGH and LOW at regular intervals.  Since this on-off pulsing is happening so quickly, the connected LED will &#8220;see&#8221; the result as a 50% reduction in the normal voltage (in this example), and will glow at roughly half its normal intensity.</p>

<div style="text-align: center;"><img src="/files/pwm-graph1.gif" alt="PWM graph" /><br /><small>Image credit: <a href="http://www.tigoe.net/pcomp/analogout.shtml" alt="">Tom Igoe</a></small></div>

<p>We can vary the output voltage percentage (the &#8220;effective voltage&#8221;) by regulating &#8212; or &#8220;modulating&#8221; &#8212; the width of the pulse.  For example, if we make the HIGH pulse 25% as &#8220;wide&#8221; (in time) as the LOW pulse, the LED will appear to glow with 25% intensity.</p>

<div style="text-align: center;"><img src="/files/pwm-graph2.gif" alt="PWM graph" /><br /><small>Image credit: <a href="http://www.tigoe.net/pcomp/analogout.shtml" alt="">Tom Igoe</a></small></div>

<p>&#8220;Okay, great,&#8221; you&#8217;re saying, &#8220;But how do I do this on the Arduino?&#8221;  Well, there are a couple of ways.  First, you could write a sketch that blinks the LED between HIGH and LOW really fast, as we discussed above.  However, this approach requires the full attention of the Arduino all the time; that is, if you want the Arduino to do anything else, you&#8217;ll be interrupting the pulse loop.</p>

<p>Luckily, the Arduino designers have already solved this problem for us with three dedicated pins and the <code>analogWrite()</code> command.</p>

<p>Notice on the Arduino board there are three digital pins (9-11) which are labeled PWM.  Devices (like LEDs) connected to these pins can employ continuous pulse width modulation using only the <code>analogWrite()</code> command like so:</p>

<pre name="code" class="arduino">
/*
 * A simple PWM example
 */

int pin         =  11;     // LED connected to PWM pin 11
int pulsewidth  =  127;    // Any value between 0 and 255

void setup() {
  // None required for analogWrite!
}

void loop() {
  analogWrite(pin, pulsewidth);
}
</pre>

<p>The example above should cause the connected LED to glow at about 50% intensity (255/2 = 127ish).  Play around with the value of the <code>pulsewidth</code> variable and note the changes in LED brightness.</p>

<p>Now, let&#8217;s take this concept one step further.  What if we <em>varied</em> the effective voltage to the LED over time?  If we could devise a way to &#8220;fade&#8221; the <code>pulsewidth</code> from zero to 255 and back again, then the LED would pulsate, as in the video above.  Here&#8217;s the code for that, using three LEDs this time, connected to pins 9-11:</p>

<pre name="code" class="arduino">
/*
 * Pulsating LEDs with Pulse Width Modulation
 */

int green   = 11;            // Digital pin 11 - Green LED
int red     = 10;            // Digital pin 10 - Red LED
int blue    = 9;             // Digital pin 9  - Blue LED
int time    = 5;             // define delay element
int pulsewidth;              // define pulsewidth (0-255)

void setup() {
  // None required for analogWrite!
}

void loop() {
  // slowly fade the LEDs to full brightness
  for (pulsewidth=0; pulsewidth <= 255; pulsewidth++){
    analogWrite(green, pulsewidth);
    analogWrite(red, pulsewidth);
    analogWrite(blue, pulsewidth);
    delay(time);
  }
  // slowly dim the LEDs
  for (pulsewidth=255; pulsewidth >= 0; pulsewidth--){
    analogWrite(green, pulsewidth);
    analogWrite(red, pulsewidth);
    analogWrite(blue, pulsewidth);
    delay(time);
  }
}
</pre>

<p>Cool, huh?</p>

<p><strong>References</strong></p>

<ol>
<li>Tom Igoe, &#8220;<a href="http://www.tigoe.net/pcomp/analogout.shtml">Analog Output</a>&#8220;</li>
<li>Sebastian Tomczak, &#8220;<a href="http://little-scale.blogspot.com/2007/09/pwm-and-you-quick-primer.html">PWM and You: A Quick Primer</a>&#8220;</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/arduino-pulse-width-modulation/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Open Source Hardware</title>
		<link>http://principialabs.com/open-source-hardware/</link>
		<comments>http://principialabs.com/open-source-hardware/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 19:34:31 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[physical computing]]></category>

		<guid isPermaLink="false">http://principialabs.com/open-source-hardware/</guid>
		<description><![CDATA[Check out this cool video from the O&#8217;Reilly Open Source Convention (OSCON) July 23-27, 2007 in Portland, Oregon, featuring (two of my heroes) Phillip Torrone, Senior Editor of MAKE Magazine and Limor Fried, founder of Adafruit Industries, discussing the relatively new idea of open-source hardware. It&#8217;s worth a look, if only to see Limor jam [...]]]></description>
			<content:encoded><![CDATA[<p>Check out <a href="http://blip.tv/file/322701">this cool video from the O&#8217;Reilly Open Source Convention</a> (OSCON) July 23-27, 2007 in Portland, Oregon, featuring (two of my heroes) Phillip Torrone, Senior Editor of MAKE Magazine and Limor Fried, founder of Adafruit Industries, discussing the relatively new idea of open-source hardware.</p>

<p>It&#8217;s worth a look, if only to see Limor jam all the WiFi in the room with her hand-held Wave Bubble!</p>

<p><span id="more-39"></span></p>

<div class="video" style="float:none;text-align:center;">
<embed src="http://blip.tv/play/AZP+ZAA" type="application/x-shockwave-flash" width="580" height="360" allowscriptaccess="always" allowfullscreen="true"></embed>
</div>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/open-source-hardware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Joining the Real and the Virtual</title>
		<link>http://principialabs.com/joining-the-real-and-the-virtual/</link>
		<comments>http://principialabs.com/joining-the-real-and-the-virtual/#comments</comments>
		<pubDate>Mon, 26 Nov 2007 19:32:29 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[physical computing]]></category>

		<guid isPermaLink="false">http://principialabs.com/joining-the-real-and-the-virtual/</guid>
		<description><![CDATA[I really enjoyed watching this hour-long talk by Jonathan Oxer, entitled &#8220;Hardware/Software Hacking: Joining the Real and the Virtual,&#8221; which addresses the growing trends in physical computing, and the process of connecting the physical world with the virtual. ~ from Google Tech Talks, July 31, 2007 ABSTRACT Software developers usually confine themselves to working entirely [...]]]></description>
			<content:encoded><![CDATA[<p>I really enjoyed watching this hour-long talk by Jonathan Oxer, entitled &#8220;<a href="http://video.google.com/videoplay?docid=3850910409804844384">Hardware/Software Hacking: Joining the Real and the Virtual</a>,&#8221; which addresses the growing trends in physical computing, and the process of connecting the physical world with the virtual.</p>

<p>~ from Google Tech Talks, July 31, 2007</p>

<blockquote>
  <p>ABSTRACT</p>
  
  <p>Software developers usually confine themselves to working entirely within the runtime environment of a computer just pushing around bits and pixels. Even virtual worlds such as Second Life exist only in the confines of our CPUs.</p>
  
  <p>On the other hand, hardware hacking has really taken off in recent years and there are now magazines such as MAKE devoted to modifying everyday objects. It&#8217;s a lot easier than software jockeys may expect, and this talk will begin with an entertaining exploration of simple ways to get started with linking a computer to real-world objects.</p>
</blockquote>

<p><span id="more-38"></span></p>

<blockquote>
  <p>But what happens when you knock down the boundaries between the real world and a virtual world? The talk goes on to show specific techniques and examples for linking real-world objects into the Second Life environment so that changes in the real world can be reflected in SL and vice versa.</p>
  
  <p>Jonathan Oxer is founder of Internet Vision Technologies, author of &#8220;How To Build A Website And Stay Sane&#8221; ( www.stay-sane.com) and &#8220;Ubuntu Hacks&#8221; (www.ubuntuhacks.com), is currently President of Linux Australia, convened the last 5 Debian Miniconferences, and sits on various boards and advisory panels for groups including Swinburne University and the federal e-Research Coordinating Committee.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/joining-the-real-and-the-virtual/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running Arduino on Ubuntu</title>
		<link>http://principialabs.com/running-arduino-on-ubuntu/</link>
		<comments>http://principialabs.com/running-arduino-on-ubuntu/#comments</comments>
		<pubDate>Sat, 24 Nov 2007 19:24:35 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://principialabs.com/running-arduino-on-ubuntu/</guid>
		<description><![CDATA[Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use microcontroller hardware and software. It&#8217;s intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments. This short tutorial will guide you through the installation of the Arduino development environment on Ubuntu. These instructions reference arduino-0010 and have been tested on [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/files/arduino-ng-1000.jpg" alt="Arduino NG" style="border: 0;"><img src="/files/arduino-ng-350.jpg" alt="" style="float:right;" /></a><a href="http://www.arduino.cc/">Arduino</a> is an open-source electronics prototyping platform based on flexible, easy-to-use microcontroller hardware and software. It&#8217;s intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.</p>

<p>This short tutorial will guide you through the installation of the <a href="http://www.arduino.cc/en/Main/Software">Arduino development environment</a> on Ubuntu.  These instructions reference <code>arduino-0010</code> and have been tested on Feisty and Gutsy, both 32-bit <em>and</em> 64-bit installations.    Thanks to <a href="http://ubuntuforums.org/showpost.php?p=3428686&amp;postcount=1&amp;highlight=arduino">this post</a> on the Ubuntu Forums for the basic setup.</p>

<div class="new"><b>Update 5/3/2008:</b> <em>  Successfully tested on Kubuntu Hardy 64 with <code>arduino-0011</code></em></div>

<p><span id="more-37"></span></p>

<p><strong>(1) Install</strong> the necessary architecture-specific dependencies (the Java runtime and the AVR microcontroller tools):
<pre>
sudo apt-get install sun-java5-bin sun-java5-jdk avr-libc gcc-avr librxtx-java
</pre></p>

<p><strong>(2) Remove</strong> one <a href="http://www.arduino.cc/playground/Linux/Ubuntu">conflicting package</a>:
<pre>
sudo apt-get remove brltty
</pre></p>

<p><strong>(3) Configure</strong> Java to work with Arduino:
<pre>
sudo update-alternatives --config java
</pre></p>

<p>You should see a dialog similar to this:</p>

<pre>
There are 5 alternatives which provide `java'.

  Selection    Alternative
-----------------------------------------------
          1    /usr/bin/gij-4.2
          2    /usr/lib/jvm/java-6-sun/jre/bin/java
 +        3    /usr/lib/j2se/1.4/bin/java
          4    /usr/lib/jvm/ia32-java-6-sun/jre/bin/java
*         5    /usr/lib/jvm/java-1.5.0-sun/jre/bin/java

Press enter to keep the default[*], or type selection number:
</pre>

<p>Locate the option containing &#8220;java-1.5.0-sun&#8221; and select it.  This will make Sun&#8217;s Java v.1.5 the default on your system (the GNU version doesn&#8217;t support the Arduino environment).</p>

<p><strong>(4) Download</strong> the latest release of the <a href="http://www.arduino.cc/en/Main/Software">Arduino IDE software</a> for Linux, and extract the compressed folder.</p>

<p><strong>(5) Open</strong> the subdirectory <code>arduino-0010/lib/</code> and rename the following files as shown (resolves conflicts with librxtx-java):
<pre>
RXTXcomm.jar
librxtxSerial.so
  ---become---
RXTXcomm.jar.BAK
librxtxSerial.so.BAK
</pre></p>

<p><strong>(6) Edit</strong> the <code>arduino</code> launcher file (<code>arduino-0010/arduino</code>) with a text editor and replace the contents with the following (resolves conflicts with librxtx-java):</p>

<pre>
#!/bin/sh

# Original: CLASSPATH=java/lib/rt.jar:lib:lib/build:lib/pde.jar:lib/core.jar:lib/antlr.jar:lib/oro.jar:lib/registry.jar:lib/mrj.jar:lib/RXTXcomm.jar
CLASSPATH=java/lib/rt.jar:lib:lib/build:lib/pde.jar:lib/core.jar:lib/antlr.jar:lib/oro.jar:lib/registry.jar:lib/mrj.jar:/usr/share/java/RXTXcomm.jar
export CLASSPATH

# put the directory where this file lives in the front of the path, because
# that directory also contains jikes, which we will need at runtime.
PATH=`pwd`/tools:${PATH}
export PATH

# put the directory with the native RXTX libs in the library path
# Original: LD_LIBRARY_PATH=`pwd`/lib:${LD_LIBRARY_PATH}
LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH

java processing.app.Base
</pre>

<p><strong>(7) Launch</strong> the Arduino IDE by navigating to the <code>arduino-0010</code> directory in a terminal and typing:
<pre>
./arduino
</pre></p>

<p><strong>(8) Learn!</strong> For more information about Arduino and learning electronics, see <a href="http://www.ladyada.net/learn/arduino/">Ladyada&#8217;s (fabulous) Arduino Tutorial</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/running-arduino-on-ubuntu/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Arduino Project #1: Morse Code</title>
		<link>http://principialabs.com/arduino-project-1-morse-code/</link>
		<comments>http://principialabs.com/arduino-project-1-morse-code/#comments</comments>
		<pubDate>Fri, 12 Oct 2007 18:20:57 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://principialabs.com/arduino-project-1-morse-code/</guid>
		<description><![CDATA[It&#8217;s hard to believe how rewarding it can be making something this pointless! This is my version of &#8220;Hello World&#8221; on the Arduino. Instead of just flashing an LED on and off, this variation flashes a three-letter Morse code navaid identifier (something familiar to aviators). The Arduino is a wonderful new open-source physical computing platform [...]]]></description>
			<content:encoded><![CDATA[<div class="video"><embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=7597826180816981605&#038;hl=en" flashvars=""> </embed></div>

<p>It&#8217;s hard to believe how rewarding it can be making something this pointless!  This is my version of &#8220;Hello World&#8221; on the Arduino.   Instead of just flashing an LED on and off, this variation flashes a three-letter Morse code navaid identifier (something familiar to aviators).</p>

<p>The Arduino is a wonderful new open-source physical computing platform and programming environment.  It is based on the Atmel ATmega8 microcontroller, and is cheap and easy to learn.  Microcontrollers can be used in everything from automation and robotics to interactive art projects.  Get the skinny at <a href="http://arduino.cc/">http://arduino.cc/</a>.</p>

<p><span id="more-17"></span></p>

<p>Here&#8217;s a (silent) video of the Morse LED flasher.  See if you can guess the identifier!  (Try not to fall asleep watching the blinkety-blinks.)</p>

<p>The code (abridged):</p>

<pre  name="code" class="arduino">
/* LED morse code blink
 * ------------
 *
 * Blinks an LED connected to a digital pin.
 * Pin 13 on the Arduino board is used because
 * it has a resistor attached to it, needing only an LED
 *
 */

  int ledPin = 13;  // digital pin 13

  void setup()
  {
  pinMode(ledPin, OUTPUT);  // sets pin 13 as output
  }

  void loop()
  {
  // V
  digitalWrite(ledPin, HIGH); // dot
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(100);

  digitalWrite(ledPin, HIGH); // dot
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(100);

  digitalWrite(ledPin, HIGH); // dot
  delay(200);
  digitalWrite(ledPin, LOW);
  delay(100);

  digitalWrite(ledPin, HIGH); // dash
  delay(600);
  digitalWrite(ledPin, LOW);
  delay(800);

  // ...

  // you get the picture!

  delay(3000);  // wait 3sec before repeat

  }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://principialabs.com/arduino-project-1-morse-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
