<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Ashish-Derhgawen/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Ashish-Derhgawen/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Ashish-Derhgawen/Posts</link>
    <language>en</language>
    <pubDate>Wed, 19 Jun 2013 06:38:03 GMT</pubDate>
    <lastBuildDate>Wed, 19 Jun 2013 06:38:03 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>3</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Webcam Based Laser Tracking for Human-Computer Interaction</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">In this article, we will put together a program which will allow us to move the mouse cursor on our computers with a laser pointer, and even generate mouse clicks using only a webcam for computer vision. One really cool use
 of this would be with a projector. With a projector, you could use this application and turn its projected image into an interactive screen, and even open files/menus by just pointing at them with a laser pointer!</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Ashish Derhgawen</div>
<div class="entry_company"><a href="http://ashishrd.blogspot.com ">http://ashishrd.blogspot.com
</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual C# Express Editions</a>,</span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">Webcam, Laser Pointer</span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://www.codeplex.com/laserinteraction">C# Download</a> </li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<div class="wlWriterSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:9250714b-fbbe-4345-87b5-1dcd8575bcf4">
<div id="480eedd3-d29d-40af-8841-cdf7feaf0926">
<div><a href="http://www.youtube.com/watch?v=ggsqsDXyiR0&amp;hl=en&amp;rel=0&amp;color1=0x006699&amp;color2=0x54abd6" target="_new"><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/videoe7070c99cf49.jpg" alt=""></a></div>
</div>
</div>
<p>I will be making use of Andrew Kirillov's <a href="http://www.codeproject.com/KB/audio-video/Motion_Detection.aspx">
motion detection code</a> for image acquisition, and the <a href="http://code.google.com/p/aforge/">
AForge.NET</a> framework, for certain image processing tasks. I'll start off by showing you how the image processing works for this program, and then I'll walk you through the important parts of the code. So, let's begin!</p>
<h2>Image processing and laser tracking...</h2>
<p>The laser tracking code works by finding the brightest pixel in the webcam's field of view. It is pretty much similar to the code I had written for my previous article -
<a href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7019142.aspx">Laser Tracking Camera</a>. However, since quick image processing is necessary for this program to work in real-time, I have modified the code a bit, and now it's much faster than before.
 The two image processing techniques I have used for optimization are - image cropping and image resizing.
</p>
<p>Image cropping is basically just trimming off the edges of an image to keep unwanted things outside the camera's view. Image cropping also reduces the number of pixels in an image, and makes image processing fast. On the other hand, resizing images reduces
 the <i>pixel resolution</i> of an image. The pixel resolution of an image describes the resolution of an image with the set of two positive integer numbers, where the first number is the number of pixel columns (width), and the second is the number of pixel
 rows (height). (Examples: 320x 40, 640x480, 1024x768). An image <a href="http://en.wikipedia.org/wiki/Image_resolution">
from Wikipedia</a> illustrates:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0024.jpg"><img height="128" alt="clip_image002[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0024_thumb.jpg" width="238" border="0"></a></p>
<p>The picture on the left is sampled at 20x20, and the image on the right is sampled at a higher pixel resolution, 100x100. Obviously, the higher resolution image has more detail. However, in image processing, while increased resolution results in greater
 information and detail, it comes at the price of memory and computing speed. <br>
For cropping the video feed from a webcam, you can click-and-drag a selection rectangle around the area you would like to keep, and the program would remove everything else.
<br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0034.jpg"><img height="200" alt="clip_image003[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0034_thumb.jpg" width="450" border="0"></a></p>
<p>The selection rectangle is a semi-transparent rubber band rectangle (picture above). A rubber band rectangle (aka focus rectangle), is a reversible rectangle that tracks with the mouse pointer while you move it around. This makes it easy to select the area
 you want to work on. If you are working with a projector, you can easily select its projected area, and the program would map its coordinates to the coordinates on your computer screen, and remove everything else.</p>
<p>Here's how you can make a rubber-band rectangle between two points (say <i>x1</i>,<i>y1</i> and
<i>x2</i>, <i>y2</i>): <br>
</p>
<pre class="csharpcode"><span class="rem">//Compute width and height of rectangle</span>
<span class="kwrd">int</span> width = Math.Abs(x2 - x1);
<span class="kwrd">int</span> height = Math.Abs(y2 - y1);                
<span class="rem">//Decide x and y of rectangle</span>
<span class="kwrd">int</span> x = 0, y = 0;
<span class="kwrd">if</span> (x1 &lt; x2)
    x = x1;
<span class="kwrd">else</span> <span class="kwrd">if</span> (x1 &gt; x2)
    x = x2;
<span class="kwrd">if</span> (y1 &lt; y2)
    y = y1;
<span class="kwrd">else</span> <span class="kwrd">if</span> (y1 &gt; y2)
    y = y2;
<span class="rem">//Draw the rectangle</span>
Rectangle rect = <span class="kwrd">new</span> Rectangle(x, y, width, height);
Graphics g = Graphics.FromImage(image);
g.FillRectangle(<span class="kwrd">new</span> SolidBrush(Color.FromArgb(60, 184, 184, 0)), rect); <span class="rem">//Draws a semi-transparent rectangle using alpha blending</span>
g.Dispose();</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><br>
You will find this code in the <b>ProcessFrame</b> event in <i>MotionDetector1.cs</i>. Here,
<i>x1</i> and <i>y1</i> are updated in the <b>MouseDown</b> event of the <i>camera window</i>, whereas
<i>x2</i> and <i>y2</i> are updated in the <b>MouseMove</b> event. <br>
After we know how big the selected area is, we can trim the edges by using the <b>
Bitmap.Clone</b> method: <br>
</p>
<pre class="csharpcode">Bitmap tmpImage0 = image.Clone(<span class="kwrd">new</span> Rectangle(x, y, width, height), <br>   System.Drawing.Imaging.PixelFormat.Format24bppRgb);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><br>
For resizing the video feed by a certain factor, adjust the resize factor numeric up/down control. If you take a resize factor, say 2, then the program would divide the length and width of the webcam images by 2, and the resulting images would actually be 2^2
 = 4x smaller. For example, if your webcam captures images of size 320 by 240, the total number of pixels in each image would be 320 x 240 = 76800.&nbsp; If we resize these images by a factor of 2, the resulting 160 by 120 size images would contain only 160 x 120
 = 19200 pixels (which is 4x less than 76800).</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0044.jpg"><img height="403" alt="clip_image004[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0044_thumb.jpg" width="312" border="0"></a></p>
<p>Here's how we can resize an image by a given factor using the Resize filter in the
<b>AForge.Imaging</b> library: <br>
</p>
<pre class="csharpcode">AForge.Imaging.Filters.Resize resize = <span class="kwrd">new</span> Resize(image.Width / resizeFactor, image.Height / resizeFactor, InterpolationMethod.NearestNeighbor);

Bitmap tmpImage1 = resize.Apply(tmpImage0);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Just keep in mind that the lesser you resize your images, the more tracking resolution you'd get while tracking lasers. However, since tracking resolution comes at the cost of memory and computing speed, pick a resize factor which works best for your computer
 and webcam. A resize factor of 2 or 3 usually works fine for me. <br>
After we're done with cropping and resizing, the program can go through the pixels on the image and find the brightest pixel (I'm assuming this would be the laser dot):
<br>
</p>
<pre class="csharpcode"><span class="kwrd">for</span> (<span class="kwrd">int</span> y = 0; y &lt; 240; y&#43;&#43;)
{
    <span class="kwrd">for</span> (<span class="kwrd">int</span> x = 0; x &lt; 320; x&#43;&#43;) 
    {
        <span class="kwrd">byte</span> red, green, blue;

        red = uBitmap.GetPixel(x, y).red;
        green = uBitmap.GetPixel(x, y).green;
        blue = uBitmap.GetPixel(x, y).blue;
        
        <span class="kwrd">float</span> brightness = (299 * red &#43; 587 * green &#43; 114 * blue) / 1000; 

        <span class="kwrd">if</span> (brightness &gt; certainValue)
            <span class="rem">// Do something</span>
    }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><em></em>
<p><br>
Here, <i>uBitmap</i>, is an instance of the <a href="http://blogs.msdn.com/coding4fun/archive/2008/01/07/7019142.aspx">
UnsafeBitmap class</a> I had discussed in my previous article. <br>
<b><br>
<i>NOTE:</i></b> <i>If you find brightness tracking unreliable in certain lighting conditions, change the above code to perform color detection instead of brightness detection by writing something like &quot;if ((red &gt; 220) &amp;&amp; (green &lt; 170) &amp;&amp; (blue &lt; 170))&quot; instead
 of writing &quot;if (brightness &gt; certainValue)&quot;.</i> <br>
After our program has the x and y coordinates of the laser dot, it can compute its position on the screen:
<br>
</p>
<pre class="csharpcode"><span class="rem">//Get screen width and height</span>
<span class="kwrd">int</span> screenWidth = Screen.GetBounds(<span class="kwrd">this</span>).Width;
<span class="kwrd">int</span> screenHeight = Screen.GetBounds(<span class="kwrd">this</span>).Height;
<span class="kwrd">float</span> cursorX, cursorY;<br>
<span class="rem">//Compute location of laser dot into camera coordinates</span>
cursorX = ((<span class="kwrd">float</span>)screenWidth / imageWidth) * x;
cursorY = ((<span class="kwrd">float</span>)screenHeight / imageHeight) * y;<br>       
<span class="rem">//Set cursor position</span>
Cursor.Position = <span class="kwrd">new</span> Point((<span class="kwrd">int</span>)cursorX, (<span class="kwrd">int</span>)cursorY);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now that you know how the code works, lets move on to the next section, in which I will tell you how to use it.
<br>
</p>
<b></b>
<h2>Some notes on using the software</h2>
<ul>
<li>The program searches for the brightest pixel in the camera's field of view, so the lighting conditions of your room can affect its performance. Adjust the brightness threshold and lighting conditions so that nothing (except the laser) exceeds the brightness
 threshold. If this doesn't work, change the brightness detection code to perform color detection instead (as described earlier).
</li></ul>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0054.jpg"><img height="423" alt="clip_image005[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/8377477/clip_image0054_thumb.jpg" width="312" align="right" border="0"></a></p>
<ul>
<li>If you want to reset video cropping to normal, just right-click anywhere in the
<i>camera window</i>. </li><li>For clicking on something with a laser pointer, just turn off the laser when the mouse cursor is over the item you want to click on. Turning the laser off simulates a left button, single-click. You might also want to change your<i> Folder Options</i> to
 allow files/folders to be opened with single-clicks. </li></ul>
<ul>
<li>While selecting a resize factor, remember that computing speed would come at the cost of tracking resolution. Say, for example, if I use a resize factor of 1, I'd get pretty good tracking resolution, but my program would slow down to a crawl. On the other
 hand, if I pick a resize factor greater than 4 or 5, I'd get a decent frame rate, but horrible tracking resolution. These values could be different for you (depending on your webcam and computer). For my computer, a resize factor of 2 or 3 works fine and I
 get about 27-30 frames/second. </li></ul>
<p><b><br>
</b><b></b></p>
<h2>Conclusion</h2>
<p><b><br>
</b>We have reached the end of this article, and I hope you enjoyed reading it. Now, here's some homework for you: Try implementing features like double clicking, right clicking and click-drag. If you've watched the video for this article, you must have noticed
 that I was drawing stuff on MS-Paint using this program. For accomplishing this, I had to modify my code to perform click-drag. If you can think of an easier, laser-based way to switch between different clicking modes, I think that would be very cool. So,
 use your ideas, and if you end up doing something cool, I'd love to hear about it. <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /> Have fun!</p>
<h2>About the Author</h2>
<p>Ashish Derhgawen is an IT student, currently living in New Delhi, India. He has been coding since fourth grade. Some of his other interests are harmonica playing, wildlife and cricket. When he’s not at school, he spends his time working on unusual projects
 related to robotics, webcams, and electronics besides others. You can reach Ashish through his blog at
<a href="http://ashishrd.blogspot.com/">http://ashishrd.blogspot.com</a>.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Ashish-Derhgawen/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d1713d86b6324460b3389e7600cfc125">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Webcam-Based-Laser-Tracking-for-Human-Computer-Interaction</comments>
      <itunes:summary>



&amp;nbsp;
In this article, we will put together a program which will allow us to move the mouse cursor on our computers with a laser pointer, and even generate mouse clicks using only a webcam for computer vision. One really cool use
 of this would be with a projector. With a projector, you could use this application and turn its projected image into an interactive screen, and even open files/menus by just pointing at them with a laser pointer!



Ashish Derhgawen
http://ashishrd.blogspot.com


Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: Free
Software: Visual C# Express Editions,
Hardware: Webcam, Laser Pointer
Download: 

C# Download 











I will be making use of Andrew Kirillov&#39;s 
motion detection code for image acquisition, and the 
AForge.NET framework, for certain image processing tasks. I&#39;ll start off by showing you how the image processing works for this program, and then I&#39;ll walk you through the important parts of the code. So, let&#39;s begin! 
Image processing and laser tracking...
The laser tracking code works by finding the brightest pixel in the webcam&#39;s field of view. It is pretty much similar to the code I had written for my previous article -
Laser Tracking Camera. However, since quick image processing is necessary for this program to work in real-time, I have modified the code a bit, and now it&#39;s much faster than before.
 The two image processing techniques I have used for optimization are - image cropping and image resizing.
 
Image cropping is basically just trimming off the edges of an image to keep unwanted things outside the camera&#39;s view. Image cropping also reduces the number of pixels in an image, and makes image processing fast. On the other hand, resizing images reduces
 the pixel resolution of an image. The pixel resolution of an image describes the resolution of an image with the set of two positive integer numbers, where the first number is the number of pixel columns (width), and the second is the number of pixel
 rows</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Webcam-Based-Laser-Tracking-for-Human-Computer-Interaction</link>
      <pubDate>Thu, 10 Apr 2008 21:47:05 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Webcam-Based-Laser-Tracking-for-Human-Computer-Interaction</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8377477_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/8377477_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Ashish Derhgawen</dc:creator>
      <itunes:author>Ashish Derhgawen</itunes:author>
      <slash:comments>25</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Webcam-Based-Laser-Tracking-for-Human-Computer-Interaction/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Laser Tracking Camera</title>
      <description><![CDATA[<table width="100%" border="0" cellspacing="0" cellpadding="1"><tbody><tr class="entry_overview"><td width="50">&nbsp;</td><td><span class="entry_description">In my last article, we saw how a stepper motor could be controlled with a computer by connecting it to its parallel port. This article will extend it to build laser following camera panner, which tracks and turns towards any laser dot in the camera's field of view. I'm assuming that you have already built a computer controlled stepper motor. If not, go through my previous article for information on how to build one. After you successfully build your laser following camera, you could use your own ideas and creativity to build even cooler things. For example, you could extend this project and build a cool laser following robot, or maybe even an autonomous laser guided turret which shoots down targets you point at! </span></td></tr><tr><td colspan="2"><div class="entry_author">Ashish Derhgawen</div><div class="entry_company"><a href="http://ashishrd.blogspot.com/">Ashish's blog</a></div><br><div class="entry_details"><strong>Difficulty: </strong><span class="entry_details_input">Intermediate</span></div><div class="entry_details"><strong>Time Required:</strong> <span class="entry_details_input">Less than 1 hour</span></div><div class="entry_details"><strong>Cost: </strong><span class="entry_details_input">Less Than $50</span></div><div class="entry_details"><strong>Software: </strong><span class="entry_details_input">Visual C# Express Edition</span></div><div class="entry_details"><strong>Hardware: </strong><span class="entry_details_input">A webcam, a laser pointer, a <a href="http://www.parallax.com/detail.asp?product_id=27964">5-wire unipolar stepper motor</a> (these could also be salvaged from old 5¼&quot; floppy disk drives), <a href="http://www.hobbyengineering.com/H1143.html">ULN2003 IC</a> (stepper motor driver), wire, stripboard (or a <a href="http://www.radioshack.com/product/index.jsp?productId=2734155&amp;cp=&amp;parentPage=search">solderless breadboard</a> ), solder and <a href="http://www.radioshack.com/product/index.jsp?productId=2103239&amp;cp">DB-25 Male connector</a> (buy these two if you can solder. Soldering is not necessary for doing this project, but it will ensure that your connections are secure), <a href="http://www.directron.com/10db25pec.html">DB25 (female/male) parallel port cable</a>, a multimeter, a power adapter (with voltage rating depending on your motor's requirements)</span></div><div class="entry_details"><strong>Download: </strong><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=371130">Download solution</a></div><div class="entry_details"><strong>Video: </strong><div>&nbsp;</div></div></td></tr></tbody></table><p><strong>Mounting your webcam on the motor<br></strong>I have simply mounted my webcam on a plastic cap. I used a heated nail for poking a hole through the cap's center:</p><p><img src="http://docs.google.com/File?id=dfjshpww_40cfnsgccd" alt=""></p><p>Then, I fixed it on the motor by pushing the motor shaft through the hole:</p><p><img src="http://docs.google.com/File?id=dfjshpww_41fg878ng8" alt=""></p><p>I taped my webcam on the cap..and that was it.</p><p><img src="http://docs.google.com/File?id=dfjshpww_42hhftshf5" alt=""></p><p>My setup looks very sloppy, and I'm sure yours will look much better than mine. <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /> Anyway, let's move on to the fun part!<br><strong><br>Finding the laser dot...<br></strong></p><p><strong><img src="http://docs.google.com/File?id=dfjshpww_39c824qkdj" alt=""></strong></p><p><strong><br></strong>Our code will locate the laser dot by finding the brightest pixel in the webcam's field of view. If something in its view is brighter than the laser, the camera will simply turn towards that point instead of the laser dot. <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /> The program captures images from a webcam, using Andrew Kirillov's <a href="http://www.codeproject.com/cs/media/Motion_Detection.asp">motion detection code</a> for image acquisition. Then, it scans the pixels in the bitmaps captured. Based on their respective RGB (Red Green Blue) values, it determines how bright they are. We could use the <strong>Bitmap.GetPixel()</strong> function for accessing pixels and calculating the brightness of any pixel in a bitmap:</p><div><div><pre><span>using</span> System.Drawing;</pre><pre>&nbsp;</pre><pre>Color c = someBitmap.GetPixel(x,y);</pre><pre><span>float</span> b = c.GetBrightness();</pre></div></div><p>Wow, that's easy! This code was simple to write, and easy to understand. However, unfortunately, it is VERY slow. If you use this code, it might take several seconds to process a single image becase the <code><strong>GetPixel()</strong></code><strong>/</strong><code><strong>SetPixel()</strong></code> methods are too slow for iterating through bitmaps of any real size. So, in this project, we'll make use of the <strong>BitmapData</strong> class in GDI&#43; to access the information we want. The <strong>BitmapData</strong> only allows us to access the data it stores through a pointer. This means that we'll have to use the <strong>unsafe</strong> keyword to scope the block of code which accesses the data. Based on an <a href="http://blogs.msdn.com/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx">article by Eric Gunnerson</a>, here's a class which will perform very quick unsafe image processing:</p><div><div><pre><span>   1:</span> <span>public</span> <span>unsafe</span> <span>class</span> UnsafeBitmap</pre><pre><span>   2:</span> {</pre><pre><span>   3:</span>     Bitmap bitmap;</pre><pre><span>   4:</span>&nbsp; </pre><pre><span>   5:</span>     <span>int</span> width;</pre><pre><span>   6:</span>     BitmapData bitmapData = <span>null</span>;</pre><pre><span>   7:</span>     Byte* pBase = <span>null</span>;</pre><pre><span>   8:</span>&nbsp; </pre><pre><span>   9:</span>     <span>public</span> UnsafeBitmap(Bitmap bitmap)</pre><pre><span>  10:</span>     {</pre><pre><span>  11:</span>         <span>this</span>.bitmap = <span>new</span> Bitmap(bitmap);</pre><pre><span>  12:</span>     }</pre><pre><span>  13:</span>&nbsp; </pre><pre><span>  14:</span>     <span>public</span> UnsafeBitmap(<span>int</span> width, <span>int</span> height)</pre><pre><span>  15:</span>     {</pre><pre><span>  16:</span>         <span>this</span>.bitmap = <span>new</span> Bitmap(width, height, PixelFormat.Format24bppRgb);</pre><pre><span>  17:</span>     }</pre><pre><span>  18:</span>&nbsp; </pre><pre><span>  19:</span>     <span>public</span> <span>void</span> Dispose()</pre><pre><span>  20:</span>     {</pre><pre><span>  21:</span>         bitmap.Dispose();</pre><pre><span>  22:</span>     }</pre><pre><span>  23:</span>&nbsp; </pre><pre><span>  24:</span>     <span>public</span> Bitmap Bitmap</pre><pre><span>  25:</span>     {</pre><pre><span>  26:</span>         get</pre><pre><span>  27:</span>         {</pre><pre><span>  28:</span>             <span>return</span> (bitmap);</pre><pre><span>  29:</span>         }</pre><pre><span>  30:</span>     }</pre><pre><span>  31:</span>&nbsp; </pre><pre><span>  32:</span>     <span>public</span> <span>struct</span> PixelData</pre><pre><span>  33:</span>     {</pre><pre><span>  34:</span>         <span>public</span> <span>byte</span> blue;</pre><pre><span>  35:</span>         <span>public</span> <span>byte</span> green;</pre><pre><span>  36:</span>         <span>public</span> <span>byte</span> red;</pre><pre><span>  37:</span>     }</pre><pre><span>  38:</span>&nbsp; </pre><pre><span>  39:</span>     <span>private</span> Point PixelSize</pre><pre><span>  40:</span>     {</pre><pre><span>  41:</span>         get</pre><pre><span>  42:</span>         {</pre><pre><span>  43:</span>             GraphicsUnit unit = GraphicsUnit.Pixel;</pre><pre><span>  44:</span>             RectangleF bounds = bitmap.GetBounds(<span>ref</span> unit);</pre><pre><span>  45:</span>&nbsp; </pre><pre><span>  46:</span>             <span>return</span> <span>new</span> Point((<span>int</span>)bounds.Width, (<span>int</span>)bounds.Height);</pre><pre><span>  47:</span>         }</pre><pre><span>  48:</span>     }</pre><pre><span>  49:</span>&nbsp; </pre><pre><span>  50:</span>     <span>public</span> <span>void</span> LockBitmap()</pre><pre><span>  51:</span>     {</pre><pre><span>  52:</span>         GraphicsUnit unit = GraphicsUnit.Pixel;</pre><pre><span>  53:</span>         RectangleF boundsF = bitmap.GetBounds(<span>ref</span> unit);</pre><pre><span>  54:</span>         Rectangle bounds = <span>new</span> Rectangle((<span>int</span>)boundsF.X,</pre><pre><span>  55:</span>       (<span>int</span>)boundsF.Y,</pre><pre><span>  56:</span>       (<span>int</span>)boundsF.Width,</pre><pre><span>  57:</span>       (<span>int</span>)boundsF.Height);</pre><pre><span>  58:</span>&nbsp; </pre><pre><span>  59:</span>         width = (<span>int</span>)boundsF.Width * <span>sizeof</span>(PixelData);</pre><pre><span>  60:</span>         <span>if</span> (width % 4 != 0)</pre><pre><span>  61:</span>         {</pre><pre><span>  62:</span>             width = 4 * (width / 4 &#43; 1);</pre><pre><span>  63:</span>         }</pre><pre><span>  64:</span>         bitmapData =</pre><pre><span>  65:</span>       bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);</pre><pre><span>  66:</span>&nbsp; </pre><pre><span>  67:</span>         pBase = (Byte*)bitmapData.Scan0.ToPointer();</pre><pre><span>  68:</span>     }</pre><pre><span>  69:</span>&nbsp; </pre><pre><span>  70:</span>     <span>public</span> PixelData GetPixel(<span>int</span> x, <span>int</span> y)</pre><pre><span>  71:</span>     {</pre><pre><span>  72:</span>         PixelData returnValue = *PixelAt(x, y);</pre><pre><span>  73:</span>         <span>return</span> returnValue;</pre><pre><span>  74:</span>     }</pre><pre><span>  75:</span>&nbsp; </pre><pre><span>  76:</span>     <span>public</span> <span>void</span> SetPixel(<span>int</span> x, <span>int</span> y, PixelData colour)</pre><pre><span>  77:</span>     {</pre><pre><span>  78:</span>         PixelData* pixel = PixelAt(x, y);</pre><pre><span>  79:</span>         *pixel = colour;</pre><pre><span>  80:</span>     }</pre><pre><span>  81:</span>&nbsp; </pre><pre><span>  82:</span>     <span>public</span> <span>void</span> UnlockBitmap()</pre><pre><span>  83:</span>     {</pre><pre><span>  84:</span>         bitmap.UnlockBits(bitmapData);</pre><pre><span>  85:</span>         bitmapData = <span>null</span>;</pre><pre><span>  86:</span>         pBase = <span>null</span>;</pre><pre><span>  87:</span>     }</pre><pre><span>  88:</span>     <span>public</span> PixelData* PixelAt(<span>int</span> x, <span>int</span> y)</pre><pre><span>  89:</span>     {</pre><pre><span>  90:</span>         <span>return</span> (PixelData*)(pBase &#43; y * width &#43; x * <span>sizeof</span>(PixelData));</pre><pre><span>  91:</span>     }</pre><pre><span>  92:</span> }</pre></div></div><p>Be sure to check Eric's article on unsafe image processing.<br>This class can be used for retrieving the red, green and blue values of any pixel as shown below:</p><div><div><pre>UnsafeBitmap uBitmap = <span>new</span> UnsafeBitmap (original_bitmap);</pre><pre>uBitmap.LockBitmap();</pre><pre>PixelData pixel = uBitmap.GetPixel (x,y);</pre><pre>uBitmap.UnlockBitmap();</pre></div></div><p>You can also alter the red, green and blue values of any pixel in your bitmap:</p><div><div><pre>UnsafeBitmap.PixelData pData = <span>new</span> UnsafeBitmap.PixelData();</pre><pre>pData.red = <span>value</span>;</pre><pre>pData.green = <span>value</span>;</pre><pre>pData.blue = <span>value</span>;</pre><pre>uBitmap.SetPixel (x, y, pData);</pre></div></div><p>To find a laser dot in a bitmap, we have to go through the pixels in the bitmap and calculate each pixel's brightness to find the brightest one. Based on a pixel's RGB values, you can calculate brightness using this formula:</p><div><div><pre>Brightness = (299 * red &#43; 587 * green &#43; 114 * blue) / 1000</pre></div></div><p>This would give a value between 0 to 255.<br>Here's a sample code to check the brightness of each pixel in a 320 x 240 bitmap:</p><div><div><pre><span>for</span> (<span>int</span> y = 0; y &lt; 240; y&#43;&#43;)</pre><pre>{ </pre><pre>    <span>for</span> (<span>int</span> x = 0; x &lt; 320; x&#43;&#43;) </pre><pre>    {</pre><pre>        <span>byte</span> red, green, blue;</pre><pre>        red = uBitmap.GetPixel(x, y).red;</pre><pre>        green = uBitmap.GetPixel(x, y).green;</pre><pre>        blue = uBitmap.GetPixel(x, y).blue;</pre><pre>&nbsp;</pre><pre>        <span>float</span> brightness = (299 * red &#43; 587 * green &#43; 114 * blue) / 1000;</pre><pre>&nbsp;</pre><pre>        <span>if</span> (brightness &gt; certainValue)</pre><pre>            <span>// Do something</span></pre><pre>    }</pre><pre>}</pre></div></div><p>After our program has the x and y coordinates of the laser dot, it can calculate the number of steps required to turn the webcam towards that point.</p><p><strong>Using the Software</strong><br>Since the program searches for the brightest pixel in the camera's field of view, the lighting conditions of your room can affect its performance. So, adjust the brightness threshold and lighting conditions so that nothing (except the laser) exceeds the brightness threshold.</p><p><img src="http://docs.google.com/File?id=dfjshpww_38hkt2n699" alt=""></p><p>If your stepper motor doesn't align your webcam with the laser dot properly, try adjusting the pixels-per-step track bar. It tells the program how much your stepper motor moves with each step. My stepper does 40 pixels/step (20 pixels while half stepping). Even though this isn't necessary, you can actually measure how many pixels your stepper moves in one step. Just comment out the calls to the <strong>MoveStepper()</strong> event in <strong>MotionDetector1.cs</strong> and run the program. Keep a laser dot fixed somewhere in your webcam's field of view and check its x coordinate in the Output window. After that, move the stepper one step in any direction with your mouse wheel, and see how much its x coordinate changes. Read my <a href="http://blogs.msdn.com/coding4fun/archive/2007/11/02/5848155.aspx">previous article</a> for information on how to move a stepper with a mouse wheel, or simply download the code for doing it from <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7019142/348240_article.zip">here</a>. Well, I still think it's not necessary that you actually measure how much your stepper moves using this tedious technique. Just play with the pixels-per-step track bar until you get things working perfectly.</p><p><strong><br></strong></p><p><strong>Now what?</strong></p><p>Now that you can track laser, and have a camera actually follow it, here are some interesting ideas to try:</p><ul><li>Wire two stepper motors to your computer. Then, you could make a dual axis, pan/tilt assembly and have your camera follow laser dots in any direction. </li><li>Use two lasers and make an <a href="http://ashishrd.blogspot.com/2007/11/object-tracking-using-camera-and-lasers.html">object tracking camera panner</a>, which makes use of <a href="http://ashishrd.blogspot.com/2006/11/obstacle-detector-using-webcam-and.html">laser rangefinding</a> to track the edge of any moving object. </li></ul><p><img src="http://docs.google.com/File?id=dfjshpww_45d9tknxg3" alt=""></p><p><strong>Conclusion<br></strong>We've reached end of this article. I hope you enjoyed reading it. Use your imagination and ideas to extend this project. If you come up with something interesting, I'd love to hear about it. <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /> Happy coding.</p><p><strong>About the Author</strong><strong><br></strong></p><p>Ashish Derhgawen is an IT student, currently living in New Delhi, India. He has been coding since fourth grade. Some of his other interests are harmonica playing, wildlife and cricket. When he's not at school, he spends his time working on unusual projects related to robotics, webcams, and electronics besides others. You can reach Ashish through his blog at <a href="http://ashishrd.blogspot.com">http://ashishrd.blogspot.com</a>.</p><p>Filed under: <a href="http://blogs.msdn.com/coding4fun/archive/tags/hardwarehacks/default.aspx">hardware hacks</a>, <a href="http://blogs.msdn.com/coding4fun/archive/tags/robotics/default.aspx">robotics</a></p><hr> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Ashish-Derhgawen/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:11e7f60491214575bf109e7600d094df">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Laser-Tracking-Camera</comments>
      <itunes:summary>&amp;nbsp;In my last article, we saw how a stepper motor could be controlled with a computer by connecting it to its parallel port. This article will extend it to build laser following camera panner, which tracks and turns towards any laser dot in the camera&#39;s field of view. I&#39;m assuming that you have already built a computer controlled stepper motor. If not, go through my previous article for information on how to build one. After you successfully build your laser following camera, you could use your own ideas and creativity to build even cooler things. For example, you could extend this project and build a cool laser following robot, or maybe even an autonomous laser guided turret which shoots down targets you point at! Ashish DerhgawenAshish&#39;s blogDifficulty: IntermediateTime Required: Less than 1 hourCost: Less Than $50Software: Visual C# Express EditionHardware: A webcam, a laser pointer, a 5-wire unipolar stepper motor (these could also be salvaged from old 5&#188;&amp;quot; floppy disk drives), ULN2003 IC (stepper motor driver), wire, stripboard (or a solderless breadboard ), solder and DB-25 Male connector (buy these two if you can solder. Soldering is not necessary for doing this project, but it will ensure that your connections are secure), DB25 (female/male) parallel port cable, a multimeter, a power adapter (with voltage rating depending on your motor&#39;s requirements)Download: Download solutionVideo: &amp;nbsp;Mounting your webcam on the motorI have simply mounted my webcam on a plastic cap. I used a heated nail for poking a hole through the cap&#39;s center:  Then, I fixed it on the motor by pushing the motor shaft through the hole:  I taped my webcam on the cap..and that was it.  My setup looks very sloppy, and I&#39;m sure yours will look much better than mine.  Anyway, let&#39;s move on to the fun part!Finding the laser dot...  Our code will locate the laser dot by finding the brightest pixel in the webcam&#39;s field of view. If something in its view is brighter than the laser, the </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Laser-Tracking-Camera</link>
      <pubDate>Mon, 07 Jan 2008 16:35:32 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Laser-Tracking-Camera</guid>      
      <dc:creator>Ashish Derhgawen</dc:creator>
      <itunes:author>Ashish Derhgawen</itunes:author>
      <slash:comments>13</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Laser-Tracking-Camera/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Computer Controlled Stepper Motor</title>
      <description><![CDATA[
<p><span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50"><img height="196" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/me2.jpg" width="153"></td>
<td><span class="entry_description">In this article, we will connect a stepper motor to our computer's parallel port, and then we will write some code to control it with the scroll wheel on a mouse (<a href="http://www.youtube.com/watch?v=RjCych2S6aE">video</a>).
 If you have never worked with stepper motors, you will surely have a lot of fun with this project. With stepper motors, you can build things such as robots, automatic fish feeder, or even a
<a href="http://neil.fraser.name/hardware/etch/">computerized etch-a-sketch</a>! I'll start off by discussing the basics of parallel ports and stepper motors. Then, we will build the driver circuit required for connecting a stepper motor to a parallel port.
 In the final section, we will learn how to communicate with parallel ports and how stepper motors are controlled.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Ashish Derhgawen</div>
<div class="entry_company"><a href="http://ashishrd.blogspot.com/">Ashish Blog</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Less Than $50</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input">Visual C# or Visual Basic Express Editions</span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">A <a href="http://www.parallax.com/detail.asp?product_id=27964">
5-wire unipolar stepper motor</a> (these could also be salvaged from old 5¼&quot; floppy disk drives),
<a></a><a href="http://www.hobbyengineering.com/H1143.html">ULN2003 IC</a> (stepper motor driver), wire, stripboard (or a
<a></a><a href="http://www.radioshack.com/product/index.jsp?productId=2734155&amp;cp=&amp;parentPage=search">solderless breadboard</a> ), solder and
<a></a><a href="http://www.radioshack.com/product/index.jsp?productId=2103239&amp;cp">DB-25 Male connector</a> (buy these two if you can solder. Soldering is not necessary for doing this project, but it will ensure that your connections are secure),
<a></a><a href="http://www.directron.com/10db25pec.html">DB25 (female/male) parallel port cable</a>, a multimeter, a power adapter (with voltage rating depending on your motor's requirements)</span></div>
<div class="entry_details"><b>Download: </b><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=348240">Download</a>
</div>
<p><strong>WARNING</strong>: Before we begin, I would warn you that the PC parallel port can be damaged quite easily if you make incorrect connections. If the parallel port is integrated to the motherboard, repairing a damaged parallel port may be expensive,
 and in many cases, it is cheaper to replace the whole motherboard than to repair that port.
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Your safest bet is to buy an inexpensive I/O card which has a parallel port and use it for your experiment. If you manage to damage the parallel port on that card, replacing it will be easy and inexpensive.
<br>
Don't let that warning worry you too much, because there is a lot of fun to be had with these types of projects. Find yourself an 'antique' PC, if you can, or just buy an I/O card which has a parallel port.
<br>
<b></b></p>
<p><b>Parallel Port Basics <br>
</b>A parallel port is a socket found in personal computers for interfacing with various peripherals such as printers, scanners and even some webcams. On many computers, particularly laptops, the parallel port is omitted for cost savings, and is considered
 to be a legacy port. However, in laptops, access to the parallel port is still commonly available through docking stations. Here's a picture of a
<a></a><a href="http://en.wikipedia.org/wiki/DB-25">DB-25</a> parallel printer port on the back of a laptop.</p>
<p>When a PC sends data to a printer or other device using a parallel port, it sends 8 bit of data (1 byte) at a time. These 8 bits are transmitted parallel to each other, as opposed to the same eight bits being transmitted serially through a serial port.
<br>
The pin assignments on a parallel port are as follows:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_2.jpg"><img height="147" alt="clip_image002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_thumb.jpg" width="175" border="0"></a>&nbsp;
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B8_5D.jpg">
<img height="126" alt="clip_image002[8]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B8_5D_thumb.jpg" width="347" border="0"></a></p>
</td>
</tr>
</tbody>
</table>
</span></p>
<div><style type="text/css">
<!--
table.msonormaltable
 {font-size:11.0pt;
 font-family:"Calibri","sans-serif"}
p.tablecontents
 {margin-bottom:.0001pt;
 font-size:10.0pt;
 font-family:"Verdana","sans-serif";
 margin-left:0in;
 margin-right:0in;
 margin-top:0in}
-->
</style>
<table class="MsoNormalTable" cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<td width="56">
<p class="TableContents">Pin No.</p>
</td>
<td width="76">
<p class="TableContents">Pin Name</p>
</td>
<td width="362">
<p class="TableContents">Description</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td width="56">
<p class="TableContents">1 </p>
</td>
<td width="76">
<p class="TableContents">Strobe</p>
</td>
<td width="362">
<p class="TableContents">Usually remains high but is pulled low whenever <br>
the computer sends a byte of data. This drop in <br>
voltage tells the printer that data is being sent. </p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">2 - 9</p>
</td>
<td width="76">
<p class="TableContents">D0 - D7</p>
</td>
<td width="362">
<p class="TableContents">The eight data ports. We will be using these in our <br>
project</p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">10 </p>
</td>
<td width="76">
<p class="TableContents">nAck </p>
</td>
<td width="362">
<p class="TableContents">Sends the acknowledge signal from the printer to <br>
the computer. </p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">11 </p>
</td>
<td width="76">
<p class="TableContents">Busy </p>
</td>
<td width="362">
<p class="TableContents">If the printer is busy, it will set this pin to high. <br>
Then, it will pull to let the computer know it is <br>
ready to receive more data. </p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">12</p>
</td>
<td width="76">
<p class="TableContents">Paper Out</p>
</td>
<td width="362">
<p class="TableContents">The printer lets the computer know if it is out of <br>
paper with this pin.</p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">13 </p>
</td>
<td width="76">
<p class="TableContents">Select </p>
</td>
<td width="362">
<p class="TableContents">Device indicates it is ready by pulling high.</p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">14 </p>
</td>
<td width="76">
<p class="TableContents">Autofeed</p>
</td>
<td width="362">
<p class="TableContents">The computer sends an auto feed signal to the <br>
printer through Pin 14. </p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">15 </p>
</td>
<td width="76">
<p class="TableContents">Error </p>
</td>
<td width="362">
<p class="TableContents">If the printer has any problems, it drops the voltage <br>
to less than 0.5 volts on Pin 15 to let the computer <br>
know that there is an error. </p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">16</p>
</td>
<td width="76">
<p class="TableContents">Initalize</p>
</td>
<td width="362">
<p class="TableContents">This pin is pulled low by the computer whenever a <br>
a new print job is ready for the printer.</p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">17</p>
</td>
<td width="76">
<p class="TableContents">Select-In</p>
</td>
<td width="362">
<p class="TableContents">Pin 17 is used by the computer to remotely take <br>
the printer offline. </p>
</td>
</tr>
<tr>
<td width="56">
<p class="TableContents">18-25</p>
</td>
<td width="76">
<p class="TableContents">Ground</p>
</td>
<td width="362">
<p class="TableContents">These are mostly used for competing circuits</p>
</td>
</tr>
</tbody>
</table>
</div>
<p><b>What are stepper motors? <br>
</b>Stepper motors are brushless, synchronous electric motors which can divide a full rotation into several steps. While conventional electric motors spin continuously, stepper motors only move one step at a time. They can be used for precise motion and position
 control as they can be turned to a precise angle. <br>
The simplest way to think of a stepper motor is a bar magnet and four coils:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B10_5D.jpg"><img height="110" alt="clip_image002[10]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B10_5D_thumb.jpg" width="560" border="0"></a></p>
<p>&nbsp;&nbsp;&nbsp; When current flows through coil &quot;A&quot; the magnet is attracted and moves one step forward. Then, coil &quot;A&quot; is turned off and coil &quot;B&quot; is turned on. Now, the magnet takes another step, and so on. A similar process happens inside a stepper motor, but the magnet
 is cylindrical and rotates inside the coils. For a stepper motor to move, these coils should be activated in a correct sequence. These sequences are called stepping modes:
</p>
<p><b>1. Single Stepping</b> <b>(Single-Coil Excitation)</b>: This is the simplest stepping mode. In this mode, each successive coil is energized and the motor moves one full step at a time. Therefore, a motor with a step angle of 7.5 degrees will rotate through
 7.5 degrees with each step. Here's how single stepping works:</p>
<table class="MsoNormalTable" cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<td width="48">
<p class="TableContents">Pulse </p>
</td>
<td width="51">
<p class="TableContents">Coil 1 </p>
</td>
<td width="46">
<p class="TableContents">Coil 2</p>
</td>
<td width="46">
<p class="TableContents">Coil 3</p>
</td>
<td width="47">
<p class="TableContents">Coil 4</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td width="48">
<p class="TableContents">1 </p>
</td>
<td width="51">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">2 </p>
</td>
<td width="51">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">3 </p>
</td>
<td width="51">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">4 </p>
</td>
<td width="51">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">1 </p>
</td>
</tr>
</tbody>
</table>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B12_5D.jpg"><img height="143" alt="clip_image002[12]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B12_5D_thumb.jpg" width="545" border="0"></a></p>
<p>2. <b>Half Stepping:</b> The difference between single stepping and half stepping is, that for the same step rate, half stepping gives you half the speed but twice the resolution of a single step. For a motor with a step angle of 7.5 degrees, half stepping
 it would result in approximately 3.75 degrees of rotation. Here's how it works:</p>
<p>
<table class="MsoNormalTable" cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<td width="48">
<p class="TableContents">Pulse </p>
</td>
<td width="46">
<p class="TableContents">Coil 1</p>
</td>
<td width="46">
<p class="TableContents">Coil 2</p>
</td>
<td width="46">
<p class="TableContents">Coil 3</p>
</td>
<td width="47">
<p class="TableContents">Coil 4</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td width="48">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">2 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">3 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">4 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">5 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">6 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="47">
<p class="TableContents">1 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">7 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">1 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">8 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">1 </p>
</td>
</tr>
</tbody>
</table>
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B14_5D.jpg"><img height="381" alt="clip_image002[14]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B14_5D_thumb.jpg" width="561" border="0"></a></p>
<p><b>3. High Torque Stepping (Two-Coil Excitation): <br>
</b><br>
As the name suggests, this stepping mode would result in higher torque:</p>
<p>
<table class="MsoNormalTable" cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<td width="48">
<p class="TableContents">Pulse </p>
</td>
<td width="46">
<p class="TableContents">Coil 1</p>
</td>
<td width="46">
<p class="TableContents">Coil 2</p>
</td>
<td width="46">
<p class="TableContents">Coil 3</p>
</td>
<td width="47">
<p class="TableContents">Coil 4</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td width="48">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">2 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="47">
<p class="TableContents">0 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">3 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="47">
<p class="TableContents">1 </p>
</td>
</tr>
<tr>
<td width="48">
<p class="TableContents">4 </p>
</td>
<td width="46">
<p class="TableContents">1 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="46">
<p class="TableContents">0 </p>
</td>
<td width="47">
<p class="TableContents">1 </p>
</td>
</tr>
</tbody>
</table>
</p>
<p>Now that we know a little about parallel ports and stepper motor, its time to get started!</p>
<p><br>
<b>Building the electronics <br>
</b>The electronics for controlling a stepper motor with a parallel port is very simple. We will be making use of the ULN2003 driver IC, which contains an array of 7 darlington transistors with integrated diode protection, each capable of driving 500mA of current.
 The easiest method of building the circuit is on an electronic breadboard. They are available at all electronics shops. Here's the circuit:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B16_5D.jpg"><img height="331" alt="clip_image002[16]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B16_5D_thumb.jpg" width="567" border="0"></a></p>
<p>As you can see in the diagram, D0 (Pin 2) on the parallel port is connected to Pin 1 on the ULN2003 stepper driver IC,
<br>
D1 (Pin 3) is connected to Pin 2 on the IC, <br>
D2 (Pin 4) is connected to Pin 3 on the IC, and <br>
D3 (Pin 5) is connected to Pin 4 on the IC. <br>
Wires on a stepper motor are color coded. For identifying which wire belongs to which coil, you could try searching for your motor's specs on the Internet. If you are unable to find detailed information for your motor (like me), then you could simply use a
 multimeter for identifying the wires on your stepper. First of all, identify the common power wire of your stepper by checking the resistance between pairs of wires using a multimeter.
<i>The common power wire will be the wire with only half as much resistance between it and all the others.
</i>For my motor, the red wire is the common power wire:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B18_5D.jpg"><img height="308" alt="clip_image002[18]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B18_5D_thumb.jpg" width="315" border="0"></a></p>
<p>Yellow wire - Coil 1 <br>
Brown wire - Coil 2 <br>
Red wire - Common power wire <br>
Orange wire - Coil 3 <br>
Black wire - Coil 4</p>
<p>However, if your guesses are not right, the motor will not rotate, but will only wiggle from side to side. So, I would recommend reading
<a></a><a href="http://wwwhomes.doc.ic.ac.uk/~ih/doc/stepper/others/">this article</a> if you're not sure. After you've recognized the wires, just build the circuit on a breadboard or a stripboard. I initially built everything on a breadboard, but in the end,
 I soldered everything on a stripboard.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B20_5D.jpg"><img height="302" alt="clip_image002[20]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B20_5D_thumb.jpg" width="403" border="0"></a></p>
<p>&nbsp;&nbsp; In the picture above, notice that I've inserted the wires from the IC directly into my parallel port. This is a very clumsy thing to do. So, I soldered a DB-25 MALE connector so that it would be easier to plug/unplug the circuit to the parallel port cable:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B22_5D.jpg"><img height="302" alt="clip_image002[22]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B22_5D_thumb.jpg" width="403" border="0"></a></p>
<p>&nbsp;&nbsp; Test the circuit with a multimeter and make sure all the connections are correct and that there are no short circuits. Then, plug one end of the parallel port cable to the circuit and the other end to the parallel port socket on your computer. That's
 it! Its time to write some code! <img src='http://ecn.channel9.msdn.com/o9/content/images/emoticons/emotion-1.gif?v=c9' alt='Smiley' /></p>
<p><b>Let the code do the rest... <br>
</b>Accessing the parallel port was much easier in versions of Windows that did not use the Windows NT kernel. In the DOS and Win9x days, programs could access the parallel port using simple inportb() and outportb() subroutine commands. The OS would happily
 let programs input and output data to the parallel port in the form of 16-bit integers. However, in operating systems such as Windows XP, access to the parallel port is inhibited. This is when the
<a></a><a href="http://logix4u.net/Legacy_Ports/Parallel_Port/Inpout32.dll_for_Windows_98/2000/NT/XP.html">InpOut32.dll</a> project came. This free library quickly became the standard way to access the parallel port in any version of Windows among people interested
 in parallel port interfacing and programming. <br>
For using inpout32.dll with your code, place the dll in your System32 folder. Now we'll use P/Invoke as shown below:</p>
<b>C#:</b>
<div>
<div>
<pre><span> 1:</span> <span>private</span> <span>class</span> PortAccess</pre>
<pre><span> 2:</span> { </pre>
<pre><span> 3:</span> [DllImport(<span>&quot;inpout32.dll&quot;</span>, EntryPoint=<span>&quot;Out32&quot;</span>)]</pre>
<pre><span> 4:</span> <span>public</span> <span>static</span> <span>extern</span> <span>void</span> Output(<span>int</span> address, <span>int</span> <span>value</span>);</pre>
<pre><span> 5:</span> }</pre>
</div>
</div>
<b>VB:</b>
<div>
<div>
<pre><span> 1:</span> <span>Private</span> <span>Class</span> PortAccess </pre>
<pre><span> 2:</span> <span>Public</span> <span>Declare</span> <span>Sub</span> Output <span>Lib</span> <span>&quot;inpout32.dll&quot;</span> <span>Alias</span> <span>&quot;Out32&quot;</span> (<span>ByVal</span> address <span>As</span> <span>Integer</span>, <span>ByVal</span> value <span>As</span> <span>Integer</span>)</pre>
<pre><span> 3:</span> <span>End</span> <span>Class</span></pre>
</div>
</div>
<p>The PortAccess.Output method takes in two parameters, <b>address</b> and <b>value</b>. For knowing your parallel port address, go to
<i>Control Panel &gt; System &gt; Hardware &gt; Device Manager &gt; Ports (COM &amp; LPT) &gt; Printer Port (LPT1/LPT2) &gt; Properties &gt; Resources &gt; Resource Settings</i>. Here, you'll see your parallel port address in hexadecimal format:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B24_5D.jpg"><img height="404" alt="clip_image002[24]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/5848155/clip_image002_5B24_5D_thumb.jpg" width="367" border="0"></a></p>
<p>As you can see in the screenshot above, my I/O range is &quot;0378 - 037F&quot;. Hexadecimal &quot;0x378&quot; is equivalent to &quot;888&quot; in decimal. If you are using LPT2, your address would probably be &quot;0x278&quot; (Decimal equivalent is &quot;632&quot;).
<br>
Now, a possible call from managed code might look like this: </p>
<b>C#:</b>
<p>PortAccess.Output(888, 255); </p>
<p><b>VB: <br>
</b>PortAccess.Output(888, 255) </p>
<p>Here, decimal &quot;255&quot; is equivalent to &quot;1111 1111&quot; in binary. Sending &quot;255&quot; would set all output ports on your parallel port (D0 - D7), to high. Similarly, sending &quot;0&quot; would set all of them to low.
<br>
Lets write some code to move our stepper motor one full step at a time. Recall that in single stepping, each successive coils in the motor are energized in the following sequence, one coil at a time.</p>
<p>Here's a sample code for executing this sequence and moving the stepper in one direction:
</p>
<p><b>C#: <br>
</b></p>
<div>
<div>
<pre><span> 1:</span> PortAccess.Output(888, 1); <span>// 1 decimal = 0001 binary. This will set D0 to high</span></pre>
<pre><span> 2:</span> System.Threading.Thread.Sleep(100); <span>// delay</span></pre>
<pre><span> 3:</span> PortAccess.Output(888, 2); <span>// 2 decimal = 0010 binary. This will set D1 to high</span></pre>
<pre><span> 4:</span> System.Threading.Thread.Sleep(100); <span>// delay</span></pre>
<pre><span> 5:</span> PortAccess.Output(888, 4); <span>// 4 decimal = 0100 binary. This will set D2 to high</span></pre>
<pre><span> 6:</span> System.Threading.Thread.Sleep(100); <span>// delay</span></pre>
<pre><span> 7:</span> PortAccess.Output(888, 8); <span>// 8 decimal = 1000 binary. This will set D3 to high</span></pre>
</div>
</div>
<p><b>VB: <br>
</b></p>
<div>
<div>
<pre><span> 1:</span> PortAccess.Output(888, 1) <span>' 1 decimal = 0001 binary. This will set D0 to high</span></pre>
<pre><span> 2:</span> System.Threading.Thread.Sleep(100) <span>' delay</span></pre>
<pre><span> 3:</span> PortAccess.Output(888, 2) <span>' 2 decimal = 0010 binary. This will set D1 to high</span></pre>
<pre><span> 4:</span> System.Threading.Thread.Sleep(100) <span>' delay</span></pre>
<pre><span> 5:</span> PortAccess.Output(888, 4) <span>' 4 decimal = 0100 binary. This will set D2 to high</span></pre>
<pre><span> 6:</span> System.Threading.Thread.Sleep(100) <span>' delay</span></pre>
<pre><span> 7:</span> PortAccess.Output(888, 8) <span>' 8 decimal = 1000 binary. This will set D3 to high</span></pre>
</div>
</div>
<p>Switch on your motor's power supply by connecting the power adapter. Then try running this piece of code to see if it works!
<br>
I like using the scroll wheel on my mouse for controlling the motor. For doing this, first create an enumeration for the different stepping modes:
</p>
<p><b>C#:</b></p>
<div>
<div>
<pre><span> 1:</span> <span>private</span> SteppingMode stepMode;</pre>
<pre><span> 2:</span>&nbsp; </pre>
<pre><span> 3:</span> <span>private</span> <span>enum</span> SteppingMode</pre>
<pre><span> 4:</span> { </pre>
<pre><span> 5:</span> SingleStep, </pre>
<pre><span> 6:</span> HalfStep, </pre>
<pre><span> 7:</span> HighTorqueStep</pre>
<pre><span> 8:</span> }</pre>
</div>
</div>
<p><b>VB:</b></p>
<div>
<div>
<pre><span> 1:</span> <span>Dim</span> stepMode <span>As</span> SteppingMode</pre>
<pre><span> 2:</span>&nbsp; </pre>
<pre><span> 3:</span> <span>Private</span> <span>Enum</span> SteppingMode </pre>
<pre><span> 4:</span> SingleStep </pre>
<pre><span> 5:</span> HalfStep </pre>
<pre><span> 6:</span> HighTorqueStep</pre>
<pre><span> 7:</span> <span>End</span> <span>Enum</span></pre>
</div>
</div>
<p>The form level variable, stepMode stores the selected stepping mode. <br>
Next, we'll wire the form's <b>MouseWheel</b> event to an event handler. Write the following code the
<b>InitializeComponent</b> function or the form's constructor: </p>
<p><strong>C#</strong>: <br>
this.MouseWheel &#43;= new System.Windows.Forms.MouseEventHandler(this.Form1_MouseWheel);
<br>
<strong>VB</strong>: <br>
AddHandler Me.MouseWheel, AddressOf Me.Form1_MouseWheel </p>
<p>Now, we will provide the implementation of <b>Form1_MouseWheel</b> in our form. I've used a StatusStrip with four labels for displaying the stepping mode, direction of movement, and the decimal value being sent to the parallel port along with its binary
 representation. For determining the direction in which the scroll wheel rotates, we'll use the
<b>MouseEventArts.Delta</b> property, which, in the words of MSDN, gives a signed count of the number of detents the mouse wheel has rotated. A detent is one notch of the mouse wheel. Here's a sample code for single stepping the motor with the scroll wheel:
</p>
<p><b>C#: </b></p>
<div>
<div>
<pre><span> 1:</span> <span>private</span> <span>int</span> output = 0;</pre>
<pre><span> 2:</span>&nbsp; </pre>
<pre><span> 3:</span> <span>private</span> <span>void</span> Form1_MouseWheel(<span>object</span> sender, MouseEventArgs e)</pre>
<pre><span> 4:</span> {</pre>
<pre><span> 5:</span> <span>switch</span> (stepMode)</pre>
<pre><span> 6:</span> {</pre>
<pre><span> 7:</span> <span>case</span> SteppingMode.SingleStep:</pre>
<pre><span> 8:</span> <span>// Single Stepping</span></pre>
<pre><span> 9:</span>&nbsp; </pre>
<pre><span> 10:</span> <span>if</span> (e.Delta &gt; 0)</pre>
<pre><span> 11:</span> {</pre>
<pre><span> 12:</span> <span>if</span> (output == 1) output = 2;</pre>
<pre><span> 13:</span> <span>else</span> <span>if</span> (output == 2) output = 4;</pre>
<pre><span> 14:</span> <span>else</span> <span>if</span> (output == 4) output = 8;</pre>
<pre><span> 15:</span> <span>else</span> <span>if</span> (output == 8) output = 1;</pre>
<pre><span> 16:</span> <span>else</span> output = 1;</pre>
<pre><span> 17:</span>&nbsp; </pre>
<pre><span> 18:</span> directionStatusStripLabel.Text = <span>&quot;Direction: 1&quot;</span>;</pre>
<pre><span> 19:</span> decimalStatusStripLabel.Text = <span>&quot;Decimal: &quot;</span> &#43; output.ToString();</pre>
<pre><span> 20:</span> binaryStatusStripLabel.Text = <span>&quot;Binary: &quot;</span> &#43; ConvertToBinary(output);</pre>
<pre><span> 21:</span> PortAccess.Output(888, output);</pre>
<pre><span> 22:</span> }</pre>
<pre><span> 23:</span> <span>else</span></pre>
<pre><span> 24:</span> {</pre>
<pre><span> 25:</span> <span>if</span> (output == 1) output = 8;</pre>
<pre><span> 26:</span> <span>else</span> <span>if</span> (output == 8) output = 4;</pre>
<pre><span> 27:</span> <span>else</span> <span>if</span> (output == 4) output = 2;</pre>
<pre><span> 28:</span> <span>else</span> <span>if</span> (output == 2) output = 1;</pre>
<pre><span> 29:</span> <span>else</span> output = 1;</pre>
<pre><span> 30:</span>&nbsp; </pre>
<pre><span> 31:</span> directionStatusStripLabel.Text = <span>&quot;Direction: 0&quot;</span>;</pre>
<pre><span> 32:</span> decimalStatusStripLabel.Text = <span>&quot;Decimal: &quot;</span> &#43; output.ToString();</pre>
<pre><span> 33:</span> binaryStatusStripLabel.Text = <span>&quot;Binary: &quot;</span> &#43; ConvertToBinary(output);</pre>
<pre><span> 34:</span> PortAccess.Output(888, output);</pre>
<pre><span> 35:</span> }</pre>
<pre><span> 36:</span> <span>break</span>;</pre>
<pre><span> 37:</span> }</pre>
<pre><span> 38:</span> }</pre>
<pre><span> 39:</span>&nbsp; </pre>
<pre><span> 40:</span> <span>private</span> <span>string</span> ConvertToBinary(<span>int</span> DecimalValue)</pre>
<pre><span> 41:</span> {</pre>
<pre><span> 42:</span> <span>// Decimal -&gt; Binary conversion</span></pre>
<pre><span> 43:</span>&nbsp; </pre>
<pre><span> 44:</span> <span>int</span> digit;</pre>
<pre><span> 45:</span> <span>string</span> binaryForm = <span>&quot;&quot;</span>;</pre>
<pre><span> 46:</span> <span>char</span>[] binaryArray;</pre>
<pre><span> 47:</span>&nbsp; </pre>
<pre><span> 48:</span> <span>do</span></pre>
<pre><span> 49:</span> {</pre>
<pre><span> 50:</span> digit = DecimalValue % 2;</pre>
<pre><span> 51:</span> binaryForm &#43;= digit;</pre>
<pre><span> 52:</span> DecimalValue /= 2;</pre>
<pre><span> 53:</span> } <span>while</span> (DecimalValue != 0);</pre>
<pre><span> 54:</span>&nbsp; </pre>
<pre><span> 55:</span> <span>//The digits in the variable, binaryForm, are in reverse order</span></pre>
<pre><span> 56:</span> <span>// We will reverse it back to normal.</span></pre>
<pre><span> 57:</span> </pre>
<pre><span> 58:</span> binaryArray = binaryForm.ToCharArray();</pre>
<pre><span> 59:</span> Array.Reverse(binaryArray);</pre>
<pre><span> 60:</span>&nbsp; </pre>
<pre><span> 61:</span> binaryForm = <span>new</span> <span>string</span>(binaryArray);</pre>
<pre><span> 62:</span>&nbsp; </pre>
<pre><span> 63:</span> <span>return</span> String.Format(<span>&quot;{0:0000}&quot;</span>, <span>int</span>.Parse(binaryForm)); ;</pre>
<pre><span> 64:</span> }</pre>
</div>
</div>
<p><b>VB:</b></p>
<div>
<div>
<pre><span> 1:</span> <span>Dim</span> output <span>as</span> <span>Integer</span> = 0</pre>
<pre><span> 2:</span> <span>Private</span> <span>Sub</span> MainForm_MouseWheel(<span>ByVal</span> sender <span>As</span> <span>Object</span>, <span>ByVal</span> e <span>As</span> MouseEventArgs)</pre>
<pre><span> 3:</span> <span>Select</span> <span>Case</span> (stepMode)</pre>
<pre><span> 4:</span> <span>Case</span> SteppingMode.SingleStep</pre>
<pre><span> 5:</span> <span>' Single Stepping</span></pre>
<pre><span> 6:</span> <span>If</span> (e.Delta &gt; 0) <span>Then</span></pre>
<pre><span> 7:</span>&nbsp; </pre>
<pre><span> 8:</span> <span>If</span> (output = 1) <span>Then</span></pre>
<pre><span> 9:</span> output = 2</pre>
<pre><span> 10:</span> <span>ElseIf</span> (output = 2) <span>Then</span></pre>
<pre><span> 11:</span> output = 4</pre>
<pre><span> 12:</span> <span>ElseIf</span> (output = 4) <span>Then</span></pre>
<pre><span> 13:</span> output = 8</pre>
<pre><span> 14:</span> <span>ElseIf</span> (output = 8) <span>Then</span></pre>
<pre><span> 15:</span> output = 1</pre>
<pre><span> 16:</span> <span>Else</span></pre>
<pre><span> 17:</span> output = 1</pre>
<pre><span> 18:</span> <span>End</span> <span>If</span></pre>
<pre><span> 19:</span>&nbsp; </pre>
<pre><span> 20:</span> directionStatusStripLabel.Text = <span>&quot;Direction: 1&quot;</span></pre>
<pre><span> 21:</span> decimalStatusStripLabel.Text = (<span>&quot;Decimal: &quot;</span> &#43; output.ToString)</pre>
<pre><span> 22:</span> binaryStatusStripLabel.Text = (<span>&quot;Binary: &quot;</span> &#43; ConvertToBinary(output))</pre>
<pre><span> 23:</span> PortAccess.Output(888, output)</pre>
<pre><span> 24:</span>&nbsp; </pre>
<pre><span> 25:</span> <span>Else</span> <span>'If (e.Delta &lt; 0)</span></pre>
<pre><span> 26:</span>&nbsp; </pre>
<pre><span> 27:</span> <span>If</span> (output = 1) <span>Then</span></pre>
<pre><span> 28:</span> output = 8</pre>
<pre><span> 29:</span> <span>ElseIf</span> (output = 8) <span>Then</span></pre>
<pre><span> 30:</span> output = 4</pre>
<pre><span> 31:</span> <span>ElseIf</span> (output = 4) <span>Then</span></pre>
<pre><span> 32:</span> output = 2</pre>
<pre><span> 33:</span> <span>ElseIf</span> (output = 2) <span>Then</span></pre>
<pre><span> 34:</span> output = 1</pre>
<pre><span> 35:</span> <span>Else</span></pre>
<pre><span> 36:</span> output = 1</pre>
<pre><span> 37:</span> <span>End</span> <span>If</span></pre>
<pre><span> 38:</span>&nbsp; </pre>
<pre><span> 39:</span> directionStatusStripLabel.Text = <span>&quot;Direction: 0&quot;</span></pre>
<pre><span> 40:</span> decimalStatusStripLabel.Text = (<span>&quot;Decimal: &quot;</span> &#43; output.ToString)</pre>
<pre><span> 41:</span> binaryStatusStripLabel.Text = (<span>&quot;Binary: &quot;</span> &#43; ConvertToBinary(output))</pre>
<pre><span> 42:</span> PortAccess.Output(888, output)</pre>
<pre><span> 43:</span> <span>End</span> <span>If</span> </pre>
<pre><span> 44:</span>&nbsp; </pre>
<pre><span> 45:</span> <span>End</span> <span>Select</span></pre>
<pre><span> 46:</span> <span>End</span> <span>Sub</span></pre>
<pre><span> 47:</span>&nbsp; </pre>
<pre><span> 48:</span> <span>Private</span> <span>Function</span> ConvertToBinary(<span>ByVal</span> decimalValue <span>As</span> <span>Integer</span>) <span>As</span> <span>String</span></pre>
<pre><span> 49:</span> <span>' Decimal -&gt; Binary conversion</span></pre>
<pre><span> 50:</span>&nbsp; </pre>
<pre><span> 51:</span> <span>Dim</span> binaryForm <span>As</span> <span>String</span> = <span>&quot;&quot;</span></pre>
<pre><span> 52:</span> <span>Dim</span> digit <span>As</span> <span>Integer</span></pre>
<pre><span> 53:</span>&nbsp; </pre>
<pre><span> 54:</span> <span>Do</span></pre>
<pre><span> 55:</span> digit = decimalValue <span>Mod</span> 2</pre>
<pre><span> 56:</span> <span>If</span> digit = 0 <span>Then</span></pre>
<pre><span> 57:</span> binaryForm = <span>&quot;0&quot;</span> &#43; binaryForm</pre>
<pre><span> 58:</span> <span>Else</span></pre>
<pre><span> 59:</span> binaryForm = <span>&quot;1&quot;</span> &#43; binaryForm</pre>
<pre><span> 60:</span> <span>End</span> <span>If</span></pre>
<pre><span> 61:</span>&nbsp; </pre>
<pre><span> 62:</span> decimalValue = decimalValue \ 2</pre>
<pre><span> 63:</span> <span>Loop</span> <span>Until</span> decimalValue = 0</pre>
<pre><span> 64:</span>&nbsp; </pre>
<pre><span> 65:</span> <span>Return</span> <span>CLng</span>(binaryForm).ToString(<span>&quot;0000&quot;</span>)</pre>
<pre><span> 66:</span> <span>End</span> <span>Function</span></pre>
</div>
</div>
<p>In the <b>MouseUp</b> event of the form, we'll write some code which will allow us to switch between different stepping modes by right clicking on the form. Left clicking on the form would release the motor (i.e. de-energize the coils).
<br>
<strong></strong></p>
<p><strong>C#:</strong></p>
<div>
<div>
<pre><span> 1:</span> <span>private</span> <span>void</span> Form1_MouseUp(<span>object</span> sender, MouseEventArgs e)</pre>
<pre><span> 2:</span> {</pre>
<pre><span> 3:</span> <span>if</span> (e.Button == MouseButtons.Right)</pre>
<pre><span> 4:</span> {</pre>
<pre><span> 5:</span> <span>// Switch between different stepping modes</span></pre>
<pre><span> 6:</span>&nbsp; </pre>
<pre><span> 7:</span> <span>switch</span> (stepMode)</pre>
<pre><span> 8:</span> {</pre>
<pre><span> 9:</span>&nbsp; </pre>
<pre><span> 10:</span> <span>case</span> SteppingMode.SingleStep:</pre>
<pre><span> 11:</span> stepMode = SteppingMode.HalfStep;</pre>
<pre><span> 12:</span> steppingModeStatusStripLabel.Text = <span>&quot;Step Mode: Half&quot;</span>;</pre>
<pre><span> 13:</span> <span>break</span>;</pre>
<pre><span> 14:</span>&nbsp; </pre>
<pre><span> 15:</span> <span>case</span> SteppingMode.HalfStep:</pre>
<pre><span> 16:</span> stepMode = SteppingMode.HighTorqueStep;</pre>
<pre><span> 17:</span> steppingModeStatusStripLabel.Text = <span>&quot;Step Mode: High Torque&quot;</span>;</pre>
<pre><span> 18:</span> <span>break</span>;</pre>
<pre><span> 19:</span>&nbsp; </pre>
<pre><span> 20:</span> <span>case</span> SteppingMode.HighTorqueStep:</pre>
<pre><span> 21:</span> stepMode = SteppingMode.SingleStep;</pre>
<pre><span> 22:</span> steppingModeStatusStripLabel.Text = <span>&quot;Step Mode: Single&quot;</span>;</pre>
<pre><span> 23:</span> <span>break</span>;</pre>
<pre><span> 24:</span>&nbsp; </pre>
<pre><span> 25:</span> }</pre>
<pre><span> 26:</span> }</pre>
<pre><span> 27:</span> <span>else</span> <span>if</span> (e.Button == MouseButtons.Left)</pre>
<pre><span> 28:</span> {</pre>
<pre><span> 29:</span> <span>// Release the motor</span></pre>
<pre><span> 30:</span>&nbsp; </pre>
<pre><span> 31:</span> output = 0;</pre>
<pre><span> 32:</span> PortAccess.Output(888, output);</pre>
<pre><span> 33:</span> decimalStatusStripLabel.Text = (<span>&quot;Decimal: &quot;</span> &#43; output.ToString);</pre>
<pre><span> 34:</span> binaryStatusStripLabel.Text = (<span>&quot;Binary: &quot;</span> &#43; ConvertToBinary(output));</pre>
<pre><span> 35:</span> }</pre>
<pre><span> 36:</span> }</pre>
</div>
</div>
<p><strong>VB:</strong></p>
<div>
<div>
<pre><span> 1:</span> <span>Private</span> <span>Sub</span> Form1_MouseUp(<span>ByVal</span> sender <span>As</span> <span>Object</span>, <span>ByVal</span> e <span>As</span> MouseEventArgs)</pre>
<pre><span> 2:</span>&nbsp; </pre>
<pre><span> 3:</span> <span>If</span> (e.Button = MouseButtons.Right) <span>Then</span></pre>
<pre><span> 4:</span> <span>'Switch between different stepping modes</span></pre>
<pre><span> 5:</span> <span>Select</span> <span>Case</span> (stepMode)</pre>
<pre><span> 6:</span>&nbsp; </pre>
<pre><span> 7:</span> <span>Case</span> SteppingMode.SingleStep</pre>
<pre><span> 8:</span> stepMode = SteppingMode.HalfStep</pre>
<pre><span> 9:</span> steppingModeStatusStripLabel.Text = <span>&quot;Step Mode: Half&quot;</span></pre>
<pre><span> 10:</span>&nbsp; </pre>
<pre><span> 11:</span> <span>Case</span> SteppingMode.HalfStep</pre>
<pre><span> 12:</span> stepMode = SteppingMode.HighTorqueStep</pre>
<pre><span> 13:</span> steppingModeStatusStripLabel.Text = <span>&quot;Step Mode: High Torque&quot;</span></pre>
<pre><span> 14:</span>&nbsp; </pre>
<pre><span> 15:</span> <span>Case</span> SteppingMode.HighTorqueStep</pre>
<pre><span> 16:</span> stepMode = SteppingMode.SingleStep</pre>
<pre><span> 17:</span> steppingModeStatusStripLabel.Text = <span>&quot;Step Mode: Single&quot;</span></pre>
<pre><span> 18:</span>&nbsp; </pre>
<pre><span> 19:</span> <span>End</span> <span>Select</span></pre>
<pre><span> 20:</span>&nbsp; </pre>
<pre><span> 21:</span> <span>ElseIf</span> (e.Button = MouseButtons.Left) <span>Then</span></pre>
<pre><span> 22:</span> <span>'Release the motor</span></pre>
<pre><span> 23:</span> output = 0</pre>
<pre><span> 24:</span> PortAccess.Output(888, output)</pre>
<pre><span> 25:</span> decimalStatusStripLabel.Text = (<span>&quot;Decimal: &quot;</span> &#43; output.ToString)</pre>
<pre><span> 26:</span> binaryStatusStripLabel.Text = (<span>&quot;Binary: &quot;</span> &#43; ConvertToBinary(output))</pre>
<pre><span> 27:</span> <span>End</span> <span>If</span></pre>
<pre><span> 28:</span>&nbsp; </pre>
<pre><span> 29:</span> <span>End</span> <span>Sub</span></pre>
</div>
</div>
<p>Releasing the motor and letting it free-wheel is important, because I've noticed that stepper motors heat up very quickly. I don't know whether one can burn out a stepper motor or not, but the safest way to turn off the motor completely would be to disconnect
 its power supply. <br>
<b></b></p>
<p><b>Conclusion <br>
</b><br>
We have reached the end of this article, but I sure hope it inspires you to start your own experiments with parallel port interfacing and programming. You can use this port to play with a lot of other things like LEDs, relays, etc. Over the last couple of months,
 I have been using my computer's parallel port for controlling several things, such as lights, fans, RC cars, robots and whatnot. There are things which could be extended, and added to this stepper motor project. You could, for example, use it as a web controlled
 camera panner. I have used mine as a camera panner which tracks moving objects using a webcam and lasers (<a></a><a href="http://www.youtube.com/watch?v=LHMiD4DAVaU">video</a>). Just remember that your imagination is the only limit. So, unleash your imagination
 and the sky is the limit. Have fun!</p>
<p><b>About the Author</b></p>
<p>Ashish Derhgawen is an IT student, currently living in New Delhi, India. He has been coding since fourth grade. Some of his other interests are harmonica playing, wildlife and cricket. When he’s not at school, he spends his time working on unusual projects
 related to robotics, webcams, and electronics besides others. You can reach Ashish through his blog at
<a href="http://ashishrd.blogspot.com/">http://ashishrd.blogspot.com</a>.</p>
<div><span id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e8c3db6c-4d51-44c2-b87d-be0a5dfb3d81">Filed under:
<a href="http://blogs.msdn.com/coding4fun/archive/tags/windows/default.aspx" rel="tag">windows</a>, <a href="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx" rel="tag">
hardware</a></span></div>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Ashish-Derhgawen/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7080b34171a44e1e85859e7600d189ed">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Computer-Controlled-Stepper-Motor</comments>
      <itunes:summary>





In this article, we will connect a stepper motor to our computer&#39;s parallel port, and then we will write some code to control it with the scroll wheel on a mouse (video).
 If you have never worked with stepper motors, you will surely have a lot of fun with this project. With stepper motors, you can build things such as robots, automatic fish feeder, or even a
computerized etch-a-sketch! I&#39;ll start off by discussing the basics of parallel ports and stepper motors. Then, we will build the driver circuit required for connecting a stepper motor to a parallel port.
 In the final section, we will learn how to communicate with parallel ports and how stepper motors are controlled.



Ashish Derhgawen
Ashish Blog

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Less Than $50
Software: Visual C# or Visual Basic Express Editions
Hardware: A 
5-wire unipolar stepper motor (these could also be salvaged from old 5&#188;&amp;quot; floppy disk drives),
ULN2003 IC (stepper motor driver), wire, stripboard (or a
solderless breadboard ), solder and
DB-25 Male connector (buy these two if you can solder. Soldering is not necessary for doing this project, but it will ensure that your connections are secure),
DB25 (female/male) parallel port cable, a multimeter, a power adapter (with voltage rating depending on your motor&#39;s requirements)
Download: Download

WARNING: Before we begin, I would warn you that the PC parallel port can be damaged quite easily if you make incorrect connections. If the parallel port is integrated to the motherboard, repairing a damaged parallel port may be expensive,
 and in many cases, it is cheaper to replace the whole motherboard than to repair that port.
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Your safest bet is to buy an inexpensive I/O card which has a parallel port and use it for your experiment. If you manage to damage the parallel port on that card, replacing it will be easy and inexpensive.

Don&#39;t let that warning worry you too much, because ther</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Computer-Controlled-Stepper-Motor</link>
      <pubDate>Fri, 02 Nov 2007 21:29:18 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Computer-Controlled-Stepper-Motor</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/5848155_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/5848155_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Ashish Derhgawen</dc:creator>
      <itunes:author>Ashish Derhgawen</itunes:author>
      <slash:comments>29</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Computer-Controlled-Stepper-Motor/RSS</wfw:commentRss>
    </item>    
</channel>
</rss>