<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Matt+Turpin</id>
	<title>Mech - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://hades.mech.northwestern.edu//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Matt+Turpin"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/Matt_Turpin"/>
	<updated>2026-04-21T00:17:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Actuators_Available_in_the_Mechatronics_Lab&amp;diff=8982</id>
		<title>Actuators Available in the Mechatronics Lab</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Actuators_Available_in_the_Mechatronics_Lab&amp;diff=8982"/>
		<updated>2008-07-08T21:21:47Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:all-actuators-captions-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
We have acquired a number of actuators that are appropriately sized for&lt;br /&gt;
many mechatronics projects.  These are the &amp;quot;standard&amp;quot; lab actuators.&lt;br /&gt;
You are welcome to borrow them for your project and return them when&lt;br /&gt;
you are finished.  In addition to the actuators mentioned below, we&lt;br /&gt;
have a number of other actuators that we have acquired over the years&lt;br /&gt;
that you are welcome to borrow.&lt;br /&gt;
&lt;br /&gt;
For your particular project, it may be best to spec out and buy a&lt;br /&gt;
particular type and size of actuator.  If your specifications are not&lt;br /&gt;
too critical, however, the actuators below will allow you to get&lt;br /&gt;
started right away.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==DC Motors (with gearheads and encoders)==&lt;br /&gt;
&lt;br /&gt;
There are many types of DC motors, but our favorites are brushed&lt;br /&gt;
permanent magnet DC motors for their power, price, ubiquity, and&lt;br /&gt;
simplicity.  Simply put a voltage across the two motor terminals, and&lt;br /&gt;
the motor spins.  (You can learn about the&lt;br /&gt;
theory of how a brushed DC &lt;br /&gt;
motor works and suggested methods&lt;br /&gt;
for driving a DC motor elsewhere on this wiki.)  &lt;br /&gt;
&lt;br /&gt;
One problem is that most DC motors tend to rotate at very high speeds,&lt;br /&gt;
typically several thousand RPM or more.  This is too fast for most&lt;br /&gt;
mechatronics applications.  Also, they tend to have too little torque.&lt;br /&gt;
Both of these problems can be solved by the use of gears on the output&lt;br /&gt;
shaft of the motor.  If the motor has an N:1 gearhead on its output&lt;br /&gt;
shaft (where N&amp;gt;1, typically), then the output shaft of the gearhead&lt;br /&gt;
reduces the speed of the motor by a factor of N and icreases the&lt;br /&gt;
torque of the motor by a factor of N.  (You can learn more&lt;br /&gt;
about how gears work including other issues&lt;br /&gt;
they introduce, such as gearhead efficiency and backlash.)&lt;br /&gt;
&lt;br /&gt;
Another issue is how to determine how far the motor has rotated.  You need&lt;br /&gt;
&amp;#039;&amp;#039;feedback&amp;#039;&amp;#039; from the motor.  There are many ways to do this; see&lt;br /&gt;
here for information on using&lt;br /&gt;
encoders, potentiometers, and tachometers.  The most common way to get angle&lt;br /&gt;
feedback is through the use of encoders.  An encoder is typically attached&lt;br /&gt;
to a motor shaft and produces pulses that encode the shaft rotation angle.&lt;br /&gt;
These pulses can be read in by the encoder inputs of the Mechatronics Lab&lt;br /&gt;
PC/104 stacks.&lt;br /&gt;
&lt;br /&gt;
So, perhaps the most versatile kind of actuator is a DC motor with a gearhead and an&lt;br /&gt;
encoder.  Below are some that we keep in the lab.  Sometimes DC motors&lt;br /&gt;
with gearheads and encoders can be purchased through surplus outlets at&lt;br /&gt;
great prices, for prices less than any of the single components (motor,&lt;br /&gt;
gearhead, encoder) could be purchased individually.  That&amp;#039;s how many&lt;br /&gt;
copies of the actuators below were purchased.  If you see a great&lt;br /&gt;
deal on a nice-sized motor plus gearhead plus encoder, of which many&lt;br /&gt;
copies can be purchased, let us know!&lt;br /&gt;
&lt;br /&gt;
===6W Maxon motor with 6:1 gearhead and 100 line encoder===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:maxon-small2.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 24 V, 41.5 ohms resistance, max current 0.58 Amps&lt;br /&gt;
* max torque:  0.15 Nm (approx)&lt;br /&gt;
* max speed:  600 RPM (approx)&lt;br /&gt;
* encoder:  600 counts/rev at output shaft, 2400 counts/rev in 4x decoding mode&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The motor is rated at 24 volts, giving a no-load (maximum)&lt;br /&gt;
speed of 3990 RPM (about 418 radians/sec) and a (maximum) stall torque of 31.9 mNm (milli&lt;br /&gt;
Newton meters).  The terminal resistance (the resistance through the&lt;br /&gt;
motor windings) is 41.5 ohms.  This means if you put 24 V across it,&lt;br /&gt;
the maximum current that it will draw is 24/41.5 = 0.58 Amps.  This&lt;br /&gt;
maximum current occurs when the motor is stalled and generating its&lt;br /&gt;
maximum torque.  Motor torque is proportional to the motor current by&lt;br /&gt;
the constant of proportionality called the &amp;#039;&amp;#039;torque constant&amp;#039;&amp;#039;,&lt;br /&gt;
which is different for every motor.&lt;br /&gt;
&lt;br /&gt;
The motor is called a 6 Watt motor because that is the maximum&lt;br /&gt;
electrical power (current times voltage) that can be put into the&lt;br /&gt;
motor on a continuous basis.  Beyond this power level, the amount of&lt;br /&gt;
power dissipated by the resistance of the motor windings will cause&lt;br /&gt;
the windings to heat up unacceptably.  (It is fine to overpower the&lt;br /&gt;
motor intermittently, allowing the coils to cool so that the average&lt;br /&gt;
power does not exceed the rated power.)  At this operating point, &lt;br /&gt;
the motor draws 244 mA, giving 24 V x 0.244 A = 5.86 W electrical input&lt;br /&gt;
power.  At this operating point, the speed of the motor is approximately&lt;br /&gt;
1689 RPM, or 177 radians/sec, and the torque of the motor is 13.5 mNm,&lt;br /&gt;
giving 177 rad/sec x 0.0135 Nm = 2.39 W of mechanical output power,&lt;br /&gt;
giving a power-conversion efficiency of about 41% at this operating point.&lt;br /&gt;
The maximum efficiency of the motor is 70%, which occurs at a higher&lt;br /&gt;
speed and lower torque.  The maximum mechanical power you can get out&lt;br /&gt;
of the motor is (1/2 max torque) x (1/2 max speed) = 3.33 W.  This is&lt;br /&gt;
beyond the continuous operation recommendation, but it is fine to&lt;br /&gt;
run it for short periods at this operating point.&lt;br /&gt;
&lt;br /&gt;
Often you will want to run the motor at lower voltages, for instance&lt;br /&gt;
at 12 V, instead of the rated 24 V.  In this case just multiply the&lt;br /&gt;
max current, speed, and torques by the factor 12/24 = 1/2.  In particular,&lt;br /&gt;
the maximum output power will be only (1/2) x (1/2) = 1/4 the maximum at 24 V.&lt;br /&gt;
&lt;br /&gt;
This actuator comes with a 6:1 spur gearhead, which increases the&lt;br /&gt;
torque available at the gearhead&amp;#039;s output shaft by a factor of 6 and&lt;br /&gt;
decreases the speed by a factor of 6.  (In this ideal case, the&lt;br /&gt;
power at the gearhead&amp;#039;s output shaft is equal to the power at the input.&lt;br /&gt;
In practice, gearheads have an efficiency also; the maximum&lt;br /&gt;
efficiency of the gearhead here is 81%.  This reduces the torque&lt;br /&gt;
available.)&lt;br /&gt;
&lt;br /&gt;
In summary, then, if your application requires no more than about 6 x&lt;br /&gt;
31.9 mNm = 0.19 Nm maximum torque, 3990 RPM / 6 = 665 RPM max speed,&lt;br /&gt;
and 3.3 W max mechanical power, this may be the motor for you.&lt;br /&gt;
Reduce those values by a factor of 1/2, 1/2, and 1/4, respectively, if&lt;br /&gt;
you are operating the motor with 12 V max instead of 24 V max.&lt;br /&gt;
&lt;br /&gt;
This actuator also comes with 100 line single-ended incremental optical encoder,&lt;br /&gt;
with outputs A+ and B+.  There is no index channel.  The encoder is&lt;br /&gt;
attached to the motor.  Each of the A+ and B+ channels makes 100 pulses&lt;br /&gt;
per revolution of the motor, or 6 x 100 = 600 pulses per revolution of&lt;br /&gt;
the output shaft of the gearhead.  This means the encoder provides&lt;br /&gt;
360 deg / 600 pulses = 0.6 deg/pulse resolution when the pulses are &lt;br /&gt;
decoded with the 1x scheme, or 0.15 deg/pulse resolution with the 4x&lt;br /&gt;
decoding scheme.&lt;br /&gt;
&lt;br /&gt;
Information about the Maxon motor is given in this [[Media:maxon-2140-specs.pdf|data sheet]] which includes &lt;br /&gt;
other motors in this family (ours is the 24V version)&lt;br /&gt;
and this [[Media:maxon-our-specific-motor.pdf|data sheet]] which gives only&lt;br /&gt;
the information on this motor.  (Note the speed-torque curve is a bit misleading,&lt;br /&gt;
as it seems to imply the maximum speed of the motor is 6100 RPM, when it should&lt;br /&gt;
be 3990 RPM.)  Information on the 6:1 gearhead can be found &lt;br /&gt;
[[Media:maxon-gearhead.pdf|here]].  The encoder pin-out is indicated below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:encoder-maxon.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The encoder comes with a 4-connector ribbon cable, corresponding to GND, Channel A, Vcc (usually +5V), and Channel B, as&lt;br /&gt;
shown on the left.  Here the ribbon cable is broken out into a 10-pin connector (which we have in the lab).  The connector&lt;br /&gt;
above is made to work with the PC/104 stacks, and the pin-out is shown.  Always make sure you have the right connections&lt;br /&gt;
for your encoder so you don&amp;#039;t damage it!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Pittman GM8224 motor with 19.5:1 gearhead and 500 line encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:pittman-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
If you need more power than the motor above, this gearmotor may be a good choice.&lt;br /&gt;
As an added bonus, it provides much higher encoder resolution.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 24 V, 4.33 ohms resistance, max current 5.54 Amps&lt;br /&gt;
* max torque:  2 Nm (approx)&lt;br /&gt;
* max speed:  500 RPM (approx)&lt;br /&gt;
* encoder:  9750 counts/rev at output shaft, 39,000 counts/rev in 4x decoding mode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This motor is also rated at 24 V, with a terminal resistance of 4.33 ohms,&lt;br /&gt;
giving a stall (maximum) current of 5.54 Amps.  The stall torque of the motor&lt;br /&gt;
itself is 0.1186 Nm&lt;br /&gt;
and the no-load (maximum) speed is 10,158 RPM (1064 radians/sec).  The&lt;br /&gt;
recommended maximum continuous torque is 0.0185 Nm which occurs at &lt;br /&gt;
8573 RPM (898 radians/sec).  Taken together, the maximum motor mechanical power&lt;br /&gt;
is (1/2 Tmax) x (1/2 nmax) = 31.5 W and the maximum recommended continuous&lt;br /&gt;
mechanical power is 16.6 W.  The maximum electrical input power occurs when&lt;br /&gt;
the motor is stalled (or starting) and is 24 V x 5.54 A = 133 W.  If you&lt;br /&gt;
operate the motor at a smaller voltage V2, then multiply the currents, speeds,&lt;br /&gt;
and torques above by a factor V2/24 and the power by a factor of (V2/24)^2.&lt;br /&gt;
&lt;br /&gt;
This motor has a 19.5:1 gearhead with a power conversion efficiency of 73%.  &lt;br /&gt;
Ignoring the efficiency for the moment, the 19.5:1 gearbox means that this&lt;br /&gt;
actuator may be appropriate if our application calls for no more than a &lt;br /&gt;
maximum speed of 10,158 RPM / 19.5 = 521 RPM and a maximum torque of&lt;br /&gt;
0.1186 Nm x 19.5 = 2.3 Nm.  In other words, the output shaft speed is similar&lt;br /&gt;
to the Maxon gearmotor above, but with about 10 times the torque.  &lt;br /&gt;
&lt;br /&gt;
This motor comes with a 500 line encoder attached to the motor shaft.  The&lt;br /&gt;
encoder has output channels A+ and B+ (no index pulse).  This means that&lt;br /&gt;
the encoder provides 500 x 19.5 = 9750 pulses per revolution of the output shaft.&lt;br /&gt;
In the 4x decoding mode, this gives 39,000 counts per revolution, or a resolution&lt;br /&gt;
of 360/39,000 = 0.00923 degrees.&lt;br /&gt;
&lt;br /&gt;
We also have a limited number of Pittman GM8712 motors with a 19.5:1 gearhead&lt;br /&gt;
and 512 line encoder.  These motors are also rated at 24V but have a higher&lt;br /&gt;
terminal resistance of 12.1 ohms, giving a maximum current of 24/12.1 = 1.99 Amps.&lt;br /&gt;
They have a maximum speed of 7847 RPM and maximum torque of 0.052 Nm before the&lt;br /&gt;
gearhead, or (ignoring gearhead efficiency) 402 RPM and 1.01 Nm after the&lt;br /&gt;
gearhead.  This motor is less powerful and draws less current, which may&lt;br /&gt;
be appropriate for some applications.&lt;br /&gt;
The encoder provides 9984 pulses per revolution of the output shaft&lt;br /&gt;
of the gearhead, or 360/(4 x 9984) = 0.009 degrees resolution in 4x decoding mode.&lt;br /&gt;
&lt;br /&gt;
See the [[Media:pittmangearmotor.pdf|data sheet]] for more detailed&lt;br /&gt;
information on these Pittman 8224 and 8712 gearmotors.  The 8712 is not treated&lt;br /&gt;
explicitly, but is believed to be similar to the 8722.&lt;br /&gt;
&lt;br /&gt;
The quadrature encoder has four wires:  black (GND), red (+5V), and blue and yellow as &lt;br /&gt;
channels A and B.&lt;br /&gt;
&lt;br /&gt;
===Faulhaber 1524E006S motor with 141:1 gearhead and HES164A magnetic quadrature encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber.png|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* motor rated at 6V, 12 ohms resistance (motor: 1524E006S123, where 123 is a special order)&lt;br /&gt;
* 141:1 gearhead (gearhead:  15/5S141:1K832)&lt;br /&gt;
* max speed at 6V:  approximately 80 RPM at gearhead output&lt;br /&gt;
* quadrature encoder with 1 line per motor revolution, or 141 x 4 = 564 counts/rev at output shaft in 4x decoding mode (encoder:  HES164A)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This little motor is the right size, speed, and torque for small wheeled mobile robots.&lt;br /&gt;
Ours were bought surplus from [http://www.bgmicro.com bgmicro.com].  This &lt;br /&gt;
[http://www.robotroom.com/FaulhaberGearmotor.html page] by&lt;br /&gt;
David Cook has a lot of great information on this motor + gearhead + encoder combination.&lt;br /&gt;
More info can be found in this [[Media:faulhaber-datasheet.pdf|data sheet]] from Faulhaber,&lt;br /&gt;
though our exact model encoder and motor are not listed.  The gearhead has a right-angle&lt;br /&gt;
drive at the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber-pinout.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
The pins on the connector are (see figure at right):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1.  Motor + &amp;lt;br&amp;gt;&lt;br /&gt;
2.  +5V (or similar) to power the encoder&amp;lt;br&amp;gt;&lt;br /&gt;
3.  Encoder channel A&amp;lt;br&amp;gt;&lt;br /&gt;
4.  Encoder channel B&amp;lt;br&amp;gt;&lt;br /&gt;
5.  GND for the encoder&amp;lt;br&amp;gt;&lt;br /&gt;
6.  Motor -&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Encoder channels A and B can sink (connect to ground) up to probably 25mA like most Hall sensors.  There is only a a weak pull-up resistor inside, perhaps 10K, so they can only source (connect to +5) about 2mA.   If you find the logic high signal from the encoder channel is not close enough to +5, which can happen even due to loading by an LED, you may want to add an external pull-up resistor from each encoder channel to +5.  470ohms is a good choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber-wheel.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
These [http://www.solarbotics.com/products/gmpw/ wheels] can be used with the motor (with the&lt;br /&gt;
right-angle drive) if you drill out the center of the wheel with a 9/32&amp;quot; bit (approximately).  Then you&lt;br /&gt;
should get a nice tight press-fit.  We have some of these wheels in the lab.  This press-fit is not &lt;br /&gt;
suitable for high-torque applications, though; the shaft may begin to slip.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Globe motor with 187.68:1 gearhead and 500 line encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:globe-motor.jpg|right|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* motor rated at 12V, 21 ohms resistance (0.57 A stall current)&lt;br /&gt;
* 187.68:1 gearhead for high torque and low speed&lt;br /&gt;
* max speed at 12V:  approximately 17 RPM at gearhead output (no load speed, motor alone:  approx 3000 RPM)&lt;br /&gt;
* torque constant (motor alone):  approximately 34 mNm/A (or 281 V/RPM)&lt;br /&gt;
* stall torque:  motor alone:  0.019 Nm; with gearhead 2.4 Nm (based on torque multiplier of 125, less than the 187 gear ratio due to efficiency losses)&lt;br /&gt;
* quadrature encoder with 500 lines per motor revolution, or 500 x 4 x 187.68 = 375,360 counts/rev at output shaft in 4x decoding mode (encoder:  HEDS-5505 A04)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small motor combines with a high resolution encoder and a high gear ratio gearbox to give a high torque, low speed actuator with high resolution position sensing (and velocity sensing by finite differencing).  The stall torque for this gearmotor (at 12 V) is approximately the same as that for the Pittman GM8224 gearmotor (at 24 V), but the max speed for the PIttman gearmotor is 20 times higher.  The pin-out for the encoder is shown below.  You can attach to the encoder using a Samtec IDSS-05-D-12.00 cable (shown in the middle below; order directly from [http://www.samtec.com Samtec], about $3.50 each) or you can make your own cable using stranded wires (22 AWG or ribbon cable) crimped or soldered in female Molex terminal pins (Molex series KK 2759, part number WM1114CT-ND on digikey) in a Molex 5 position connector housing (Molex series KK 2695, part number WM1578-ND on digikey), shown at right below.  (See [[Making a Molex Connector]] for more details.) The [[Media:HEDS5500-encoder.pdf|datasheet]] for the encoder recommends putting a 3.2k pull-up resistor on Channels A and B (i.e., 3.2k resistors from these lines to +5V).  The encoder works without these, but the datasheet indicates that you get better rise times on the encoder signals at high speeds when the pull-up resistors are added.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-encoder-cable.jpg|200px]]&lt;br /&gt;
[[image:globe-encoder-cable-molex.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
If you want a higher-speed (up to 3000 RPM at 12V) lower-torque actuator, you can try removing the gearbox.  This task takes a bit of work and may require a bit of machining.  See [[Accessing_Pinion_of_Globe_Motor|here]].&lt;br /&gt;
&lt;br /&gt;
The two motor power leads are wound through a ferrite toroid to suppress EMI &amp;quot;noise.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Here you can find a [[Media:globe-cad.pdf|cad file]] describing this actuator, a [[Media:HEDS5500-encoder.pdf|datasheet]] for the encoder, and a [[Media:idss-connector.pdf|datasheet]] for the Samtec IDSS-05-D-12.00 connector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===GM3 and GM9 Gearmotors===&lt;br /&gt;
&lt;br /&gt;
[[image:GM3.png|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;  (GM3 pictured at right)&lt;br /&gt;
* rated at 6V, approx 10 ohms resistance&lt;br /&gt;
* 224:1 gearhead (GM3) or 143:1 gearhead (GM9)&lt;br /&gt;
* max speed at 6V approximately 43 RPM (GM3) or 84 RPM (GM9)&lt;br /&gt;
* stall torque at 6V approximately 73 oz-in (GM3) or 52 oz-in (GM9)&lt;br /&gt;
* no encoder installed, but can be modified to add one; see [[Adding_a_magnetic_encoder_to_a_GM3_Gearmotor|here]]&lt;br /&gt;
* size:  70 x 22.5 x 37 mm&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These highly-geared motors can be bought new at [http://www.solarbotics.com solarbotics.com] or [http://www.hobbyengineering.com hobbyengineering.com].  These motors work with these [http://www.solarbotics.com/products/gmpw/ wheels], which we have in&lt;br /&gt;
the lab.  The motors do not come with encoders, but you can [[Adding_a_magnetic_encoder_to_a_GM3_Gearmotor|add one yourself]],&lt;br /&gt;
similar to the magnetic encoder on the Faulhaber motor above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Stepper Motors==&lt;br /&gt;
&lt;br /&gt;
Stepper motors move in discrete steps.  The controller energizes electromagnet&lt;br /&gt;
coils, and the motor&amp;#039;s rotor rotates to the nearest equilibrium point.  By&lt;br /&gt;
proper sequencing of which coils are energized, the motor rotates as desired&lt;br /&gt;
(and, if the rotation is fast enough, may simply pass through the equilibrium&lt;br /&gt;
points without stopping).  &lt;br /&gt;
&lt;br /&gt;
One nice thing about stepper motors is that they do not require&lt;br /&gt;
feedback; we know how far the motor has rotated, because we commanded&lt;br /&gt;
the motion.  This becomes a problem if we try to rotate the motor too&lt;br /&gt;
fast, or if the load is larger than expected --- the motor may not&lt;br /&gt;
actually do what we commanded.  Stepper motors are a &lt;br /&gt;
good choice for relatively low-torque applications where the loads&lt;br /&gt;
are consistent, so we can be assured our commanded motions are followed.&lt;br /&gt;
&lt;br /&gt;
===Jameco 163395 8.4V bipolar stepper motor===&lt;br /&gt;
&lt;br /&gt;
[[image:small-stepper.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
Although this motor is rated at 8.4V, it is possible&lt;br /&gt;
to run it at lower or slightly higher voltages.&lt;br /&gt;
&lt;br /&gt;
* 1.8 deg/step (0.9 deg/half step)&lt;br /&gt;
* 8.4V, 2 phases, 30 ohms resistance, 280 mA current&lt;br /&gt;
* holding torque:  0.081 Nm (coils energized)&lt;br /&gt;
* detent torque:  0.0037 Nm (coils off)&lt;br /&gt;
* size:  1.64&amp;quot; motor diameter, 1.2&amp;quot; motor height&lt;br /&gt;
* shaft: 0.29&amp;quot; x 0.155&amp;quot; diameter&lt;br /&gt;
* mass:  0.24 kg&lt;br /&gt;
&lt;br /&gt;
More information can be found on this&lt;br /&gt;
[[Media:jameco-stepper-163395.pdf|data sheet]].&lt;br /&gt;
There are four leads, two for each independent coil.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jameco 162026CX 12V unipolar stepper motor===&lt;br /&gt;
&lt;br /&gt;
[[image:stepper-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
If you need more holding torque, this stepper may be a&lt;br /&gt;
good choice.&lt;br /&gt;
&lt;br /&gt;
* 1.8 deg/step (0.9 deg/half step)&lt;br /&gt;
* 12V, 4 phases, 20 ohms resistance, 600 mA current&lt;br /&gt;
* holding torque:  0.588 Nm (coils energized)&lt;br /&gt;
* detent torque:  0.071 Nm (coils off)&lt;br /&gt;
* size:  2.2&amp;quot; motor diameter, 2.0&amp;quot; motor height&lt;br /&gt;
* shaft:  1&amp;quot; x 0.25&amp;quot; diameter&lt;br /&gt;
* mass:  0.65 kg&lt;br /&gt;
&lt;br /&gt;
More information can be found on this&lt;br /&gt;
[[Media:jameco-stepper-162026.pdf|data sheet]] (ours is the &lt;br /&gt;
57BYG084).  There are six leads, three for each independent&lt;br /&gt;
coil.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==RC Servo Motors==&lt;br /&gt;
&lt;br /&gt;
RC servos are convenient for positioning applications that require&lt;br /&gt;
significant torque, not much speed, and only moderate positioning&lt;br /&gt;
precision.  They take three connections, power (+5V, typically),&lt;br /&gt;
ground, and a pulsing signal that tells the motor the desired angle (typically a&lt;br /&gt;
pulse of 0.5 - 3 ms every 20 ms or so, where the duration of the pulse&lt;br /&gt;
indicates the desired angle of the motor).&lt;br /&gt;
Inside the motor is a potentiometer that senses the actual angle of&lt;br /&gt;
the motor output shaft and a feedback controller that tries to make&lt;br /&gt;
the motor angle match that specified by the pulsed signal.  There is&lt;br /&gt;
also a large gear ratio such that the motor provides high torque at&lt;br /&gt;
low speed.  Most RC servos have limited angle range, like 180 degrees,&lt;br /&gt;
due to the angle-sensing potentiometer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Futaba S3004 standard ball bearing RC servo motor===&lt;br /&gt;
&lt;br /&gt;
[[image:RC-servo-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
* motor rotation:  180 degrees&lt;br /&gt;
* speed:  60 degrees in 0.23 sec at 4.8V, 0.19 sec at 6V&lt;br /&gt;
* torque:  0.31 Nm at 4.8V, 0.4 Nm at 6V&lt;br /&gt;
* size:  1.4&amp;quot; height, 0.8&amp;quot; width&lt;br /&gt;
* mass:  37.2 g&lt;br /&gt;
&lt;br /&gt;
These were purchased from Tower Hobbies, part number LM1954.&lt;br /&gt;
Higher torque versions are also available.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Solenoids==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Solenoids are simple on-off actuators consisting of a plunger moving in an&lt;br /&gt;
electromagnetic field.  If you power the electromagnet, the plunger is&lt;br /&gt;
&amp;quot;pushed&amp;quot; or &amp;quot;pulled&amp;quot; a particular stroke length, and if you unpower the&lt;br /&gt;
coil, the plunger returns to its original position, usually by a return &lt;br /&gt;
spring or gravity.  These are simple to control and useful for applications&lt;br /&gt;
where the actuator only has to take one of two positions.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We stock two solenoids (in addition to many random ones) which are basically&lt;br /&gt;
the same, except one is a &amp;quot;pull type&amp;quot; solenoid and the other is a &amp;quot;push type.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Jameco 262262 (pull) and 262271 (push) 12V open frame solenoid===&lt;br /&gt;
&lt;br /&gt;
[[image:solenoids-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
* 12 V, 36 ohm resistance, 333 mA&lt;br /&gt;
* holding force:  0.5 N&lt;br /&gt;
* stroke:  6 mm&lt;br /&gt;
* size:  1.5&amp;quot; length x 1.0&amp;quot; x 0.8&amp;quot; diameter&lt;br /&gt;
* shaft diameter: 0.310&amp;quot;&lt;br /&gt;
* mass:  96 g&lt;br /&gt;
&lt;br /&gt;
You can find a data sheet [[Media:jameco-solenoid-262262.pdf|here]].&lt;br /&gt;
You can attach a lever (or other mechanical transformer) to the plunger to&lt;br /&gt;
get more stroke and less force, or more force and less stroke.  If no lever&lt;br /&gt;
will meet your specs,&lt;br /&gt;
then you will need another solenoid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==AC Motors==&lt;br /&gt;
&lt;br /&gt;
[[image:ac-servo-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
Some projects need more power than any of the actuators above can&lt;br /&gt;
provide.  In that case, you may be able to use a Yaskawa AC motor.&lt;br /&gt;
These are technically in the Laboratory for Intelligent Mechanical&lt;br /&gt;
Systems, but they are available for Mechatronics use.  These should&lt;br /&gt;
not be a first choice, as (1) they can be dangerous due to their high&lt;br /&gt;
power, and (2) they limit the mobility of your project as they must be&lt;br /&gt;
plugged into the wall to get 110V AC.  You can find information&lt;br /&gt;
on these motors and their amplifiers&lt;br /&gt;
[http://www.mech.northwestern.edu/courses/433/Writeups/YaskawaMotors/YakawaACservomotors.htm  here].&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Actuators_Available_in_the_Mechatronics_Lab&amp;diff=8981</id>
		<title>Actuators Available in the Mechatronics Lab</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Actuators_Available_in_the_Mechatronics_Lab&amp;diff=8981"/>
		<updated>2008-07-08T21:13:47Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Globe motor with 187.68:1 gearhead and 500 line encoder */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:all-actuators-captions-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
We have acquired a number of actuators that are appropriately sized for&lt;br /&gt;
many mechatronics projects.  These are the &amp;quot;standard&amp;quot; lab actuators.&lt;br /&gt;
You are welcome to borrow them for your project and return them when&lt;br /&gt;
you are finished.  In addition to the actuators mentioned below, we&lt;br /&gt;
have a number of other actuators that we have acquired over the years&lt;br /&gt;
that you are welcome to borrow.&lt;br /&gt;
&lt;br /&gt;
For your particular project, it may be best to spec out and buy a&lt;br /&gt;
particular type and size of actuator.  If your specifications are not&lt;br /&gt;
too critical, however, the actuators below will allow you to get&lt;br /&gt;
started right away.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==DC Motors (with gearheads and encoders)==&lt;br /&gt;
&lt;br /&gt;
There are many types of DC motors, but our favorites are brushed&lt;br /&gt;
permanent magnet DC motors for their power, price, ubiquity, and&lt;br /&gt;
simplicity.  Simply put a voltage across the two motor terminals, and&lt;br /&gt;
the motor spins.  (You can learn about the&lt;br /&gt;
theory of how a brushed DC &lt;br /&gt;
motor works and suggested methods&lt;br /&gt;
for driving a DC motor elsewhere on this wiki.)  &lt;br /&gt;
&lt;br /&gt;
One problem is that most DC motors tend to rotate at very high speeds,&lt;br /&gt;
typically several thousand RPM or more.  This is too fast for most&lt;br /&gt;
mechatronics applications.  Also, they tend to have too little torque.&lt;br /&gt;
Both of these problems can be solved by the use of gears on the output&lt;br /&gt;
shaft of the motor.  If the motor has an N:1 gearhead on its output&lt;br /&gt;
shaft (where N&amp;gt;1, typically), then the output shaft of the gearhead&lt;br /&gt;
reduces the speed of the motor by a factor of N and icreases the&lt;br /&gt;
torque of the motor by a factor of N.  (You can learn more&lt;br /&gt;
about how gears work including other issues&lt;br /&gt;
they introduce, such as gearhead efficiency and backlash.)&lt;br /&gt;
&lt;br /&gt;
Another issue is how to determine how far the motor has rotated.  You need&lt;br /&gt;
&amp;#039;&amp;#039;feedback&amp;#039;&amp;#039; from the motor.  There are many ways to do this; see&lt;br /&gt;
here for information on using&lt;br /&gt;
encoders, potentiometers, and tachometers.  The most common way to get angle&lt;br /&gt;
feedback is through the use of encoders.  An encoder is typically attached&lt;br /&gt;
to a motor shaft and produces pulses that encode the shaft rotation angle.&lt;br /&gt;
These pulses can be read in by the encoder inputs of the Mechatronics Lab&lt;br /&gt;
PC/104 stacks.&lt;br /&gt;
&lt;br /&gt;
So, perhaps the most versatile kind of actuator is a DC motor with a gearhead and an&lt;br /&gt;
encoder.  Below are some that we keep in the lab.  Sometimes DC motors&lt;br /&gt;
with gearheads and encoders can be purchased through surplus outlets at&lt;br /&gt;
great prices, for prices less than any of the single components (motor,&lt;br /&gt;
gearhead, encoder) could be purchased individually.  That&amp;#039;s how many&lt;br /&gt;
copies of the actuators below were purchased.  If you see a great&lt;br /&gt;
deal on a nice-sized motor plus gearhead plus encoder, of which many&lt;br /&gt;
copies can be purchased, let us know!&lt;br /&gt;
&lt;br /&gt;
===6W Maxon motor with 6:1 gearhead and 100 line encoder===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:maxon-small2.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 24 V, 41.5 ohms resistance, max current 0.58 Amps&lt;br /&gt;
* max torque:  0.15 Nm (approx)&lt;br /&gt;
* max speed:  600 RPM (approx)&lt;br /&gt;
* encoder:  600 counts/rev at output shaft, 2400 counts/rev in 4x decoding mode&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The motor is rated at 24 volts, giving a no-load (maximum)&lt;br /&gt;
speed of 3990 RPM (about 418 radians/sec) and a (maximum) stall torque of 31.9 mNm (milli&lt;br /&gt;
Newton meters).  The terminal resistance (the resistance through the&lt;br /&gt;
motor windings) is 41.5 ohms.  This means if you put 24 V across it,&lt;br /&gt;
the maximum current that it will draw is 24/41.5 = 0.58 Amps.  This&lt;br /&gt;
maximum current occurs when the motor is stalled and generating its&lt;br /&gt;
maximum torque.  Motor torque is proportional to the motor current by&lt;br /&gt;
the constant of proportionality called the &amp;#039;&amp;#039;torque constant&amp;#039;&amp;#039;,&lt;br /&gt;
which is different for every motor.&lt;br /&gt;
&lt;br /&gt;
The motor is called a 6 Watt motor because that is the maximum&lt;br /&gt;
electrical power (current times voltage) that can be put into the&lt;br /&gt;
motor on a continuous basis.  Beyond this power level, the amount of&lt;br /&gt;
power dissipated by the resistance of the motor windings will cause&lt;br /&gt;
the windings to heat up unacceptably.  (It is fine to overpower the&lt;br /&gt;
motor intermittently, allowing the coils to cool so that the average&lt;br /&gt;
power does not exceed the rated power.)  At this operating point, &lt;br /&gt;
the motor draws 244 mA, giving 24 V x 0.244 A = 5.86 W electrical input&lt;br /&gt;
power.  At this operating point, the speed of the motor is approximately&lt;br /&gt;
1689 RPM, or 177 radians/sec, and the torque of the motor is 13.5 mNm,&lt;br /&gt;
giving 177 rad/sec x 0.0135 Nm = 2.39 W of mechanical output power,&lt;br /&gt;
giving a power-conversion efficiency of about 41% at this operating point.&lt;br /&gt;
The maximum efficiency of the motor is 70%, which occurs at a higher&lt;br /&gt;
speed and lower torque.  The maximum mechanical power you can get out&lt;br /&gt;
of the motor is (1/2 max torque) x (1/2 max speed) = 3.33 W.  This is&lt;br /&gt;
beyond the continuous operation recommendation, but it is fine to&lt;br /&gt;
run it for short periods at this operating point.&lt;br /&gt;
&lt;br /&gt;
Often you will want to run the motor at lower voltages, for instance&lt;br /&gt;
at 12 V, instead of the rated 24 V.  In this case just multiply the&lt;br /&gt;
max current, speed, and torques by the factor 12/24 = 1/2.  In particular,&lt;br /&gt;
the maximum output power will be only (1/2) x (1/2) = 1/4 the maximum at 24 V.&lt;br /&gt;
&lt;br /&gt;
This actuator comes with a 6:1 spur gearhead, which increases the&lt;br /&gt;
torque available at the gearhead&amp;#039;s output shaft by a factor of 6 and&lt;br /&gt;
decreases the speed by a factor of 6.  (In this ideal case, the&lt;br /&gt;
power at the gearhead&amp;#039;s output shaft is equal to the power at the input.&lt;br /&gt;
In practice, gearheads have an efficiency also; the maximum&lt;br /&gt;
efficiency of the gearhead here is 81%.  This reduces the torque&lt;br /&gt;
available.)&lt;br /&gt;
&lt;br /&gt;
In summary, then, if your application requires no more than about 6 x&lt;br /&gt;
31.9 mNm = 0.19 Nm maximum torque, 3990 RPM / 6 = 665 RPM max speed,&lt;br /&gt;
and 3.3 W max mechanical power, this may be the motor for you.&lt;br /&gt;
Reduce those values by a factor of 1/2, 1/2, and 1/4, respectively, if&lt;br /&gt;
you are operating the motor with 12 V max instead of 24 V max.&lt;br /&gt;
&lt;br /&gt;
This actuator also comes with 100 line single-ended incremental optical encoder,&lt;br /&gt;
with outputs A+ and B+.  There is no index channel.  The encoder is&lt;br /&gt;
attached to the motor.  Each of the A+ and B+ channels makes 100 pulses&lt;br /&gt;
per revolution of the motor, or 6 x 100 = 600 pulses per revolution of&lt;br /&gt;
the output shaft of the gearhead.  This means the encoder provides&lt;br /&gt;
360 deg / 600 pulses = 0.6 deg/pulse resolution when the pulses are &lt;br /&gt;
decoded with the 1x scheme, or 0.15 deg/pulse resolution with the 4x&lt;br /&gt;
decoding scheme.&lt;br /&gt;
&lt;br /&gt;
Information about the Maxon motor is given in this [[Media:maxon-2140-specs.pdf|data sheet]] which includes &lt;br /&gt;
other motors in this family (ours is the 24V version)&lt;br /&gt;
and this [[Media:maxon-our-specific-motor.pdf|data sheet]] which gives only&lt;br /&gt;
the information on this motor.  (Note the speed-torque curve is a bit misleading,&lt;br /&gt;
as it seems to imply the maximum speed of the motor is 6100 RPM, when it should&lt;br /&gt;
be 3990 RPM.)  Information on the 6:1 gearhead can be found &lt;br /&gt;
[[Media:maxon-gearhead.pdf|here]].  The encoder pin-out is indicated below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:encoder-maxon.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The encoder comes with a 4-connector ribbon cable, corresponding to GND, Channel A, Vcc (usually +5V), and Channel B, as&lt;br /&gt;
shown on the left.  Here the ribbon cable is broken out into a 10-pin connector (which we have in the lab).  The connector&lt;br /&gt;
above is made to work with the PC/104 stacks, and the pin-out is shown.  Always make sure you have the right connections&lt;br /&gt;
for your encoder so you don&amp;#039;t damage it!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Pittman GM8224 motor with 19.5:1 gearhead and 500 line encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:pittman-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
If you need more power than the motor above, this gearmotor may be a good choice.&lt;br /&gt;
As an added bonus, it provides much higher encoder resolution.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 24 V, 4.33 ohms resistance, max current 5.54 Amps&lt;br /&gt;
* max torque:  2 Nm (approx)&lt;br /&gt;
* max speed:  500 RPM (approx)&lt;br /&gt;
* encoder:  9750 counts/rev at output shaft, 39,000 counts/rev in 4x decoding mode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This motor is also rated at 24 V, with a terminal resistance of 4.33 ohms,&lt;br /&gt;
giving a stall (maximum) current of 5.54 Amps.  The stall torque of the motor&lt;br /&gt;
itself is 0.1186 Nm&lt;br /&gt;
and the no-load (maximum) speed is 10,158 RPM (1064 radians/sec).  The&lt;br /&gt;
recommended maximum continuous torque is 0.0185 Nm which occurs at &lt;br /&gt;
8573 RPM (898 radians/sec).  Taken together, the maximum motor mechanical power&lt;br /&gt;
is (1/2 Tmax) x (1/2 nmax) = 31.5 W and the maximum recommended continuous&lt;br /&gt;
mechanical power is 16.6 W.  The maximum electrical input power occurs when&lt;br /&gt;
the motor is stalled (or starting) and is 24 V x 5.54 A = 133 W.  If you&lt;br /&gt;
operate the motor at a smaller voltage V2, then multiply the currents, speeds,&lt;br /&gt;
and torques above by a factor V2/24 and the power by a factor of (V2/24)^2.&lt;br /&gt;
&lt;br /&gt;
This motor has a 19.5:1 gearhead with a power conversion efficiency of 73%.  &lt;br /&gt;
Ignoring the efficiency for the moment, the 19.5:1 gearbox means that this&lt;br /&gt;
actuator may be appropriate if our application calls for no more than a &lt;br /&gt;
maximum speed of 10,158 RPM / 19.5 = 521 RPM and a maximum torque of&lt;br /&gt;
0.1186 Nm x 19.5 = 2.3 Nm.  In other words, the output shaft speed is similar&lt;br /&gt;
to the Maxon gearmotor above, but with about 10 times the torque.  &lt;br /&gt;
&lt;br /&gt;
This motor comes with a 500 line encoder attached to the motor shaft.  The&lt;br /&gt;
encoder has output channels A+ and B+ (no index pulse).  This means that&lt;br /&gt;
the encoder provides 500 x 19.5 = 9750 pulses per revolution of the output shaft.&lt;br /&gt;
In the 4x decoding mode, this gives 39,000 counts per revolution, or a resolution&lt;br /&gt;
of 360/39,000 = 0.00923 degrees.&lt;br /&gt;
&lt;br /&gt;
We also have a limited number of Pittman GM8712 motors with a 19.5:1 gearhead&lt;br /&gt;
and 512 line encoder.  These motors are also rated at 24V but have a higher&lt;br /&gt;
terminal resistance of 12.1 ohms, giving a maximum current of 24/12.1 = 1.99 Amps.&lt;br /&gt;
They have a maximum speed of 7847 RPM and maximum torque of 0.052 Nm before the&lt;br /&gt;
gearhead, or (ignoring gearhead efficiency) 402 RPM and 1.01 Nm after the&lt;br /&gt;
gearhead.  This motor is less powerful and draws less current, which may&lt;br /&gt;
be appropriate for some applications.&lt;br /&gt;
The encoder provides 9984 pulses per revolution of the output shaft&lt;br /&gt;
of the gearhead, or 360/(4 x 9984) = 0.009 degrees resolution in 4x decoding mode.&lt;br /&gt;
&lt;br /&gt;
See the [[Media:pittmangearmotor.pdf|data sheet]] for more detailed&lt;br /&gt;
information on these Pittman 8224 and 8712 gearmotors.  The 8712 is not treated&lt;br /&gt;
explicitly, but is believed to be similar to the 8722.&lt;br /&gt;
&lt;br /&gt;
The quadrature encoder has four wires:  black (GND), red (+5V), and blue and yellow as &lt;br /&gt;
channels A and B.&lt;br /&gt;
&lt;br /&gt;
===Faulhaber 1524E006S motor with 141:1 gearhead and HES164A magnetic quadrature encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber.png|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* motor rated at 6V, 12 ohms resistance (motor: 1524E006S123, where 123 is a special order)&lt;br /&gt;
* 141:1 gearhead (gearhead:  15/5S141:1K832)&lt;br /&gt;
* max speed at 6V:  approximately 80 RPM at gearhead output&lt;br /&gt;
* quadrature encoder with 1 line per motor revolution, or 141 x 4 = 564 counts/rev at output shaft in 4x decoding mode (encoder:  HES164A)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This little motor is the right size, speed, and torque for small wheeled mobile robots.&lt;br /&gt;
Ours were bought surplus from [http://www.bgmicro.com bgmicro.com].  This &lt;br /&gt;
[http://www.robotroom.com/FaulhaberGearmotor.html page] by&lt;br /&gt;
David Cook has a lot of great information on this motor + gearhead + encoder combination.&lt;br /&gt;
More info can be found in this [[Media:faulhaber-datasheet.pdf|data sheet]] from Faulhaber,&lt;br /&gt;
though our exact model encoder and motor are not listed.  The gearhead has a right-angle&lt;br /&gt;
drive at the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber-pinout.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
The pins on the connector are (see figure at right):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1.  Motor + &amp;lt;br&amp;gt;&lt;br /&gt;
2.  +5V (or similar) to power the encoder&amp;lt;br&amp;gt;&lt;br /&gt;
3.  Encoder channel A&amp;lt;br&amp;gt;&lt;br /&gt;
4.  Encoder channel B&amp;lt;br&amp;gt;&lt;br /&gt;
5.  GND for the encoder&amp;lt;br&amp;gt;&lt;br /&gt;
6.  Motor -&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Encoder channels A and B can sink (connect to ground) up to probably 25mA like most Hall sensors.  There is only a a weak pull-up resistor inside, perhaps 10K, so they can only source (connect to +5) about 2mA.   If you find the logic high signal from the encoder channel is not close enough to +5, which can happen even due to loading by an LED, you may want to add an external pull-up resistor from each encoder channel to +5.  470ohms is a good choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber-wheel.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
These [http://www.solarbotics.com/products/gmpw/ wheels] can be used with the motor (with the&lt;br /&gt;
right-angle drive) if you drill out the center of the wheel with a 9/32&amp;quot; bit (approximately).  Then you&lt;br /&gt;
should get a nice tight press-fit.  We have some of these wheels in the lab.  This press-fit is not &lt;br /&gt;
suitable for high-torque applications, though; the shaft may begin to slip.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Globe motor with 187.68:1 gearhead and 500 line encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:globe-motor.jpg|right|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* motor rated at 12V, 21 ohms resistance (0.57 A stall current)&lt;br /&gt;
* 187.68:1 gearhead for high torque and low speed&lt;br /&gt;
* max speed at 12V:  approximately 17 RPM at gearhead output (no load speed, motor alone:  approx 3000 RPM)&lt;br /&gt;
* torque constant (motor alone):  approximately 34 mNm/A (or 281 V/RPM)&lt;br /&gt;
* stall torque:  motor alone:  0.019 Nm; with gearhead 2.4 Nm (based on torque multiplier of 125, less than the 187 gear ratio due to efficiency losses)&lt;br /&gt;
* quadrature encoder with 500 lines per motor revolution, or 500 x 4 x 187.68 = 375,360 counts/rev at output shaft in 4x decoding mode (encoder:  HEDS-5505 A04)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small motor combines with a high resolution encoder and a high gear ratio gearbox to give a high torque, low speed actuator with high resolution position sensing (and velocity sensing by finite differencing).  The stall torque for this gearmotor (at 12 V) is approximately the same as that for the Pittman GM8224 gearmotor (at 24 V), but the max speed for the PIttman gearmotor is 20 times higher.  The pin-out for the encoder is shown below.  You can attach to the encoder using a Samtec IDSS-05-D-12.00 cable (shown in the middle below; order directly from [http://www.samtec.com Samtec], about $3.50 each) or you can make your own cable using stranded wires (22 AWG or ribbon cable) crimped or soldered in female Molex terminal pins (Molex series KK 2759, part number WM1114CT-ND on digikey) in a Molex 5 position connector housing (Molex series KK 2695, part number WM1578-ND on digikey), shown at right below.  (See [[Making a Molex Connector]] for more details.) The [[Media:HEDS5500-encoder.pdf|datasheet]] for the encoder recommends putting a 3.2k pull-up resistor on Channels A and B (i.e., 3.2k resistors from these lines to +5V).  The encoder works without these, but the datasheet indicates that you get better rise times on the encoder signals at high speeds when the pull-up resistors are added.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-encoder-cable.jpg|200px]]&lt;br /&gt;
[[image:globe-encoder-cable-molex.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
An inside peek at the gearbox is shown below.  If you want a higher-speed (up to 3000 RPM at 12V) lower-torque actuator, you can try removing the gearbox.  This task takes a bit of work and depending on what output you want, may require a bit of machining.  See [[Accessing_Pinion_of_Globe_Motor|here]].&lt;br /&gt;
&lt;br /&gt;
The two motor power leads are wound through a ferrite toroid to suppress EMI &amp;quot;noise.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Here you can find a [[Media:globe-cad.pdf|cad file]] describing this actuator, a [[Media:HEDS5500-encoder.pdf|datasheet]] for the encoder, and a [[Media:idss-connector.pdf|datasheet]] for the Samtec IDSS-05-D-12.00 connector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===GM3 and GM9 Gearmotors===&lt;br /&gt;
&lt;br /&gt;
[[image:GM3.png|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;  (GM3 pictured at right)&lt;br /&gt;
* rated at 6V, approx 10 ohms resistance&lt;br /&gt;
* 224:1 gearhead (GM3) or 143:1 gearhead (GM9)&lt;br /&gt;
* max speed at 6V approximately 43 RPM (GM3) or 84 RPM (GM9)&lt;br /&gt;
* stall torque at 6V approximately 73 oz-in (GM3) or 52 oz-in (GM9)&lt;br /&gt;
* no encoder installed, but can be modified to add one; see [[Adding_a_magnetic_encoder_to_a_GM3_Gearmotor|here]]&lt;br /&gt;
* size:  70 x 22.5 x 37 mm&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These highly-geared motors can be bought new at [http://www.solarbotics.com solarbotics.com] or [http://www.hobbyengineering.com hobbyengineering.com].  These motors work with these [http://www.solarbotics.com/products/gmpw/ wheels], which we have in&lt;br /&gt;
the lab.  The motors do not come with encoders, but you can [[Adding_a_magnetic_encoder_to_a_GM3_Gearmotor|add one yourself]],&lt;br /&gt;
similar to the magnetic encoder on the Faulhaber motor above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Stepper Motors==&lt;br /&gt;
&lt;br /&gt;
Stepper motors move in discrete steps.  The controller energizes electromagnet&lt;br /&gt;
coils, and the motor&amp;#039;s rotor rotates to the nearest equilibrium point.  By&lt;br /&gt;
proper sequencing of which coils are energized, the motor rotates as desired&lt;br /&gt;
(and, if the rotation is fast enough, may simply pass through the equilibrium&lt;br /&gt;
points without stopping).  &lt;br /&gt;
&lt;br /&gt;
One nice thing about stepper motors is that they do not require&lt;br /&gt;
feedback; we know how far the motor has rotated, because we commanded&lt;br /&gt;
the motion.  This becomes a problem if we try to rotate the motor too&lt;br /&gt;
fast, or if the load is larger than expected --- the motor may not&lt;br /&gt;
actually do what we commanded.  Stepper motors are a &lt;br /&gt;
good choice for relatively low-torque applications where the loads&lt;br /&gt;
are consistent, so we can be assured our commanded motions are followed.&lt;br /&gt;
&lt;br /&gt;
===Jameco 163395 8.4V bipolar stepper motor===&lt;br /&gt;
&lt;br /&gt;
[[image:small-stepper.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
Although this motor is rated at 8.4V, it is possible&lt;br /&gt;
to run it at lower or slightly higher voltages.&lt;br /&gt;
&lt;br /&gt;
* 1.8 deg/step (0.9 deg/half step)&lt;br /&gt;
* 8.4V, 2 phases, 30 ohms resistance, 280 mA current&lt;br /&gt;
* holding torque:  0.081 Nm (coils energized)&lt;br /&gt;
* detent torque:  0.0037 Nm (coils off)&lt;br /&gt;
* size:  1.64&amp;quot; motor diameter, 1.2&amp;quot; motor height&lt;br /&gt;
* shaft: 0.29&amp;quot; x 0.155&amp;quot; diameter&lt;br /&gt;
* mass:  0.24 kg&lt;br /&gt;
&lt;br /&gt;
More information can be found on this&lt;br /&gt;
[[Media:jameco-stepper-163395.pdf|data sheet]].&lt;br /&gt;
There are four leads, two for each independent coil.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jameco 162026CX 12V unipolar stepper motor===&lt;br /&gt;
&lt;br /&gt;
[[image:stepper-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
If you need more holding torque, this stepper may be a&lt;br /&gt;
good choice.&lt;br /&gt;
&lt;br /&gt;
* 1.8 deg/step (0.9 deg/half step)&lt;br /&gt;
* 12V, 4 phases, 20 ohms resistance, 600 mA current&lt;br /&gt;
* holding torque:  0.588 Nm (coils energized)&lt;br /&gt;
* detent torque:  0.071 Nm (coils off)&lt;br /&gt;
* size:  2.2&amp;quot; motor diameter, 2.0&amp;quot; motor height&lt;br /&gt;
* shaft:  1&amp;quot; x 0.25&amp;quot; diameter&lt;br /&gt;
* mass:  0.65 kg&lt;br /&gt;
&lt;br /&gt;
More information can be found on this&lt;br /&gt;
[[Media:jameco-stepper-162026.pdf|data sheet]] (ours is the &lt;br /&gt;
57BYG084).  There are six leads, three for each independent&lt;br /&gt;
coil.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==RC Servo Motors==&lt;br /&gt;
&lt;br /&gt;
RC servos are convenient for positioning applications that require&lt;br /&gt;
significant torque, not much speed, and only moderate positioning&lt;br /&gt;
precision.  They take three connections, power (+5V, typically),&lt;br /&gt;
ground, and a pulsing signal that tells the motor the desired angle (typically a&lt;br /&gt;
pulse of 0.5 - 3 ms every 20 ms or so, where the duration of the pulse&lt;br /&gt;
indicates the desired angle of the motor).&lt;br /&gt;
Inside the motor is a potentiometer that senses the actual angle of&lt;br /&gt;
the motor output shaft and a feedback controller that tries to make&lt;br /&gt;
the motor angle match that specified by the pulsed signal.  There is&lt;br /&gt;
also a large gear ratio such that the motor provides high torque at&lt;br /&gt;
low speed.  Most RC servos have limited angle range, like 180 degrees,&lt;br /&gt;
due to the angle-sensing potentiometer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Futaba S3004 standard ball bearing RC servo motor===&lt;br /&gt;
&lt;br /&gt;
[[image:RC-servo-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
* motor rotation:  180 degrees&lt;br /&gt;
* speed:  60 degrees in 0.23 sec at 4.8V, 0.19 sec at 6V&lt;br /&gt;
* torque:  0.31 Nm at 4.8V, 0.4 Nm at 6V&lt;br /&gt;
* size:  1.4&amp;quot; height, 0.8&amp;quot; width&lt;br /&gt;
* mass:  37.2 g&lt;br /&gt;
&lt;br /&gt;
These were purchased from Tower Hobbies, part number LM1954.&lt;br /&gt;
Higher torque versions are also available.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Solenoids==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Solenoids are simple on-off actuators consisting of a plunger moving in an&lt;br /&gt;
electromagnetic field.  If you power the electromagnet, the plunger is&lt;br /&gt;
&amp;quot;pushed&amp;quot; or &amp;quot;pulled&amp;quot; a particular stroke length, and if you unpower the&lt;br /&gt;
coil, the plunger returns to its original position, usually by a return &lt;br /&gt;
spring or gravity.  These are simple to control and useful for applications&lt;br /&gt;
where the actuator only has to take one of two positions.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We stock two solenoids (in addition to many random ones) which are basically&lt;br /&gt;
the same, except one is a &amp;quot;pull type&amp;quot; solenoid and the other is a &amp;quot;push type.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Jameco 262262 (pull) and 262271 (push) 12V open frame solenoid===&lt;br /&gt;
&lt;br /&gt;
[[image:solenoids-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
* 12 V, 36 ohm resistance, 333 mA&lt;br /&gt;
* holding force:  0.5 N&lt;br /&gt;
* stroke:  6 mm&lt;br /&gt;
* size:  1.5&amp;quot; length x 1.0&amp;quot; x 0.8&amp;quot; diameter&lt;br /&gt;
* shaft diameter: 0.310&amp;quot;&lt;br /&gt;
* mass:  96 g&lt;br /&gt;
&lt;br /&gt;
You can find a data sheet [[Media:jameco-solenoid-262262.pdf|here]].&lt;br /&gt;
You can attach a lever (or other mechanical transformer) to the plunger to&lt;br /&gt;
get more stroke and less force, or more force and less stroke.  If no lever&lt;br /&gt;
will meet your specs,&lt;br /&gt;
then you will need another solenoid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==AC Motors==&lt;br /&gt;
&lt;br /&gt;
[[image:ac-servo-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
Some projects need more power than any of the actuators above can&lt;br /&gt;
provide.  In that case, you may be able to use a Yaskawa AC motor.&lt;br /&gt;
These are technically in the Laboratory for Intelligent Mechanical&lt;br /&gt;
Systems, but they are available for Mechatronics use.  These should&lt;br /&gt;
not be a first choice, as (1) they can be dangerous due to their high&lt;br /&gt;
power, and (2) they limit the mobility of your project as they must be&lt;br /&gt;
plugged into the wall to get 110V AC.  You can find information&lt;br /&gt;
on these motors and their amplifiers&lt;br /&gt;
[http://www.mech.northwestern.edu/courses/433/Writeups/YaskawaMotors/YakawaACservomotors.htm  here].&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Globe-machined-motor-head.jpg&amp;diff=8980</id>
		<title>File:Globe-machined-motor-head.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Globe-machined-motor-head.jpg&amp;diff=8980"/>
		<updated>2008-07-08T21:05:20Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: A machined motor head.  This can be achieved through milling or interrupted turning of the top part of the motor.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A machined motor head.  This can be achieved through milling or interrupted turning of the top part of the motor.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Accessing_Pinion_of_Globe_Motor&amp;diff=8979</id>
		<title>Accessing Pinion of Globe Motor</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Accessing_Pinion_of_Globe_Motor&amp;diff=8979"/>
		<updated>2008-07-08T21:04:43Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Globe motor we have in stock can be modified to be high speed and low torque with a few adjustments.&lt;br /&gt;
&lt;br /&gt;
It is easy to do until the disassembled photo below.  Simply unscrew the three long screws and pull off the top of the gearbox, along with the output shaft of the gearbox.  Now you can see two shafts holding the stacks of gears actually implementing the reduction ratio.  Using a pair of pliers, pull off the spacers near the tops of these shafts (these are press-fitted onto the shafts).  Now the gears slide off the shafts.  (Actually, when I tried it, one shaft came out with the spacer, while the other shaft remained in place and only the spacer came off.)  The photo below shows the new state of the gearbox.  &amp;#039;&amp;#039;&amp;#039;Be careful not to manhandle the encoder when you apply large forces pulling off the spacers!&amp;#039;&amp;#039;&amp;#039;  You could damage the encoder.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-gearbox-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-nogearhead.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
The rest of the gearbox is held in place by two long screws that run the full length from the back of the motor.  These screws cannot be removed without removing the encoder.  Therefore, if you want to better expose the motor&amp;#039;s output shaft without entirely disassembling the motor, you can use a band saw to cut off the nearby posts (or to cut off the entire gearhead from the lip up) and to destroy and remove the pinion gear on the motor output shaft.&lt;br /&gt;
&lt;br /&gt;
The more involved but safer method to access the pinion or output shaft is to disassemble to motor.  To do this, use a small screwdriver to rotate the internal mechanism in the encoder.  See the picture below.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-scredriver-inserted.jpg|300px]]&lt;br /&gt;
[[image:globe-hex-wrench-inserted.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Rotate this as far as it will go until the one dot lines up with the one dot on the outside of the encoder.  This will line up a slot of the side of the encoder which a 0.035&amp;quot; hex wrench can be inserted into.  While applying a bit of pressure to the wrench, turn the pinion until the hex wrench fits into a set screw.  Unscrew this set screw a couple of turns and then pull gently on the encoder.  This will get to the following image:&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-removed.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Now unscrew the two exposed screws and then you will have access to the two bolts holding the motor together.  Unscrew these and the top portion of the motor can now be removed.  The best way to expose the pinion is to mill the top section of the motor to be much lower.  See the following photos for results.  Assemble the motor in reverse order, ensuring the set screw is tightened sufficiently.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-dissassembled.jpg|300px]]&lt;br /&gt;
[[image:globe-machined-motor-head.jpg|300px]]&lt;br /&gt;
[[image:globe-exposed-pinion.jpg|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Accessing_Pinion_of_Globe_Motor&amp;diff=8978</id>
		<title>Accessing Pinion of Globe Motor</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Accessing_Pinion_of_Globe_Motor&amp;diff=8978"/>
		<updated>2008-07-08T21:04:09Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Globe motor we have in stock can be modified to be high speed and low torque with a few adjustments.&lt;br /&gt;
&lt;br /&gt;
It is easy to do until the disassembled photo below.  Simply unscrew the three long screws and pull off the top of the gearbox, along with the output shaft of the gearbox.  Now you can see two shafts holding the stacks of gears actually implementing the reduction ratio.  Using a pair of pliers, pull off the spacers near the tops of these shafts (these are press-fitted onto the shafts).  Now the gears slide off the shafts.  (Actually, when I tried it, one shaft came out with the spacer, while the other shaft remained in place and only the spacer came off.)  The photo below shows the new state of the gearbox.  &amp;#039;&amp;#039;&amp;#039;Be careful not to manhandle the encoder when you apply large forces pulling off the spacers!&amp;#039;&amp;#039;&amp;#039;  You could damage the encoder.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-gearbox-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-nogearhead.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
The rest of the gearbox is held in place by two long screws that run the full length from the back of the motor.  These screws cannot be removed without removing the encoder.  Therefore, if you want to better expose the motor&amp;#039;s output shaft without entirely disassembling the motor, you can use a band saw to cut off the nearby posts (or to cut off the entire gearhead from the lip up) and to destroy and remove the pinion gear on the motor output shaft.&lt;br /&gt;
&lt;br /&gt;
The more involved but safer method to access the pinion or output shaft is to disassemble to motor.  To do this, use a small screwdriver to rotate the internal mechanism in the encoder.  See the picture below.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-scredriver-inserted.jpg|300px]]&lt;br /&gt;
[[image:globe-hex-wrench-inserted.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Rotate this as far as it will go until the one dot lines up with the one dot on the outside of the encoder.  This will line up a slot of the side of the encoder which a 0.035&amp;quot; hex wrench can be inserted into.  While applying a bit of pressure to the wrench, turn the pinion until the hex wrench fits into a set screw.  Unscrew this set screw a couple of turns and then pull gently on the encoder.  This will get to the following image:&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-removed.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Now unscrew the two exposed screws and then you will have access to the two bolts holding the motor together.  Unscrew these and the top portion of the motor can now be removed.  The best way to expose the pinion is to mill the top section of the motor to be much lower.  See the following photos for results.  Assemble the motor in reverse order, ensuring the set screw is tightened sufficiently.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-dissassembled.jpg|300px]]&lt;br /&gt;
[[image:globe-machined-encoder-head.jpg|300px]]&lt;br /&gt;
[[image:globe-exposed-pinion.jpg|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Globe-exposed-pinion.jpg&amp;diff=8977</id>
		<title>File:Globe-exposed-pinion.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Globe-exposed-pinion.jpg&amp;diff=8977"/>
		<updated>2008-07-08T21:03:03Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Example of a final exposed pinion.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Example of a final exposed pinion.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Globe-dissassembled.jpg&amp;diff=8976</id>
		<title>File:Globe-dissassembled.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Globe-dissassembled.jpg&amp;diff=8976"/>
		<updated>2008-07-08T21:00:31Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Disassembled Globe motor.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Disassembled Globe motor.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Globe-encoder-removed.jpg&amp;diff=8975</id>
		<title>File:Globe-encoder-removed.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Globe-encoder-removed.jpg&amp;diff=8975"/>
		<updated>2008-07-08T20:59:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Image of the Globe motor with the encoder removed.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Image of the Globe motor with the encoder removed.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Globe-scredriver-inserted.jpg&amp;diff=8974</id>
		<title>File:Globe-scredriver-inserted.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Globe-scredriver-inserted.jpg&amp;diff=8974"/>
		<updated>2008-07-08T20:57:31Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Insert a small screwdriver into the slot as shown and rotate until the dots line up.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Insert a small screwdriver into the slot as shown and rotate until the dots line up.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Globe-hex-wrench-inserted.jpg&amp;diff=8973</id>
		<title>File:Globe-hex-wrench-inserted.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Globe-hex-wrench-inserted.jpg&amp;diff=8973"/>
		<updated>2008-07-08T20:51:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Insert the 0.035 inch hex wrench into the newly exposed slot and turn the pinion until the wrench is inserted into a set screw holding on the encoder wheel.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Insert the 0.035 inch hex wrench into the newly exposed slot and turn the pinion until the wrench is inserted into a set screw holding on the encoder wheel.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Accessing_Pinion_of_Globe_Motor&amp;diff=8972</id>
		<title>Accessing Pinion of Globe Motor</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Accessing_Pinion_of_Globe_Motor&amp;diff=8972"/>
		<updated>2008-07-08T20:49:02Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The Globe motor we have in stock can be modified to be high speed and low torque with a few adjustments.&lt;br /&gt;
&lt;br /&gt;
It is easy to do until the disassembled photo below.  Simply unscrew the three long screws and pull off the top of the gearbox, along with the output shaft of the gearbox.  Now you can see two shafts holding the stacks of gears actually implementing the reduction ratio.  Using a pair of pliers, pull off the spacers near the tops of these shafts (these are press-fitted onto the shafts).  Now the gears slide off the shafts.  (Actually, when I tried it, one shaft came out with the spacer, while the other shaft remained in place and only the spacer came off.)  The photo below shows the new state of the gearbox.  &amp;#039;&amp;#039;&amp;#039;Be careful not to manhandle the encoder when you apply large forces pulling off the spacers!&amp;#039;&amp;#039;&amp;#039;  You could damage the encoder.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-gearbox-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-nogearhead.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
The rest of the gearbox is held in place by two long screws that run the full length from the back of the motor.  These screws cannot be removed without removing the encoder.  Therefore, if you want to better expose the motor&amp;#039;s output shaft without entirely disassembling the motor, you can use a band saw to cut off the nearby posts (or to cut off the entire gearhead from the lip up) and to destroy and remove the pinion gear on the motor output shaft.&lt;br /&gt;
&lt;br /&gt;
The more involved but safer method to access the pinion or output shaft is to disassemble to motor.  To do this, use a small screwdriver to rotate the internal mechanism in the encoder.  See the picture below.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-scredriver-inserted.jpg|300px]]&lt;br /&gt;
[[image:globe-hex-wrench-inserted.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Rotate this as far as it will go until the one dot lines up with the one dot on the outside of the encoder.  This will line up a slot of the side of the encoder which a 0.035&amp;quot; hex wrench can be inserted into.  While applying a bit of pressure to the wrench, turn the pinion until the hex wrench fits into a set screw.  Unscrew this set screw a couple of turns and then pull gently on the encoder.  This will get to the following image:&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-removed.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Now unscrew the two exposed screws and then you will have access to the two bolts holding the motor together.  Unscrew these and the top portion of the motor can now be removed.  The best way to expose the pinion is to mill the top section of the motor to be much lower.  See the following photos for results.  Assemble the motor in reverse order, ensuring the set screw is tightened sufficiently.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-dissassembled.jpg|300px]]&lt;br /&gt;
[[image:globe-exposed-pinion.jpg|300px]]&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Actuators_Available_in_the_Mechatronics_Lab&amp;diff=8971</id>
		<title>Actuators Available in the Mechatronics Lab</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Actuators_Available_in_the_Mechatronics_Lab&amp;diff=8971"/>
		<updated>2008-07-08T20:48:23Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Globe motor with 187.68:1 gearhead and 500 line encoder */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:all-actuators-captions-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
We have acquired a number of actuators that are appropriately sized for&lt;br /&gt;
many mechatronics projects.  These are the &amp;quot;standard&amp;quot; lab actuators.&lt;br /&gt;
You are welcome to borrow them for your project and return them when&lt;br /&gt;
you are finished.  In addition to the actuators mentioned below, we&lt;br /&gt;
have a number of other actuators that we have acquired over the years&lt;br /&gt;
that you are welcome to borrow.&lt;br /&gt;
&lt;br /&gt;
For your particular project, it may be best to spec out and buy a&lt;br /&gt;
particular type and size of actuator.  If your specifications are not&lt;br /&gt;
too critical, however, the actuators below will allow you to get&lt;br /&gt;
started right away.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==DC Motors (with gearheads and encoders)==&lt;br /&gt;
&lt;br /&gt;
There are many types of DC motors, but our favorites are brushed&lt;br /&gt;
permanent magnet DC motors for their power, price, ubiquity, and&lt;br /&gt;
simplicity.  Simply put a voltage across the two motor terminals, and&lt;br /&gt;
the motor spins.  (You can learn about the&lt;br /&gt;
theory of how a brushed DC &lt;br /&gt;
motor works and suggested methods&lt;br /&gt;
for driving a DC motor elsewhere on this wiki.)  &lt;br /&gt;
&lt;br /&gt;
One problem is that most DC motors tend to rotate at very high speeds,&lt;br /&gt;
typically several thousand RPM or more.  This is too fast for most&lt;br /&gt;
mechatronics applications.  Also, they tend to have too little torque.&lt;br /&gt;
Both of these problems can be solved by the use of gears on the output&lt;br /&gt;
shaft of the motor.  If the motor has an N:1 gearhead on its output&lt;br /&gt;
shaft (where N&amp;gt;1, typically), then the output shaft of the gearhead&lt;br /&gt;
reduces the speed of the motor by a factor of N and icreases the&lt;br /&gt;
torque of the motor by a factor of N.  (You can learn more&lt;br /&gt;
about how gears work including other issues&lt;br /&gt;
they introduce, such as gearhead efficiency and backlash.)&lt;br /&gt;
&lt;br /&gt;
Another issue is how to determine how far the motor has rotated.  You need&lt;br /&gt;
&amp;#039;&amp;#039;feedback&amp;#039;&amp;#039; from the motor.  There are many ways to do this; see&lt;br /&gt;
here for information on using&lt;br /&gt;
encoders, potentiometers, and tachometers.  The most common way to get angle&lt;br /&gt;
feedback is through the use of encoders.  An encoder is typically attached&lt;br /&gt;
to a motor shaft and produces pulses that encode the shaft rotation angle.&lt;br /&gt;
These pulses can be read in by the encoder inputs of the Mechatronics Lab&lt;br /&gt;
PC/104 stacks.&lt;br /&gt;
&lt;br /&gt;
So, perhaps the most versatile kind of actuator is a DC motor with a gearhead and an&lt;br /&gt;
encoder.  Below are some that we keep in the lab.  Sometimes DC motors&lt;br /&gt;
with gearheads and encoders can be purchased through surplus outlets at&lt;br /&gt;
great prices, for prices less than any of the single components (motor,&lt;br /&gt;
gearhead, encoder) could be purchased individually.  That&amp;#039;s how many&lt;br /&gt;
copies of the actuators below were purchased.  If you see a great&lt;br /&gt;
deal on a nice-sized motor plus gearhead plus encoder, of which many&lt;br /&gt;
copies can be purchased, let us know!&lt;br /&gt;
&lt;br /&gt;
===6W Maxon motor with 6:1 gearhead and 100 line encoder===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:maxon-small2.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 24 V, 41.5 ohms resistance, max current 0.58 Amps&lt;br /&gt;
* max torque:  0.15 Nm (approx)&lt;br /&gt;
* max speed:  600 RPM (approx)&lt;br /&gt;
* encoder:  600 counts/rev at output shaft, 2400 counts/rev in 4x decoding mode&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The motor is rated at 24 volts, giving a no-load (maximum)&lt;br /&gt;
speed of 3990 RPM (about 418 radians/sec) and a (maximum) stall torque of 31.9 mNm (milli&lt;br /&gt;
Newton meters).  The terminal resistance (the resistance through the&lt;br /&gt;
motor windings) is 41.5 ohms.  This means if you put 24 V across it,&lt;br /&gt;
the maximum current that it will draw is 24/41.5 = 0.58 Amps.  This&lt;br /&gt;
maximum current occurs when the motor is stalled and generating its&lt;br /&gt;
maximum torque.  Motor torque is proportional to the motor current by&lt;br /&gt;
the constant of proportionality called the &amp;#039;&amp;#039;torque constant&amp;#039;&amp;#039;,&lt;br /&gt;
which is different for every motor.&lt;br /&gt;
&lt;br /&gt;
The motor is called a 6 Watt motor because that is the maximum&lt;br /&gt;
electrical power (current times voltage) that can be put into the&lt;br /&gt;
motor on a continuous basis.  Beyond this power level, the amount of&lt;br /&gt;
power dissipated by the resistance of the motor windings will cause&lt;br /&gt;
the windings to heat up unacceptably.  (It is fine to overpower the&lt;br /&gt;
motor intermittently, allowing the coils to cool so that the average&lt;br /&gt;
power does not exceed the rated power.)  At this operating point, &lt;br /&gt;
the motor draws 244 mA, giving 24 V x 0.244 A = 5.86 W electrical input&lt;br /&gt;
power.  At this operating point, the speed of the motor is approximately&lt;br /&gt;
1689 RPM, or 177 radians/sec, and the torque of the motor is 13.5 mNm,&lt;br /&gt;
giving 177 rad/sec x 0.0135 Nm = 2.39 W of mechanical output power,&lt;br /&gt;
giving a power-conversion efficiency of about 41% at this operating point.&lt;br /&gt;
The maximum efficiency of the motor is 70%, which occurs at a higher&lt;br /&gt;
speed and lower torque.  The maximum mechanical power you can get out&lt;br /&gt;
of the motor is (1/2 max torque) x (1/2 max speed) = 3.33 W.  This is&lt;br /&gt;
beyond the continuous operation recommendation, but it is fine to&lt;br /&gt;
run it for short periods at this operating point.&lt;br /&gt;
&lt;br /&gt;
Often you will want to run the motor at lower voltages, for instance&lt;br /&gt;
at 12 V, instead of the rated 24 V.  In this case just multiply the&lt;br /&gt;
max current, speed, and torques by the factor 12/24 = 1/2.  In particular,&lt;br /&gt;
the maximum output power will be only (1/2) x (1/2) = 1/4 the maximum at 24 V.&lt;br /&gt;
&lt;br /&gt;
This actuator comes with a 6:1 spur gearhead, which increases the&lt;br /&gt;
torque available at the gearhead&amp;#039;s output shaft by a factor of 6 and&lt;br /&gt;
decreases the speed by a factor of 6.  (In this ideal case, the&lt;br /&gt;
power at the gearhead&amp;#039;s output shaft is equal to the power at the input.&lt;br /&gt;
In practice, gearheads have an efficiency also; the maximum&lt;br /&gt;
efficiency of the gearhead here is 81%.  This reduces the torque&lt;br /&gt;
available.)&lt;br /&gt;
&lt;br /&gt;
In summary, then, if your application requires no more than about 6 x&lt;br /&gt;
31.9 mNm = 0.19 Nm maximum torque, 3990 RPM / 6 = 665 RPM max speed,&lt;br /&gt;
and 3.3 W max mechanical power, this may be the motor for you.&lt;br /&gt;
Reduce those values by a factor of 1/2, 1/2, and 1/4, respectively, if&lt;br /&gt;
you are operating the motor with 12 V max instead of 24 V max.&lt;br /&gt;
&lt;br /&gt;
This actuator also comes with 100 line single-ended incremental optical encoder,&lt;br /&gt;
with outputs A+ and B+.  There is no index channel.  The encoder is&lt;br /&gt;
attached to the motor.  Each of the A+ and B+ channels makes 100 pulses&lt;br /&gt;
per revolution of the motor, or 6 x 100 = 600 pulses per revolution of&lt;br /&gt;
the output shaft of the gearhead.  This means the encoder provides&lt;br /&gt;
360 deg / 600 pulses = 0.6 deg/pulse resolution when the pulses are &lt;br /&gt;
decoded with the 1x scheme, or 0.15 deg/pulse resolution with the 4x&lt;br /&gt;
decoding scheme.&lt;br /&gt;
&lt;br /&gt;
Information about the Maxon motor is given in this [[Media:maxon-2140-specs.pdf|data sheet]] which includes &lt;br /&gt;
other motors in this family (ours is the 24V version)&lt;br /&gt;
and this [[Media:maxon-our-specific-motor.pdf|data sheet]] which gives only&lt;br /&gt;
the information on this motor.  (Note the speed-torque curve is a bit misleading,&lt;br /&gt;
as it seems to imply the maximum speed of the motor is 6100 RPM, when it should&lt;br /&gt;
be 3990 RPM.)  Information on the 6:1 gearhead can be found &lt;br /&gt;
[[Media:maxon-gearhead.pdf|here]].  The encoder pin-out is indicated below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:encoder-maxon.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The encoder comes with a 4-connector ribbon cable, corresponding to GND, Channel A, Vcc (usually +5V), and Channel B, as&lt;br /&gt;
shown on the left.  Here the ribbon cable is broken out into a 10-pin connector (which we have in the lab).  The connector&lt;br /&gt;
above is made to work with the PC/104 stacks, and the pin-out is shown.  Always make sure you have the right connections&lt;br /&gt;
for your encoder so you don&amp;#039;t damage it!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Pittman GM8224 motor with 19.5:1 gearhead and 500 line encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:pittman-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
If you need more power than the motor above, this gearmotor may be a good choice.&lt;br /&gt;
As an added bonus, it provides much higher encoder resolution.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 24 V, 4.33 ohms resistance, max current 5.54 Amps&lt;br /&gt;
* max torque:  2 Nm (approx)&lt;br /&gt;
* max speed:  500 RPM (approx)&lt;br /&gt;
* encoder:  9750 counts/rev at output shaft, 39,000 counts/rev in 4x decoding mode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This motor is also rated at 24 V, with a terminal resistance of 4.33 ohms,&lt;br /&gt;
giving a stall (maximum) current of 5.54 Amps.  The stall torque of the motor&lt;br /&gt;
itself is 0.1186 Nm&lt;br /&gt;
and the no-load (maximum) speed is 10,158 RPM (1064 radians/sec).  The&lt;br /&gt;
recommended maximum continuous torque is 0.0185 Nm which occurs at &lt;br /&gt;
8573 RPM (898 radians/sec).  Taken together, the maximum motor mechanical power&lt;br /&gt;
is (1/2 Tmax) x (1/2 nmax) = 31.5 W and the maximum recommended continuous&lt;br /&gt;
mechanical power is 16.6 W.  The maximum electrical input power occurs when&lt;br /&gt;
the motor is stalled (or starting) and is 24 V x 5.54 A = 133 W.  If you&lt;br /&gt;
operate the motor at a smaller voltage V2, then multiply the currents, speeds,&lt;br /&gt;
and torques above by a factor V2/24 and the power by a factor of (V2/24)^2.&lt;br /&gt;
&lt;br /&gt;
This motor has a 19.5:1 gearhead with a power conversion efficiency of 73%.  &lt;br /&gt;
Ignoring the efficiency for the moment, the 19.5:1 gearbox means that this&lt;br /&gt;
actuator may be appropriate if our application calls for no more than a &lt;br /&gt;
maximum speed of 10,158 RPM / 19.5 = 521 RPM and a maximum torque of&lt;br /&gt;
0.1186 Nm x 19.5 = 2.3 Nm.  In other words, the output shaft speed is similar&lt;br /&gt;
to the Maxon gearmotor above, but with about 10 times the torque.  &lt;br /&gt;
&lt;br /&gt;
This motor comes with a 500 line encoder attached to the motor shaft.  The&lt;br /&gt;
encoder has output channels A+ and B+ (no index pulse).  This means that&lt;br /&gt;
the encoder provides 500 x 19.5 = 9750 pulses per revolution of the output shaft.&lt;br /&gt;
In the 4x decoding mode, this gives 39,000 counts per revolution, or a resolution&lt;br /&gt;
of 360/39,000 = 0.00923 degrees.&lt;br /&gt;
&lt;br /&gt;
We also have a limited number of Pittman GM8712 motors with a 19.5:1 gearhead&lt;br /&gt;
and 512 line encoder.  These motors are also rated at 24V but have a higher&lt;br /&gt;
terminal resistance of 12.1 ohms, giving a maximum current of 24/12.1 = 1.99 Amps.&lt;br /&gt;
They have a maximum speed of 7847 RPM and maximum torque of 0.052 Nm before the&lt;br /&gt;
gearhead, or (ignoring gearhead efficiency) 402 RPM and 1.01 Nm after the&lt;br /&gt;
gearhead.  This motor is less powerful and draws less current, which may&lt;br /&gt;
be appropriate for some applications.&lt;br /&gt;
The encoder provides 9984 pulses per revolution of the output shaft&lt;br /&gt;
of the gearhead, or 360/(4 x 9984) = 0.009 degrees resolution in 4x decoding mode.&lt;br /&gt;
&lt;br /&gt;
See the [[Media:pittmangearmotor.pdf|data sheet]] for more detailed&lt;br /&gt;
information on these Pittman 8224 and 8712 gearmotors.  The 8712 is not treated&lt;br /&gt;
explicitly, but is believed to be similar to the 8722.&lt;br /&gt;
&lt;br /&gt;
The quadrature encoder has four wires:  black (GND), red (+5V), and blue and yellow as &lt;br /&gt;
channels A and B.&lt;br /&gt;
&lt;br /&gt;
===Faulhaber 1524E006S motor with 141:1 gearhead and HES164A magnetic quadrature encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber.png|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* motor rated at 6V, 12 ohms resistance (motor: 1524E006S123, where 123 is a special order)&lt;br /&gt;
* 141:1 gearhead (gearhead:  15/5S141:1K832)&lt;br /&gt;
* max speed at 6V:  approximately 80 RPM at gearhead output&lt;br /&gt;
* quadrature encoder with 1 line per motor revolution, or 141 x 4 = 564 counts/rev at output shaft in 4x decoding mode (encoder:  HES164A)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This little motor is the right size, speed, and torque for small wheeled mobile robots.&lt;br /&gt;
Ours were bought surplus from [http://www.bgmicro.com bgmicro.com].  This &lt;br /&gt;
[http://www.robotroom.com/FaulhaberGearmotor.html page] by&lt;br /&gt;
David Cook has a lot of great information on this motor + gearhead + encoder combination.&lt;br /&gt;
More info can be found in this [[Media:faulhaber-datasheet.pdf|data sheet]] from Faulhaber,&lt;br /&gt;
though our exact model encoder and motor are not listed.  The gearhead has a right-angle&lt;br /&gt;
drive at the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber-pinout.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
The pins on the connector are (see figure at right):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1.  Motor + &amp;lt;br&amp;gt;&lt;br /&gt;
2.  +5V (or similar) to power the encoder&amp;lt;br&amp;gt;&lt;br /&gt;
3.  Encoder channel A&amp;lt;br&amp;gt;&lt;br /&gt;
4.  Encoder channel B&amp;lt;br&amp;gt;&lt;br /&gt;
5.  GND for the encoder&amp;lt;br&amp;gt;&lt;br /&gt;
6.  Motor -&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Encoder channels A and B can sink (connect to ground) up to probably 25mA like most Hall sensors.  There is only a a weak pull-up resistor inside, perhaps 10K, so they can only source (connect to +5) about 2mA.   If you find the logic high signal from the encoder channel is not close enough to +5, which can happen even due to loading by an LED, you may want to add an external pull-up resistor from each encoder channel to +5.  470ohms is a good choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:faulhaber-wheel.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
These [http://www.solarbotics.com/products/gmpw/ wheels] can be used with the motor (with the&lt;br /&gt;
right-angle drive) if you drill out the center of the wheel with a 9/32&amp;quot; bit (approximately).  Then you&lt;br /&gt;
should get a nice tight press-fit.  We have some of these wheels in the lab.  This press-fit is not &lt;br /&gt;
suitable for high-torque applications, though; the shaft may begin to slip.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Globe motor with 187.68:1 gearhead and 500 line encoder===&lt;br /&gt;
&lt;br /&gt;
[[image:globe-motor.jpg|right|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* motor rated at 12V, 21 ohms resistance (0.57 A stall current)&lt;br /&gt;
* 187.68:1 gearhead for high torque and low speed&lt;br /&gt;
* max speed at 12V:  approximately 17 RPM at gearhead output (no load speed, motor alone:  approx 3000 RPM)&lt;br /&gt;
* torque constant (motor alone):  approximately 34 mNm/A (or 281 V/RPM)&lt;br /&gt;
* stall torque:  motor alone:  0.019 Nm; with gearhead 2.4 Nm (based on torque multiplier of 125, less than the 187 gear ratio due to efficiency losses)&lt;br /&gt;
* quadrature encoder with 500 lines per motor revolution, or 500 x 4 x 187.68 = 375,360 counts/rev at output shaft in 4x decoding mode (encoder:  HEDS-5505 A04)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small motor combines with a high resolution encoder and a high gear ratio gearbox to give a high torque, low speed actuator with high resolution position sensing (and velocity sensing by finite differencing).  The stall torque for this gearmotor (at 12 V) is approximately the same as that for the Pittman GM8224 gearmotor (at 24 V), but the max speed for the PIttman gearmotor is 20 times higher.  The pin-out for the encoder is shown below.  You can attach to the encoder using a Samtec IDSS-05-D-12.00 cable (shown in the middle below; order directly from [http://www.samtec.com Samtec], about $3.50 each) or you can make your own cable using stranded wires (22 AWG or ribbon cable) crimped or soldered in female Molex terminal pins (Molex series KK 2759, part number WM1114CT-ND on digikey) in a Molex 5 position connector housing (Molex series KK 2695, part number WM1578-ND on digikey), shown at right below.  (See [[Making a Molex Connector]] for more details.) The [[Media:HEDS5500-encoder.pdf|datasheet]] for the encoder recommends putting a 3.2k pull-up resistor on Channels A and B (i.e., 3.2k resistors from these lines to +5V).  The encoder works without these, but the datasheet indicates that you get better rise times on the encoder signals at high speeds when the pull-up resistors are added.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-encoder-cable.jpg|200px]]&lt;br /&gt;
[[image:globe-encoder-cable-molex.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
An inside peek at the gearbox is shown below.  If you want a higher-speed (up to 3000 RPM at 12V) lower-torque actuator, you can try removing the gearbox.  This task takes a bit of work and depending on what output you want, may require a bit of machining.  See [[Accessing_Pinion_of_Globe_Motor|here]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Globe motor we have in stock can be modified to be high speed and low torque with a few adjustments.&lt;br /&gt;
&lt;br /&gt;
It is easy to do until the disassembled photo below.  Simply unscrew the three long screws and pull off the top of the gearbox, along with the output shaft of the gearbox.  Now you can see two shafts holding the stacks of gears actually implementing the reduction ratio.  Using a pair of pliers, pull off the spacers near the tops of these shafts (these are press-fitted onto the shafts).  Now the gears slide off the shafts.  (Actually, when I tried it, one shaft came out with the spacer, while the other shaft remained in place and only the spacer came off.)  The photo below shows the new state of the gearbox.  &amp;#039;&amp;#039;&amp;#039;Be careful not to manhandle the encoder when you apply large forces pulling off the spacers!&amp;#039;&amp;#039;&amp;#039;  You could damage the encoder.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-gearbox-annotated.jpg|300px]]&lt;br /&gt;
[[image:globe-nogearhead.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
The rest of the gearbox is held in place by two long screws that run the full length from the back of the motor.  These screws cannot be removed without removing the encoder.  Therefore, if you want to better expose the motor&amp;#039;s output shaft without entirely disassembling the motor, you can use a band saw to cut off the nearby posts (or to cut off the entire gearhead from the lip up) and to destroy and remove the pinion gear on the motor output shaft.&lt;br /&gt;
&lt;br /&gt;
The more involved but safer method to access the pinion or output shaft is to disassemble to motor.  To do this, use a small screwdriver to rotate the internal mechanism in the encoder.  See the picture below.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-scredriver-inserted.jpg|300px]]&lt;br /&gt;
[[image:globe-hex-wrench-inserted.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Rotate this as far as it will go until the one dot lines up with the one dot on the outside of the encoder.  This will line up a slot of the side of the encoder which a 0.035&amp;quot; hex wrench can be inserted into.  While applying a bit of pressure to the wrench, turn the pinion until the hex wrench fits into a set screw.  Unscrew this set screw a couple of turns and then pull gently on the encoder.  This will get to the following image:&lt;br /&gt;
&lt;br /&gt;
[[image:globe-encoder-removed.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Now unscrew the two exposed screws and then you will have access to the two bolts holding the motor together.  Unscrew these and the top portion of the motor can now be removed.  The best way to expose the pinion is to mill the top section of the motor to be much lower.  See the following photos for results.  Assemble the motor in reverse order, ensuring the set screw is tightened sufficiently.&lt;br /&gt;
&lt;br /&gt;
[[image:globe-dissassembled.jpg|300px]]&lt;br /&gt;
[[image:globe-exposed-pinion.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The two motor power leads are wound through a ferrite toroid to suppress EMI &amp;quot;noise.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Here you can find a [[Media:globe-cad.pdf|cad file]] describing this actuator, a [[Media:HEDS5500-encoder.pdf|datasheet]] for the encoder, and a [[Media:idss-connector.pdf|datasheet]] for the Samtec IDSS-05-D-12.00 connector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===GM3 and GM9 Gearmotors===&lt;br /&gt;
&lt;br /&gt;
[[image:GM3.png|right]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Summary:&amp;#039;&amp;#039;&amp;#039;  (GM3 pictured at right)&lt;br /&gt;
* rated at 6V, approx 10 ohms resistance&lt;br /&gt;
* 224:1 gearhead (GM3) or 143:1 gearhead (GM9)&lt;br /&gt;
* max speed at 6V approximately 43 RPM (GM3) or 84 RPM (GM9)&lt;br /&gt;
* stall torque at 6V approximately 73 oz-in (GM3) or 52 oz-in (GM9)&lt;br /&gt;
* no encoder installed, but can be modified to add one; see [[Adding_a_magnetic_encoder_to_a_GM3_Gearmotor|here]]&lt;br /&gt;
* size:  70 x 22.5 x 37 mm&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These highly-geared motors can be bought new at [http://www.solarbotics.com solarbotics.com] or [http://www.hobbyengineering.com hobbyengineering.com].  These motors work with these [http://www.solarbotics.com/products/gmpw/ wheels], which we have in&lt;br /&gt;
the lab.  The motors do not come with encoders, but you can [[Adding_a_magnetic_encoder_to_a_GM3_Gearmotor|add one yourself]],&lt;br /&gt;
similar to the magnetic encoder on the Faulhaber motor above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Stepper Motors==&lt;br /&gt;
&lt;br /&gt;
Stepper motors move in discrete steps.  The controller energizes electromagnet&lt;br /&gt;
coils, and the motor&amp;#039;s rotor rotates to the nearest equilibrium point.  By&lt;br /&gt;
proper sequencing of which coils are energized, the motor rotates as desired&lt;br /&gt;
(and, if the rotation is fast enough, may simply pass through the equilibrium&lt;br /&gt;
points without stopping).  &lt;br /&gt;
&lt;br /&gt;
One nice thing about stepper motors is that they do not require&lt;br /&gt;
feedback; we know how far the motor has rotated, because we commanded&lt;br /&gt;
the motion.  This becomes a problem if we try to rotate the motor too&lt;br /&gt;
fast, or if the load is larger than expected --- the motor may not&lt;br /&gt;
actually do what we commanded.  Stepper motors are a &lt;br /&gt;
good choice for relatively low-torque applications where the loads&lt;br /&gt;
are consistent, so we can be assured our commanded motions are followed.&lt;br /&gt;
&lt;br /&gt;
===Jameco 163395 8.4V bipolar stepper motor===&lt;br /&gt;
&lt;br /&gt;
[[image:small-stepper.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
Although this motor is rated at 8.4V, it is possible&lt;br /&gt;
to run it at lower or slightly higher voltages.&lt;br /&gt;
&lt;br /&gt;
* 1.8 deg/step (0.9 deg/half step)&lt;br /&gt;
* 8.4V, 2 phases, 30 ohms resistance, 280 mA current&lt;br /&gt;
* holding torque:  0.081 Nm (coils energized)&lt;br /&gt;
* detent torque:  0.0037 Nm (coils off)&lt;br /&gt;
* size:  1.64&amp;quot; motor diameter, 1.2&amp;quot; motor height&lt;br /&gt;
* shaft: 0.29&amp;quot; x 0.155&amp;quot; diameter&lt;br /&gt;
* mass:  0.24 kg&lt;br /&gt;
&lt;br /&gt;
More information can be found on this&lt;br /&gt;
[[Media:jameco-stepper-163395.pdf|data sheet]].&lt;br /&gt;
There are four leads, two for each independent coil.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jameco 162026CX 12V unipolar stepper motor===&lt;br /&gt;
&lt;br /&gt;
[[image:stepper-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
If you need more holding torque, this stepper may be a&lt;br /&gt;
good choice.&lt;br /&gt;
&lt;br /&gt;
* 1.8 deg/step (0.9 deg/half step)&lt;br /&gt;
* 12V, 4 phases, 20 ohms resistance, 600 mA current&lt;br /&gt;
* holding torque:  0.588 Nm (coils energized)&lt;br /&gt;
* detent torque:  0.071 Nm (coils off)&lt;br /&gt;
* size:  2.2&amp;quot; motor diameter, 2.0&amp;quot; motor height&lt;br /&gt;
* shaft:  1&amp;quot; x 0.25&amp;quot; diameter&lt;br /&gt;
* mass:  0.65 kg&lt;br /&gt;
&lt;br /&gt;
More information can be found on this&lt;br /&gt;
[[Media:jameco-stepper-162026.pdf|data sheet]] (ours is the &lt;br /&gt;
57BYG084).  There are six leads, three for each independent&lt;br /&gt;
coil.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==RC Servo Motors==&lt;br /&gt;
&lt;br /&gt;
RC servos are convenient for positioning applications that require&lt;br /&gt;
significant torque, not much speed, and only moderate positioning&lt;br /&gt;
precision.  They take three connections, power (+5V, typically),&lt;br /&gt;
ground, and a pulsing signal that tells the motor the desired angle (typically a&lt;br /&gt;
pulse of 0.5 - 3 ms every 20 ms or so, where the duration of the pulse&lt;br /&gt;
indicates the desired angle of the motor).&lt;br /&gt;
Inside the motor is a potentiometer that senses the actual angle of&lt;br /&gt;
the motor output shaft and a feedback controller that tries to make&lt;br /&gt;
the motor angle match that specified by the pulsed signal.  There is&lt;br /&gt;
also a large gear ratio such that the motor provides high torque at&lt;br /&gt;
low speed.  Most RC servos have limited angle range, like 180 degrees,&lt;br /&gt;
due to the angle-sensing potentiometer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Futaba S3004 standard ball bearing RC servo motor===&lt;br /&gt;
&lt;br /&gt;
[[image:RC-servo-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
* motor rotation:  180 degrees&lt;br /&gt;
* speed:  60 degrees in 0.23 sec at 4.8V, 0.19 sec at 6V&lt;br /&gt;
* torque:  0.31 Nm at 4.8V, 0.4 Nm at 6V&lt;br /&gt;
* size:  1.4&amp;quot; height, 0.8&amp;quot; width&lt;br /&gt;
* mass:  37.2 g&lt;br /&gt;
&lt;br /&gt;
These were purchased from Tower Hobbies, part number LM1954.&lt;br /&gt;
Higher torque versions are also available.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Solenoids==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Solenoids are simple on-off actuators consisting of a plunger moving in an&lt;br /&gt;
electromagnetic field.  If you power the electromagnet, the plunger is&lt;br /&gt;
&amp;quot;pushed&amp;quot; or &amp;quot;pulled&amp;quot; a particular stroke length, and if you unpower the&lt;br /&gt;
coil, the plunger returns to its original position, usually by a return &lt;br /&gt;
spring or gravity.  These are simple to control and useful for applications&lt;br /&gt;
where the actuator only has to take one of two positions.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We stock two solenoids (in addition to many random ones) which are basically&lt;br /&gt;
the same, except one is a &amp;quot;pull type&amp;quot; solenoid and the other is a &amp;quot;push type.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Jameco 262262 (pull) and 262271 (push) 12V open frame solenoid===&lt;br /&gt;
&lt;br /&gt;
[[image:solenoids-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
* 12 V, 36 ohm resistance, 333 mA&lt;br /&gt;
* holding force:  0.5 N&lt;br /&gt;
* stroke:  6 mm&lt;br /&gt;
* size:  1.5&amp;quot; length x 1.0&amp;quot; x 0.8&amp;quot; diameter&lt;br /&gt;
* shaft diameter: 0.310&amp;quot;&lt;br /&gt;
* mass:  96 g&lt;br /&gt;
&lt;br /&gt;
You can find a data sheet [[Media:jameco-solenoid-262262.pdf|here]].&lt;br /&gt;
You can attach a lever (or other mechanical transformer) to the plunger to&lt;br /&gt;
get more stroke and less force, or more force and less stroke.  If no lever&lt;br /&gt;
will meet your specs,&lt;br /&gt;
then you will need another solenoid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==AC Motors==&lt;br /&gt;
&lt;br /&gt;
[[image:ac-servo-small.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
Some projects need more power than any of the actuators above can&lt;br /&gt;
provide.  In that case, you may be able to use a Yaskawa AC motor.&lt;br /&gt;
These are technically in the Laboratory for Intelligent Mechanical&lt;br /&gt;
Systems, but they are available for Mechatronics use.  These should&lt;br /&gt;
not be a first choice, as (1) they can be dangerous due to their high&lt;br /&gt;
power, and (2) they limit the mobility of your project as they must be&lt;br /&gt;
plugged into the wall to get 110V AC.  You can find information&lt;br /&gt;
on these motors and their amplifiers&lt;br /&gt;
[http://www.mech.northwestern.edu/courses/433/Writeups/YaskawaMotors/YakawaACservomotors.htm  here].&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=IR_Tracker&amp;diff=8177</id>
		<title>IR Tracker</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=IR_Tracker&amp;diff=8177"/>
		<updated>2008-03-20T17:44:22Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Problems Encountered */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:IR_Tracker_Header.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:IR_Tracker_Team.jpg|right|Left to right: Matt, Mark and Alice|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
* Mark Straccia (Mechanical Engineering, Class of 2009)&lt;br /&gt;
* Matt Turpin (Mechanical Engineering, Class of 2009)&lt;br /&gt;
* Alice Zhao (Electrical Engineering, Class of 2008)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The goal of this project was to create a device that would follow a moving infrared light. The IR Tracker does this by continuously detecting the position of an infrared emitter in two axises, and then tracking the emitter with a laser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The IR Tracker follows two major steps: (1) Identify the position of the IR emitter (2) Rotate the device to align itself with the IR emitter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# The IR Tracker finds the location of the maximum infrared intensity in both the x-axis and y-axis. Two encoders continuously record the position of the IR emitter based on intensity levels detected by two IT detectors.&lt;br /&gt;
# Given the information about the location of the IR emitter, the device rotates itself in two dimensions to adjusts its plane to be normal to the IR emitter. At this point, the laser should point to the IR emitter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will discuss the mechanical design, electrical design, PIC code, resulting project and our team reflections.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
===Primary Components===&lt;br /&gt;
&lt;br /&gt;
The primary components used in this device are:&lt;br /&gt;
&lt;br /&gt;
* 2 Pitman Motors&lt;br /&gt;
* 2 RC Servos&lt;br /&gt;
* 1 Turntable (6031K17, McMaster-Carr, $2.20, readily available)&lt;br /&gt;
* 1 Cylindrical Bearing&lt;br /&gt;
* 1 Laser&lt;br /&gt;
* Mirror&lt;br /&gt;
* Plexiglas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Mechanical_Design.jpg|center|Mechanical Design|700px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:Detecting_Component.jpg|right|Detecting Component|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
===Detecting Component===&lt;br /&gt;
On the main plane of the device, two encoders are placed perpendicular to each other (able to track on two axises). Mirrors are placed on the output shafts of the two encoders at 45 degree angles. Two infrared detectors are placed in line with the encoders. While the encoders are constantly spinning, the mirrors detect light from the IR emitter and bounce the light to the IR detectors.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:Rotating_Component.jpg|right|Rotating Component|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
===Rotating Component===&lt;br /&gt;
Below the main plane of the device, two servos are used to rotate the entire device to align the main plane to be normal to the emitter. The main plane is attached to a block of Plexiglas that surrounds a cylindrical bearing. This bearing allows the main plane to rotate along the y-axis. This block of Plexiglas is mounted on a turntable which allows the main plane to rotate along the x-axis.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
===Primary Components===&lt;br /&gt;
&lt;br /&gt;
The primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* 1 PIC (18F4520)&lt;br /&gt;
* 2 IR Detector / Emitter Pairs&lt;br /&gt;
* 2 Hall Sensors &amp;amp; Small Magnets&lt;br /&gt;
* 1 H-Bridge (L298)&lt;br /&gt;
* 1 Inverting Schmidt Trigger (74HC14)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Circuit_Diagram.jpg|left|IR Tracker Schematic|thumb|500px]]&lt;br /&gt;
[[image:Circuit_Top_View.jpg|right|IR Tracker Top View|thumb|500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:IR_Detector_Emitter.jpg|left|IR Detector|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
===IR Detector / Emitter Pairs===&lt;br /&gt;
The IR Detector detects the intensity of IR light coming from the IR Emitter. Over each revolution of the encoder&amp;#039;s output shaft, the location of the maximum IR intensity is recorded. This information is given to the PIC to determine the servo&amp;#039;s next position.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Hall_Sensors.jpg|left|Hall Sensors|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
===Hall Sensors===&lt;br /&gt;
The Hall Sensors are used as a position marker for the encoders. They are located just below the output shafts of the encoders. A small magnet is placed on the side of the output shafts. As both encoder shafts spin, the Hall Sensor detects the location of the magnet. The purpose of the Hall Sensors is to use this information to sync the rotations of the two encoder shafts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = +1&amp;gt; &lt;br /&gt;
&amp;lt;b&amp;gt;PIC &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = -1&amp;gt;&lt;br /&gt;
The PIC is the central controller of the IR Tracker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = +1&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; MOSFETs &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = -1&amp;gt;&lt;br /&gt;
The MOSFETs are used as intermediate components between the PIC and the servo motors. It allows the Pittman motors to run in one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = +1&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; Inverting Schmidt Trigger &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = -1&amp;gt;&lt;br /&gt;
The Schmidt Trigger acts as an intermediate between both the PIC to the encoders on the motors and the PIC to the Hall Sensors. It helps filter out noisy signals and invert signals to be readable for the PIC.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:IR_Tracker_Code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
===Outline of Code===&lt;br /&gt;
&lt;br /&gt;
Here is a general outline of what the IR Tracker does:&lt;br /&gt;
&lt;br /&gt;
# Spin encoder shafts&lt;br /&gt;
# Record current position of the servo&lt;br /&gt;
# Determine location of the maximum IR intensity detected&lt;br /&gt;
# Convert encoder position to servo position&lt;br /&gt;
# Rotate the main plane to the new servo position&lt;br /&gt;
# Sync rotations of the two encoder shafts&lt;br /&gt;
# Repeat steps 2-6&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===main()===&lt;br /&gt;
&lt;br /&gt;
This is the main function of our code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   runsetup();&lt;br /&gt;
 &lt;br /&gt;
   while (TRUE)&lt;br /&gt;
   {&lt;br /&gt;
      encodersave();&lt;br /&gt;
      positioncount();&lt;br /&gt;
      ircheck();&lt;br /&gt;
      equalize();&lt;br /&gt;
   }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The five functions it encompasses are described in detail below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===runsetup()===&lt;br /&gt;
&lt;br /&gt;
The interrupts for both servos and Hall sensors are set, and motors begin to spin at full velocity. This function is only called once at the beginning of the main function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void runsetup()&lt;br /&gt;
{&lt;br /&gt;
   setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_1);       //External input from quadrature encoder 0&lt;br /&gt;
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);          //External input from quadrature encoder 1&lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 255, 5);                //Servo incrememnting timer at 1 kHz&lt;br /&gt;
   setup_timer_3(T3_INTERNAL | T3_DIV_BY_4);          //Servo reseting timer&lt;br /&gt;
 &lt;br /&gt;
   enable_interrupts(INT_TIMER2);                     //Enable ISR2 for servo&lt;br /&gt;
   enable_interrupts(INT_TIMER3);                     //Enable ISR3 for servo&lt;br /&gt;
   enable_interrupts(INT_EXT);                        //Enable Interrupt for Hall sensor X&lt;br /&gt;
   enable_interrupts(INT_EXT1);                       //Enable Interrupt for Hall sensor Y&lt;br /&gt;
   enable_interrupts(global);&lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(ccp_pwm);                               //Setup PWM1&lt;br /&gt;
   setup_ccp2(ccp_pwm);                               //Setup PWM2&lt;br /&gt;
 &lt;br /&gt;
   set_timer0(0);                                     //Clear starting point of counters&lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
 &lt;br /&gt;
   set_PWM1_duty(0);                                  //Motors off for startup&lt;br /&gt;
   set_PWM2_duty(0);&lt;br /&gt;
 &lt;br /&gt;
   for(ii=0;ii&amp;lt;3;ii++)                                //Start up flashing lights&lt;br /&gt;
   {&lt;br /&gt;
      output_d(0x55);&lt;br /&gt;
      delay_ms(100);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(100);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   set_PWM1_duty(1023);                               //Motors start at full velocity&lt;br /&gt;
   set_PWM2_duty(1023);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===encodersave()===&lt;br /&gt;
&lt;br /&gt;
This records the current servo positions in the both the x and y direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void encodersave()                                    //Counters will return the number of pulses to the inputs.&lt;br /&gt;
{ &lt;br /&gt;
   PositionCountX = get_timer0();                     //Relative position of the X encoder&lt;br /&gt;
   delay_us(10);&lt;br /&gt;
 &lt;br /&gt;
   PositionCountY = get_timer1();                     //Relative position of the Y encoder&lt;br /&gt;
   delay_us(10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===positioncount()===&lt;br /&gt;
&lt;br /&gt;
This uses LEDs to represent where in the rotation the mirrors are, with one LED for each axis. The LEDs are on for half of the rotation and off for the other half.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void positioncount()                                  //Gives visual information about where in the rotation the mirrors are&lt;br /&gt;
{&lt;br /&gt;
   if (PositionCountX &amp;gt;4875)&lt;br /&gt;
   {&lt;br /&gt;
      output_high(pin_D3);&lt;br /&gt;
   }&lt;br /&gt;
   else if(PositionCountX&amp;gt;0)&lt;br /&gt;
   {&lt;br /&gt;
      output_low(pin_D3);&lt;br /&gt;
   }&lt;br /&gt;
   if (PositionCountY &amp;gt; 4875)&lt;br /&gt;
   {&lt;br /&gt;
      output_high(pin_D4);&lt;br /&gt;
   }&lt;br /&gt;
   else if(PositionCountY&amp;gt;0)&lt;br /&gt;
   {&lt;br /&gt;
      output_low(pin_D4);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ircheck()===&lt;br /&gt;
&lt;br /&gt;
This finds the location of maximum infrared light in both the x-axis and y-axis. This information is originally collected as an encoder position count value, is converted into an angle in degrees and is then converted again into servo position count value, so that the servo can move to the appropriate location.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ircheck()                                        //Check to see where in the rotation&lt;br /&gt;
{&lt;br /&gt;
   if(PositionCountX&amp;lt;4875)                            //First half of rotation, facing up&lt;br /&gt;
   {&lt;br /&gt;
      if(input(PIN_C6)==0)                            //If IR detector is detecting encoded signal&lt;br /&gt;
      {&lt;br /&gt;
         output_high(PIN_D5);                         //Gives visual representation&lt;br /&gt;
         MomentX+=PositionCountX;                     //Increase moment count by position&lt;br /&gt;
         MomentCountX+=1;                             //Increase count of moments&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         output_low(PIN_D5);                          //Clear B5 if mirror is facing down&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else if((PositionCountX&amp;gt;=4875)&amp;amp;&amp;amp;(MomentCountX&amp;gt;5)) //Runs when this function is called and IR detector&lt;br /&gt;
   {&lt;br /&gt;
      AverageAngleX = (MomentX/MomentCountX);         //Average the moment to give the center of IR in terms of motor encoder counts&lt;br /&gt;
&lt;br /&gt;
      if (((AverageAngleX)&amp;gt;650)&amp;amp;&amp;amp;((AverageAngleX)&amp;lt;4800))&lt;br /&gt;
      {&lt;br /&gt;
         AnglePositionX = 3647-23*AverageAngleX/34;   //Convert motor encoder counts to servo values&lt;br /&gt;
       &lt;br /&gt;
         if (ServoCurrent[0] + AnglePositionX &amp;lt; 1950) //Less than 90 degress&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetX = 400;&lt;br /&gt;
         }&lt;br /&gt;
         else if (ServoCurrent[0] + AnglePositionX&amp;gt; 4250) //Greater than 450 degrees&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetX = 2700;&lt;br /&gt;
         }&lt;br /&gt;
         else                                         //between 90 and 450 degrees&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetX = AnglePositionX + ServoCurrent[0] - 1550;&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
      MomentX = 0;                                    //reset moment variables&lt;br /&gt;
      MomentCountX = 0;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   if(PositionCountY&amp;lt;4875)&lt;br /&gt;
   {&lt;br /&gt;
      if(input(PIN_C5)==0)&lt;br /&gt;
      {&lt;br /&gt;
         output_high(PIN_D6);&lt;br /&gt;
         MomentY+=PositionCountY;   &lt;br /&gt;
         MomentCountY+=1;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         output_low(PIN_D6);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else if((PositionCountY&amp;gt;=4875)&amp;amp;&amp;amp;(MomentCountY&amp;gt;5))&lt;br /&gt;
   {&lt;br /&gt;
      AverageAngleY = (MomentY/MomentCountY);&lt;br /&gt;
      &lt;br /&gt;
      if (((AverageAngleY)&amp;gt;650)&amp;amp;&amp;amp;((AverageAngleY)&amp;lt;4800))&lt;br /&gt;
      {&lt;br /&gt;
         AnglePositionY = 3647-23*AverageAngleY/34;&lt;br /&gt;
       &lt;br /&gt;
         // find target location in terms of servo counts&lt;br /&gt;
         if (ServoCurrent[1] + AnglePositionY &amp;lt; 1950) //less than 90 degress&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetY = 400;&lt;br /&gt;
         }&lt;br /&gt;
         else if (ServoCurrent[1] + AnglePositionY&amp;gt; 4250) // greater 450 deg&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetY = 2700;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetY = AnglePositionY + ServoCurrent[1] - 1550;&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
      MomentY = 0;&lt;br /&gt;
      MomentCountY = 0;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===equalize()===&lt;br /&gt;
&lt;br /&gt;
This syncs the speed and direction of the rotation of the two encoder motors.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void equalize()                                       //puts motors in phase with each other&lt;br /&gt;
{&lt;br /&gt;
  if(PositionCountX&amp;gt;PositionCountY)&lt;br /&gt;
  {&lt;br /&gt;
     set_PWM1_duty(850);&lt;br /&gt;
     set_PWM2_duty(1023);&lt;br /&gt;
  }&lt;br /&gt;
  else if (PositionCountX&amp;lt;PositionCountY)&lt;br /&gt;
  {&lt;br /&gt;
     set_PWM2_duty(850);&lt;br /&gt;
     set_PWM1_duty(1023);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===servotrack()===&lt;br /&gt;
&lt;br /&gt;
While this function isn&amp;#039;t in the main function, it is called in one of the interrupts. Its purpose is to slowly move the servos from their current location to its destination.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void servotrack() //Slowly adjusts the pulsing of the servo to place the plan in the appropriate location&lt;br /&gt;
{&lt;br /&gt;
if(((SlowServoX&amp;gt;15)&amp;amp;&amp;amp;(abs(ServoTargetX-ServoCurrent[0])&amp;gt;5))||((SlowServoX&amp;gt;8)&amp;amp;&amp;amp;(abs(ServoTargetX-ServoCurrent[0])&amp;gt;125))&lt;br /&gt;
  ||((SlowServoX&amp;gt;3)&amp;amp;&amp;amp;(abs(ServoTargetX-ServoCurrent[0])&amp;gt;450))||SlowServoX&amp;gt;100)  //Can be used to slow down motion of Servos&lt;br /&gt;
   {&lt;br /&gt;
      if (ServoCurrent[0] &amp;lt; ServoTargetX - ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextX = ServoCurrent[0] + ServoMove;&lt;br /&gt;
         ServoCurrent[0] = ServoNextX;&lt;br /&gt;
      }&lt;br /&gt;
      else if (ServoCurrent[0] &amp;gt; ServoTargetX + ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextX = ServoCurrent[0] - ServoMove;&lt;br /&gt;
         ServoCurrent[0] = ServoNextX;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         ServoCurrent[0] = ServoTargetX;&lt;br /&gt;
      }&lt;br /&gt;
      SlowServoX=0;&lt;br /&gt;
   }&lt;br /&gt;
   if(((SlowServoY&amp;gt;15)&amp;amp;&amp;amp;(abs(ServoTargetY-ServoCurrent[1])&amp;gt;5))||((SlowServoY&amp;gt;8)&amp;amp;&amp;amp;(abs(ServoTargetY-ServoCurrent[1])&amp;gt;125))&lt;br /&gt;
     ||((SlowServoY&amp;gt;3)&amp;amp;&amp;amp;(abs(ServoTargetY-ServoCurrent[1])&amp;gt;450))||SlowServoY&amp;gt;100)&lt;br /&gt;
     &lt;br /&gt;
   {&lt;br /&gt;
      if (ServoCurrent[1] &amp;lt; ServoTargetY - ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextY = ServoCurrent[1] + ServoMove;&lt;br /&gt;
         ServoCurrent[1] = ServoNextY;&lt;br /&gt;
      }&lt;br /&gt;
      else if (ServoCurrent[1] &amp;gt; ServoTargetY + ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextY = ServoCurrent[1] - ServoMove;&lt;br /&gt;
         ServoCurrent[1] = ServoNextY;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         ServoCurrent[1] = ServoTargetY;&lt;br /&gt;
      }&lt;br /&gt;
      SlowServoY=0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   SlowServoX++;&lt;br /&gt;
   SlowServoY++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
===Final Design===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Final_Design.jpg|600px|center]]&lt;br /&gt;
&lt;br /&gt;
===Video===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;See Spot Run&amp;quot;: Click [http://depot.northwestern.edu/mht363/public_html/IR%20Track/Mar%2019%20IR%20tracker.mp4 here] to see a movie of our final project.&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
Overall, our team is very satisfied with our end result.&lt;br /&gt;
&lt;br /&gt;
===Objectives Met===&lt;br /&gt;
* Ability to locate the position of an IR emitter on two axises.&lt;br /&gt;
* Ability to rotate to align its plane to be normal to an IR emitter.&lt;br /&gt;
* Ability to continuously track an IR signal.&lt;br /&gt;
&lt;br /&gt;
===Problems Encountered===&lt;br /&gt;
* (Mechanical) Initially, the device had very shaky movements. We added additional screws to make the device more stable.&lt;br /&gt;
* (Electrical) We added Schmidt Triggers to clean up the noisy signals from the servo motors to the PICs.&lt;br /&gt;
* (Code) Originally coded to track direction of change of the IR emitter and supposed to move accordingly. We encountered a lot of noise. We changed the code to find the exact position of the IR emitter instead.&lt;br /&gt;
* (Electrical) The L298N H-bridge ended up heating up the entire circuit. In our final design, we chose to use MOSFETS in their place.&lt;br /&gt;
&lt;br /&gt;
===Future Work===&lt;br /&gt;
* More powerful servos and a more accurately calculated counterweight would help smooth the movement of the device.&lt;br /&gt;
* A more sensitive IR detector could track lower intensities of IR light in a room, instead of specifically an IR emitter.&lt;br /&gt;
* With more precise measurements of the relationship between the encoder and servo values, the IR Tracker could more accurately determine the position of an IR signal.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=IR_Tracker&amp;diff=8175</id>
		<title>IR Tracker</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=IR_Tracker&amp;diff=8175"/>
		<updated>2008-03-20T17:43:06Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Hall Sensors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:IR_Tracker_Header.jpg|400px|right]]&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:IR_Tracker_Team.jpg|right|Left to right: Matt, Mark and Alice|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
* Mark Straccia (Mechanical Engineering, Class of 2009)&lt;br /&gt;
* Matt Turpin (Mechanical Engineering, Class of 2009)&lt;br /&gt;
* Alice Zhao (Electrical Engineering, Class of 2008)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The goal of this project was to create a device that would follow a moving infrared light. The IR Tracker does this by continuously detecting the position of an infrared emitter in two axises, and then tracking the emitter with a laser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The IR Tracker follows two major steps: (1) Identify the position of the IR emitter (2) Rotate the device to align itself with the IR emitter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# The IR Tracker finds the location of the maximum infrared intensity in both the x-axis and y-axis. Two encoders continuously record the position of the IR emitter based on intensity levels detected by two IT detectors.&lt;br /&gt;
# Given the information about the location of the IR emitter, the device rotates itself in two dimensions to adjusts its plane to be normal to the IR emitter. At this point, the laser should point to the IR emitter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will discuss the mechanical design, electrical design, PIC code, resulting project and our team reflections.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Design==&lt;br /&gt;
&lt;br /&gt;
===Primary Components===&lt;br /&gt;
&lt;br /&gt;
The primary components used in this device are:&lt;br /&gt;
&lt;br /&gt;
* 2 Pitman Motors&lt;br /&gt;
* 2 RC Servos&lt;br /&gt;
* 1 Turntable (6031K17, McMaster-Carr, $2.20, readily available)&lt;br /&gt;
* 1 Cylindrical Bearing&lt;br /&gt;
* 1 Laser&lt;br /&gt;
* Mirror&lt;br /&gt;
* Plexiglas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Mechanical_Design.jpg|center|Mechanical Design|700px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:Detecting_Component.jpg|right|Detecting Component|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
===Detecting Component===&lt;br /&gt;
On the main plane of the device, two encoders are placed perpendicular to each other (able to track on two axises). Mirrors are placed on the output shafts of the two encoders at 45 degree angles. Two infrared detectors are placed in line with the encoders. While the encoders are constantly spinning, the mirrors detect light from the IR emitter and bounce the light to the IR detectors.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:Rotating_Component.jpg|right|Rotating Component|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
===Rotating Component===&lt;br /&gt;
Below the main plane of the device, two servos are used to rotate the entire device to align the main plane to be normal to the emitter. The main plane is attached to a block of Plexiglas that surrounds a cylindrical bearing. This bearing allows the main plane to rotate along the y-axis. This block of Plexiglas is mounted on a turntable which allows the main plane to rotate along the x-axis.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Electrical Design==&lt;br /&gt;
&lt;br /&gt;
===Primary Components===&lt;br /&gt;
&lt;br /&gt;
The primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* 1 PIC (18F4520)&lt;br /&gt;
* 2 IR Detector / Emitter Pairs&lt;br /&gt;
* 2 Hall Sensors &amp;amp; Small Magnets&lt;br /&gt;
* 1 H-Bridge (L298)&lt;br /&gt;
* 1 Inverting Schmidt Trigger (74HC14)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Circuit_Diagram.jpg|left|IR Tracker Schematic|thumb|500px]]&lt;br /&gt;
[[image:Circuit_Top_View.jpg|right|IR Tracker Top View|thumb|500px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:IR_Detector_Emitter.jpg|left|IR Detector|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
===IR Detector / Emitter Pairs===&lt;br /&gt;
The IR Detector detects the intensity of IR light coming from the IR Emitter. Over each revolution of the encoder&amp;#039;s output shaft, the location of the maximum IR intensity is recorded. This information is given to the PIC to determine the servo&amp;#039;s next position.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Hall_Sensors.jpg|left|Hall Sensors|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
===Hall Sensors===&lt;br /&gt;
The Hall Sensors are used as a position marker for the encoders. They are located just below the output shafts of the encoders. A small magnet is placed on the side of the output shafts. As both encoder shafts spin, the Hall Sensor detects the location of the magnet. The purpose of the Hall Sensors is to use this information to sync the rotations of the two encoder shafts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = +1&amp;gt; &lt;br /&gt;
&amp;lt;b&amp;gt;PIC &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = -1&amp;gt;&lt;br /&gt;
The PIC is the central controller of the IR Tracker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = +1&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; MOSFETs &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = -1&amp;gt;&lt;br /&gt;
The MOSFETs are used as intermediate components between the PIC and the servo motors. It allows the Pittman motors to run in one direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = +1&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt; Inverting Schmidt Trigger &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font size = -1&amp;gt;&lt;br /&gt;
The Schmidt Trigger acts as an intermediate between both the PIC to the encoders on the motors and the PIC to the Hall Sensors. It helps filter out noisy signals and invert signals to be readable for the PIC.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:IR_Tracker_Code.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
===Outline of Code===&lt;br /&gt;
&lt;br /&gt;
Here is a general outline of what the IR Tracker does:&lt;br /&gt;
&lt;br /&gt;
# Spin encoder shafts&lt;br /&gt;
# Record current position of the servo&lt;br /&gt;
# Determine location of the maximum IR intensity detected&lt;br /&gt;
# Convert encoder position to servo position&lt;br /&gt;
# Rotate the main plane to the new servo position&lt;br /&gt;
# Sync rotations of the two encoder shafts&lt;br /&gt;
# Repeat steps 2-6&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===main()===&lt;br /&gt;
&lt;br /&gt;
This is the main function of our code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   runsetup();&lt;br /&gt;
 &lt;br /&gt;
   while (TRUE)&lt;br /&gt;
   {&lt;br /&gt;
      encodersave();&lt;br /&gt;
      positioncount();&lt;br /&gt;
      ircheck();&lt;br /&gt;
      equalize();&lt;br /&gt;
   }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The five functions it encompasses are described in detail below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===runsetup()===&lt;br /&gt;
&lt;br /&gt;
The interrupts for both servos and Hall sensors are set, and motors begin to spin at full velocity. This function is only called once at the beginning of the main function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void runsetup()&lt;br /&gt;
{&lt;br /&gt;
   setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_1);       //External input from quadrature encoder 0&lt;br /&gt;
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);          //External input from quadrature encoder 1&lt;br /&gt;
   setup_timer_2(T2_DIV_BY_4, 255, 5);                //Servo incrememnting timer at 1 kHz&lt;br /&gt;
   setup_timer_3(T3_INTERNAL | T3_DIV_BY_4);          //Servo reseting timer&lt;br /&gt;
 &lt;br /&gt;
   enable_interrupts(INT_TIMER2);                     //Enable ISR2 for servo&lt;br /&gt;
   enable_interrupts(INT_TIMER3);                     //Enable ISR3 for servo&lt;br /&gt;
   enable_interrupts(INT_EXT);                        //Enable Interrupt for Hall sensor X&lt;br /&gt;
   enable_interrupts(INT_EXT1);                       //Enable Interrupt for Hall sensor Y&lt;br /&gt;
   enable_interrupts(global);&lt;br /&gt;
 &lt;br /&gt;
   setup_ccp1(ccp_pwm);                               //Setup PWM1&lt;br /&gt;
   setup_ccp2(ccp_pwm);                               //Setup PWM2&lt;br /&gt;
 &lt;br /&gt;
   set_timer0(0);                                     //Clear starting point of counters&lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
 &lt;br /&gt;
   set_PWM1_duty(0);                                  //Motors off for startup&lt;br /&gt;
   set_PWM2_duty(0);&lt;br /&gt;
 &lt;br /&gt;
   for(ii=0;ii&amp;lt;3;ii++)                                //Start up flashing lights&lt;br /&gt;
   {&lt;br /&gt;
      output_d(0x55);&lt;br /&gt;
      delay_ms(100);&lt;br /&gt;
      output_d(0);&lt;br /&gt;
      delay_ms(100);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   set_PWM1_duty(1023);                               //Motors start at full velocity&lt;br /&gt;
   set_PWM2_duty(1023);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===encodersave()===&lt;br /&gt;
&lt;br /&gt;
This records the current servo positions in the both the x and y direction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void encodersave()                                    //Counters will return the number of pulses to the inputs.&lt;br /&gt;
{ &lt;br /&gt;
   PositionCountX = get_timer0();                     //Relative position of the X encoder&lt;br /&gt;
   delay_us(10);&lt;br /&gt;
 &lt;br /&gt;
   PositionCountY = get_timer1();                     //Relative position of the Y encoder&lt;br /&gt;
   delay_us(10);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===positioncount()===&lt;br /&gt;
&lt;br /&gt;
This uses LEDs to represent where in the rotation the mirrors are, with one LED for each axis. The LEDs are on for half of the rotation and off for the other half.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void positioncount()                                  //Gives visual information about where in the rotation the mirrors are&lt;br /&gt;
{&lt;br /&gt;
   if (PositionCountX &amp;gt;4875)&lt;br /&gt;
   {&lt;br /&gt;
      output_high(pin_D3);&lt;br /&gt;
   }&lt;br /&gt;
   else if(PositionCountX&amp;gt;0)&lt;br /&gt;
   {&lt;br /&gt;
      output_low(pin_D3);&lt;br /&gt;
   }&lt;br /&gt;
   if (PositionCountY &amp;gt; 4875)&lt;br /&gt;
   {&lt;br /&gt;
      output_high(pin_D4);&lt;br /&gt;
   }&lt;br /&gt;
   else if(PositionCountY&amp;gt;0)&lt;br /&gt;
   {&lt;br /&gt;
      output_low(pin_D4);&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ircheck()===&lt;br /&gt;
&lt;br /&gt;
This finds the location of maximum infrared light in both the x-axis and y-axis. This information is originally collected as an encoder position count value, is converted into an angle in degrees and is then converted again into servo position count value, so that the servo can move to the appropriate location.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void ircheck()                                        //Check to see where in the rotation&lt;br /&gt;
{&lt;br /&gt;
   if(PositionCountX&amp;lt;4875)                            //First half of rotation, facing up&lt;br /&gt;
   {&lt;br /&gt;
      if(input(PIN_C6)==0)                            //If IR detector is detecting encoded signal&lt;br /&gt;
      {&lt;br /&gt;
         output_high(PIN_D5);                         //Gives visual representation&lt;br /&gt;
         MomentX+=PositionCountX;                     //Increase moment count by position&lt;br /&gt;
         MomentCountX+=1;                             //Increase count of moments&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         output_low(PIN_D5);                          //Clear B5 if mirror is facing down&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else if((PositionCountX&amp;gt;=4875)&amp;amp;&amp;amp;(MomentCountX&amp;gt;5)) //Runs when this function is called and IR detector&lt;br /&gt;
   {&lt;br /&gt;
      AverageAngleX = (MomentX/MomentCountX);         //Average the moment to give the center of IR in terms of motor encoder counts&lt;br /&gt;
&lt;br /&gt;
      if (((AverageAngleX)&amp;gt;650)&amp;amp;&amp;amp;((AverageAngleX)&amp;lt;4800))&lt;br /&gt;
      {&lt;br /&gt;
         AnglePositionX = 3647-23*AverageAngleX/34;   //Convert motor encoder counts to servo values&lt;br /&gt;
       &lt;br /&gt;
         if (ServoCurrent[0] + AnglePositionX &amp;lt; 1950) //Less than 90 degress&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetX = 400;&lt;br /&gt;
         }&lt;br /&gt;
         else if (ServoCurrent[0] + AnglePositionX&amp;gt; 4250) //Greater than 450 degrees&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetX = 2700;&lt;br /&gt;
         }&lt;br /&gt;
         else                                         //between 90 and 450 degrees&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetX = AnglePositionX + ServoCurrent[0] - 1550;&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
      MomentX = 0;                                    //reset moment variables&lt;br /&gt;
      MomentCountX = 0;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   if(PositionCountY&amp;lt;4875)&lt;br /&gt;
   {&lt;br /&gt;
      if(input(PIN_C5)==0)&lt;br /&gt;
      {&lt;br /&gt;
         output_high(PIN_D6);&lt;br /&gt;
         MomentY+=PositionCountY;   &lt;br /&gt;
         MomentCountY+=1;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         output_low(PIN_D6);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else if((PositionCountY&amp;gt;=4875)&amp;amp;&amp;amp;(MomentCountY&amp;gt;5))&lt;br /&gt;
   {&lt;br /&gt;
      AverageAngleY = (MomentY/MomentCountY);&lt;br /&gt;
      &lt;br /&gt;
      if (((AverageAngleY)&amp;gt;650)&amp;amp;&amp;amp;((AverageAngleY)&amp;lt;4800))&lt;br /&gt;
      {&lt;br /&gt;
         AnglePositionY = 3647-23*AverageAngleY/34;&lt;br /&gt;
       &lt;br /&gt;
         // find target location in terms of servo counts&lt;br /&gt;
         if (ServoCurrent[1] + AnglePositionY &amp;lt; 1950) //less than 90 degress&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetY = 400;&lt;br /&gt;
         }&lt;br /&gt;
         else if (ServoCurrent[1] + AnglePositionY&amp;gt; 4250) // greater 450 deg&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetY = 2700;&lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
            ServoTargetY = AnglePositionY + ServoCurrent[1] - 1550;&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
      MomentY = 0;&lt;br /&gt;
      MomentCountY = 0;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===equalize()===&lt;br /&gt;
&lt;br /&gt;
This syncs the speed and direction of the rotation of the two encoder motors.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void equalize()                                       //puts motors in phase with each other&lt;br /&gt;
{&lt;br /&gt;
  if(PositionCountX&amp;gt;PositionCountY)&lt;br /&gt;
  {&lt;br /&gt;
     set_PWM1_duty(850);&lt;br /&gt;
     set_PWM2_duty(1023);&lt;br /&gt;
  }&lt;br /&gt;
  else if (PositionCountX&amp;lt;PositionCountY)&lt;br /&gt;
  {&lt;br /&gt;
     set_PWM2_duty(850);&lt;br /&gt;
     set_PWM1_duty(1023);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===servotrack()===&lt;br /&gt;
&lt;br /&gt;
While this function isn&amp;#039;t in the main function, it is called in one of the interrupts. Its purpose is to slowly move the servos from their current location to its destination.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void servotrack() //Slowly adjusts the pulsing of the servo to place the plan in the appropriate location&lt;br /&gt;
{&lt;br /&gt;
if(((SlowServoX&amp;gt;15)&amp;amp;&amp;amp;(abs(ServoTargetX-ServoCurrent[0])&amp;gt;5))||((SlowServoX&amp;gt;8)&amp;amp;&amp;amp;(abs(ServoTargetX-ServoCurrent[0])&amp;gt;125))&lt;br /&gt;
  ||((SlowServoX&amp;gt;3)&amp;amp;&amp;amp;(abs(ServoTargetX-ServoCurrent[0])&amp;gt;450))||SlowServoX&amp;gt;100)  //Can be used to slow down motion of Servos&lt;br /&gt;
   {&lt;br /&gt;
      if (ServoCurrent[0] &amp;lt; ServoTargetX - ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextX = ServoCurrent[0] + ServoMove;&lt;br /&gt;
         ServoCurrent[0] = ServoNextX;&lt;br /&gt;
      }&lt;br /&gt;
      else if (ServoCurrent[0] &amp;gt; ServoTargetX + ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextX = ServoCurrent[0] - ServoMove;&lt;br /&gt;
         ServoCurrent[0] = ServoNextX;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         ServoCurrent[0] = ServoTargetX;&lt;br /&gt;
      }&lt;br /&gt;
      SlowServoX=0;&lt;br /&gt;
   }&lt;br /&gt;
   if(((SlowServoY&amp;gt;15)&amp;amp;&amp;amp;(abs(ServoTargetY-ServoCurrent[1])&amp;gt;5))||((SlowServoY&amp;gt;8)&amp;amp;&amp;amp;(abs(ServoTargetY-ServoCurrent[1])&amp;gt;125))&lt;br /&gt;
     ||((SlowServoY&amp;gt;3)&amp;amp;&amp;amp;(abs(ServoTargetY-ServoCurrent[1])&amp;gt;450))||SlowServoY&amp;gt;100)&lt;br /&gt;
     &lt;br /&gt;
   {&lt;br /&gt;
      if (ServoCurrent[1] &amp;lt; ServoTargetY - ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextY = ServoCurrent[1] + ServoMove;&lt;br /&gt;
         ServoCurrent[1] = ServoNextY;&lt;br /&gt;
      }&lt;br /&gt;
      else if (ServoCurrent[1] &amp;gt; ServoTargetY + ServoMove)&lt;br /&gt;
      {&lt;br /&gt;
         ServoNextY = ServoCurrent[1] - ServoMove;&lt;br /&gt;
         ServoCurrent[1] = ServoNextY;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
         ServoCurrent[1] = ServoTargetY;&lt;br /&gt;
      }&lt;br /&gt;
      SlowServoY=0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   SlowServoX++;&lt;br /&gt;
   SlowServoY++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
===Final Design===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:Final_Design.jpg|600px|center]]&lt;br /&gt;
&lt;br /&gt;
===Video===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;See Spot Run&amp;quot;: Click [http://depot.northwestern.edu/mht363/public_html/IR%20Track/Mar%2019%20IR%20tracker.mp4 here] to see a movie of our final project.&lt;br /&gt;
&lt;br /&gt;
==Reflections==&lt;br /&gt;
&lt;br /&gt;
Overall, our team is very satisfied with our end result.&lt;br /&gt;
&lt;br /&gt;
===Objectives Met===&lt;br /&gt;
* Ability to locate the position of an IR emitter on two axises.&lt;br /&gt;
* Ability to rotate to align its plane to be normal to an IR emitter.&lt;br /&gt;
* Ability to continuously track an IR signal.&lt;br /&gt;
&lt;br /&gt;
===Problems Encountered===&lt;br /&gt;
* (Mechanical) Initially, the device had very shaky movements. We added additional screws to make the device more stable.&lt;br /&gt;
* (Electrical) We added Schmidt Triggers to clean up the noisy signals from the servo motors to the PICs.&lt;br /&gt;
* (Code) Originally coded to track direction of change of the IR emitter and supposed to move accordingly. We encountered a lot of noise. We changed the code to find the exact position of the IR emitter instead.&lt;br /&gt;
* (Electrical) The Schmidt Triggers ended up heating up the entire circuit. In our final design, we chose to use MOSFETS in their place.&lt;br /&gt;
&lt;br /&gt;
===Future Work===&lt;br /&gt;
* More powerful servos and a more accurately calculated counterweight would help smooth the movement of the device.&lt;br /&gt;
* A more sensitive IR detector could track lower intensities of IR light in a room, instead of specifically an IR emitter.&lt;br /&gt;
* With more precise measurements of the relationship between the encoder and servo values, the IR Tracker could more accurately determine the position of an IR signal.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:I2CMotorControllerCode.zip&amp;diff=7552</id>
		<title>File:I2CMotorControllerCode.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:I2CMotorControllerCode.zip&amp;diff=7552"/>
		<updated>2008-03-17T03:02:26Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: The PIC C and MATLAB code for the I2C motor controller&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The PIC C and MATLAB code for the I2C motor controller&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_Motor_Controller&amp;diff=7551</id>
		<title>I2C Motor Controller</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_Motor_Controller&amp;diff=7551"/>
		<updated>2008-03-17T02:59:08Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This design is intended as a cost effective, readily available motor controller solution capable of handling multiple controllers from one master device in a logical, powerful and easy to use interface.&lt;br /&gt;
	&lt;br /&gt;
This solution is best suited to drive DC brush motors at encoder rates up to and exceeding 2 MHz.  Motor positions are measured with hardware quadrature encoding to achieve this high rate.  A built in PID controller with adjustable gains is used to control each motor to be flexible enough for any choice of motor.&lt;br /&gt;
&lt;br /&gt;
See the datasheet [[Media:I2CMotorController.PDF|&amp;#039;&amp;#039;&amp;#039;here&amp;#039;&amp;#039;&amp;#039;]] for more information about using this I2C motor controller.&lt;br /&gt;
&lt;br /&gt;
Download zip file of code [[Media:I2CMotorControllerCode.zip|&amp;#039;&amp;#039;&amp;#039;here&amp;#039;&amp;#039;&amp;#039;]]&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:I2CMotorController.PDF&amp;diff=7550</id>
		<title>File:I2CMotorController.PDF</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:I2CMotorController.PDF&amp;diff=7550"/>
		<updated>2008-03-17T02:57:27Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: A simple easy to construct I2C motor controller for the PIC 18F4520.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A simple easy to construct I2C motor controller for the PIC 18F4520.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_Motor_Controller&amp;diff=7549</id>
		<title>I2C Motor Controller</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_Motor_Controller&amp;diff=7549"/>
		<updated>2008-03-17T02:51:50Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This design is intended as a cost effective, readily available motor controller solution capable of handling multiple controllers from one master device in a logical, powerful and easy to use interface.&lt;br /&gt;
	&lt;br /&gt;
This solution is best suited to drive DC brush motors at encoder rates up to and exceeding 2 MHz.  Motor positions are measured with hardware quadrature encoding to achieve this high rate.  A built in PID controller with adjustable gains is used to control each motor to be flexible enough for any choice of motor.&lt;br /&gt;
&lt;br /&gt;
See the datasheet [[Media:I2CMotorController.PDF|&amp;#039;&amp;#039;&amp;#039;here&amp;#039;&amp;#039;&amp;#039;]] for more information about using this I2C motor controller.&lt;br /&gt;
&lt;br /&gt;
Download I2CMotorControllerCode.zip of code [[Media:I2CMotorControllerCode.zip|&amp;#039;&amp;#039;&amp;#039;here&amp;#039;&amp;#039;&amp;#039;]]&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Main_Page&amp;diff=7548</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Main_Page&amp;diff=7548"/>
		<updated>2008-03-17T02:46:15Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Northwestern University mechatronics design wiki provides reference material on the theory and applications of electronics, sensors, actuators, etc., for use in mechatronics-related research and projects.  Practical applications often refer to equipment and supplies available in the [http://mechatronics.mech.northwestern.edu/ Northwestern Mechatronics Design Lab].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Important:  Please be sure to read the [http://mechatronics.mech.northwestern.edu/mech-rules.pdf Rules for Using the Mechatronics Design Lab].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Design Competition 2008&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wiki pages on sensors, actuators, programming, and microcontrollers: use pages below&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* [http://www.mech.northwestern.edu/courses/433/Writeups/QuickStart/ Parts in the DC2008 quick start pack]&lt;br /&gt;
* [http://peshkin.mech.northwestern.edu/pic/info/piccintro_2008-01-24.pdf PIC C intro slides, as presented 2008/01/24 (pdf)]&lt;br /&gt;
* [http://peshkin.mech.northwestern.edu/pic/info/picinterfacing_2008-01-28.pdf PIC interfacing slides, as presented 2008/01/28 (pdf)]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Sensors and actuators for DC&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Using Solderless Breadboard|Solderless Breadboard &amp;amp; wiring that works]]&lt;br /&gt;
* [[Using LEDs &amp;amp; IREDs]]&lt;br /&gt;
* [[Using a laser]]&lt;br /&gt;
* [[Sensing optical tape|Infrared reflectivity]]&lt;br /&gt;
** Using phototransistors&lt;br /&gt;
** Sensing optical tape&lt;br /&gt;
* [[Comparators | Comparators : the analog digital interface]]&lt;br /&gt;
* [[Driving a DC Motor using PWM]]&lt;br /&gt;
* [http://www.robotroom.com/FaulhaberGearmotor.html Faulhaber MiniMotor SA gearmotor with encoder], as well as [[Actuators_Available_in_the_Mechatronics_Lab#Faulhaber_1524E006S_motor_with_141:1_gearhead_and_HES164A_magnetic_quadrature_encoder|the local wiki page]]&lt;br /&gt;
* [[Adding a magnetic encoder to a GM3 Gearmotor]]&lt;br /&gt;
** Using magnetic switches (Hall Effect)&lt;br /&gt;
* [[Driving using a single MOSFET | Driving a DC motor using a single MOSFET]]&lt;br /&gt;
* [[High-current devices|Driving high-current devices: several options]]&lt;br /&gt;
* [[Driving a Stepper Motor]]&lt;br /&gt;
* [[Driving an RC Servo]]&lt;br /&gt;
* [[Accelerometers]]&lt;br /&gt;
* [[Strain gauges]]&lt;br /&gt;
* [[Using the Basic Stamp Microcontroller|Basic Stamp Microcontroller]] &amp;lt;b&amp;gt;Not recommended for DC2008&amp;lt;/b&amp;gt;&lt;br /&gt;
* [http://www.mech.northwestern.edu/courses/433/Writeups/Battery_NiMH/ NiMH rechargable batteries and chargers]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt; [http://peshkin.mech.northwestern.edu/datasheets Prof. Peshkin&amp;#039;s favorite datasheets]&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;PIC 18F4520 prototyping board &amp;lt;/h3&amp;gt;&lt;br /&gt;
*[[4520 Board intro|Prototyping board intro]]&lt;br /&gt;
*[[4520 Board construction|Assembling the 18F4520 prototyping board, circuit, parts]]&lt;br /&gt;
*[[4520 Board use|Using the 18F4520 prototyping board]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Programming with CCS C &amp;lt;/h3&amp;gt;&lt;br /&gt;
*[[C language|The C language]]&lt;br /&gt;
*[[CCS C|CCS C, specifically for the 18F4520]]&lt;br /&gt;
*[[CCS IDE|Using the CCS development environment]]&lt;br /&gt;
*[[Debugging C on a PIC]]&lt;br /&gt;
*[[More debugging tips]]&lt;br /&gt;
*[http://www.ccsinfo.com/forum/ CCS user forum]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Interfacing and skeleton code for the PIC 18F4520&amp;lt;/h3&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;These topics have wiki pages &amp;lt;i&amp;gt;and&amp;lt;/i&amp;gt; sample code available&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;[http://peshkin.mech.northwestern.edu/pic/code Link to all sample code here.]&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Digital inputs &amp;amp; outputs]] (filename: DigitalIO)&lt;br /&gt;
* [[Analog Input]] (filename: AnalogInput)&lt;br /&gt;
** reading a trimpot&lt;br /&gt;
** reading a phototransistor&lt;br /&gt;
** amplified phototransistor, and IRED strobing&lt;br /&gt;
** using an instrumentation amp (example: for a strain gauge)&lt;br /&gt;
* [[Analog Output|Analog Output, and the I2C bus]] (filename: AnalogOutput)&lt;br /&gt;
*[[Pulse width modulation|Pulse width modulation (PWM) for driving motors or other high current devices]] (filename: MotorPWM)&lt;br /&gt;
** using H-bridges&lt;br /&gt;
* [[Interrupts]]&lt;br /&gt;
* [[Quadrature decoding in software]] (filename: QuadratureSoft)&lt;br /&gt;
* [[Quadrature decoding in hardware, or just counters]] (filename: QuadratureHard)&lt;br /&gt;
* [[Running RC servos]] (filename: RCservoSoft &amp;amp; RCservoHard)&lt;br /&gt;
* [[Watchdog timer]] (filename: Watchdog)&lt;br /&gt;
* [[PIC RS232|RS-232 serial communication between a PC and a PIC]] (filename: RS232)&lt;br /&gt;
* [[C Example: Serial LCD|Text output to a serial LCD display]]&lt;br /&gt;
* [[C Example: Parallel Interfacing with LCDs|Text output to a parallel LCD display]]&lt;br /&gt;
* [[Servo skeleton with fast &amp;amp; slow interrupts]]&lt;br /&gt;
* [[XBee radio communication between PICs]]&lt;br /&gt;
* [[I2C communication between PICs]]&lt;br /&gt;
* [[Serial communication with Matlab]]&lt;br /&gt;
* [[SPI communication between PICs]] &amp;lt;b&amp;gt; (Note:  this function has not been successfully tested)&amp;lt;/b&amp;gt;&lt;br /&gt;
* [[Microphones]]&lt;br /&gt;
* [[Ambient light color sensing]]&lt;br /&gt;
* [[Controlling a seven segment display]]&lt;br /&gt;
* [[Storing constant data in program memory]]&lt;br /&gt;
* [[PIC computation time benchmarks]]&lt;br /&gt;
* [[Stepper motor control with the PIC]]&lt;br /&gt;
* [[Global Positioning System]]&lt;br /&gt;
* [[IR communication between PICs]] &amp;lt;b&amp;gt; (Note:  this function has not been successfully tested) &amp;lt;/b&amp;gt;&lt;br /&gt;
* [[Interfacing to External EEPROM]]&lt;br /&gt;
* [[I2C Motor Controller]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;These topics have sample code available, but no wiki pages yet&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;[http://peshkin.mech.northwestern.edu/pic/code Link to all sample code here.]&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Counter0 - Counting pulses with Timer0]&lt;br /&gt;
* Counter1 - Counting pulses with Timer1]&lt;br /&gt;
* Interrupt0 - Periodic servo cycles using interrupt routines, 10mS &amp;amp; slower; Timer 0]&lt;br /&gt;
* Interrupt2 - Periodic servo cycles using interrupt routines; 10mS &amp;amp; faster; Timer 2]&lt;br /&gt;
* InterruptExternal - Interrupts generated by an external pulse]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;These topics need more development&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;[http://peshkin.mech.northwestern.edu/pic/code Link to all sample code here.]&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
* AnalogOutputParallel - Analog output using 8 digital lines]&lt;br /&gt;
* PIC-to-PIC communication &lt;br /&gt;
* Zigbee radio communication&lt;br /&gt;
* Modulated IR communication&lt;br /&gt;
* Strobing LEDs or IREDs for better range and immunity to background light&lt;br /&gt;
* I2C communication &lt;br /&gt;
* CAN bus&lt;br /&gt;
* Capturing data to Matlab&lt;br /&gt;
* Running stepper motors&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;PIC Microcontrollers&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[PIC Microcontrollers with CCS Compiler]], for DC, 333, etc, using the CCS ICD-U40 device &amp;lt;b&amp;gt;[this section has been replaced by the material above]&amp;lt;/b&amp;gt;&lt;br /&gt;
* [[PIC Microcontrollers with C18 Compiler]], for e-puck, or using the Microchip ICD device or&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;e-puck Mobile Robot&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[e-puck Mobile Robot]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;[[Printing Circuit Boards]]&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt; Basic Electronics &amp;lt;/h3&amp;gt;&lt;br /&gt;
* [http://hades.mech.northwestern.edu/wiki/index.php/Category:Electronics Electronics]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Analog and Digital chips&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Comparators | Comparators: the analog to digital interface]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Operational_amplifier_applications Opamps : building blocks of analog computation]&lt;br /&gt;
* [http://www.mech.northwestern.edu/courses/433/Writeups/InstAmp/instamp.htm Instrumentation amps, and NU circuit board for them]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;[[:Category:Sensors|Sensors]]&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Potentiometers|Angle, Linear Position: Potentiometers]]&lt;br /&gt;
* [[Optointerrupter|Beam Breaker: Optointerrupter]]&lt;br /&gt;
* [[Optoreflector|Proximity: Optoreflector]]&lt;br /&gt;
* [[Sensing optical tape|Infrared reflectivity : Sensing optical tape]]&lt;br /&gt;
* [[Reed Switch|Proximity: Reed Switch]]&lt;br /&gt;
* [[Hall Effect Sensor|Proximity, Angle: Hall Effect Sensor]]&lt;br /&gt;
* [[Rotary Encoder|Angle: Rotary Encoder]]&lt;br /&gt;
* Angular Velocity: Tachometer&lt;br /&gt;
* [[Photodiodes and Phototransistors|Light: Photodiodes and Phototransistors]]&lt;br /&gt;
* [[Photocell|Ambient Light: Photocell]]&lt;br /&gt;
* [[Thermistor|Temperature: Thermistor]]&lt;br /&gt;
* Temperature: Thermotransistor IC&lt;br /&gt;
* Audio: [[Microphones]]&lt;br /&gt;
* [[Accelerometers|Tilt, Acceleration: Accelerometers]]&lt;br /&gt;
* [[Strain Gauge|Force: Strain Gauge]]&lt;br /&gt;
* Current: Current Sense Resistor&lt;br /&gt;
* [[Limit Switch|Contact: Microswitch (Limit Switch)]]&lt;br /&gt;
* [[Ambient light color sensing]]&lt;br /&gt;
* [[Global Positioning System]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;[[:Category:Actuators|Actuators]]&amp;lt;/h3&amp;gt;&lt;br /&gt;
[[image:All-actuators-captions-small.jpg|thumb|300px|[[Actuators Available in the Mechatronics Lab|Available Actuators]]|right]]&lt;br /&gt;
&lt;br /&gt;
* [[Brushed DC Motor Theory|Brushed DC Motors]]&lt;br /&gt;
** [[Choosing a Motor and Gearing Combination|Choosing a Motor and Gearing Combination]]&lt;br /&gt;
** [[Linear Amplifier Motor Driver|Driving Using a Linear Amplifier]]&lt;br /&gt;
** [[Driving using a single MOSFET|Driving using a single MOSFET]]&lt;br /&gt;
** [[Pulse Width Modulation|Driving Using Pulse Width Modulation]]&lt;br /&gt;
** [[PIC PWM Motor Driver]]&lt;br /&gt;
** [[Gear Motor]]&lt;br /&gt;
*** [http://www.mech.northwestern.edu/courses/433/Writeups/AddEncoderHobbyEngGearMotor Adding a rotation encoder to a gearmotor]&lt;br /&gt;
* [[Brushless DC Motors]]&lt;br /&gt;
** [[Driving Brushless DC Motors]]&lt;br /&gt;
* [[Stepper Motor Theory|Stepper Motors]]&lt;br /&gt;
** [[Stepper Motor Circuits|Driving Stepper Motors]]&lt;br /&gt;
** [[Unipolar Stepper Motor Driver Circuit]]&lt;br /&gt;
** [[Bipolar Stepper Motor Driver Circuit]]&lt;br /&gt;
* [[RC Servo Theory|RC Servos]]&lt;br /&gt;
** [[555 Servo Circuit|Driving Your Servo Using a 555 Timer]]&lt;br /&gt;
* [[Solenoid Theory|Solenoids]]&lt;br /&gt;
** Practice: Driving Your Solenoid&lt;br /&gt;
* AC Motors&lt;br /&gt;
** [[Using the Yaskawa Motors]]&lt;br /&gt;
* [[Actuators Available in the Mechatronics Lab]]&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Mechanical Design&amp;lt;/h3&amp;gt;&lt;br /&gt;
*Mechanics of Materials&lt;br /&gt;
**Beam Mechanics&lt;br /&gt;
**[[Mohr&amp;#039;s Circle]]&lt;br /&gt;
*Failure Theories&lt;br /&gt;
**Static Loading&lt;br /&gt;
**Variable Loading and Fatigue&lt;br /&gt;
*Fastening&lt;br /&gt;
**Nuts and Bolts&lt;br /&gt;
**Keys and Keyways&lt;br /&gt;
**Press-fits&lt;br /&gt;
**Set Screws&lt;br /&gt;
*Support&lt;br /&gt;
**Housings&lt;br /&gt;
**Shafts&lt;br /&gt;
**[[Bearings]]&lt;br /&gt;
*Transmission&lt;br /&gt;
**Rigid: [[Gears]]&lt;br /&gt;
**Flexible: Belts, Chains&lt;br /&gt;
**Motion Connection/Separation: Clutches, Brakes, Couplings&lt;br /&gt;
*Linkages&lt;br /&gt;
**Serial Chains&lt;br /&gt;
**Parallel and Closed-Loop Chains&lt;br /&gt;
*Other: springs/dampers, cams, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;The PC/104 Stack&amp;lt;/h3&amp;gt;&lt;br /&gt;
[[Image:Img0174.jpg|thumb|300px|[[PC104 Overview|The PC104 Stack]]|right]]&lt;br /&gt;
* [[PC104 Overview|Overview]]&lt;br /&gt;
* [[The PC/104 Lab Kit]]&lt;br /&gt;
* Hardware:&lt;br /&gt;
** [[Advantech CPU Card]]&lt;br /&gt;
** [[Sensoray 526 Data Aquisition Card]]&lt;br /&gt;
&lt;br /&gt;
** [http://www.mech.northwestern.edu/courses/433/Writeups/PC104BoB/stack.htm#power[Power Components]]&lt;br /&gt;
** [http://www.mech.northwestern.edu/courses/433/Writeups/PC104BoB/stack.htm#electrical[I/O Electronics: Analog I/O, Digital I/O, Encoder Connections]]&lt;br /&gt;
* Advanced: Creating a Working Stack from Parts&lt;br /&gt;
** [http://www.mech.northwestern.edu/courses/433/Writeups/PC104BoB/stack.htm [Building the Breakout Board]]&lt;br /&gt;
** [http://www.mech.northwestern.edu/courses/433/Writeups/PC104BoB/stack.htm#ribboncables[Breakout Board Ribbon Cables]]&lt;br /&gt;
** [http://www.mech.northwestern.edu/courses/433/Writeups/PC104BoB/stack.htm#mechanical[Assembling the PC104 Stack]]&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;[[Creating an xPC Flash Boot Disk]]&amp;#039;&amp;#039;&amp;#039; &amp;lt;- when new version of MATLAB&lt;br /&gt;
* Custom Boards&lt;br /&gt;
** Dual PWM Motor Controller&lt;br /&gt;
** Dual Linear Amplifier Motor Controller&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;xPC Target Real-Time Operating System&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[xPC Overview|Overview of Real-Time Programming with Simulink and xPC Target]]&lt;br /&gt;
* [[Configuring xPC Target PC|Configuring xPC Host/Target PC]]&lt;br /&gt;
* [[Creating a Simple xPC Program|&amp;#039;&amp;#039;&amp;#039;Quickstart&amp;#039;&amp;#039;&amp;#039;:Creating a simple xPC Program]]&lt;br /&gt;
* [[Common xPC Blocks|Commonly Used Blocks]]&lt;br /&gt;
* [[Using the Host Scope]]&lt;br /&gt;
*Advanced&lt;br /&gt;
** Model Properties&lt;br /&gt;
** [[XPC M-file Communication|M-file communication]]&lt;br /&gt;
** Using outside of the lab&lt;br /&gt;
** [[media:standalone.pdf|Standalone Mode]]&lt;br /&gt;
** Stateflow&lt;br /&gt;
* Code Examples&lt;br /&gt;
** [[Controlling a DC Motor with an Encoder]]&lt;br /&gt;
** Something With State Machine&lt;br /&gt;
** [[Using RS-232 and Printing to LCD]]&lt;br /&gt;
**[[UDP Communications between Target and Host PC]]&lt;br /&gt;
** M-functions and S-functions&lt;br /&gt;
** [[xPC Code From Student Projects]]&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;QNX Real-Time Operating System&amp;lt;/h3&amp;gt;&lt;br /&gt;
*[[media:qnxtemplate.zip|QNX Control Program with Interrupts]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Lab Supplies and Data Sheets&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://spreadsheets.google.com/pub?key=pa_bNAhFF-OvvxpSje1KDYg&amp;amp;output=html&amp;amp;gid=0&amp;amp;single=true Generally stocked lab inventory ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;[[Vendors]]&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Other Software&amp;lt;/h3&amp;gt;&lt;br /&gt;
*[[List of Useful Software for Download]]&lt;br /&gt;
*Circuit Schematics and PCB Layout&lt;br /&gt;
*LaTex Document Preparation&lt;br /&gt;
** [http://meta.wikimedia.org/wiki/Help:Formula Mathematical Formulae]&lt;br /&gt;
** Document Formatting&lt;br /&gt;
** [[LaTeX Software Setup|Software Setup]]&lt;br /&gt;
** IEEE Styles&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;[[Other Lab Equipment]]&amp;lt;/h3&amp;gt;&lt;br /&gt;
* Prototyping Tools&lt;br /&gt;
** [[Tektronix TDS220 Oscilloscope]]&lt;br /&gt;
** [[Tektronix CFG253 Function Generator]]&lt;br /&gt;
** [[media:Mastech_power_supply_manual.pdf|Mastech Power Supply]]&lt;br /&gt;
** Fluke III Multimeter&lt;br /&gt;
** Benchtop Multimeter&lt;br /&gt;
** Powered Breadboard&lt;br /&gt;
** Soldering Iron&lt;br /&gt;
* [http://ediacaran.mech.northwestern.edu/neuromech/index.php/Lab_Equipment High Performance Neuromechatronics Benches]&lt;br /&gt;
* The Sensoray 626 DAQ Card&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Course Material&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[ME 224 Experimental Engineering]]&lt;br /&gt;
* [http://lims.mech.northwestern.edu/~lynch/courses/ME333/2008/index.html ME 333 Introduction to Mechatronics]&lt;br /&gt;
** [[Lab 5]]&lt;br /&gt;
** [[Suggested final projects]]&lt;br /&gt;
** [[ME 333 final projects]]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* [http://www.mech.northwestern.edu/hartmann/ME333_CourseInformation.html ME 333 Mechatronics]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://www.mech.northwestern.edu/courses/433/ ME 433 Advanced Mechatronics] &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Miscellaneous&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Swarm Robot Project]]&lt;br /&gt;
** [[Swarm Robot Project Links]]&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6990</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6990"/>
		<updated>2008-02-18T06:38:14Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf I2C] is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  This protocol was designed by Phillips Semiconductors around 1992 to allow easy communication between components on the same circuit board and can achieve transfer rates of up to 400 kbit/sec.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown in the example image.  It is possible to use lines accessible from the prototyping board to communicate via software I2C, but this has data rates of less than one fourth those of hardware I2C and will therefore be omitted.  I2C requires the lines to be high unless the master or the slave is pulling the line down, so you will need to use pull up resistors on both the clock and data lines.&lt;br /&gt;
&lt;br /&gt;
An communication diagram is shown:&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
* P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
* B - Individual bits being transferred.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.  The first line is the issuing of the start command and this forces all slave devices on the bus to wait for their address.  The next write command is the address of the slave.  The following byte is the data being sent to the slave.  All communication must terminate with a stop command or the line will remain open and no future communication is possible until the command is given.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
The definition of state is to determine whether or not the master is requesting or sending data.&lt;br /&gt;
&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
State is less than 0x80 for all read operations.&lt;br /&gt;
&lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
State will be equal to 0x80 for write commands.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below with an analogue input on the slave and three switches.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
The first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
Phillips Brief on I2c: http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf&lt;br /&gt;
&lt;br /&gt;
An I2C Primer: http://www.i2c-bus.org/I2C-Primer.520.0.html&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6989</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6989"/>
		<updated>2008-02-18T06:15:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
[http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf I2C] is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  This protocol was designed by Phillips Semiconductors around 1992 to allow easy communication between components on the same circuit board and can achieve transfer rates of up to 400 kbit/sec.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown in the example image.  I2C requires the lines to be high unless the master or the slave is pulling the line down, so you will need to use pull up resistors on both the clock and data lines.&lt;br /&gt;
&lt;br /&gt;
An communication diagram is shown:&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
* P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
* B - Individual bits being transferred.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.  The first line is the issuing of the start command and this forces all slave devices on the bus to wait for their address.  The next write command is the address of the slave.  The following byte is the data being sent to the slave.  All communication must terminate with a stop command or the line will remain open and no future communication is possible until the command is given.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
The definition of state is to determine whether or not the master is requesting or sending data.&lt;br /&gt;
&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
State is less than 0x80 for all read operations.&lt;br /&gt;
&lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
State will be equal to 0x80 for write commands.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below with an analogue input on the slave and three switches.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
The first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
Phillips Brief on I2c: http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf&lt;br /&gt;
&lt;br /&gt;
An I2C Primer: http://www.i2c-bus.org/I2C-Primer.520.0.html&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6988</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6988"/>
		<updated>2008-02-18T06:05:21Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Two Way Communication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown in the example image.  I2C requires the lines to be high unless the master or the slave is pulling the line down, so you will need to use pull up resistors on both the clock and data lines.&lt;br /&gt;
&lt;br /&gt;
An communication diagram is shown:&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
* P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
* B - Individual bits being transferred.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.  The first line is the issuing of the start command and this forces all slave devices on the bus to wait for their address.  The next write command is the address of the slave.  The following byte is the data being sent to the slave.  All communication must terminate with a stop command or the line will remain open and no future communication is possible until the command is given.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
The definition of state is to determine whether or not the master is requesting or sending data.&lt;br /&gt;
&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
State is less than 0x80 for all read operations.&lt;br /&gt;
&lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
State will be equal to 0x80 for write commands.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below with an analogue input on the slave and three switches.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
The first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6987</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6987"/>
		<updated>2008-02-18T05:50:42Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown in the example image.  I2C requires the lines to be high unless the master or the slave is pulling the line down, so you will need to use pull up resistors on both the clock and data lines.&lt;br /&gt;
&lt;br /&gt;
An communication diagram is shown:&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
* P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
* B - Individual bits being transferred.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.  The first line is the issuing of the start command and this forces all slave devices on the bus to wait for their address.  The next write command is the address of the slave.  The following byte is the data being sent to the slave.  All communication must terminate with a stop command or the line will remain open and no future communication is possible until the command is given.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
&lt;br /&gt;
The definition of state is to determine whether or not the master is requesting or sending data.&lt;br /&gt;
&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
State is less than 0x80 for all read operations.&lt;br /&gt;
&lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
State will be equal to 0x80 for write commands.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
the first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6986</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6986"/>
		<updated>2008-02-18T03:12:53Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown in the example image.  I2C requires the lines to be high unless the master or the slave is pulling the line down, so you will need to use pull up resistors on both the clock and data lines.&lt;br /&gt;
&lt;br /&gt;
An communication diagram is shown:&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
* P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
* B - Individual bits being transferred.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
the first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6985</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6985"/>
		<updated>2008-02-18T03:02:16Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown below.&lt;br /&gt;
&lt;br /&gt;
An example communication diagram is shown below&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
* P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
the first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6984</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6984"/>
		<updated>2008-02-18T03:01:51Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown below.&lt;br /&gt;
&lt;br /&gt;
An example communication diagram is shown below&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
S - As the master pulls down the data line, the falling edge of the data line signifies the start condition.&lt;br /&gt;
P - As the master allows the data line to rise, the rising edge of the data line signifies the stop condition.&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
the first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6983</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6983"/>
		<updated>2008-02-18T02:59:22Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown below.&lt;br /&gt;
&lt;br /&gt;
An example communication diagram is shown below&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
S - Start condition; P - Stop condition; B - One bit transferred&lt;br /&gt;
&lt;br /&gt;
The data line can only change while the clock line is low.  The data line is only read when the clock line is high and therefore 1 bit can be transferred per cycle of the clock line.&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
the first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:I2C_Data_Transfer.jpg&amp;diff=6982</id>
		<title>File:I2C Data Transfer.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:I2C_Data_Transfer.jpg&amp;diff=6982"/>
		<updated>2008-02-18T02:58:44Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A sequence diagram of data transfer on the I²C bus S - Start condition; P - Stop condition; B - One bit transferred; data changes allowed when clock low (blue)&lt;br /&gt;
&lt;br /&gt;
Thanks to Marcin Floryan from http://en.wikipedia.org/wiki/Image:I2C_data_transfer.svg for releasing this image into the public domain.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6902</id>
		<title>I2C communication between PICs</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=I2C_communication_between_PICs&amp;diff=6902"/>
		<updated>2008-02-11T17:38:00Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Microcontrollers commonly talk to each other using protocols such as RS-232, SPI (for &amp;quot;serial peripheral interface&amp;quot;), I2C (or I^2C, &amp;quot;I squared C,&amp;quot; for inter-integrated circuit), CAN bus, or other.  This project is to demonstrate bidirectional I2C communication between two PICs.  A demonstration might have the value of an analog input (potentiometer) at one PIC displayed as a &amp;quot;light bar&amp;quot; on the LEDs of the other PIC board, and simultaneously vice-versa.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
I2C is pronounced &amp;quot;I squared C&amp;quot; and stands for Inter-Integrated Circuit.  Is is a 2 line (plus common ground) communication method for one master device to control up to 112 slave devices.  While it is possible to have multiple masters on the same I2c bus, this page will only deal with a one master configuration.&lt;br /&gt;
&lt;br /&gt;
The two lines are named SCL and SDA where SCL is the CLock line and SDA is the DAta line.  The PIC 4520 is designed to use pin 18 as SCL and pin 23 as SDA for hardware I2C.  Note that pin 18 is one of the only pins not accessible on the prototyping board.  An additional wire can be added as shown below.&lt;br /&gt;
&lt;br /&gt;
An example communication diagram is shown below&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Data_Transfer.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
S - Start condition; P - Stop condition; B - One bit transferred; data changes allowed when clock low (blue)&lt;br /&gt;
&lt;br /&gt;
The master is initially sends a start bit followed by the 7-bit address of the slave it wishes to communicate with. The next bit represents whether it wishes to write(0) to or read(1) from the slave.&lt;br /&gt;
&lt;br /&gt;
The slave then responds with an acknowledge bit. The transmission continues according to whether the master is attempting to read to or write from the device.&lt;br /&gt;
&lt;br /&gt;
The master then ends the transmission with a stop bit.  Another option is to send another start bit to continue the transfer in a combined message.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Below is a simple circuit diagram showing the master PIC with 2 close button switches.  Note that pin 18 (RC3) is not brought out to the circuit board, but a wire can be soldered next to the PIC itself.  Both SDA and SCL need pull up resistors as either the master or the slave can hold the line low to stop communication.&lt;br /&gt;
[[image:I2C Circuit Diagram.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example image of how to wire this.&lt;br /&gt;
[[image:I2C Wiring Image.jpg|center|600px]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
Code for master to slave transfer of one byte with switch de-bouncing can be found here:&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Master.c|&amp;#039;&amp;#039;&amp;#039;Master Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Slave.c|&amp;#039;&amp;#039;&amp;#039;Slave Code&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Master PIC, we first need to define the output pins and force hardware I2C communication.&lt;br /&gt;
&lt;br /&gt;
   #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built into the PIC, make sure to include this line in any master I2C program&lt;br /&gt;
&lt;br /&gt;
To communicate with a device, we use the following lines of code where 0x14 is the device name.&lt;br /&gt;
&lt;br /&gt;
   i2c_start();               //begin transmission&lt;br /&gt;
   i2c_write(0x14);           //select address of device to communicate with&lt;br /&gt;
   i2c_write(data);           //send actual data&lt;br /&gt;
   i2c_stop();                //terminate communication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the Slave PIC, we first need to define the output pins, define the name of the device and force hardware I2C communication.  This device was randomly assigned name 0x14, but could have been just about any even hex number with a few exceptions noted below code.&lt;br /&gt;
&lt;br /&gt;
   #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0x14, FORCE_HW) //make sure to include this line in any Slave I2C program&lt;br /&gt;
&lt;br /&gt;
The SSP interrupt is used for I2C communication.  When the master begins to transmit data, the PIC goes into this interrupt.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP                      //Interrupt for I2C activity&lt;br /&gt;
   void sspinterupt()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();   //Reading the type of transmission&lt;br /&gt;
   &lt;br /&gt;
      if(state &amp;lt; 0x80)           //Master is sending data&lt;br /&gt;
      {&lt;br /&gt;
         data = i2c_read();      //An array will be needed to store data if more than one byte is transferred&lt;br /&gt;
      }&lt;br /&gt;
      if(state == 0x80)          //Master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write(data);&lt;br /&gt;
      } &lt;br /&gt;
      output_d(data);            //Output data to port D to visualize&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Somewhere in the main section of the program, probably right away, the SSP interrupt will need to be enabled.&lt;br /&gt;
&lt;br /&gt;
   enable_interrupts(INT_SSP);&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
&lt;br /&gt;
Address exceptions:&lt;br /&gt;
&lt;br /&gt;
   0000 000 1 START byte - for slow micros without I2C h/w&lt;br /&gt;
   0000 001 X CBUS address - a different bus protocol&lt;br /&gt;
   0000 010 X Reserved for different bus format&lt;br /&gt;
   0000 011 X Reserved for future purposes&lt;br /&gt;
   0000 1XX X Hs-mode master code&lt;br /&gt;
   1111 1XX X Reserved for future purposes&lt;br /&gt;
   1111 0XX X 10-bit slave addressing&lt;br /&gt;
&lt;br /&gt;
== Two Way Communication ==&lt;br /&gt;
&lt;br /&gt;
An alternate circuit diagram is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:I2C_Alternate_Circuit_Diagram|center|600px]]&lt;br /&gt;
&lt;br /&gt;
Changes are made to the code to allow more than one bit of data as well as data transferred from the slave to the master.&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Master.c|&amp;#039;&amp;#039;&amp;#039;Alternate Master&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
[[Media:I2C_Alternate_Slave.c|&amp;#039;&amp;#039;&amp;#039;Alternate Slave&amp;#039;&amp;#039;&amp;#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Master&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An alternate address of 0xa0 is used to demonstrate any address can be used.&lt;br /&gt;
&lt;br /&gt;
To read from the slave, the first byte sent is the address of the slave.  The second byte is the location of the data on the slave being requested.  The communication is terminated before being restarted.&lt;br /&gt;
&lt;br /&gt;
   i2c_start ();           //begin communication&lt;br /&gt;
   i2c_write (0xa0);       //send slave address&lt;br /&gt;
   i2c_write (0x02);       //request slave internal memory address for analogue data&lt;br /&gt;
   i2c_stop();             //stop write cycle to shift to read cycle&lt;br /&gt;
   i2c_start ();           //send repeated start command to begin read cycle&lt;br /&gt;
&lt;br /&gt;
Immediately after restarting, the address plus one read bit added is sent.  The data requested previously is read and the communication is terminated.&lt;br /&gt;
&lt;br /&gt;
   i2c_write (0xa1);       //add 1 to the address to send a read bit&lt;br /&gt;
   result = i2c_read(0);   //read analogue information from the slave&lt;br /&gt;
   i2c_stop ();            //terminate communication&lt;br /&gt;
   output_d(result);       //display analogue information from the slave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Slave&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example a larger information buffer is used, an array of 0x03 bytes, but this can be as large as needed.&lt;br /&gt;
&lt;br /&gt;
   int address, buffer[0x03]; &lt;br /&gt;
&lt;br /&gt;
In the interrupt, most of the same code is used as before.&lt;br /&gt;
&lt;br /&gt;
   #INT_SSP&lt;br /&gt;
   void ssp_interupt ()&lt;br /&gt;
   {&lt;br /&gt;
      state = i2c_isr_state();&lt;br /&gt;
      if(state &amp;lt; 0x80)                 //master is sending data&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
the first command bit is empty, so nothing is done.&lt;br /&gt;
&lt;br /&gt;
         if(state == 0)&lt;br /&gt;
         {&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The first data byte returns state 1 and is the address to be written to.  &lt;br /&gt;
&lt;br /&gt;
         if(state == 1)                   //first received byte is address&lt;br /&gt;
         {&lt;br /&gt;
            address = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The second data byte is the information being received from the master and is stored in the address sent in the first data byte.&lt;br /&gt;
&lt;br /&gt;
         if(state == 2)                   //second received byte is data&lt;br /&gt;
         {&lt;br /&gt;
            buffer[address] = i2c_read();&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
If the master is requesting data, the slave sends data from the requested address.&lt;br /&gt;
&lt;br /&gt;
      if(state == 0x80)                //master is requesting data&lt;br /&gt;
      {&lt;br /&gt;
         i2c_write (buffer[address]);  //send requested data&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6838</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6838"/>
		<updated>2008-02-07T04:11:10Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf Parallax GPS (Global Positioning System) Receiver Module] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS module was designed to be used with a Basic Stamp and to use two directional information transmission.  In order to use this chip with a PIC, we will need to read in long serial strings containing all data and then parse the strings for important data to export. The PIC can use RS232 to read in the serial data and store a large array of all characters, which can then be parsed by searching for comma seperated values.&lt;br /&gt;
&lt;br /&gt;
The NEMA strings this particular GPS outputs are GPGGA,GPGSA,GPGSV, and GPRMC in that order.  For additional information about what data can be retrieved from these strings, go [http://home.mira.net/~gnb/gps/nmea.html here].&lt;br /&gt;
&lt;br /&gt;
Here is an example string:&lt;br /&gt;
[[image:GPS_Raw_Data_Stream|center]]&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
Parallax Info: http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf&lt;br /&gt;
&lt;br /&gt;
Circuit Info: http://hades.mech.northwestern.edu/wiki/index.php/C_Example:_Parallel_Interfacing_with_LCDs&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:GPS_Raw_Data_Stream&amp;diff=6837</id>
		<title>File:GPS Raw Data Stream</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:GPS_Raw_Data_Stream&amp;diff=6837"/>
		<updated>2008-02-07T04:02:05Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Here is an example of the serial output of a Parallax GPS module.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here is an example of the serial output of a Parallax GPS module.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6836</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6836"/>
		<updated>2008-02-07T04:01:08Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf Parallax GPS (Global Positioning System) Receiver Module] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The NEMA strings this particular GPS outputs are GPGGA,GPGSA,GPGSV, and GPRMC in that order.  For additional information about what data can be retrieved from these strings, go [http://home.mira.net/~gnb/gps/nmea.html here].&lt;br /&gt;
&lt;br /&gt;
Here is an example string:&lt;br /&gt;
[[image:GPS_Raw_Data_Stream|center]]&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
Parallax Info: http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf&lt;br /&gt;
&lt;br /&gt;
Circuit Info: http://hades.mech.northwestern.edu/wiki/index.php/C_Example:_Parallel_Interfacing_with_LCDs&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6835</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6835"/>
		<updated>2008-02-07T03:55:29Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf Parallax GPS (Global Positioning System) Receiver Module] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The NEMA strings this particular GPS outputs are GPGGA,GPGSA,GPGSV, and GPRMC in that order.  For additional information about what data can be retrieved from these strings, go [http://home.mira.net/~gnb/gps/nmea.html here].&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
Parallax Info: http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf&lt;br /&gt;
&lt;br /&gt;
Circuit Info: http://hades.mech.northwestern.edu/wiki/index.php/C_Example:_Parallel_Interfacing_with_LCDs&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:ParallaxGPS.c&amp;diff=6834</id>
		<title>File:ParallaxGPS.c</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:ParallaxGPS.c&amp;diff=6834"/>
		<updated>2008-02-07T03:54:32Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Full Parallax GPS code with parsing of 3 data selections.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Full Parallax GPS code with parsing of 3 data selections.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6833</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6833"/>
		<updated>2008-02-07T03:52:07Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf Parallax GPS (Global Positioning System) Receiver Module] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The NEMA strings this particular GPS outputs are GPGGA,GPGSA,GPGSV, and GPRMC in that order.  For additional information about what data can be retrieved from these strings, go [http://home.mira.net/~gnb/gps/nmea.html here].&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6832</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6832"/>
		<updated>2008-02-07T03:48:19Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf Parallax GPS (Global Positioning System) Receiver Module] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6831</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6831"/>
		<updated>2008-02-07T03:48:01Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [[http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf Parallax GPS (Global Positioning System) Receiver Module]] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Parallax_GPS_(Global_Positioning_System)_Receiver_Module&amp;diff=6830</id>
		<title>Parallax GPS (Global Positioning System) Receiver Module</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Parallax_GPS_(Global_Positioning_System)_Receiver_Module&amp;diff=6830"/>
		<updated>2008-02-07T03:46:56Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://info.hobbyengineering.com/specs/PX-GPSManualV1.1.pdf&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6829</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6829"/>
		<updated>2008-02-07T03:46:43Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The [[Parallax GPS (Global Positioning System) Receiver Module]] is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:GPS_Circuit.jpg&amp;diff=6828</id>
		<title>File:GPS Circuit.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:GPS_Circuit.jpg&amp;diff=6828"/>
		<updated>2008-02-07T03:43:28Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: An example of how to wire a parallax GPS on one solderless breadboard.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An example of how to wire a parallax GPS on one solderless breadboard.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6827</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6827"/>
		<updated>2008-02-07T03:41:49Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
[[image:GPS_Circuit.jpg|400px|center]]&lt;br /&gt;
Image 3 is an example of how to wire all these elements together on one breadboard&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6826</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6826"/>
		<updated>2008-02-07T03:40:03Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|400px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6825</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6825"/>
		<updated>2008-02-07T03:39:48Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|200px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|300px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Parallel_LCD_Wiring_Digram.jpg&amp;diff=6824</id>
		<title>File:Parallel LCD Wiring Digram.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Parallel_LCD_Wiring_Digram.jpg&amp;diff=6824"/>
		<updated>2008-02-07T03:37:27Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: Taken from http://hades.mech.northwestern.edu/wiki/index.php/C_Example:_Parallel_Interfacing_with_LCDs
See that page for code and additional information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Taken from http://hades.mech.northwestern.edu/wiki/index.php/C_Example:_Parallel_Interfacing_with_LCDs&lt;br /&gt;
See that page for code and additional information.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6823</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6823"/>
		<updated>2008-02-07T03:35:53Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|size=200px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|size=300px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6822</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6822"/>
		<updated>2008-02-07T03:33:36Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|size=200px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt; that the pin labeled &amp;quot;Raw&amp;quot; needs to be grounded with a 1K resistor.  The serial line also needs to be pulled high with a 1K resistor.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|size=300px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Parallax_GPS_Wiring_Digram.jpg&amp;diff=6821</id>
		<title>File:Parallax GPS Wiring Digram.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Parallax_GPS_Wiring_Digram.jpg&amp;diff=6821"/>
		<updated>2008-02-07T03:22:26Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: 4 pin connections for the Parallax GPS chip.  Note that the pin labeled &amp;quot;Raw&amp;quot; needs to pulled high with a 10k resistor.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;4 pin connections for the Parallax GPS chip.  Note that the pin labeled &amp;quot;Raw&amp;quot; needs to pulled high with a 10k resistor.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6820</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6820"/>
		<updated>2008-02-07T03:20:27Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image:Parallax_GPS_Wiring_Digram.jpg|size=300px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
[[image:Parallel_LCD_Wiring_Digram.jpg|size=300px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6819</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6819"/>
		<updated>2008-02-07T03:19:58Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
[[image=Parallax_GPS_Wiring_Digram.jpg|size=300px|center]]&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
[[image=Parallel_LCD_Wiring_Digram.jpg|size=300px|center]]&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6818</id>
		<title>Global Positioning System</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Global_Positioning_System&amp;diff=6818"/>
		<updated>2008-02-07T03:11:15Z</updated>

		<summary type="html">&lt;p&gt;Matt Turpin: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
&lt;br /&gt;
The goal of this assignment is to provide the code and circuitry necessary to retrieve data from a Parallax GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Parallax GPS (Global Positioning System) Receiver Module is a fully integrated, low-cost unit with an on-board patch antenna. It provides standard, raw NMEA0183 (National Marine Electronics Association) strings or specific data from up to 12 satellites via its serial command interface. It can provide the current time, date, latitude, longitude, altitude, speed, travel direction, and other data.&lt;br /&gt;
&lt;br /&gt;
The goal of the project was to set up a one-way connection between the PIC and the GPS Receiver Module, in which the PIC interprets the raw data collected by the GPS Receiver Module and displays it in a user-friendly format on a parallel LCD (Liquid Crystal Display). Specifically for this project, there are three sets of information that can be displayed: Position (Latitude / Longitude); Time &amp;amp; Number of Satellites Detectable; Velocity / Direction of Movement.&lt;br /&gt;
&lt;br /&gt;
We will first discuss the circuitry of PIC-GPS connection, followed by the method used to allow the PIC to gather data from the GPS Module, and finally how to display specific information on the parallel LCD.&lt;br /&gt;
&lt;br /&gt;
==Circuit==&lt;br /&gt;
&lt;br /&gt;
The four primary components used in this circuit are:&lt;br /&gt;
&lt;br /&gt;
* Controller (PIC)&lt;br /&gt;
* Parallax GPS Receiver Module&lt;br /&gt;
* Liquid Crystal Display&lt;br /&gt;
* Three buttons&lt;br /&gt;
&lt;br /&gt;
Image 1 shows the connection between the PIC and GPS Receiver Module.&lt;br /&gt;
&lt;br /&gt;
Image 2 shows the connection between the PIC and LCD.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[[media:ParallaxGPS.c|See full code here]]&lt;br /&gt;
&lt;br /&gt;
Include headers and set serial rate to 4800 baud&lt;br /&gt;
&lt;br /&gt;
   #include &amp;lt;18F4520.h&amp;gt;&lt;br /&gt;
   #fuses HS,NOWDT,PUT,NOLVP&lt;br /&gt;
   #use delay(clock=20000000)&lt;br /&gt;
   #use rs232(baud=4800, rcv=PIN_C1)        //can use any pin to read from GPS, but define it here&lt;br /&gt;
   #include &amp;quot;flex_lcd.c&amp;quot;                    //included to allow easy writing to a parallel LCD display&lt;br /&gt;
   &lt;br /&gt;
Variable declarations and start of main loop&lt;br /&gt;
&lt;br /&gt;
   char letter[300];&lt;br /&gt;
   int go = 0,wait = 0,commacount = 0,dataoutput = 1,j = 0;&lt;br /&gt;
   int16 i;&lt;br /&gt;
   int16 comma[90];&lt;br /&gt;
   &lt;br /&gt;
   void main()&lt;br /&gt;
   {&lt;br /&gt;
      lcd_init();&lt;br /&gt;
      while(TRUE)&lt;br /&gt;
      {&lt;br /&gt;
&lt;br /&gt;
One of the most important aspects of this code is waiting for signal to return to high.  Without this section, the rs232 command could end up in the middle of the output of the GPS and render all information unusable.  This loop waits for the signal to remain high for over 2 bytes to ensure it is at the stop position before beginning to read.&lt;br /&gt;
&lt;br /&gt;
         for (wait=0;wait&amp;lt;20;)               //for loop used to wait until signal has reset.  20*50us=1ms&amp;gt;two bytes of ones at 4800 baud&lt;br /&gt;
         {&lt;br /&gt;
            if (input(PIN_C1)==1)&lt;br /&gt;
            {&lt;br /&gt;
               wait++;&lt;br /&gt;
            }&lt;br /&gt;
            else if (input(pin_c1)==0)&lt;br /&gt;
            {&lt;br /&gt;
               wait = 0;&lt;br /&gt;
            }&lt;br /&gt;
            delay_us(50);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
After getting into the data loop, all data is recorded into a 300 character matrix letter&lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //record 300 characters into letter matrix&lt;br /&gt;
         {&lt;br /&gt;
            letter[i]= getc();&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The data is then parsed into sets of commas.  &lt;br /&gt;
&lt;br /&gt;
         for(i=0;i&amp;lt;300;i++)                  //parse matrix for commas (ascii=44 for a comma)&lt;br /&gt;
         {&lt;br /&gt;
            if (letter[i] == 44)&lt;br /&gt;
            {&lt;br /&gt;
               comma[commacount] = i;&lt;br /&gt;
               commacount++;&lt;br /&gt;
            }            &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
Counting variables are reset to zero at the end of the while loop&lt;br /&gt;
&lt;br /&gt;
         go = 0;                             //reset testing variables back to zero&lt;br /&gt;
         commacount=0;&lt;br /&gt;
&lt;br /&gt;
To finish the program, data must be converted into a usable format and output to the LCD screen.  See full code above for an example of how to do this.&lt;/div&gt;</summary>
		<author><name>Matt Turpin</name></author>
	</entry>
</feed>