<?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>Starlino Electronics</title>
	<atom:link href="http://www.starlino.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.starlino.com</link>
	<description>Electronics and Robotics Projects, Tutorials, Reviews, Experiments</description>
	<lastBuildDate>Fri, 27 Aug 2010 23:12:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Hakko 808 Desoldering Tool Review</title>
		<link>http://www.starlino.com/hakko-808-desoldering-tool-review.html</link>
		<comments>http://www.starlino.com/hakko-808-desoldering-tool-review.html#comments</comments>
		<pubDate>Tue, 27 Jul 2010 16:20:03 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[desoldering]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://starlino_wp/?p=42</guid>
		<description><![CDATA[If you&#39;re into electronics sooner or later you will need to desolder something. Also, if you don&#39;t have the proper tools or skills you&#39;ll damage a component or two or even the PCB. Been there done that &#8211; desoldering braid, cheap one-shot mechanical pumps, running the soldering iron from one pin to another &#8230; until [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#39;re into electronics sooner or later you will need to desolder something. Also, if you don&#39;t have the proper tools or skills you&#39;ll damage a component or two or even the PCB. Been there done that &#8211; desoldering braid, cheap one-shot mechanical pumps, running the soldering iron from one pin to another &#8230; until one day I decided to look for a good professional desoldering tool. First I&nbsp; purchased an all-in-one system that among the soldering iron and hot air,&nbsp; had a desoldering funtion. The pump was in the main unit and the desoldering iron was connected by a rubber tube. As it turns out these units have a typical design flaw &#8211; because the pump is so far away from the desoldering iron&nbsp; tip the suction is somewhat weak. Keep in mind that air is flexible so the longer the tube the more pressure is lost along the way. So if you&#39;re buying such a unit make sure the pump is really strong and has a gauge that will allow you to monitor the pressure. That unit has been returned and I am not even going to mention its name ! Then I came across Hakko 808 and until this day this is one of my favorite tools in my workshop. The suction power of this tool is amazing, easy to handle , heats up quickly , not very expensive. It requires regular maintenance (it&#39;s almost like a pet), but if you take care of it you&#39;ll save hours of work and many components and PCBs. Here is an example of what it can do, I received this LiPo charger with some terminal headers that I wanted to replace with different ones:</p>
<p><object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/e3MCUf1ISAw&amp;hl=en_US&amp;fs=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/e3MCUf1ISAw&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" width="480"></embed></object></p>
<p><span id="more-42"></span>Here are close-ups of the before and after desoldering:</p>
<p><img alt="" height="480" src="/wp-content/uploads/data/hako_808_desoldering_tool_review/IMG_1383.JPG" width="640" /></p>
<p><img alt="" height="480" src="/wp-content/uploads/data/hako_808_desoldering_tool_review/IMG_1379.JPG" width="640" /></p>
<p>As you can see desoldering something is really easy, and you get a really-really clean result with this tool.</p>
<p>There are few things to take care of though:</p>
<p>- do not touch the PCB traces for more than one second, this tool is hot and if you heat up the pads for too long it will suck them up<br />
	- buy several tip sizes for different jobs ,&nbsp; i got&nbsp; 1mm (comes in the kit) and additionally I got&nbsp; 1.8mm and 2.3mm tips<br />
	- clean your tool regularly. The most replaced items are the ceramic filters so stock up on those, when they harden from the flux it&#39;s time to replace them.</p>
<p><img alt="" height="897" src="http://www.starlino.com/wp-content/uploads/data/hako_808_desoldering_tool_review/hakko_808_how_to_use.png" width="533" /></p>
<p><em>Source: <a href="http://www.starlino.com/wp-content/uploads/data/hako_808_desoldering_tool_review/Hakko_808_Manual.pdf" target="_blank">Hakko 808 Manual&nbsp; (Download PDF)</a><br />
	</em></p>
<p>Hakko 808 Kit comes with a carry-on case and few spare parts. What is missing is a holder, that you can buy separately (Hakko 633), however the tool will lay on it&#39;s side on the table without touching the surface so that will suffice if you don&#39;t have a holder. Another feature that is missing is a&nbsp; an on/off switch, unplugging this from power outlet is not convenient especially if you have to crawl under the table with a hot tool on the table <img src='http://www.starlino.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.starlino.com/wp-content/uploads/data/hako_808_desoldering_tool_review/IMG_1490.JPG" target="_blank"><img alt=""  src="http://www.starlino.com/wp-content/uploads/data/hako_808_desoldering_tool_review/IMG_1490.JPG" width="740" /></p>
</a><p><img alt="" height="480" src="/wp-content/uploads/data/hako_808_desoldering_tool_review/IMG_1385.JPG" width="640" /></p>
<p>Overall Hakko 808 is great tool , worth every penny, and I would buy it again if it breaks, speaking of which it is nicely build and has spare parts available so self-repair is possible and even encouraged and explained in the manual.</p>
<p>//starlino//</p>
<p>&nbsp;</p>
<p><iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?lt1=_blank&amp;bc1=000000&amp;IS1=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=librarian06-20&amp;o=1&amp;p=8&amp;l=as1&amp;m=amazon&amp;f=ifr&amp;asins=B000ARPULW" style="width: 120px; height: 240px;"></iframe></p>
<p><a href="http://www.amazon.com/gp/product/B000B63604?ie=UTF8&amp;tag=librarian06-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000B63604">Hakko A1229: Hakko Replacement Pre-Filters for 808-5, 10/pkg.</a><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=librarian06-20&amp;l=as2&amp;o=1&amp;a=B000B63604" style="border: medium none ! important; margin: 0px ! important;" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/hakko-808-desoldering-tool-review.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrade your RC Transmitter with a DIY Tilt Motion Control Module</title>
		<link>http://www.starlino.com/rc_transmitter_accelerometer.html</link>
		<comments>http://www.starlino.com/rc_transmitter_accelerometer.html#comments</comments>
		<pubDate>Thu, 24 Jun 2010 23:44:03 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[imu]]></category>
		<category><![CDATA[motion]]></category>
		<category><![CDATA[op-amp]]></category>
		<category><![CDATA[rc]]></category>
		<category><![CDATA[transmitter]]></category>

		<guid isPermaLink="false">http://rc_transmitter_accelerometer</guid>
		<description><![CDATA[If you are into Radio Control Models or robotics chances are that you have an old RC transmitter laying around. This article describes how to create a motion control module for your RC transmitter, that will allow you to control your model or robot by simply tilting the transmitter case. That's right no more wiggling the sticks!]]></description>
			<content:encoded><![CDATA[<p>If you are into Radio Control Models or robotics chances are that you have an old RC transmitter laying around. This article describes how to create a motion control module for your RC transmitter, that will allow you to control your model or robot by simply tilting the transmitter case. That&#39;s right not sticks!</p>
<h2>Demo</h2>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="344" width="425"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/U0FaM6A1zDE&amp;hl=en&amp;fs=1" /><embed allowfullscreen="true" allowscriptaccess="always" height="344" src="http://www.youtube.com/v/U0FaM6A1zDE&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" width="425"></embed></object></p>
<p><span id="more-23"></span>Testing one axis:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="344" width="425"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/GqEDDWv6-ak&amp;hl=en&amp;fs=1" /><embed allowfullscreen="true" allowscriptaccess="always" height="344" src="http://www.youtube.com/v/GqEDDWv6-ak&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" width="425"></embed></object></p>
<h2>Schematic</h2>
<p><img alt="rc_transmitter_motion_control_schematic_full.png" src="data/rc_transmitter_accelerometer/rc_transmitter_motion_control_schematic_full.png" /></p>
<p>&nbsp;</p>
<h2>How it Works</h2>
<p>The RC transmitter uses a potentiometer for each axis, it acts as a voltage divider sending a voltage of 0..5V (the middle position corresponds to 2.5V) to the analog input that is converted into a pule of&nbsp; 1..2ms that is sent over RF.</p>
<p>This module converts (amplifies and shifts) the accelerometer analog output , usually&nbsp; 1.65 +/- 0.4V to the same range of the potentiometer and sends it to the transmitter instead.</p>
<p>An op-amp in an inverting amplifier configuration is used. Vref is set manually by tuning the output to be 2.5V (or the PWM pulse to be 1.5 ms). However it is possible to calculate the theoretical value as follows:</p>
<p>Note that according to the rules of&nbsp; a feedback op-amp the voltage on it&#39;s inverting/non-inverting terminals tends to equalize so &nbsp; V(+) = V(-) and in our case&nbsp; = Vref.</p>
<p>Since no significant current enters the op-amp , the currents going through R1 and R2 are equal:</p>
<p>( V(-) &#8211; Vin ) / R1 = ( Vout &#8211; V(-) ) / R2&nbsp;&nbsp;</p>
<p>(Vref &#8211; Vin) / R1 = (Vout &#8211; Vref) / R2</p>
<p>solving for Vout gives us</p>
<p>Vout = Vref -&nbsp; R2/R1 (Vin &#8211; Vref)&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp; Vref( 1 + R2/R1)&nbsp; &#8211; R2/R1 * Vin</p>
<p>now let&#39;s do some notations</p>
<p>G = &#8211; R2/R1</p>
<p>Vout = Vref( 1 &#8211; G)&nbsp; -&nbsp; G * Vin</p>
<p>According to our schematic&nbsp; G =&nbsp; R2 / R1 =&nbsp; &#8211; 5.12 , this will convert the accelerometer swing of 0.4 V to a swing of&nbsp;&nbsp; 0.4 V * 5.12&nbsp; ~&nbsp; 2V .</p>
<p>We want&nbsp; to make &nbsp; Vin = 1.65&nbsp; correspond to a&nbsp; Vout = 2.5 so we&nbsp; have the equation</p>
<p>2.5 =&nbsp; Vref (1 + 5.12)&nbsp; &#8211; 5.12 * 1.65</p>
<p>from here we find</p>
<p>Vref =&nbsp; (2.5 + 5.12 * 1.65 ) /&nbsp; (1 + 5.12) = 1.78888 V</p>
<p>Well, this is the theoretical value , in practice we adjust the trimmer R3 until the output is 2.5 while the accelerometer is in laying in horizontal position (has an output of 1.65V).</p>
<h2>How to Build</h2>
<p>To build use a small proto-board following schematic. Part numbers are mentioned on schematic. Hook-up with the transmitter is described in images below and on the schematic. For accelerometer use <a href="http://www.gadgetgangster.com/213">Acc_Gyro</a> or similar module, <a href="surface_mount_reflow.html">or build your own accelerometer break-out board</a>.</p>
<h2><img alt="rc_transmitter_tap_in.jpg" src="data/rc_transmitter_accelerometer/rc_transmitter_tap_in.jpg" /></h2>
<h2>&nbsp;</h2>
<h2><img alt="rc_transmitter_tap_in_switch.JPG" src="data/rc_transmitter_accelerometer/rc_transmitter_tap_in_switch.JPG" /></h2>
<p>&nbsp;</p>
<p>The module is mounted in a free space under antenna using double-sided foam tape &#8211; best way to mount an accelerometer to avoid vibration. Note that we get +5V power for the module from the potentiometer contacts. You can test&nbsp; with a led that the power contacts can deliver at least 20mV, the module uses far less &lt;5mA.</p>
<p><img alt="IMG_1485.JPG" src="data/rc_transmitter_accelerometer/IMG_1485.JPG" /></p>
<p>Here is a close-up of the module, as you can see I did&nbsp; <a href="surface_mount_reflow.html">my own accelerometer break-out board</a>, but you can buy a pre-assembled one , there are many choices. You will need an analog accelerometer for this project.</p>
<p><img alt="IMG_1483.JPG" src="data/rc_transmitter_accelerometer/IMG_1483.JPG" /></p>
<p>&nbsp;</p>
<p>Enjoy your new RC Tilt Transmitter. For any comments/questions use the comment form below.</p>
<p>&nbsp;</p>
<p>//starlino//</p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/rc_transmitter_accelerometer.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quadcopter Prototype using Acc_Gyro and a PIC</title>
		<link>http://www.starlino.com/quadcopter_acc_gyro.html</link>
		<comments>http://www.starlino.com/quadcopter_acc_gyro.html#comments</comments>
		<pubDate>Wed, 09 Jun 2010 23:27:15 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[gyroscope]]></category>
		<category><![CDATA[imu]]></category>
		<category><![CDATA[pic]]></category>
		<category><![CDATA[quadcopter]]></category>

		<guid isPermaLink="false">http://quadcopter_acc_gyro</guid>
		<description><![CDATA[<p>This article introduces a new project I am working on - a&#160; Quadcopter using Acc_Gyro and a PIC. I share some things I learned along the way so far.</p>]]></description>
			<content:encoded><![CDATA[<p>For anyone following this site, here is what I&#39;ve been up to lately &#8211; building a quadcopter based on the <a href="http://gadgetgangster.com/213">Acc_Gyro 5DOF IMU</a> sensor and a 16bit PIC. Although it&#39;s still a work in progress I decided to start putting together an article placeholder and build it up as project evolves. It&#39;s going to be a long one !</p>
<p>The source code will be Open-Source and will be hosted here:</p>
<p><a href="http://code.google.com/p/picquadcontroller/source/browse/#svn/trunk">http://code.google.com/p/picquadcontroller/source/browse/#svn/trunk</a></p>
<p>As usual I like to start with a video demo, it&#39;s basically me controlling the tilt of the quad using a RC controller:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="505" width="640"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/q_BZfG2xYdI&amp;hl=en_US&amp;fs=1&amp;" /><embed allowfullscreen="true" allowscriptaccess="always" height="505" src="http://www.youtube.com/v/q_BZfG2xYdI&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" width="640"></embed></object></p>
<p><span id="more-22"></span>This is a PID feedback algorithm and a &quot;Simplified Kalman Filter&quot; as&nbsp; described in my other articles.</p>
<p>First of all there&#39;s a a RCGroups thread where I first introduced the project</p>
<p>http://www.rcgroups.com/forums/showthread.php?t=1235360</p>
<p>You&#39;ll find some specs there and I will put some material here&nbsp; as well.</p>
<p>Here is Revision 0.1 of schematic (what I started with):</p>
<p><a href="data/PicQuadController/PicQuadControllerRev01.pdf">PicQuadControllerRev01.pdf</a></p>
<p>The major parts list is as follows:</p>
<p><strong>MCU:</strong>&nbsp; DSPIC33FJ128MC802&nbsp; (<a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en532302">http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en532302</a>)</p>
<p><strong>Sensors</strong>: 5DOF Acc_Gyro ( <a href="http://gadgetgangster.com/213">http://gadgetgangster.com/213</a> )&nbsp; + 1Dof Pololu LIST300AL-BREAKOUT (<a href="http://www.pololu.com/catalog/product/765">http://www.pololu.com/catalog/product/765</a>).</p>
<p><strong>Motor Drivers:</strong>&nbsp; Power N-Channel Mosfets (Many choices -Low Rds(on) and rated for the current , I used&nbsp; IRLR8743 ). Schottky diodes to protect against back-EMF ( I used SS2H10-E3/52T )</p>
<p><strong>Frame , motors propellers</strong>: I picked a ready platform that was on sale <a href="http://www.rctoys.com/rc-toys-and-parts/DF-COMPLETE-AIRFRAME/RC-PARTS-DRAGANFLYER-FRAME.html" target="_blank">Dragandfly IV Frame</a> these are actually brushed motors same ones as used in Esky helicopters.</p>
<p>I did some tests on the lift force potential of this frame+motors+props, and was surprise to find out it performed better than some entry-level brushless motors. The lift force of this platform is up to 2.25 lbs.&nbsp; The results of lift-force experiments are compiled in this spreadheet: <a href="data/PicQuadController/MotorLiftPower.pdf" target="_blank">MotorLiftPower.pdf</a>.</p>
<p>How I measured the lift force ?&nbsp; I didn&#39;t have any fancy equipment so I simply fixed the quad in a vise and weighted&nbsp; it it at different throttle levels &#8211; the difference in weight gave me the lift power.</p>
<p><img alt="IMG_1463.JPG" src="data/PicQuadController/IMG_1463.JPG" /></p>
<p>For testing just one motor, I used a string attached to the weight:</p>
<p><img alt="IMG_1460.JPG" src="data/PicQuadController/IMG_1460.JPG" /></p>
<p>I built a test rig out of wood for testing the tilt balancing algorithm as you see in the video.</p>
<p>Here are some close-ups of the motor drivers. You&#39;ll&nbsp; see the Mosfets and the Schottky diodes, also note the extra solder added to support the high currents that will flow through those traces ( up to 5A per motor !).</p>
<p><img alt="IMG_1465.JPG" src="data/PicQuadController/IMG_1465.JPG" /></p>
<p>Finally here is a view on the top of the board ( notice the PIC , the switching regulator&nbsp; ,&nbsp; Acc_Gyro 5DOF IMU and single axes Gyro breakout , from top-left to bottom right).</p>
<p><img alt="IMG_1466.JPG" src="data/PicQuadController/IMG_1466.JPG" /></p>
<p>This is it for now hope to bring you more interesting stuff on this and other projects if time allows&nbsp; !</p>
<p>//starlino//</p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/quadcopter_acc_gyro.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Play PC games the iPad style  &#8211; Using a PIC with  USB,  accelerometer  and optional Gyroscope</title>
		<link>http://www.starlino.com/usb_thumb_imu.html</link>
		<comments>http://www.starlino.com/usb_thumb_imu.html#comments</comments>
		<pubDate>Tue, 06 Apr 2010 12:43:50 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[Acc_Gyro]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[imu]]></category>
		<category><![CDATA[motion]]></category>
		<category><![CDATA[usb]]></category>
		<category><![CDATA[UsbThumb]]></category>

		<guid isPermaLink="false">http://usb_thumb_imu</guid>
		<description><![CDATA[<p>The iPad is finally out - one feature that might caught your attention is the built-in accelerometer and the ability to control a game by tilting the device. But it turns out you can do same thing on your laptop. Read on to find out how.</p>]]></description>
			<content:encoded><![CDATA[<p>The iPad is finally out &#8211; one feature that might caught your attention is the built-in accelerometer and the ability to control a game by tilting the device. For more than a year I was working on a similar idea for the PC Notebook market based on my original&nbsp; motion gamepad project that would&nbsp; allow playing a game by tilting the laptop/netbook. Now that iPad is out I hope that the notebook/netbook manufactures will catch up by incorporating MEMS sensor into their devices. Here is the result of my prototype , it is a USB attached device, but ideally I think this should be embedded into the laptop.</p>
<p><strong>Demo:</strong></p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="385" width="640"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/CTSlfDLNlUo&amp;hl=en_US&amp;fs=1&amp;" /><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/CTSlfDLNlUo&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" width="640"></embed></object></p>
<p><span id="more-21"></span></p>
<p><strong>About the project:</strong></p>
<p>For the hardware I used the <a href="http://www.gadgetgangster.com/213">Acc_Gyro</a> sensor and a thumb-size PIC platform <a href="http://www.gadgetgangster.com/240">UsbThumb</a> built around the inexpensive PIC18F14K50 chip that provides all the necessary USB connectivity and ADC inputs.</p>
<p>This setup is actually hardware compatible with my original <a href="http://www.gadgetgangster.com/231">Motion Gamepad</a> design so all the software utilities and firmware will work on the Acc_Gyro + UsbThumb combination that is available as a kit under the name of <a href="http://www.gadgetgangster.com/290">UsbThumbImu </a>. The Acc_Gyro fits on top of UsbThumb and this is not a coincidence since UsbThumb was designed as microcontroller helper for the Acc_Gyro with the idea of being able to provide the USB/Serial/SPI/I2C interface, as well as making use of the built-in 10bit ADC module of the PIC18F14K50.</p>
<p><img alt="" height="244" src="http://www.gadgetgangster.com/scripts/thumbs/pic/290/4433949229_26c3104238_b.jpg" width="300" /></p>
<p>&nbsp;</p>
<p><img alt="" height="244" src="http://www.gadgetgangster.com/scripts/thumbs/pic/290/4434725210_859ebbffe2_b.jpg" width="300" /></p>
<p>&nbsp;</p>
<p>In the pictures above headers are used to connect the device, so the end result is a little taller&nbsp; than you could get if you&#39;d simply solder the two boards together. Both devices have been designed for people that would like to extend&nbsp; or experiment with the existing solution so there is a second row of connectors on the UsbThumb that can be used to connect buttons or other devices to the project.&nbsp;</p>
<p>&nbsp;</p>
<p>All that&#39;s it for now &#8211; hope you liked the project. It was really easy to built having the two important components UsbThumb and Acc_Gyro. You&#39;ll find more info on individual components on my website as well as&nbsp; on the <a href="http://www.gadgetgangster.com/290">GadgetGangster</a> site with whom I partnered to provide kits for anyone interested. If you don&#39;t find the necessary information, or you have any any suggestions, ideas or questions &#8211; as always feel free to drop me a line with in the comment area below.</p>
<p>&nbsp;</p>
<p>//starlino//</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://www.gadgetgangster.com/240"><br />
	</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/usb_thumb_imu.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Trickster Mouse Emulator – April Fools Day Practical Joke</title>
		<link>http://www.starlino.com/usbthumb_mouse_emulator.html</link>
		<comments>http://www.starlino.com/usbthumb_mouse_emulator.html#comments</comments>
		<pubDate>Wed, 31 Mar 2010 18:57:43 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[mouse]]></category>
		<category><![CDATA[pic]]></category>
		<category><![CDATA[usb]]></category>
		<category><![CDATA[UsbThumb]]></category>

		<guid isPermaLink="false">http://usbthumb_mouse_emulator</guid>
		<description><![CDATA[<p>Trickster is a simple application built on UsbThumb platform. It tricks your victim into thinking they have a virus on their computer, by hardware emulating and moving their mouse in circles on intermittent intervals.</p>]]></description>
			<content:encoded><![CDATA[<p>Trickster is a simple application built on UsbThumb platform. It tricks your victim into thinking they have a virus on their computer, by hardware emulating and moving their mouse in circles on intermittent intervals.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" height="300" width="400"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=10510369&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed allowfullscreen="true" allowscriptaccess="always" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=10510369&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" width="400"></embed></object></p>
<p><span id="more-20"></span>It is basically a customization of Mouse emulation demo that Microchip bundles with their USB Framework.</p>
<p>The code responsible for enabling/disabling mouse emulation is triggered by a timer interrupt like so:</p>
<p>
	<span class="edit_monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenTimer0( TIMER_INT_ON &amp;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T0_16BIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T0_SOURCE_INT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T0_PS_1_256);</p>
<p>	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;.</span></p>
<p><span class="edit_monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //These are your actual interrupt handling routines.</span></p>
<p>&nbsp;</p>
<p><span class="edit_monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #pragma interrupt YourHighPriorityISRCode<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void YourHighPriorityISRCode()<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Check which interrupt flag caused the interrupt.<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Service the interrupt<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Clear the interrupt flag<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Etc.<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #if defined(USB_INTERRUPT)<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; USBDeviceTasks();<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #endif<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(INTCONbits.TMR0IF){<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; counter_s++; <br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //to interrupt every 1s we need to count FOSC / 4/ 256&nbsp; = 46875 ticks (0xB71B)<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //to count these ticks till overflow we need to set TMR0 to&nbsp; 0xFFFF &#8211; 0xB71B = 0x48E4 <br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TMR0H = 0&#215;48; //will write to TMR0H buffer<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TMR0L = 0xE4; //will write actual TMR0L / TMR0H&nbsp; </p>
<p>	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INTCONbits.TMR0IF = 0;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //This return will be a &quot;retfie fast&quot;, since this is in a #pragma interrupt section</span></p>
<p class="edit_monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;&#8230;..</p>
<p>	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INTCONbits.TMR0IE = 0;&nbsp; //disable Timer0 interrupt<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(emulate_mode &amp;&amp; counter_s &gt; 3){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // seconds on<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; counter_s = 0;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emulate_mode = 0;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }else if (!emulate_mode &amp;&amp; counter_s &gt; 60){&nbsp;&nbsp;&nbsp;&nbsp; //seconds off<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; counter_s = 0;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emulate_mode = 1;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INTCONbits.TMR0IE = 1;</p>
<p>&nbsp;</p>
<p><span class="edit_monospace"><br />
	</span></p>
<p>For full source code see:</p>
<p><a href="http://code.google.com/p/usbthumb/source/browse/#svn/trunk/UsbThumbMousePrank" target="_blank">http://code.google.com/p/usbthumb/source/browse/#svn/trunk/UsbThumbMousePrank</a></p>
<p><strong>UsbThumb is an open-hardware platform, anyone can build their own:</strong></p>
<p><a href="http://code.google.com/p/usbthumb/source/browse/#svn/trunk/Hardware" target="_blank">http://code.google.com/p/usbthumb/source/browse/#svn/trunk/Hardware</a></p>
<p>or pick up a prebuilt SMT version of UsbThumb here: <a href="http://www.gadgetgangster.com/303">http://www.gadgetgangster.com/303</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/usbthumb_mouse_emulator.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Updating Firmware on USBThumb</title>
		<link>http://www.starlino.com/usbthumb_firmware_upgrade.html</link>
		<comments>http://www.starlino.com/usbthumb_firmware_upgrade.html#comments</comments>
		<pubDate>Thu, 18 Mar 2010 16:57:21 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Parts]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[pic]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[propeller]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[usb]]></category>
		<category><![CDATA[UsbThumb]]></category>

		<guid isPermaLink="false">http://usbthumb_firmware_upgrade</guid>
		<description><![CDATA[<p>This article describes how to update firmware on USBThumb.</p>]]></description>
			<content:encoded><![CDATA[<p>USBThumb can be programmed with different firmware, including all Microchip samples from <a href="http://www.google.com/search?q=Microchip+USB+Framework" target="_blank">USB Framwework</a> (use the ones for low pin count USB demo board).</p>
<p>In order to upload a new firmware to USBThumb you need to enter the bootloader mode. This is done by connecting the&nbsp; VPP pin to ground during the time when device is plugged into the USB port.</p>
<p>This can achieved by placing a jumper wire or a 1K resistor (recommended) between GND and VPP pin.</p>
<p>GND pin is number 1, and VPP is number 5. Make sure you do not confuse VPP with the nearby VDD(number 4) or you will get a short !!! To be safe use a 1K resistor instead of the wire. Wire/resistor can be held by the spring action, it only needs to make contact during a split second while the device is plugged. If you plan on making frequent firmware updates , soldering a header is recommended.</p>
<p><img alt="IMG_1408.JPG" src="http://www.starlino.com/wp-content/uploads/data/usbthumb_firmware_upgrade/IMG_1408.JPG" /></p>
<p><span id="more-19"></span>Before plugging the device to USB port,&nbsp; start the &quot;USB HID Bootloader&quot; application (it is installed as part of the Microchip USB Framework, look in C:\Microchip Solutions\USB Device &#8211; Bootloaders\HID &#8211; Bootloader), a copy is placed here for download:</p>
<p><a href="data/usbthumb_firmware_upgrade/HIDBootLoader.zip">HIDBootLoader.zip</a></p>
<p>Next insert the USBThumb into the USB port (with the VPP and GND pins connected) , you should see a &quot;Device attached.&quot; message in the USB HID Bootloader window.</p>
<p>Next steps are simple:</p>
<p>1. Click on &ldquo;Open Hex File&rdquo; button and select the new firmware .HEX file you want to load<br />
	2. Click on &ldquo;Program/Verify&rdquo; and wait for the process to complete<br />
	3. Unplug the device from USB port. Remove the jumber wire/resistor between GND and VPP pin.<br />
	4. Plug the device back and verify the new firmware is working (it depends on firmware and what you expect it to do).</p>
<p>The pictures below illustrate the above steps:</p>
<p><img alt="UsbHidBootloaderSelectFile.png" src="http://www.starlino.com/wp-content/uploads/data/usbthumb_firmware_upgrade/UsbHidBootloaderSelectFile.png" /></p>
<p>&nbsp;</p>
<p><img alt="UsbHidBootloaderBurnFirmware.png" src="http://www.starlino.com/wp-content/uploads/data/usbthumb_firmware_upgrade/UsbHidBootloaderBurnFirmware.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/usbthumb_firmware_upgrade.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using USBThumb as a Propeller Programmer  and  as a USB to Serial Converter</title>
		<link>http://www.starlino.com/usbthumb_propeller_programmer.html</link>
		<comments>http://www.starlino.com/usbthumb_propeller_programmer.html#comments</comments>
		<pubDate>Mon, 15 Mar 2010 22:44:19 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Parts]]></category>
		<category><![CDATA[pic]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[propeller]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[usb]]></category>
		<category><![CDATA[UsbThumb]]></category>

		<guid isPermaLink="false">http://usbthumb_propeller_programmer</guid>
		<description><![CDATA[<p>This article describes how you can use USBThumb as a Propeller Programmer or USB to Serial converter.</p>]]></description>
			<content:encoded><![CDATA[<p>The Parallax&#39;s classic propeller programmer PropPlug&nbsp; is simply a USB to Serial converter, the DTR/RTS signals are used to reset the Propeller chip before starting the programming sequence.</p>
<p>A custom PIC firmware&nbsp; comes preloaded on the <br />
	<a href="http://www.gadgetgangster.com/289" target="_blank">&quot;USBThumb Propeller Programmer&quot;</a> available on GadgetGangster.com, it allows you to use USBThumb as a Propeller Programmer but also as USB to Serial converter.</p>
<p>USBThumb (loaded with <a href="http://code.google.com/p/usbthumb/">USBThumbSerial </a>firmware)&nbsp; is detected on your computer as a standard&nbsp; CDC Modem device and works on all modern operating systems (Windows, Mac os , Linux).</p>
<p>On Windows you might be asked for driver path once you attach the device, simply use the driver part of the Microchip&#39;s USB Framework (it can be found in C:\Microchip Solutions\USB Device &#8211; CDC &#8211; Serial Emulator\inf\win2k_winxp ) , and I am including a copy for direct download here:</p>
<p><a href="data/usbthumb_propeller_programmer/microchip_cdc_win2k_winxp.zip">microchip_cdc_win2k_winxp.zip</a></p>
<p>On Windows you can identify USBThumb&#39;s COM port number from Device Manager:</p>
<p><img alt="3-15-2010 10-24-15 PM.png" src="/wp-content/uploads/data/usbthumb_propeller_programmer/3-15-2010 10-24-15 PM.png" /></p>
<p><span id="more-18"></span>On Mac OS, once you attach the device&nbsp; you will get a prompt &quot;A new network interface has been detected&quot;. Look in the /dev folder. You should see it as &quot;/dev/tty.usbmodem411&quot; or similar.</p>
<p>PropellerTool can scan all available ports and find the one that has a propeller chip attached. So the above step might not be necessary, however if you already know the COM port of USBThumb you can specify it explicitly.</p>
<p>In the PropellerTool go to&nbsp; Edit &gt; Preferences&gt;Operation and update the &quot;Serial Port Search&quot; to the port number of USBThumb (COM15 in my example). In the &quot;Propeller Reset Signal&quot; choose DTR.</p>
<p><img alt="3-15-2010 10-37-28 PM.png" src="/wp-content/uploads/data/usbthumb_propeller_programmer/3-15-2010 10-37-28 PM.png" /></p>
<p>&nbsp;</p>
<p>Next attach the USBThumb to your Propeller development board, USBThumb&#39;s serial&nbsp; 4-pin connector is pin compatible with PropPlug. The pins are marked as follows RX,TX,RST,GND.</p>
<p>To test the communication with the propeller board press F7.</p>
<p>If you experience problems make sure the port is not open by any other software (like for example the propeller terminal software)</p>
<p>In some rare cases if you computer power supply is too noisy, to ensure greater stability you can place a 18pF filtering capacitor between pins 24 (RB5)&nbsp; and 25 (RB6). See picture below:</p>
<p><img alt="usbthumb_adding_filter_capacitor.jpg" src="/wp-content/uploads/data/usbthumb_propeller_programmer/usbthumb_adding_filter_capacitor.jpg" /></p>
<p>You can solder the capacitor permanently between these pins, or if you&#39;re planning to use USBThumb for other projects and you have soldered sockets to the board simply insert the capacitor in the socket between pins 24 and 25. You only need to take this step if you have intermittent problems with PropellerTool not detecting the Propeller chip.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/usbthumb_propeller_programmer.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Exploring a digital I2C/SPI accelerometer (MMA7456L) with Bus Pirate</title>
		<link>http://www.starlino.com/bus_pirate_i2c_tutorial.html</link>
		<comments>http://www.starlino.com/bus_pirate_i2c_tutorial.html#comments</comments>
		<pubDate>Sat, 20 Feb 2010 12:34:45 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[Parts]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[i2c]]></category>
		<category><![CDATA[spi]]></category>

		<guid isPermaLink="false">http://bus_pirate_i2c_tutorial</guid>
		<description><![CDATA[<p>Bus Pirate is a great tool for exploring new chips using your PC , without the need to integrate the chip into a MCU project. Once I received my unit, i decided to put it to the test by exploring an accelerometer with I2C/SPI interface - the MMA7456L from Freescale. I am writing this in hope that it will help other people get started with BusPirate and I2C protocol in particular. I will only describe the I2C interface in this article but BusPirate is capable of so much more !</p>]]></description>
			<content:encoded><![CDATA[<p>Bus Pirate is a great tool for exploring new chips using your PC , without the need to integrate the chip into a MCU project. Once I received my unit, i decided to put it to the test by exploring an accelerometer with I2C/SPI interface &#8211; the MMA7456L from Freescale. I am writing this in hope that it will help other people get started with BusPirate and I2C protocol in particular. I will only describe the I2C interface in this article but BusPirate is capable of so much more !</p>
<p>The setup of BusPirate was simple. Simply plug it to your USB port, install the FDTI driver (if necessary). After that it will appear as a virtual COM port on you computer. You then can use your terminal of choice to interact with it. Here is sample session in Termite (my choice of terminal software):</p>
<p><img alt="bus pirate terminal termite" height="420" src="/wp-content/uploads/data/bus_pirate_i2c_tutorial/bus_pirate_termite_terminal.png" width="635" /></p>
<p><span id="more-17"></span>You will have to figure out which port your BusPirate is on. If you can&#39;t figure it out, unplug it , observe list of ports, then plug it back to see which new port appeared &#8211; that&#39;s the one. List of COM ports can be found in Device Manager on Windows or in Termite Settings menu. Other COM settings are as follows:</p>
<p><img alt="terminal settigs for buspirate" height="238" src="data/bus_pirate_i2c_tutorial/termite_rs-232_ settigs_for_bus_pirate.png" width="558" /></p>
<p>Using the probe cable accessory, I did all connections on a breadboard guided by the schematic from <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;ved=0CAYQFjAA&amp;url=http%3A%2F%2Fwww.freescale.com%2Ffiles%2Fsensors%2Fdoc%2Fdata_sheet%2FMMA7456L.pdf&amp;ei=oPp_S4fjOY_T8Abh1bGHBQ&amp;usg=AFQjCNGNzsWiW40VGH6FwGZ9fN5lSUbYlw&amp;sig2=HNX96KK5hB-cLjoAekWL5w" target="_blank">MMA7456L datasheet</a> . You will need just 4 Bus Pirate probes connected to the accelerometer. Below I am showing which ones and where you should connect them:</p>
<p><img alt="buspirate and MMA7456L digital accelerometer connection diagram" height="499" src="/wp-content/uploads/data/bus_pirate_i2c_tutorial/bus_pirate_MMA7456L_connection_schematic.png" width="611" /></p>
<p>On the breadboard this looks something like this (I also have the oscilloscope probes connected to CLK and MOSI):</p>
<p><img alt="bus pirate connected to a breadboard accelerometer" height="480" src="/wp-content/uploads/data/bus_pirate_i2c_tutorial/bus_pirate_breadboard_accelerometer.JPG" width="640" /></p>
<p>First thing to note &#8211; I used some shrink-wrap to isolate the Bus Pirate, but you can also put it in a case.</p>
<p>Second thing to note is that my accelerometer was mounted on a breakout board I made myself, I have a detailed tutorial how you can do SMT mounting and etch your own boards in my article <a href="surface_mount_reflow.html">&quot;DIY Surface Mount on a Budget &#8211; Complete Walkthrough from PCB etching to Reflow&quot; </a>, check it out</p>
<p>Third thing &#8211; don&#39;t forget the the pull-up resistors (10K) on each bus line. It is required to pull-up the SDA and SCL lines (see resistors R1 and R2 on schematic). You can also try the BP pullup feature instead of external resistors.&nbsp; The BusPirate on-board 10K pull-up resistors can be connected to the bus pins, by connecting&nbsp; Vpu pin to a volate pin (3.3V), and then entering the p command to turn the pull-up feature on.</p>
<p>Finally, I used just one decoupling capacitor 0.1uF (the schematic shows 4 caps), also I did not bother to connect the N/C pins to ground.</p>
<p>However for stability you should ground the IADDR0 pin (3), on schematic they show a switch that allows a position where you can change the default address of the device. We won&#39;t need the switch for this experiment.</p>
<p>I later discovered that while using the BusPirate internal pull-up feature (Vpu connected to 3.3V),&nbsp; after I disconnect the oscilloscope probes the setup was no longer working!!! It must be the noise on the bus &#8211; I said to myself. Oscilloscope probes have 18-22pf capacitors that actually eliminate some noise. I encountered this phenomenon many times, so I knew what is going on. I simply added two 18pF capacitors between SDA/SCL pins and ground and I was back in business. The noise is coming most of all from my computer power supply , and while working at 100Khz it becomes an issue.</p>
<p>Ok, so once done with the hardware part, moving on to the BusPirate interface. First send a reset command and check your firmware/hardware version. A command is sent in bus pirate by typing the command # followed by Enter. Now take note of the version I am using , if you&#39;re reading this article in a year or two there might be other versions available, so if something doesn&#39;t make sense , it might be because your have a different version of BusPirate.</p>
<p class="edit_monospace">I2C&gt;<strong style="color: red;">#</strong><br />
	#<br />
	RESET</p>
<p class="edit_monospace">Bus Pirate v3<br />
	Firmware v4.1 Bootloader v4.1<br />
	DEVID:0&#215;0447 REVID:0&#215;3043 (B5)<br />
	http://dangerousprototypes.com<br />
	HiZ&gt;</p>
<p>For a complete list of commands you can type ?, I won&#39;t cover all commands in this article I&#39;ll just explain the ones we use. By default BP is in HiZ mode. HiZ means &quot;High Impedance&quot;. Z is a common symbol for impedance &#8211; simply a fancy way to say that all probes are disconnected. To enter I2C mode simply type <strong>m</strong> and choose the I2C option ( 4 &#8211; in my version of BP). You will be asked other details about I2C setup, I chose 100Khz speed. Once you enter a mode other than HiZ the green MODE led should turn on on your BusPirate.</p>
<p class="edit_monospace">HiZ&gt;<strong style="color: red;">m</strong><br />
	m<br />
	1. HiZ<br />
	2. 1-WIRE<br />
	3. UART<br />
	<strong>4. I2C</strong><br />
	5. SPI<br />
	6. JTAG<br />
	7. RAW2WIRE<br />
	8. RAW3WIRE<br />
	9. PC KEYBOARD<br />
	10. LCD<br />
	(1) &gt;<strong style="color: red;">4</strong><br />
	4<br />
	Mode selected<br />
	Set speed:<br />
	1. ~50KHz<br />
	<strong>2. ~100KHz</strong><br />
	3. ~400KHz<br />
	(1) &gt;<strong style="color: red;">2</strong><br />
	2<br />
	READY</p>
<p>Next step &#8211; you need to turn power supplies on &#8211; you do this by typing W (must be capital <strong>W</strong> !!! lower <strong>w</strong> turns them off). Once this is done, the VREG led will turn on, indicating you have power on your 3.3 and/or 5V pins. We&#39;ll just use the 3.3V pin to power our project and leave the 5V pin alone, however you could selectively turn the later off.</p>
<p class="edit_monospace">I2C&gt;<strong style="color: red;">W</strong><br />
	W<br />
	<strong>POWER SUPPLIES ON</strong></p>
<p>Now it&#39;s time to interact with our accelerometer, BP has a set of macros for each mode that you can check with the (0) command, the (1) macro happens to be a macro that scans all I2C address on the bus and displays the ones present. Each I2C slave device will have a 7bit address ($1D for MMA7456L) that comes in two flavors read(R) and write (W). To obtain the 8bit read/write address you shift the 7bit address to the left (same as multiply by 2) and set the 0th bit to 0 for write, and to 1 for read.</p>
<p class="edit_monospace">
	I2C&gt;<strong style="color: red;">(1)</strong><br />
	(1)<br />
	Searching 7bit I2C address space. <br />
	Found devices at:<br />
	<strong>0x3A(0x1D W) 0x3B(0x1D R) </strong></p>
<p>You can verify that 0x1D * 2 + 0 = 0x3A , 0x1D * 2 +1 = 0x3B.</p>
<p>Now it&#39;s time to read something from the device. The MMA7456L configuration is divided into 1 byte registers that are described in the datasheet, for testing purposes let&#39;s read the register $0D that should contain the device I2C address (0x1D):</p>
<p>Let&#39;s send the following command and look at the output:</p>
<p><span class="edit_monospace">I2C&gt;<strong style="color: red;">{0x3A 0x0D {0x3B r}</strong><br />
	{0x3A 0x0D {0x3B r}<br />
	I2C START BIT<br />
	WRITE: 0x3A ACK<br />
	WRITE: 0x0D ACK<br />
	I2C START BIT<br />
	WRITE: 0x3B ACK<br />
	<strong>READ: 0x1D</strong> NACK<br />
	I2C STOP BIT</span></p>
<p>Now let me explain the BusPirate commands:</p>
<p>{ &#8211; sends a I2C start condition (ST)</p>
<p>} &#8211; send a I2C stop condition (SP)</p>
<p>0x3A 0x0D 0x3B are simply hex numbers representing bytes sent over the bus</p>
<p>r &#8211; reads one byte</p>
<p>There&#39;s no need to send the NAK signal, BusPirate will do it for you and also it will detect and display any AK(ACK) signals received from the slave (the accelerometer).</p>
<p>If this looks like magic to you right now , the following diagram will clarify things, it shows how I used the datasheet in order to construct a BusPirate command that would read one register. The register I am reading is $0D , which happens to be the device address, it should return $1D which is the I2C address for MMA7456L.</p>
<p><img alt="bus pirate i2c timing diagram" height="433" src="/wp-content/uploads/data/bus_pirate_i2c_tutorial/bus_pirate_i2c_tutorial.png" width="735" /></p>
<p>Now let&#39;s talk about writing a byte on the I2C bus.</p>
<p>Before getting acceleration data , we need to put MMA7456L into measurement mode, we also need to specify the sensibility for which there are 3 options 2g/4g/8g. This configuration is done through the Mode Control Register $16 (get the details from <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;ved=0CAYQFjAA&amp;url=http%3A%2F%2Fwww.freescale.com%2Ffiles%2Fsensors%2Fdoc%2Fdata_sheet%2FMMA7456L.pdf&amp;ei=oPp_S4fjOY_T8Abh1bGHBQ&amp;usg=AFQjCNGNzsWiW40VGH6FwGZ9fN5lSUbYlw&amp;sig2=HNX96KK5hB-cLjoAekWL5w" target="_blank">MMA7456L datasheet</a> , page 9). For our settings we need to send the binary value of : 0b00000101 which sets mode to &quot;measurement&quot;, and g-select to 2g. Let&#39;s do it:</p>
<p class="edit_monospace">I2C&gt;<strong style="color: red;">{0x3A 0&#215;16 0b00000101}</strong><br />
	{0x3A 0&#215;16 0b00000101}<br />
	I2C START BIT<br />
	WRITE: 0x3A ACK<br />
	WRITE: 0&#215;16 ACK<br />
	WRITE: 0&#215;05 ACK<br />
	I2C STOP BIT</p>
<p>Writing a register is even simpler than reading and I will show you how the BusPirate write command relates to the diagram from the MMA7456L datasheet:</p>
<p><a href="/wp-content/uploads/data/bus_pirate_i2c_tutorial/bus_pirate_i2c_write_command.png" target="_blank"><img alt="i2c write command"  src="/wp-content/uploads/data/bus_pirate_i2c_tutorial/bus_pirate_i2c_write_command.png" width="740" /></p>
</a><p>Now that we&#39;ve mastered reading/writing to an I2C bus , we&#39;re ready to read acceleration data. We have the option of reading 8-bit signed values from registers $06,$07,$08. These registers have a 64count/g resolution in 2g mode, meaning that an acceleration of 1 g will be represented as 64 (0&#215;40) and&nbsp; -1g will be represented as -64 (0xBF). We can read 3 consecutive registers from one command line as follows:</p>
<p class="edit_monospace">I2C&gt;<strong style="color: red;">{0x3A 0&#215;06 {0x3B r:3}</strong><br />
	{0x3A 0&#215;06 {0x3B r:3}<br />
	I2C START BIT<br />
	WRITE: 0x3A ACK<br />
	WRITE: 0&#215;06 ACK<br />
	I2C START BIT<br />
	WRITE: 0x3B ACK<br />
	READ 0&#215;03 BYTES:<br />
	<strong>0xFF ACK 0xF8 ACK 0x4A NACK</strong><br />
	I2C STOP BIT</p>
<p>So we got following accelerometer output values for X,Y,Z axes: 0xFF (-1) , 0xF8 (-8) , 0x4A (74) which divided by sensitivity of 64counts per g, give us the values in Gs ~ -0.015g , -0.125g , 1.16g . It is close to what is expected from the output when the device is in horizontal position. The Z output seems to be off. We&#39;ll double check this and deal with it later.</p>
<p>Let&#39;s tilt the device on the X axis and see if it makes any difference in output, I tilted it roughly 45 degrees so that X and Z axis modulus should be roughly close to 64/2 = 32 and Y should remain close to 0.</p>
<p><span class="edit_monospace">I2C&gt;<strong style="color: red;">{0x3A 0&#215;06 {0x3B r:3}</strong><br />
	{0x3A 0&#215;06 {0x3B r:3}<br />
	I2C START BIT<br />
	WRITE: 0x3A ACK<br />
	WRITE: 0&#215;06 ACK<br />
	I2C START BIT<br />
	WRITE: 0x3B ACK<br />
	READ 0&#215;03 BYTES:<br />
	<strong>0xD7 ACK 0xF8 ACK 0x3F NACK</strong><br />
	I2C STOP BIT</span></p>
<p>The results we got this time are X = 0xD7 (-41), Y = 0xF8 (-8), <strong>Z = 0x3F(63 !!!)</strong>, now we can see clear that Z axis reading is offset. Luckily MMA7456L offers a way to correct these values and we&#39;ll use it. From first experiment we can see it needs to be offset by 74 &#8211; 64 ~ 10 counts. We can correct the accelerometer drift (for each axis). For Z axis we&#39;ll be using 2 registers:</p>
<p>&quot;Offset drift Z value (LSB)&quot; &#8211; register $14 <br />
	&quot;Offset drift Z value (MSB)&quot; &#8211; register $15.</p>
<p>But what values should we write ? Let&#39;s start with the fact that our drift is about 10 counts, but this is in 2g scale. Scale in which drift must be specified is apparently 4g , so we need to offset Z by 10*4g/2g = 20 counts (in 4g scale) . Also our correction must be in different direction so the value to write is -20. Expressed as a signed DWORD this is 0xFFEC.</p>
<p>We&#39;ll write 2 registeres at once LSB (least significant byte) first.</p>
<p class="edit_monospace">I2C&gt;<strong style="color: red;">{0x3A 0&#215;14 0xEC 0xFF}</strong><br />
	{0x3A 0&#215;14 0xEC 0xFF}<br />
	I2C START BIT<br />
	WRITE: 0x3A ACK<br />
	WRITE: 0&#215;14 ACK<br />
	WRITE: 0xEC ACK<br />
	WRITE: 0xFF ACK<br />
	I2C STOP BIT</p>
<p>Now let&#39;s check the readings in horizontal position again.</p>
<p class="edit_monospace">I2C&gt;<strong style="color: red;">{0x3A 0&#215;06 {0x3B r:3}</strong><br />
	{0x3A 0&#215;06 {0x3B r:3}<br />
	I2C START BIT<br />
	WRITE: 0x3A ACK<br />
	WRITE: 0&#215;06 ACK<br />
	I2C START BIT<br />
	WRITE: 0x3B ACK<br />
	READ 0&#215;03 BYTES:<br />
	<strong>0xFB ACK 0xF6 ACK 0&#215;41 NACK</strong><br />
	I2C STOP BIT</p>
<p>And here you go &#8211; the value for Z axis has been corrected to 0&#215;41 (65) , close to what&#39;s expected ( 64).</p>
<p><strong><em>In Conclusion:</em></strong></p>
<p>This real life example of exploring and troubleshooting a chip with I2C interface shows what a valuable tool Bus Pirate is. Rather than bore you with a lot of theory and specs I tried to walk you through an example scenario I encountered myself. I hope that I interested you enough in Bus Pirate , accelerometers and digital interfaces in general to do your own further research of this topic.</p>
<p>//starlino//</p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/bus_pirate_i2c_tutorial.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino code for simplified Kalman filter. Using a 5DOF IMU (accelerometer and gyroscope combo)</title>
		<link>http://www.starlino.com/imu_kalman_arduino.html</link>
		<comments>http://www.starlino.com/imu_kalman_arduino.html#comments</comments>
		<pubDate>Fri, 22 Jan 2010 14:03:44 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[gyroscope]]></category>
		<category><![CDATA[imu]]></category>

		<guid isPermaLink="false">http://imu_kalman_arduino</guid>
		<description><![CDATA[<p>This article introduces an&#160; implementation of a simplified filtering algorithm that was inspired by Kalman filter. The Arduino code is tested using a 5DOF IMU unit from GadgetGangster - <a href="http://www.gadgetgangster.com/213">Acc_Gyro</a> . The theory behind this algorithm was first introduced in my <a href="imu_guide.html">Imu Guide article</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>This article introduces an&nbsp; implementation of a simplified filtering algorithm that was inspired by Kalman filter. The Arduino code is tested using a 5DOF IMU unit from GadgetGangster &#8211; <a href="http://www.gadgetgangster.com/213">Acc_Gyro</a> . The theory behind this algorithm was first introduced in my <a href="imu_guide.html">Imu Guide article</a>.</p>
<p>The <a href="http://www.gadgetgangster.com/213">Acc_Gyro</a> is mounted on a regular proto-shield on top of an Arduino Duemilanove board.</p>
<p><img alt="IMG_1359.JPG" src="/wp-content/uploads/data/imu_kalman_arduino/IMG_1359.JPG" /></p>
<p><span id="more-16"></span></p>
<p><strong>Parts needed to complete the project:</strong></p>
<p>- Arduino Duemilanove (or similar Arduino platform)<br />
	- <a href="http://www.gadgetgangster.com/213">Acc_Gyro 5DOF IMU board<br />
	</a>- Protoshield (optional)<br />
	- Breadboard<br />
	- Hook-up wire 22AWG</p>
<p>The hook-up diagram is as follows:</p>
<p><strong>Acc_Gyro</strong> &lt;&#8212;&gt;&nbsp; <strong>Arduino</strong><br />
	5V&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; 5V&nbsp; <br />
	GND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; GND<br />
	AX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; AN0<br />
	AY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; AN1<br />
	AZ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; AN2<br />
	GX4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; AN3&nbsp; <br />
	GY4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8212;&gt;&nbsp; AN4&nbsp;&nbsp;</p>
<p>Once you have completed the hardware part, load the following sketch to your Arduino.</p>
<p><a href="data/imu_kalman_arduino/Imu_Arduino.zip">imu_arduino.zip</a></p>
<p>Run the project and make sure you are receiving an output on your serial terminal (you can start the terminal from your Arduino IDE).</p>
<p>To analyze the data I have developed a small utility called SerialChart. It is open-source so feel free to customize it for your own needs.</p>
<p>Here is the output from SerialChart software:</p>
<p><img alt="imu_arduino_serial_chart.png" src="/wp-content/uploads/data/imu_kalman_arduino/imu_arduino_serial_chart.png" /></p>
<p>&nbsp;</p>
<p>The test was performed as follows:</p>
<p>- first I was tilting the board slowly (marked &quot;smooth tilting&quot; on the screenshot)</p>
<p>- next I continued tilting the board, but I also started applying some vibration &#8211; by tapping the board quickly with my finger (marked &quot;Titlting with vibration noise&quot;)</p>
<p>As you can see from the chart the filtered&nbsp; signal (red line)&nbsp; is indeed more immune to noise than the accelerometer readings alone (blue line). The filtered signal was obtained by combining the Accelerometer and Gyroscope data. Gyroscope data is important, because if you would simply average the Accelerometer data you would get a delayed signal. Given the simplicity of the code and of the algorithm I am satisfied with the results. One feature that I would like to add is compensation for the drift effect that you might encounter with some gyroscopes. However the Acc_Gyro board proved to be very stable in this respect, since it has built-in high pass filters.</p>
<p>If you&#39;d like to experiment on your own, I recommended first reproducing this testing setup ,&nbsp; then shift slowly towards your application needs. For example you may take the C code and port it to PIC&#39;s C18/C30 or AVR-GCC (it shouldn&#39;t be too dificult).</p>
<p>Below are some useful resources and their descriptions.</p>
<p>SerialChart executables can be downloaded from here:</p>
<p><a href="data/imu_kalman_arduino/SerialChart_01.zip">SerialChart_01.zip</a></p>
<p>Once you start SerialChart application you will need to load the <strong>imu_arduino.scc</strong> configuration file for this project(included in the <a href="data/imu_kalman_arduino/Imu_Arduino.zip">imu_arduino.zip</a>) archive.</p>
<p>In this configuration file make sure to update the &#39;port&#39; settings to Arduino&#39;s COM port. On my computer Arduino was detected on COM3, on yours it might be different.</p>
<p>For more information on configuration file syntax see:</p>
<p><a href="http://code.google.com/p/serialchart/wiki/ConfigurationFileSyntax" target="_blank">http://code.google.com/p/serialchart/wiki/ConfigurationFileSyntax</a></p>
<p>You can also download and compile SerialChart from Google Code:</p>
<p><a href="http://code.google.com/p/serialchart/source/browse/#svn/trunk">http://code.google.com/p/serialchart/source/browse/#svn/trunk</a></p>
<p>You will need a SVN client to checkout the code (I use RapidSVN for Windows).</p>
<p>SerialChart was developed using&nbsp; Qt SDK from Nokia: <a href="http://qt.nokia.com/downloads">http://qt.nokia.com/downloads</a></p>
<p>&nbsp;</p>
<p><strong>UPDATE 2010-03-18</strong></p>
<p>Many people ask me what about the other 2 axis, here is the code that outputs 3 axis, including the SerialChart configuration script.</p>
<p><a href="data/imu_kalman_arduino/Imu_Arduino_3axis_output_2010-03-18.zip">Imu_Arduino_3axis_output_2010-03-18.zip</a></p>
<p>I also removed some overhead code that Alex pointed out in the comments, this reduced the interval between samples.</p>
<p>In the example below I rotate the board around the X axis(blue) which is parallel to the ground.I do it by hand so X is not exactly 0, but close. The axes that change are Y(red) and Z(green).&nbsp; Please note the relationship X^2+Y^2+Z^2 = 1. The dashed&nbsp; cyan, magenta and lime lines are unfiltered signals coming from accelerometer alone (RwAcc).</p>
<p><img alt="imu_kalman_arduino_3_axis_captured.png" src="/wp-content/uploads/data/imu_kalman_arduino/imu_kalman_arduino_3_axis_captured.png" /></p>
<p>&nbsp;</p>
<p>//starlino//</p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/imu_kalman_arduino.html/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>A Guide To using  IMU (Accelerometer and Gyroscope Devices)  in Embedded Applications.</title>
		<link>http://www.starlino.com/imu_guide.html</link>
		<comments>http://www.starlino.com/imu_guide.html#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:39:13 +0000</pubDate>
		<dc:creator>starlino</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[accelerometer]]></category>
		<category><![CDATA[Acc_Gyro]]></category>
		<category><![CDATA[gyroscope]]></category>
		<category><![CDATA[imu]]></category>
		<category><![CDATA[motion]]></category>

		<guid isPermaLink="false">http://imu_guide</guid>
		<description><![CDATA[<p>This article discussed the theory behind accelerometer and gyroscope devices. It shows a simple&#160; Kalman filter alternative, that allows you to combine accelerometer and gyroscope data in order to obtain more accurate estimates about the inclination of the device relative to the ground plane.</p>]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This guide is intended to everyone interested in inertial MEMS (Micro-Electro-Mechanical Systems) sensors, in particular Accelerometers and Gyroscopes as well as combination IMU devices (<a href="http://en.wikipedia.org/wiki/Inertial_measurement_unit" title="Inertial Measurment Unit">Inertial Measurement Unit</a>).</p>
<p>I&#39;ll try try to cover few basic but important topics in this article:</p>
<p>- what does an accelerometer measure<br />
	- what does a gyroscope (aka gyro) measure <br />
	- how to convert analog-to-digital (ADC) readings that you get from these sensor to physical units (those would be g for accelerometer, deg/s for gyroscope)<br />
	- how to combine accelerometer and gyroscope readings in order to obtain accurate information about the inclination of your device relative to the ground plane</p>
<p><span id="more-15"></span>Throughout the article I will try to keep the math to the minimum. If you know what Sine/Cosine/Tangent are then you should be able to understand and use these ideas in your project no matter what platform you&#39;re using Arduino, Propeller, Basic Stamp, Atmel chips, Microchip PIC, etc. There are people out there who believe that you need complex math in order to make use of an IMU unit (complex FIR or IIR filters such as Kalman filters, Parks-McClellan filters, etc). You can research all those and achieve wonderful but complex results. My way of explaining things require just basic math. I am a great believer in simplicity. I think a system that is simple is easier to control and monitor, besides many embedded devices do not have the power and resources to implement complex algorithms requiring matrix calculations.</p>
<p>I&#39;ll use as an example a new IMU unit that GadgetGangster just launched &#8211; the <a href="http://www.gadgetgangster.com/213" target="_blank" title="Acc_Gyro Accelerometer + Gyro IMU">Acc_Gyro Accelerometer + Gyro IMU.</a> We&#39;ll use parameters of this device in our examples below. This unit is a good device to start with because it consists of 2 devices:</p>
<p>- LIS331AL (<a href="http://www.st.com/stonline/books/pdf/docs/13947.pdf" rel="nofollow" target="_blank">data sheet</a>) &#8211; a triaxial 2G accelerometer <br />
	- LPR550AL (<a href="http://www.st.com/stonline/books/pdf/docs/15813.pdf" rel="nofollow" target="_blank">data sheet</a>) &#8211; a dual-axis pitch and roll, 500 deg/sec gyroscope</p>
<p>Together they represent a 5-Degrees of Freedom Inertial Measurement Unit. Now that&#39;s a fancy name! Nevertheless, behind the fancy name is a very useful combination device that we&#39;ll cover and explain in detail below.</p>
<h2>Part 1. Accelerometer</h2>
<p>To understand this unit we&#39;ll start with the accelerometer. When thinking about accelerometers it is often useful to image a box in shape of a cube with a ball inside it. You may imagine something else like a cookie or a donut , but I&#39;ll imagine a ball:</p>
<p><img alt="accelerometer model" height="310" src="/wp-content/uploads/data/imu_guide/04.png" width="450" /></p>
<p>If we take this box in a place with no gravitation fields or for that matter with no other fields that might affect the ball&#39;s position &#8211; the ball will simply float in the middle of the box. You can imagine the box is in outer-space far-far away from any cosmic bodies, or if such a place is hard to find imagine at least a space craft orbiting around the planet where everything is in weightless state . From the picture above you can see that we assign to each axis a pair of walls (we removed the wall Y+ so we can look inside the box). Imagine that each wall is pressure sensitive. If we move suddenly the box to the left (we accelerate it with acceleration 1g = 9.8m/s^2), the ball will hit the wall X-. We then measure the pressure force that the ball applies to the wall and output a value of -1g on the X axis.</p>
<p><img alt="accelerometer model" height="280" src="/wp-content/uploads/data/imu_guide/05.png" width="450" /></p>
<p>Please note that the accelerometer will actually detect a force that is directed in the opposite direction from the acceleration vector. This force is often called <a href="http://en.wikipedia.org/wiki/Fictitious_force">Inertial Force or Fictitious Force </a>. One thing you should learn from this is that an accelerometer measures acceleration indirectly through a force that is applied to one of it&#39;s walls (according to our model, it might be a spring or something else in real life accelerometers). This force can be caused by the acceleration , but as we&#39;ll see in the next example it is not always caused by acceleration.</p>
<p>If we take our model and put it on Earth the ball will fall on the Z- wall and will apply a force of 1g on the bottom wall, as shown in the picture below:</p>
<p><img alt="accelerometer model" height="300" src="/wp-content/uploads/data/imu_guide/06.png" width="450" /></p>
<p>In this case the box isn&#39;t moving but we still get a reading of -1g on the Z axis. The pressure that the ball has applied on the wall was caused by a gravitation force. In theory it could be a different type of force &#8211; for example, if you imagine that our ball is metallic, placing a magnet next to the box could move the ball so it hits another wall. This was said just to prove that in essence accelerometer measures force not acceleration. It just happens that acceleration causes an inertial force that is captured by the force detection mechanism of the accelerometer.</p>
<p>While this model is not exactly how a MEMS sensor is constructed it is often useful in solving accelerometer related problems. There are actually similar sensors that have metallic balls inside, they are called tilt switches, however they are more primitive and usually they can only tell if the device is inclined within some range or not, not the extent of inclination.</p>
<p>So far we have analyzed the accelerometer output on a single axis and this is all you&#39;ll get with a single axis accelerometers. The real value of triaxial accelerometers comes from the fact that they can detect inertial forces on all three axes. Let&#39;s go back to our box model, and let&#39;s rotate the box 45 degrees to the right. The ball will touch 2 walls now: Z- and X- as shown in the picture below:</p>
<p><img alt="accelerometer model" height="390" src="/wp-content/uploads/data/imu_guide/07.png" width="450" /></p>
<p>The values of 0.71 are not arbitrary, they are actually an approximation for SQRT(1/2). This will become more clear as we introduce our next model for the accelerometer.</p>
<p>In the previous model we have fixed the gravitation force and rotated our imaginary box. In last 2 examples we have analyzed the output in 2 different box positions, while the force vector remained constant. While this was useful in understanding how the accelerometer interacts with outside forces, it is more practical to perform calculations if we fix the coordinate system to the axes of the accelerometer and imagine that the force vector rotates around us.</p>
<p><img alt="accelerometer model" height="370" src="/wp-content/uploads/data/imu_guide/01.png" width="450" /></p>
<p>Please have a look at the model above, I preserved the colors of the axes so you can make a mental transition from the previous model to the new one. Just imagine that each axis in the new model is perpendicular to the respective faces of the box in the previous model. The vector R is the force vector that the accelerometer is measuring (it could be either the gravitation force or the inertial force from the examples above or a combination of both). Rx, Ry, Rz are projection of the R vector on the X,Y,Z axes. Please notice the following relation:</p>
<p>R^2 = Rx^2 + Ry^2 + Rz^2 <strong>&nbsp;&nbsp;&nbsp;&nbsp;(Eq. 1)</strong></p>
<p>which is basically the equivalent of the <a href="http://demonstrations.wolfram.com/PythagoreanTheorem3D/">Pythagorean theorem in 3D</a>.</p>
<p>Remember that a little bit earlier I told you that the values of SQRT(1/2) ~ 0.71 are not random. If you plug them in the formula above, after recalling that our gravitation force was 1 g we can verify that:</p>
<p>1^2 = (-SQRT(1/2) )^2 + 0 ^2 + (-SQRT(1/2))^2</p>
<p>simply by substituting R=1, Rx = -SQRT(1/2), Ry = 0 , Rz = -SQRT(1/2) in <strong>Eq.1</strong></p>
<p>After a long preamble of theory we&#39;re getting closer to real life accelerometers. The values Rx, Ry, Rz are actually linearly related to the values that your real-life accelerometer will output and that you can use for performing various calculations.</p>
<p>Before we get there let&#39;s talk a little about the way accelerometers will deliver this information to us. Most accelerometers will fall in two categories: digital and analog. Digital accelerometers will give you information using a serial protocol like I2C , SPI or USART, while analog accelerometers will output a voltage level within a predefined range that you have to convert to a digital value using an ADC (analog to digital converter) module. I will not go into much detail about how ADC works, partly because it is such an extensive topic and partly because it is different from one platform to another. Some microcontroller will have a built-in ADC modules some of them will need external components in order to perform the ADC conversions. No matter what type of ADC module you use you&#39;ll end up with a value in a certain range. For example a 10-bit ADC module will output a value in the range of 0..1023, note that 1023 = 2^10 -1. A 12-bit ADC module will output a value in the range of 0..4095, note that 4095 = 2^12-1.</p>
<p>Let&#39;s move on by considering a simple example, suppose our 10bit ADC module gave us the following values for the three accelerometer channels (axes):</p>
<p>AdcRx = 586<br />
	AdcRy = 630<br />
	AdcRz = 561</p>
<p>Each ADC module will have a reference voltage, let&#39;s assume in our example it is 3.3V. To convert a 10bit adc value to voltage we use the following formula:</p>
<p>VoltsRx = AdcRx * Vref / 1023</p>
<p>A quick note here: that for 8bit ADC the last divider would be 255 = 2 ^ 8 -1 , and for 12bit ADC last divider would be 4095 = 2^12 -1.</p>
<p>Applying this formula to all 3 channels we get:</p>
<p>VoltsRx = 586 * 3.3V / 1023 =~ 1.89V (we round all results to 2 decimal points)<br />
	VoltsRy = 630 * 3.3V / 1023 =~ 2.03V<br />
	VoltsRz = 561 * 3.3V / 1023 =~ 1.81V</p>
<p>Each accelerometer has a zero-g voltage level, you can find it in specs, this is the voltage that corresponds to 0g. To get a signed voltage value we need to calculate the shift from this level. Let&#39;s say our 0g voltage level is VzeroG = 1.65V. We calculate the voltage shifts from zero-g voltage as follows::</p>
<p>DeltaVoltsRx = 1.89V &#8211; 1.65V = 0.24V<br />
	DeltaVoltsRy = 2.03V &#8211; 1.65V = 0.38V<br />
	DeltaVoltsRz = 1.81V &#8211; 1.65V = 0.16V</p>
<p>We now have our accelerometer readings in Volts , it&#39;s still not in g (9.8 m/s^2), to do the final conversion we apply the accelerometer sensitivity, usually expressed in mV/g. Lets say our Sensitivity = 478.5mV/g = 0.4785V/g. Sensitivity values can be found in accelerometer specifications. To get the final force values expressed in g we use the following formula:</p>
<p>Rx = DeltaVoltsRx / Sensitivity</p>
<p>Rx = 0.24V / 0.4785V/g =~ 0.5g<br />
	Ry = 0.38V / 0.4785V/g =~ 0.79g<br />
	Rz = 0.16V / 0.4785V/g =~ 0.33g</p>
<p>We could of course combine all steps in one formula, but I went through all the steps to make it clear how you go from ADC readings to a force vector component expressed in g.</p>
<p>Rx = (AdcRx * Vref / 1023 &#8211; VzeroG) / Sensitivity <strong>(Eq.2</strong>)<br />
	Ry = (AdcRy * Vref / 1023 &#8211; VzeroG) / Sensitivity<br />
	Rz = (AdcRz * Vref / 1023 &#8211; VzeroG) / Sensitivity</p>
<p>We now have all 3 components that define our inertial force vector, if the device is not subject to other forces other than gravitation, we can assume this is the direction of our gravitation force vector. If you want to calculate inclination of device relative to the ground you can calculate the angle between this vector and Z axis. If you are also interested in per-axis direction of inclination you can split this result into 2 components: inclination on the X and Y axis that can be calculated as the angle between gravitation vector and X / Y axes. Calculating these angles is more simple than you might think, now that we have calculated the values for Rx,Ry and Rz. Let&#39;s go back to our last accelerometer model and do some additional notations:</p>
<p><img alt="" height="370" src="/wp-content/uploads/data/imu_guide/02.png" width="450" /></p>
<p>The angles that we are interested in are the angles between X,Y,Z axes and the force vector R. We&#39;ll define these angles as Axr, Ayr, Azr. You can notice from the right-angle triangle formed by R and Rx that:</p>
<p>cos(Axr) = Rx / R , and similarly :<br />
	cos(Ayr) = Ry / R<br />
	cos(Azr) = Rz / R</p>
<p>We can deduct from <strong>Eq.1</strong> that R = SQRT( Rx^2 + Ry^2 + Rz^2).</p>
<p>We can find now our angles by using arccos() function (the inverse cos() function ):</p>
<p>Axr = arccos(Rx/R)<br />
	Ayr = arccos(Ry/R)<br />
	Azr = arccos(Rz/R)</p>
<p>We&#39;ve gone a long way to explain the accelerometer model, just to come up to these formulas. Depending on your applications you might want to use any intermediate formulas that we have derived. We&#39;ll also introduce the gyroscope model soon, and we&#39;ll see how accelerometer and gyroscope data can be combined to provide even more accurate inclination estimations.</p>
<p>But before we do that let&#39;s do some more useful notations:</p>
<p>cosX = cos(Axr) = Rx / R<br />
	cosY = cos(Ayr) = Ry / R<br />
	cosZ = cos(Azr) = Rz / R</p>
<p>This triplet is often called <a href="http://en.wikipedia.org/wiki/Direction_cosine" target="_blank">Direction Cosine</a> , and it basically represents the unit vector (vector with length 1) that has same direction as our R vector. You can easily verify that:</p>
<p>SQRT(cosX^2 + cosY^2 + cosZ^2) = 1</p>
<p>This is a nice property since it absolve us from monitoring the modulus(length) of R vector. Often times if we&#39;re just interested in direction of our inertial vector, it makes sense to normalize it&#39;s modulus in order to simplify other calculations.</p>
<h2>Part 2. Gyroscope</h2>
<p>We&#39;re not going to introduce any equivalent box model for the gyroscope like we did for accelerometer, instead we&#39;re going to jump straight to the second accelerometer model and we&#39;ll show what does the gyroscope measure according to this model.</p>
<p><img alt="" height="380" src="/wp-content/uploads/data/imu_guide/03.png" width="450" /></p>
<p>Each gyroscope channel measures the rotation around one of the axes. For instance a 2-axes gyroscope will measure the rotation around (or some may say &quot;about&quot;) the X and Y axes. To express this rotation in numbers let&#39;s do some notations. First let&#39;s define:</p>
<p>Rxz &#8211; is the projection of the inertial force vector R on the XZ plane<br />
	Ryz &#8211; is the projection of the inertial force vector R on the YZ plane</p>
<p>From the right-angle triangle formed by Rxz and Rz, using Pythagorean theorem we get:</p>
<p>Rxz^2 = Rx^2 + Rz^2 , and similarly:<br />
	Ryz^2 = Ry^2 + Rz^2</p>
<p>also note that:</p>
<p>R^2 = Rxz^2 + Ry^2 , this can be derived from<strong> Eq.1</strong> and above equations, or it can be derived from right-angle triangle formed by R and Ryz<br />
	R^2 = Ryz^2 + Rx^2</p>
<p>We&#39;re not going to use these formulas in this article but it is useful to note the relation between all the values in our model.</p>
<p>Instead we&#39;re going to define the angle between the Z axis and Rxz, Ryz vectors as follows:</p>
<p>Axz &#8211; is the angle between the Rxz (projection of R on XZ plane) and Z axis<br />
	Ayz &#8211; is the angle between the Ryz (projection of R on YZ plane) and Z axis</p>
<p>Now we&#39;re getting closer to what the gyroscope measures. Gyroscope measures the rate of changes of the angles defined above. In other words it will output a value that is linearly related to the rate of change of these angles. To explain this let&#39;s assume that we have measured the rotation angle around axis Y (that would be Axz angle) at time t0, and we define it as Axz0, next we measured this angle at a later time t1 and it was Axz1. The rate of change will be calculated as follows:</p>
<p>RateAxz = (Axz1 &#8211; Axz0) / (t1 &#8211; t0).</p>
<p>If we express Axz in degrees, and time in seconds , then this value will be expressed in deg/s . This is what a gyroscope measures.</p>
<p>In practice a gyroscope(unless it is a special digital gyroscope) will rarely give you a value expressed in deg/s. Same as for accelerometer you&#39;ll get an ADC value that you&#39;ll need to convert to deg/s using a formula similar to <strong>Eq. 2</strong> that we have defined for accelerometer. Let&#39;s introduce the ADC to deg/s conversion formula for gyroscope (we assume we&#39;re using a 10bit ADC module , for 8bit ADC replace 1023 with 255, for 12bit ADC replace 1023 with 4095).</p>
<p>RateAxz = (AdcGyroXZ * Vref / 1023 &#8211; VzeroRate) / Sensitivity <strong>Eq.3</strong><br />
	RateAyz = (AdcGyroYZ * Vref / 1023 &#8211; VzeroRate) / Sensitivity</p>
<p>AdcGyroXZ, AdcGyroYZ &#8211; are obtained from our adc module and they represent the channels that measure the rotation of projection of R vector in XZ respectively in YZ planes, which is the equivalent to saying rotation was done around Y and X axes respectively.</p>
<p>	Vref &#8211; is the ADC reference voltage we&#39;ll use 3.3V in the example below</p>
<p>	VzeroRate &#8211; is the zero-rate voltage, in other words the voltage that the gyroscope outputs when it is not subject to any rotation, for the <a href="http://gadgetgangster.com/213" target="_blank">Acc_Gyro</a> board it is for example 1.23V (you can find this values in the specs)</p>
<p>	Sensitivity &#8211; is the sensitivity of your gyroscope it is expressed in mV / (deg / s) often written as mV/deg/s , it basically tells you how many mV will the gyroscope output increase , if you increase the rotation speed by one deg/s. The sensitivity of <a href="http://gadgetgangster.com/213" target="_blank">Acc_Gyro</a> board is for example 2mV/deg/s or 0.002V/deg/s</p>
<p>Let&#39;s take an example, suppose our ADC module returned following values:</p>
<p>AdcGyroXZ = 571<br />
	AdcGyroXZ = 323</p>
<p>Using the above formula, and using the specs parameters of <a href="http://gadgetgangster.com/213" target="_blank">Acc_Gyro</a> board we&#39;ll get:</p>
<p>RateAxz = (571 * 3.3V / 1023 &#8211; 1.23V) / ( 0.002V/deg/s) =~ 306 deg/s<br />
	RateAyz = (323 * 3.3V / 1023 &#8211; 1.23V) / ( 0.002V/deg/s) =~ -94 deg/s</p>
<p>In other words the device rotates around the Y axis (or we can say it rotates in XZ plane) with a speed of 306 deg/s and around the X axis (or we can say it rotates in YZ plane) with a speed of -94 deg/s. Please note that the negative sign means that the device rotates in the opposite direction from the conventional positive direction. By convention one direction of rotation is positive. A good gyroscope specification sheet will show you which direction is positive, otherwise you&#39;ll have to find it by experimenting with the device and noting which direction of rotation results in increasing voltage on the output pin. This is best done using an oscilloscope since as soon as you stop the rotation the voltage will drop back to the zero-rate level. If you&#39;re using a multimeter you&#39;d have to maintain a constant rotation rate for at least few seconds and note the voltage during this rotation, then compare it with the zero-rate voltage. If it is greater than the zero-rate voltage it means that direction of rotation is positive.</p>
<h2>Part 3. Putting it all together. Combining accelerometer and gyroscope data.</h2>
<p>If you&#39;re reading this article you probably acquired or are planning to acquire a IMU device, or probably you&#39;re planning to build one from separate accelerometer and gyroscope devices.</p>
<p>The first step in using a combination IMU device that combines an accelerometer and a gyroscope is to align their coordinate systems. The easiest way to do it is to choose the coordinate system of accelerometer as your reference coordinate system. Most accelerometer data sheets will display the direction of X,Y,Z axes relative to the image of the physical chip or device. For example here are the directions of X,Y,Z axes as shown in specifications for the <a href="http://gadgetgangster.com/213" target="_blank">Acc_Gyro</a> board:</p>
<p><img alt="acc_gyro axes" height="164" src="/wp-content/uploads/data/imu_guide/acc_gyro_axes.png" width="272" /></p>
<p>Next steps are:</p>
<p>- identify the gyroscope outputs that correspond to RateAxz , RateAyz values discussed above. <br />
	- determine if these outputs need to be inverted due to physical position of gyroscope relative to the accelerometer</p>
<p>Do not assume that if a gyroscope has an output marked X or Y, it will correspond to any axis in the accelerometer coordinate system, even if this output is part of an IMU unit. The best way is to test it.</p>
<p>Here is a sample sequence to determine which output of gyroscope corresponds to RateAxz value discussed above.</p>
<p>- start from placing the device in horizontal position. Both X and Y outputs of accelerometer would output the zero-g voltage (for example for <a href="http://gadgetgangster.com/213" target="_blank">Acc_Gyro</a> board this is 1.65V)<br />
	- next start rotating the device around the Y axis, another way to say it is that you rotate the device in XZ plane, so that X and Z accelerometer outputs change and Y output remains constant. <br />
	- while rotating the device at a constant speed note which gyroscope output changes, the other gyroscope outputs should remain constant<br />
	- the gyroscope output that changed during the rotation around Y axis (rotation in XZ plane) will provide the input value for AdcGyroXZ, from which we calculate RateAxz<br />
	- the final step is to ensure the rotation direction corresponds to our model, in some cases you may have to invert the RateAxz value due to physical position of gyroscope relative to the accelerometer<br />
	- perform again the above test, rotating the device around the Y axis, this time monitor the X output of accelerometer (AdcRx in our model). If AdcRx grows (the first 90 degrees of rotation from horizontal position), then AdcGyroXZ should decrease. This is due to the fact that we are monitoring the gravitation vector and when device rotates in one direction the vector will rotate in oposite direction (relative to the device coordonate system, which we are using). So, otherwise you need to invert RateAxz , you can achieve this by introducing a sign factor in <strong>Eq.3</strong>, as follows:</p>
<p>RateAxz = InvertAxz * (AdcGyroXZ * Vref / 1023 &#8211; VzeroRate) / Sensitivity , where InvertAxz is 1 or -1</p>
<p>same test can be done for RateAyz , by rotating the device around the X axis, and you can identify which gyroscope output corresponds to RateAyz, and if it needs to be inverted. Once you have the value for InvertAyz, you should use the following formula to calculate RateAyz:</p>
<p>RateAyz = InvertAyz * (AdcGyroYZ * Vref / 1023 &#8211; VzeroRate) / Sensitivity</p>
<p>If you would do these tests on <a href="http://gadgetgangster.com/213">Acc_Gyro</a> board you would get following results:</p>
<p>- the output pin for RateAxz is GX4 and InvertAxz = 1<br />
	- the output pin for RateAyz is GY4 and InvertAyz = 1</p>
<p>From this point on we&#39;ll consider that you have setup your IMU in such a way that you can calculate correct values for Axr, Ayr, Azr (as defined Part 1. Accelerometer) and RateAxz, RateAyz (as defined in Part 2. Gyroscope). Next we&#39;ll analyze the relations between these values that turn out useful in obtaining more accurate estimation of the inclination of the device relative to the ground plane.</p>
<p>You might be asking yourself by this point, if accelerometer model already gave us inclination angles of Axr,Ayr,Azr why would we want to bother with the gyroscope data ? The answer is simple: accelerometer data can&#39;t always be trusted 100%. There are several reason, remember that accelerometer measures inertial force, such a force can be caused by gravitation (and ideally only by gravitation), but it might also be caused by acceleration (movement) of the device. As a result even if accelerometer is in a relatively stable state, it is still very sensitive to vibration and mechanical noise in general. This is the main reason why most IMU systems use a gyroscope to smooth out any accelerometer errors. But how is this done ? And is the gyroscope free from noise ?</p>
<p>The gyroscope is not free from noise however because it measures rotation it is less sensitive to linear mechanical movements, the type of noise that accelerometer suffers from, however gyroscopes have other types of problems like for example drift (not coming back to zero-rate value when rotation stops). Nevertheless by averaging data that comes from accelerometer and gyroscope we can obtain a relatively better estimate of current device inclination than we would obtain by using the accelerometer data alone.</p>
<p>In the next steps I will introduce an algorithm that was inspired by some ideas used in Kalman filter, however it is by far more simple and easier to implement on embedded devices. Before that let&#39;s see first what we want our algorithm to calculate. Well , it is the direction of gravitation force vector R = [Rx,Ry,Rz] from which we can derive other values like Axr,Ayr,Azr or cosX,cosY,cosZ that will give us an idea about the inclination of our device relative to the ground plane, we discuss the relation between these values in Part 1. One might say &#8211; don&#39;t we already have these values Rx, Ry , Rz from <strong>Eq.2</strong> in Part 1 ? Well yes, but remember that these values are derived from accelerometer data only, so if you would be to use them directly in your application you might get more noise than your application can tolerate. To avoid further confusion let&#39;s re-define the accelerometer measurements as follows:</p>
<p>Racc &#8211; is the inertial force vector as measured by accelerometer, that consists of following components (projections on X,Y,Z axes):</p>
<p>RxAcc = (AdcRx * Vref / 1023 &#8211; VzeroG) / Sensitivity<br />
	RyAcc = (AdcRy * Vref / 1023 &#8211; VzeroG) / Sensitivity<br />
	RzAcc = (AdcRz * Vref / 1023 &#8211; VzeroG) / Sensitivity</p>
<p>So far we have a set of measured values that we can obtain purely from accelerometer ADC values. We&#39;ll call this set of data a &quot;vector&quot; and we&#39;ll use the following notation.</p>
<p>Racc = [RxAcc,RyAcc,RzAcc]</p>
<p>Because these components of Racc can be obtained from accelerometer data , we can consider it an input to our algorithm.</p>
<p>Please note that because Racc measures the gravitation force you&#39;ll be correct if you assume that the length of this vector defined as follows is equal or close to 1g.</p>
<p>|Racc| = SQRT(RxAcc^2 +RyAcc^2 + RzAcc^2),</p>
<p>However to be sure it makes sense to update this vector as follows:</p>
<p>Racc(normalized) = [RxAcc/|Racc| , RyAcc/|Racc| , RzAcc/|Racc|].</p>
<p>This will ensure the length of your normalized Racc vector is always 1.</p>
<p>Next we&#39;ll introduce a new vector and we&#39;ll call it</p>
<p>Rest = [RxEst,RyEst,RzEst]</p>
<p>This will be the output of our algorithm , these are corrected values based on gyroscope data and based on past estimated data.</p>
<p>Here is what our algorithm will do:<br />
	- accelerometer tells us: &quot;You are now at position Racc&quot;<br />
	- we say &quot;Thank you, but let me check&quot;,<br />
	- then correct this information with gyroscope data as well as with past Rest data and we output a new estimated vector Rest. <br />
	- we consider Rest to be our &quot;best bet&quot; as to the current position of the device.</p>
<p>Let&#39;s see how we can make it work.</p>
<p>We&#39;ll start our sequence by trusting our accelerometer and assigning:</p>
<p>Rest(0) = Racc(0)</p>
<p>By the way remember Rest and Racc are vectors , so the above equation is just a simple way to write 3 sets of equations, and avoid repetition:</p>
<p>RxEst(0) = RxAcc(0)<br />
	RyEst(0) = RyAcc(0)<br />
	RzEst(0) = RzAcc(0)</p>
<p>Next we&#39;ll do regular measurements at equal time intervals of T seconds, and we&#39;ll obtain new measurements that we&#39;ll define as Racc(1), Racc(2) , Racc(3) and so on. We&#39;ll also issue new estimates at each time intervals Rest(1), Rest(2), Rest(3) and so on.</p>
<p>Suppose we&#39;re at step n. We have two known sets of values that we&#39;d like to use:</p>
<p>Rest(n-1) &#8211; our previous estimate, with Rest(0) = Racc(0)<br />
	Racc(n) &#8211; our current accelerometer measurement</p>
<p>Before we can calculate Rest(n) , let&#39;s introduce a new measured value, that we can obtain from our gyroscope and a previous estimate.</p>
<p>We&#39;ll call it Rgyro , and it is also a vector consisting of 3 components:</p>
<p>Rgyro = [RxGyro,RyGyro,RzGyro]</p>
<p>We&#39;ll calculate this vector one component at a time. We&#39;ll start with RxGyro.</p>
<p><img alt="gyro model" height="380" src="/wp-content/uploads/data/imu_guide/03.png" width="450" /></p>
<p>Let&#39;s start by observing the following relation in our gyroscope model, from the right-angle triangle formed by Rz and Rxz we can derive that:</p>
<p>tan(Axz) = Rx/Rz =&gt; Axz = atan2(Rx,Rz)</p>
<p>Atan2 might be a function you never used before, it is similar to atan, except it returns values in range of (-PI,PI) as opposed to (-PI/2,PI/2) as returned by atan, and it takes 2 arguments instead of one. It allows us to convert the two values of Rx,Rz to angles in the full range of 360 degrees (-PI to PI). You can read more about <a href="http://en.wikipedia.org/wiki/Atan2" target="_blank">atan2 here</a>.</p>
<p>So knowing RxEst(n-1) , and RzEst(n-1) we can find:</p>
<p>Axz(n-1) = atan2( RxEst(n-1) , RzEst(n-1) ).</p>
<p>Remember that gyroscope measures the rate of change of the Axz angle. So we can estimate the new angle Axz(n) as follows:</p>
<p>Axz(n) = Axz(n-1) + RateAxz(n) * T</p>
<p>Remember that RateAxz can be obtained from our gyroscope ADC readings. A more precise formula can use an average rotation rate calculated as follows:</p>
<p>RateAxzAvg = ( RateAxz(n) + RateAxz(n-1) ) / 2 <br />
	Axz(n) = Axz(n-1) + RateAxzAvg * T</p>
<p>The same way we can find:</p>
<p>Ayz(n) = Ayz(n-1) + RateAyz(n) * T</p>
<p>Ok so now we have Axz(n) and Ayz(n). Where do we go from here to deduct RxGyro/RyGyro ? From <strong>Eq. 1</strong> we can write the length of vector Rgyro as follows:</p>
<p>|Rgyro| = SQRT(RxGyro^2 + RyGyro^2 + RzGyro^2)</p>
<p>Also because we normalized our Racc vector, we may assume that it&#39;s length is 1 and it hasn&#39;t changed after the rotation, so it is relatively safe to write:</p>
<p>|Rgyro| = 1</p>
<p>Let&#39;s adopt a temporary shorter notation for the calculations below:</p>
<p>x =RxGyro , y=RyGyro, z=RzGyro</p>
<p>Using the relations above we can write:</p>
<p>x = x / 1 = x / SQRT(x^2+y^2+z^2)</p>
<p>Let&#39;s divide numerator and denominator of fraction by SQRT(x^2 + z^2)</p>
<p>x = ( x / SQRT(x^2 + z^2) ) / SQRT( (x^2 + y^2 + z^2) / (x^2 + z^2) )</p>
<p>Note that x / SQRT(x^2 + z^2) = sin(Axz), so:</p>
<p>x = sin(Axz) / SQRT (1 + y^2 / (x^2 + z^2) )</p>
<p>Now multiply numerator and denominator of fraction inside SQRT by z^2</p>
<p>x = sin(Axz) / SQRT (1 + y^2&nbsp; * z ^2 / (z^2 * (x^2 + z^2)) )</p>
<p>Note that z / SQRT(x^2 + z^2) = cos(Axz) and y / z = tan(Ayz), so finally:</p>
<p>x = sin(Axz) / SQRT (1 + cos(Axz)^2 * tan(Ayz)^2 )</p>
<p>Going back to our notation we get:</p>
<p>RxGyro = sin(Axz(n)) / SQRT (1 + cos(Axz(n))^2 * tan(Ayz(n))^2 )</p>
<p>same way we find that</p>
<p>RyGyro = sin(Ayz(n)) / SQRT (1 + cos(Ayz(n))^2 * tan(Axz(n))^2 )</p>
<p>Now, finally we can find:</p>
<p>RzGyro&nbsp; =&nbsp; Sign(RzGyro)*SQRT(1 &#8211; RxGyro^2 &#8211; RyGyro^2).</p>
<p>Where Sign(RzGyro) = 1 when RzGyro&gt;=0 , and Sign(RzGyro) = -1 when RzGyro&lt;0.</p>
<p>One simple way to estimate this is to take:</p>
<p>Sign(RzGyro) = Sign(RzEst(n-1))</p>
<p><em>In practice be careful when RzEst(n-1) is close to 0. You may skip the gyro phase altogether in this case and assign:&nbsp; Rgyro = Rest(n-1). Rz is used as a reference for calculating Axz and Ayz angles and when it&#39;s close to 0, values may overflow and trigger bad results. You&#39;ll be in domain of large floating point numbers where tan() / atan() function implementations may lack precision.<br />
	</em></p>
<p>So let&#39;s recap what we have so far, we are at step <strong>n</strong> of our algorithm and we have calculated the following values:</p>
<p>Racc &#8211; current readings from our accelerometer<br />
	Rgyro &#8211; obtained from Rest(n-1) and current gyroscope readings</p>
<p>Which values do we use to calculate the updated estimate Rest(n) ? You probably guessed that we&#39;ll use both. We&#39;ll use a weighted average, so that:</p>
<p>Rest(n) = (Racc * w1 + Rgyro * w2 ) / (w1 + w2)</p>
<p>We can simplify this formula by dividing both numerator and denominator of the fraction by w1.</p>
<p>Rest(n) = (Racc * w1/w1 + Rgyro * w2/w1 ) / (w1/w1 + w2/w1)</p>
<p>and after substituting w2/w1 = wGyro we get:</p>
<p>Rest(n) = (Racc + Rgyro * wGyro ) / (1 + wGyro)</p>
<p>In the above formula wGyro tells us how much we trust our gyro compared to our accelerometer. This value can be chosen experimentally usually values between 5..20 will trigger good results.</p>
<p>The main difference of this algorithm from Kalman filter is that this weight is relatively fixed , whereas in Kalman filter the weights are permanently updated based on the measured noise of the accelerometer readings. Kalman filter is focused at giving you &quot;the best&quot; theoretical results, whereas this algorithm can give you results &quot;good enough&quot; for your practical application. You can implement an algorithm that adjusts wGyro depending on some noise factors that you measure, but fixed values will work well for most applications.</p>
<p>We are one step away from getting our updated estimated values:</p>
<p>RxEst(n) = (RxAcc + RxGyro * wGyro ) / (1 + wGyro)<br />
	RyEst(n) = (RyAcc + RyGyro * wGyro ) / (1 + wGyro)<br />
	RzEst(n) = (RzAcc + RzGyro * wGyro ) / (1 + wGyro)</p>
<p>Now let&#39;s&nbsp; normalize this vector again:</p>
<p>R = SQRT(RxEst(n) ^2 + RyEst(n)^2 +&nbsp; RzEst(n)^2 )</p>
<p>RxEst(n) = RxEst(n)/R<br />
	RyEst(n) = RyEst(n)/R<br />
	RzEst(n) = RzEst(n)/R</p>
<p>And we&#39;re ready to repeat our loop again.</p>
<p>&nbsp;</p>
<p><strong>Other Resources on Accelerometer and Gyroscope IMU Fusion:</strong></p>
<p><a href="http://www.mikroquad.com/pub/Research/ComplementaryFilter/filter.pdf">http://www.mikroquad.com/pub/Research/ComplementaryFilter/filter.pdf</a><strong><br />
	</strong></p>
<p><a href="imu_kalman_arduino.html">http://starlino.com/imu_kalman_arduino.html</a><strong><br />
	</strong></p>
<p><a href="http://stackoverflow.com/questions/1586658/combine-gyroscope-and-accelerometer-data">http://stackoverflow.com/questions/1586658/combine-gyroscope-and-accelerometer-data</a></p>
<p><a href="http://www.dimensionengineering.com/accelerometers.htm">http://www.dimensionengineering.com/accelerometers.htm</a></p>
<p><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=librarian06-20&amp;l=as2&amp;o=1&amp;a=1580532551" style="border: medium none ! important; margin: 0px ! important;" width="1" /></p>
<p><iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=librarian06-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=1580532551&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width: 120px; height: 240px;"></iframe></p>
<p>//starlino//</p>
]]></content:encoded>
			<wfw:commentRss>http://www.starlino.com/imu_guide.html/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
