<?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=JonathanShih</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=JonathanShih"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/JonathanShih"/>
	<updated>2026-05-16T14:00:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8695</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8695"/>
		<updated>2008-03-21T19:32:07Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional file BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
Note: Thanks to Matt Turpin (of the [[IR Tracker]] project) whose code from his 399 independent study proved incredibly useful for our project.&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. Once all the code is loaded onto the correct PICs, everything can be run through BKSBallControl.m.&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
At the time of our presentation, we were able to demonstrate rotation along two axes by using the drive motor and Lazy Susan. Additionally, we were able to show effective and consistent communication of multiple bytes of data from MATLAB to the master PIC vis RS-232. Unfortunately, we were unable to get the hardware for I2C working, despite the code working on Matt&#039;s setup. Overall, we were pleased with our progress in a relatively short amount of time.&lt;br /&gt;
&lt;br /&gt;
We hope to fix the hardware issue in the near future and possibly consolidate all the circuitry onto a PCB for a more robust device. We would also like to add a hall effect switch or limit switch to indicate a set &amp;quot;Home&amp;quot; position. Additional work can be done on the motor control functions to implement feedback control as necessary. As there are clients that would like to see this project come to fruition, we want to make sure they are given a robust and flexible system for their use.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8694</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8694"/>
		<updated>2008-03-21T19:31:48Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Programming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional file BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
Note: Thanks to Matt Turpin (of the IR Tracker project) whose code from his 399 independent study proved incredibly useful for our project.&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. Once all the code is loaded onto the correct PICs, everything can be run through BKSBallControl.m.&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
At the time of our presentation, we were able to demonstrate rotation along two axes by using the drive motor and Lazy Susan. Additionally, we were able to show effective and consistent communication of multiple bytes of data from MATLAB to the master PIC vis RS-232. Unfortunately, we were unable to get the hardware for I2C working, despite the code working on Matt&#039;s setup. Overall, we were pleased with our progress in a relatively short amount of time.&lt;br /&gt;
&lt;br /&gt;
We hope to fix the hardware issue in the near future and possibly consolidate all the circuitry onto a PCB for a more robust device. We would also like to add a hall effect switch or limit switch to indicate a set &amp;quot;Home&amp;quot; position. Additional work can be done on the motor control functions to implement feedback control as necessary. As there are clients that would like to see this project come to fruition, we want to make sure they are given a robust and flexible system for their use.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8693</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8693"/>
		<updated>2008-03-21T19:25:55Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Results */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional file BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. Once all the code is loaded onto the correct PICs, everything can be run through BKSBallControl.m.&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
At the time of our presentation, we were able to demonstrate rotation along two axes by using the drive motor and Lazy Susan. Additionally, we were able to show effective and consistent communication of multiple bytes of data from MATLAB to the master PIC vis RS-232. Unfortunately, we were unable to get the hardware for I2C working, despite the code working on Matt&#039;s setup. Overall, we were pleased with our progress in a relatively short amount of time.&lt;br /&gt;
&lt;br /&gt;
We hope to fix the hardware issue in the near future and possibly consolidate all the circuitry onto a PCB for a more robust device. We would also like to add a hall effect switch or limit switch to indicate a set &amp;quot;Home&amp;quot; position. Additional work can be done on the motor control functions to implement feedback control as necessary. As there are clients that would like to see this project come to fruition, we want to make sure they are given a robust and flexible system for their use.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8692</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8692"/>
		<updated>2008-03-21T19:18:18Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Programming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional file BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. Once all the code is loaded onto the correct PICs, everything can be run through BKSBallControl.m.&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8691</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8691"/>
		<updated>2008-03-21T19:16:12Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8690</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8690"/>
		<updated>2008-03-21T19:16:02Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8689</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8689"/>
		<updated>2008-03-21T19:15:54Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8688</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8688"/>
		<updated>2008-03-21T19:15:43Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8687</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8687"/>
		<updated>2008-03-21T19:15:09Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code BKSMotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8686</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8686"/>
		<updated>2008-03-21T19:14:06Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code MotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSMotorControllerFunctions.c|BKSMotorControllerFunctions.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:BKSMotorControllerFunctions.c&amp;diff=8685</id>
		<title>File:BKSMotorControllerFunctions.c</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:BKSMotorControllerFunctions.c&amp;diff=8685"/>
		<updated>2008-03-21T19:13:58Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8684</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8684"/>
		<updated>2008-03-21T19:12:42Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding. All required code is provided below (note an additional code MotorControllerFunctions.c which is used by the master PIC as well).&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8683</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8683"/>
		<updated>2008-03-21T19:11:04Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate I2C commands for the slave PICs, which were completely dedicated to motor control and encoding.&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8682</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8682"/>
		<updated>2008-03-21T19:05:38Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
Three sets of code were required for our project: the MATLAB code for the user interface, C code for the master PIC, and C code for the slave PICs. The MATLAB code set up a GUI for intuitive control of the ball. The master PIC code read all the serial communication from MATLAB and converted it into appropriate commands for the slave PICs, which were completely dedicated to motor control and encoding.&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8681</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8681"/>
		<updated>2008-03-21T18:57:30Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Programming */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;br /&gt;
&lt;br /&gt;
==Results==&lt;br /&gt;
&lt;br /&gt;
Das.&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8666</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8666"/>
		<updated>2008-03-21T10:52:30Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8665</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8665"/>
		<updated>2008-03-21T10:41:07Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlavev1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:BKSBallSlavev1.c&amp;diff=8664</id>
		<title>File:BKSBallSlavev1.c</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:BKSBallSlavev1.c&amp;diff=8664"/>
		<updated>2008-03-21T10:40:48Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8663</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8663"/>
		<updated>2008-03-21T10:40:07Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlave1v1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
[[Image:BKSBallSlave1v1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8662</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8662"/>
		<updated>2008-03-21T10:39:43Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlave1v1.c|BKSBallSlavev1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8661</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8661"/>
		<updated>2008-03-21T10:38:59Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallMasterv1.c|BKSBallMasterv1.c]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallSlave1v1.c|BKSBallSlave1v1.c]]&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8660</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8660"/>
		<updated>2008-03-21T10:37:05Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8659</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8659"/>
		<updated>2008-03-21T10:36:54Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Matlab Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PIC Code==&lt;br /&gt;
&lt;br /&gt;
==Programming==&lt;br /&gt;
&lt;br /&gt;
===Code Overview===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PIC Code===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MATLAB Code===&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8658</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8658"/>
		<updated>2008-03-21T10:35:53Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PIC Code==&lt;br /&gt;
&lt;br /&gt;
==Matlab Code==&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8657</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8657"/>
		<updated>2008-03-21T10:35:40Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Matlab Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PIC Code==&lt;br /&gt;
&lt;br /&gt;
==Matlab Code==&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m|BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig|BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8656</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8656"/>
		<updated>2008-03-21T10:33:43Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Matlab Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PIC Code==&lt;br /&gt;
&lt;br /&gt;
==Matlab Code==&lt;br /&gt;
&lt;br /&gt;
The GUIDE toolset in MATLAB was used to create the GUI. &lt;br /&gt;
&lt;br /&gt;
[[Media:BKSBallControl.m]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Media:BKSBallControl.fig]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8655</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8655"/>
		<updated>2008-03-21T10:30:50Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Matlab Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PIC Code==&lt;br /&gt;
&lt;br /&gt;
==Matlab Code==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:BKSBallControl.m]]&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:BKSBallSlave1v1.c&amp;diff=8654</id>
		<title>File:BKSBallSlave1v1.c</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:BKSBallSlave1v1.c&amp;diff=8654"/>
		<updated>2008-03-21T10:28:39Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:BKSBallMasterv1.c&amp;diff=8653</id>
		<title>File:BKSBallMasterv1.c</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:BKSBallMasterv1.c&amp;diff=8653"/>
		<updated>2008-03-21T10:28:15Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:BKSBallControl.fig&amp;diff=8652</id>
		<title>File:BKSBallControl.fig</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:BKSBallControl.fig&amp;diff=8652"/>
		<updated>2008-03-21T10:27:55Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:BKSBallControl.m&amp;diff=8651</id>
		<title>File:BKSBallControl.m</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:BKSBallControl.m&amp;diff=8651"/>
		<updated>2008-03-21T10:27:23Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=ME_333_final_projects&amp;diff=8650</id>
		<title>ME 333 final projects</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=ME_333_final_projects&amp;diff=8650"/>
		<updated>2008-03-21T10:25:22Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Granular Flow Rotating Sphere */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;[[ME 333 end of course schedule]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== ME 333 Final Projects 2008 ==&lt;br /&gt;
&lt;br /&gt;
=== [[IR Tracker]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:IR_Tracker_Main.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
The IR Tracker (aka &amp;quot;Spot&amp;quot;) is a device that follows a moving infrared light. It continuously detects the position of an infrared emitter in two axes, and then tracks the emitter with a laser. [http://depot.northwestern.edu/mht363/public_html/IR%20Track/Mar%2019%20IR%20tracker.mp4 See Spot Run.]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Robot Snake]] ===&lt;br /&gt;
[[Image:HLSSnakeMain.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
This remote control robotic snake uses servo motors with a traveling sine wave motion profile to mimic serpentine motion.  The robotic snake is capable of moving forward, left, right and in reverse.   &lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Programmable Stiffness Joint]] === &lt;br /&gt;
&lt;br /&gt;
[[Image:SteelToePic2.jpg|thumb|200px|The &#039;Steel Toe&#039; programmable stiffness joint|right]]&lt;br /&gt;
&lt;br /&gt;
The Programmable Stiffness Joint varies rotational stiffness as desired by the user.  It is the first step in modeling the mechanical impedance of the human ankle joint (both stiffness and damping) for the purpose of determining the respective breakdown of the two properties over the gait cycle.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [[Magnetic based sample purification]] ===&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;
=== [[Continuously Variable Transmission]] ===&lt;br /&gt;
&lt;br /&gt;
[[image:CVT_setup1.jpg|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
This prototype is a proof of concept model of a variable ratio transmission to be implemented in the 2008-2009 Formula SAE competition vehicle.  The gear ratio is determined by the distances between the pulley halves which are controllable electronically.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Granular Flow Rotating Sphere]] ===&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|thumb|200px]]&lt;br /&gt;
This device will be used to study the granular flow of particles within a rotating sphere. The sphere is filled with grains of varying size and then rotated about two different axes according to a series of position and angular velocity inputs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Vibratory Clock]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Vibratory_Clock.jpg|right|thumb|Vibratory Clock|200px]]&lt;br /&gt;
&lt;br /&gt;
The Vibratory Clock allows a small object to act as an hour &amp;quot;hand&amp;quot; on a horizontal circular platform that is actuated from underneath by three speakers.  The object slides around the circular platform, impelled by friction forces due to the vibration.  [http://www.youtube.com/watch?v=KhgTNCfdwZw Check it out!]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[WiiMouse]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:HPIM1027.jpg|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
The WiiMouse is a handheld remote that can be used to move a cursor on a windows-based PC, via accelerometer input captured through device movement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Intelligent Oscillation Controller]] ===&lt;br /&gt;
&lt;br /&gt;
[[image:ME333_learning_oscillator.jpg|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
This device &amp;quot;learns&amp;quot; a forcing function that is applied to a spring and mass system to match an arbitrary, periodic acceleration profile.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Baseball]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Baseball_Playfield.jpg|Sweet Baseball Game|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
An interactive baseball game inspired by pinball, featuring pitching, batting, light up bases and a scoreboard to keep track of the game.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Ball Balancing Challenge]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Ballbalancechallenge.JPG|right|thumb|200px]]&lt;br /&gt;
&lt;br /&gt;
An interactive game involving ball balancing on a touchscreen with touchscreen feedback and joystick action. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8638</id>
		<title>Granular Flow Rotating Sphere</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Granular_Flow_Rotating_Sphere&amp;diff=8638"/>
		<updated>2008-03-21T08:17:01Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Schematic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[ME 333 final projects]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-main-picture.JPG|right|Our Final Design|thumb|500px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
*Brian Kephart - Electrical Engineering Class of 2009&lt;br /&gt;
*Jonathan Shih - Mechanical Engineering Class of 2009&lt;br /&gt;
*Kristi Bond - Mechanical Engineering Class of 2008&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
A clear sphere is filled with grains of different sizes.  Our apparatus rotates this ball about two different axis based on a series of user inputs.  The user inputs the specific values for things such as angle and rotational speed into Matlab. Our device takes these inputs and processes them using a series of master and slave PICs to appropriately control the motors.  The motors then turn for the input duration at the desired speed causing the ball to spin correctly due to the frictional connection between both motors and the sphere or lazy susan, respectively.  &lt;br /&gt;
&lt;br /&gt;
This apparatus will be used for the study of granular flow and the mixing of particles within the sphere.  It was important to leave the ball as visible as possible to allow for pictures to be taken of the grains within from many angles.  With this apparatus we hope to aide the study of granular flow theory and allow the researches to use the device for many different applications.&lt;br /&gt;
&lt;br /&gt;
==Mechanical Set-up==&lt;br /&gt;
&lt;br /&gt;
====Main Housing====&lt;br /&gt;
&lt;br /&gt;
The main housing, or case, for our design is composed of the following pieces.&lt;br /&gt;
&lt;br /&gt;
*One 13.5” x 12” x ¾” plywood rectangle&lt;br /&gt;
*One 13.5” x 12”  x ¾” plywood rectangle with a 3.5” diameter circle removed from the center&lt;br /&gt;
*Two 12” x 2.5”x ¾” plywood rectangles&lt;br /&gt;
&lt;br /&gt;
The two larger rectangles form the top and bottom of the set-up with the two smaller rectangles placed vertically between to form a box with two open ends on the front and back face.  &lt;br /&gt;
&lt;br /&gt;
====Ball Support====&lt;br /&gt;
&lt;br /&gt;
Three ball casters are placed on vertical mounts around the center circle of the top piece of the housing at equal angles.  These casters prevent the ball from moving in any horizontal direction so it is only free to rotate.  One of these casters is adjustable to allow the user to make sure the ball is correctly supported above the drive wheel.  The force of gravity is strong enough to prevent the ball from moving up and out of the housing and also ensures a good connection with the drive wheel that is placed directly under the center of the sphere.&lt;br /&gt;
&lt;br /&gt;
====Main Drive Wheel====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel is centered under the rotating sphere.  The wheel is mounted onto a ¼” aluminum shaft which is connected to the Pittman motor with a flexible coupling and is also supported by a sleeve bearing on the other side of the wheel.  &lt;br /&gt;
&lt;br /&gt;
====Lazy Susan====&lt;br /&gt;
&lt;br /&gt;
The main drive wheel with its corresponding motor and other components are all mounted on top of a lazy susan that is centered on the bottom piece of the housing and secured with screws.  This lazy susan allows rotational motion but prevents movement in any other direction allowing the wheel to turn but always have the same center of contact with the sphere above.  It is important to ensure that the drive wheel has a good connection with the sphere above because the frictional force between the wheel and the sphere must be as large as possible so that as the wheel spins the ball spins at the same rate.  &lt;br /&gt;
&lt;br /&gt;
====Position Control Motor====&lt;br /&gt;
&lt;br /&gt;
A second motor is used in our design to turn the lazy susan.  The motor is mounted vertically through the top plate.  Another, smaller, drive wheel is mounted directly to the motor shaft and then aligned with only the top, free half of the lazy susan.  A second, idler wheel is mounted on the bottom plate, so the drive wheel is sandwiched between this wheel and the lazy susan. This ensures that the drive wheel is always in contact with the lazy susan because the idler wheel exerts only a normal force.  Again, this is to ensure there is no slip between the lazy susan and the drive wheel so it is automatically controlled more easily.&lt;br /&gt;
&lt;br /&gt;
====Complete Parts List====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman GM8224 motor &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Helical Beam Set-Screw Shaft Coupling&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; 9861T508 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Mounted Sleeve Bearing&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5912K21 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Flange Mount Ball Caster&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5674K77  &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Lazy Susan&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1443T2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K23 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Small Drive Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2471K12 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Idler Wheel&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;60885K79 &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1/4” Aluminum Rod&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Aluminum Sheet Metal&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Plywood&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Circuitry==&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
Our project was unique in that we relied on the use of three different PICs to precisely coordinate the motion of our ball. The main reason for this was because the 18F4520 chip only has enough encoder inputs for one Pittman motor. &lt;br /&gt;
&lt;br /&gt;
===Component List===&lt;br /&gt;
&amp;lt;table border=1&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Part&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Part No.&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;PIC18F4520 Prototyping Board&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Microchip 8-bit PIC Microcontroller&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PIC18F4520&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Pittman Motor with Encoder&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;GM8224&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;3&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hex Inverter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;SN74HC04&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Counter Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;LS7083&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;H-Bridge Chip&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;L293&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Diodes&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1N4001&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;10K Resistor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;---&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Hall Effect Sensor&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;A3240LUA-T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Big Cat Super Strong Magnet&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;PM20134&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Set Up===&lt;br /&gt;
The electrical design for our project was pretty basic. All of our components (including the Pittman motors) were powered with 5V DC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;PICs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The three PICs communicated via I2C, which enabled us to control the two motors by telling the master PIC what to do (more information can be found [[I2C communication between PICs|here]]). We designated the PIC on the 18F4520 Prototyping Board as the &amp;quot;Master&amp;quot; and the other two PICs as the &amp;quot;Slaves.&amp;quot; It is important to connect the clock from the prototyping board to the two Slave PICs, but the two main lines of communication are shared on pin 18 (RC3) on each chip, and pin 23 (RC4).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;H-Bridge&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each slave PIC sends an individual pulse to one of the two H-bridges (the L298 has two). The pulse width determines the direction and speed of each motor. At 50% duty cycle, the motor is at rest, while at 0 and 100% duty cycles the motor runs at maximum speed but in opposite directions. Pin 16 from the first slave PIC needs to connect to pin 10 on the L298, while other other should connect to pin 5.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Hex Inverter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now pins 5 and 10 from the H-bridge needs to go into pins 1 and 13 on the hex inverter chip. The outputs of these two need to go back the the H-bridge as an inverted signal for pulse width modulation (pin 1 to L298&#039;s pin 12, and pin 14 to L298&#039;s pin 7).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Counter&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last main component that needs to be implemented in the counter chip. This enables us to take fewer counts from the high encoder on the Pittman motors to control the movement of the motor. Pins 4 and 5 are used to connect directly to the blue and yellow lines on each Pittman encoder. Pins 1, 3, and 6 should all be hooked to ground, while pin 2 should be +5V. Pins 7 and 8 should connect to pins 15 and 6, respectively on the slave PIC that is correspondent to this counter chip.&lt;br /&gt;
&lt;br /&gt;
===Schematic===&lt;br /&gt;
Here is a visual representation of how our circuit components fit together:&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit.JPG|left|Team Granular Flow Schematic|thumb|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Image:Team-21-circuit-image.JPG|left|Team Granular Flow Circuit|thumb|300px]] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PIC Code==&lt;br /&gt;
&lt;br /&gt;
==Matlab Code==&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7140</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7140"/>
		<updated>2008-02-21T01:36:11Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Using a Loop to Write Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into flash program memory. If the keyword CONST is used before the identifier, the identifier is treated as a constant. These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data into flash program memory with 3 bytes per instruction space. The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical. Physical memory space is how the data is laid out on the memory in hardware, and may be spaced apart. This is in contrast to logical, or virtual memory, which is how the software views the memory.&lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. This means you cannot use a loop to directly initialize the constant variable (in the case of large arrays). It is also not possible to use a temporary variable to run calculations in a loop before storing in a constant variable because the compiler will not let you declare new variables after running the calculations in the loop.&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1,3,5,7,9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Using a Loop to Write Constant Data===&lt;br /&gt;
Although we must initialize a constant variable when we declare it, it is possible to use loops to calculate an array, which is then stored into program memory via other means.&lt;br /&gt;
&lt;br /&gt;
The code below creates a list of 100 integers using a loop and writes them to program memory:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdlibm.h&amp;gt;&lt;br /&gt;
 int * listptr;&lt;br /&gt;
 int i;&lt;br /&gt;
 listptr = calloc(1000, sizeof(int)); //allocates memory space for temporary variable&lt;br /&gt;
 for(i=0x1000;i&amp;lt;=0x13e8;i++){&lt;br /&gt;
     listptr[i]=i;&lt;br /&gt;
     write_program_memory(i, listptr[i], 1);}&lt;br /&gt;
 free(listptr); //deallocates memory used by temporary variable for future use&lt;br /&gt;
&lt;br /&gt;
The data can be retrieved by read_program_memory(address, pointer, count) :ex. read_program_memory(0x1000,listptr,1);&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
The above sine table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
*PIC MCU C Compiler&lt;br /&gt;
*PICmicro MCU C&lt;br /&gt;
*http://en.wikipedia.org/wiki/Memory_address&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7138</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7138"/>
		<updated>2008-02-21T01:24:39Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into flash program memory. If the keyword CONST is used before the identifier, the identifier is treated as a constant. These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data into flash program memory with 3 bytes per instruction space. The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical. Physical memory space is how the data is laid out on the memory in hardware, and may be spaced apart. This is in contrast to logical, or virtual memory, which is how the software views the memory.&lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. This means you cannot use a loop to directly initialize the constant variable (in the case of large arrays). It is also not possible to use a temporary variable to run calculations in a loop before storing in a constant variable because the compiler will not let you declare new variables after running the calculations in the loop.&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1,3,5,7,9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Using a Loop to Write Constant Data===&lt;br /&gt;
Although we must initialize a constant variable when we declare it, it is possible to use loops to calculate an array, which is then stored into program memory via other means.&lt;br /&gt;
&lt;br /&gt;
The code below creates a list of 100 integers using a loop and writes them to program memory:&lt;br /&gt;
#include &amp;lt;stdlibm.h&amp;gt;&lt;br /&gt;
 int * listptr;&lt;br /&gt;
 int i;&lt;br /&gt;
 listptr = calloc(100, sizeof(int)); //allocates memory space for temporary variable&lt;br /&gt;
 for(i=0x1000;i&amp;lt;=0x1064;i++){&lt;br /&gt;
     listptr[i]=i;&lt;br /&gt;
     write_program_memory(i, listptr[i], 1);}&lt;br /&gt;
 free(listptr); //deallocates memory used by temporary variable for future use&lt;br /&gt;
&lt;br /&gt;
The data can be retrieved by &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
The above sine table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
*PIC MCU C Compiler&lt;br /&gt;
*PICmicro MCU C&lt;br /&gt;
http://en.wikipedia.org/wiki/Memory_address&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7137</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7137"/>
		<updated>2008-02-21T00:40:27Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into flash program memory. If the keyword CONST is used before the identifier, the identifier is treated as a constant. These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data into flash program memory with 3 bytes per instruction space. The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical. Physical memory space is how the data is laid out on the memory in hardware, and may be spaced apart. This is in contrast to logical, or virtual memory, which is how the software views the memory.&lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. This means you cannot use a loop to directly initialize the constant variable (in the case of large arrays). It is also not possible to use a temporary variable to run calculations in a loop before storing in a constant variable because the compiler will not let you declare new variables after running the calculations in the loop.&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1,3,5,7,9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Using a Loop to Write Constant Data===&lt;br /&gt;
Although we must initialize a constant variable when we declare it, it is possible to use loops to calculate an array, which is then stored into program memory via other means.&lt;br /&gt;
&lt;br /&gt;
The code below creates a list of 100 integers using a loop and writes them to program memory:&lt;br /&gt;
#include &amp;lt;stdlibm.h&amp;gt;&lt;br /&gt;
 int * listptr;&lt;br /&gt;
 int i;&lt;br /&gt;
 listptr = calloc(100, sizeof(int)); //allocates memory space for temporary variable&lt;br /&gt;
 for(i=0x1000;i&amp;lt;=0x1064;i++){&lt;br /&gt;
     listptr[i]=i;&lt;br /&gt;
     write_program_memory(i, listptr[i], 1);}&lt;br /&gt;
 free(listptr); //deallocates memory used by temporary variable for future use&lt;br /&gt;
&lt;br /&gt;
The data can be retrieved by &lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
The above sine table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
*PIC MCU C Compiler&lt;br /&gt;
*PICmicro MCU C&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7136</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7136"/>
		<updated>2008-02-21T00:09:13Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into flash program memory. If the keyword CONST is used before the identifier, the identifier is treated as a constant. These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data into flash program memory with 3 bytes per instruction space. The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical. Physical memory space is how the data is laid out on the memory in hardware, and may be spaced apart. This is in contrast to logical, or virtual memory, which is how the software views the memory.&lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. This means you cannot use a loop to directly initialize the constant variable (in the case of large arrays). It is also not possible to use a temporary variable to run calculations in a loop before storing in a constant variable because the compiler will not let you declare new variables after running the calculations in the loop.&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1,3,5,7,9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Using a Loop to Write Constant Data===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
*PIC MCU C Compiler&lt;br /&gt;
*PICmicro MCU C&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7120</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7120"/>
		<updated>2008-02-20T23:38:06Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
It is also not possible to use a temporary variable to run calculations in a loop before storing in a constant variable because the compiler will not let you declare new variables after running the calculations in the loop.&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Using a Loop to Write Constant Data===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
==References==&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7119</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7119"/>
		<updated>2008-02-20T23:36:32Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
It is also not possible to use a temporary variable to run calculations in a loop before storing in a constant variable because the compiler will not let you declare new variables after running the calculations in the loop.&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7109</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7109"/>
		<updated>2008-02-20T18:31:30Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of flash program memory (32 Kbytes) but relatively little data memory (1536 bytes of SRAM), as well as a very small amount of EEPROM (256 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int * temp;&lt;br /&gt;
 temp = (int*) calloc(num, sizeof(int)); //allocates memory space for temporary variable&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp; //still need to try this...&lt;br /&gt;
 free(temp); //deallocates memory used by temporary variable for future use&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7108</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7108"/>
		<updated>2008-02-20T18:29:27Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
32 KB of flash program memory&lt;br /&gt;
1536 bytes SRAM&lt;br /&gt;
256 bytes EEPROM&lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int * temp;&lt;br /&gt;
 temp = (int*) calloc(num, sizeof(int)); //allocates memory space for temporary variable&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp; //still need to try this...&lt;br /&gt;
 free(temp); //deallocates memory used by temporary variable for future use&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==References==&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7107</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7107"/>
		<updated>2008-02-20T18:21:02Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
32 KB of flash program memory&lt;br /&gt;
1536 bytes SRAM&lt;br /&gt;
256 bytes EEPROM&lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int * temp;&lt;br /&gt;
 temp = (int*) calloc(num, sizeof(int)); //allocates memory space for temporary variable&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp; //still need to try this...&lt;br /&gt;
 free(temp); //deallocates memory used by temporary variable for future use&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7106</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=7106"/>
		<updated>2008-02-20T18:19:57Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
32 KB of flash program memory&lt;br /&gt;
1536 bytes SRAM&lt;br /&gt;
256 bytes EEPROM&lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int * temp;&lt;br /&gt;
 temp = (int*) calloc(num, sizeof(int));&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp;&lt;br /&gt;
 free(temp); //still need to try this&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6969</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6969"/>
		<updated>2008-02-14T00:56:28Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sine function to illustrate one of these methods. &lt;br /&gt;
&lt;br /&gt;
32 KB of flash program memory&lt;br /&gt;
1536 bytes SRAM&lt;br /&gt;
256 bytes EEPROM&lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int temp[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp; //still need to try this&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6968</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6968"/>
		<updated>2008-02-14T00:43:30Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.  &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is: const &#039;&#039;type&#039;&#039; &#039;&#039;name&#039;&#039;[&#039;&#039;size&#039;&#039;] = {&#039;&#039;values&#039;&#039;}&lt;br /&gt;
Here&#039;s an example storing a list of numbers from 1 to 10 in program memory:&lt;br /&gt;
 const int iCanCount[10] = {1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int temp[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp; //still need to try this&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6964</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6964"/>
		<updated>2008-02-13T23:33:19Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.  &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is:  const type id[cexpr] = {value}&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
What you may be able to do, though, is this:&lt;br /&gt;
 int temp[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     temp[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
 const int listOfNumbers[100] = temp;&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6963</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6963"/>
		<updated>2008-02-13T23:29:55Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.  &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is:  const type id[cexpr] = {value}&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6890</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6890"/>
		<updated>2008-02-11T10:57:40Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Constant Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.  &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is:  const type id[cexpr] = {value}&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 const int listOfNumbers[100];&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
We have no circuit.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6856</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6856"/>
		<updated>2008-02-07T18:12:41Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Creating a sine look-up table using EEPROM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.  &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is:  const type id[cexpr] = {value}&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     const float listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
We have no circuit.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
Because int8 cannot hold decimal values, and can only have up to 256 different values, a table made with int8 values might be difficult.&lt;br /&gt;
A more realistic version using int16 would be more useful, and could start off like this:&lt;br /&gt;
&lt;br /&gt;
 {0,175,349,523,697,872,1045,1219,1392,1564,1736,&lt;br /&gt;
 1908,2079,2250,2419,2588,2756,2924,3090,3256...}&lt;br /&gt;
&lt;br /&gt;
In your main program, you could insert a function that divides all these values by 10,000 to obtain the decimal value for the sine table.&lt;br /&gt;
In the previous example, a sine table would take up 180 bytes. We could theoretically hold a sine lookup table precise to 0.00562° (32000/180 = 177.8x larger size; 1°/177.8 = 0.00562°).&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
Writing a sine table to EEPROM:&lt;br /&gt;
&lt;br /&gt;
 float data[4];&lt;br /&gt;
 for (i = 0,i &amp;lt;= 90&amp;gt;&amp;gt;2, i++)&lt;br /&gt;
     for (j = 0,j&amp;lt;4,j++)&lt;br /&gt;
         data[j]=sineTable[i&amp;lt;&amp;lt;2 + j];&lt;br /&gt;
     end&lt;br /&gt;
     write_program_eeprom(i,data);&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6742</id>
		<title>Storing constant data in program memory</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Storing_constant_data_in_program_memory&amp;diff=6742"/>
		<updated>2008-02-06T18:10:03Z</updated>

		<summary type="html">&lt;p&gt;JonathanShih: /* Creating a sine look-up table using EEPROM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
Your PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes).  For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory.  This project is to demonstrate how to write a program that stores constant data in program memory.  Test your ability to do this by creating a look-up table for the sin function.  This is a 1-d array with integer index corresponding to an angle (e.g., numbers 0 to 89 if the index is in degrees; angles in other quadrants can be determined by simple transformations).  Depending on your choice of int8, int16, or float to represent the number, what angle resolution can you use for the index before you reach the limits of program memory?&lt;br /&gt;
&lt;br /&gt;
See p. 43 of the PIC MCU C Compiler book.&lt;br /&gt;
&lt;br /&gt;
Finally, give sample code for storing data in the EEPROM, too.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The PIC has a relatively large amount of program memory (32 Kbytes) but relatively little data memory (1536 bytes). For some applications, we want to have lookup tables or calibration data stored on our PIC, but we don&#039;t want it hogging data memory. The CCS C Compiler provides a few different ways to use program memory for data, discussed below.  We have also provided an example of how to create a look-up table for the sin function to illustrate one of these methods.  &lt;br /&gt;
&lt;br /&gt;
=== Constant Data ===&lt;br /&gt;
The CONST qualifier will place variables into program memory.  If the keyword CONST is used before the identifier, the identifier is treated as a constant.  These constants need to be initialized and cannot be changed at run-time.  &lt;br /&gt;
&lt;br /&gt;
The ROM qualifier puts data in program memory with 3 bytes per instruction space.  The address used for ROM data is a true byte address not a physical address. The &amp;amp; operator can be used on ROM variables even though the address is logical not physical.  &lt;br /&gt;
&lt;br /&gt;
The syntax is:  const type id[cexpr] = {value}&lt;br /&gt;
&lt;br /&gt;
You must initialize the constant variable when you declare it or the compiler will spit out an error at you. Which means, unfortunately, you can&#039;t do something like:&lt;br /&gt;
&lt;br /&gt;
 for (i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
     const float listOfNumbers[i] = i;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== #ROM Directive ===&lt;br /&gt;
Another method that can be used to assign data to program memory is the #ROM directive.&lt;br /&gt;
&lt;br /&gt;
The syntax is:  #rom address = {data, data, ... , data}&lt;br /&gt;
&lt;br /&gt;
The following example places the numbers 1, 3, 5, 7, 9 into ROM addresses starting at 0x2000:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x2000 = {1, 3, 5, 7, 9}&lt;br /&gt;
&lt;br /&gt;
You can also put strings into program memory using the #ROM directive:&lt;br /&gt;
&lt;br /&gt;
 #rom 0x3000 = {&amp;quot;mechatronicsrocks&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
=== Built-in Functions ===&lt;br /&gt;
The compiler provides built in functions to place data in program memory.&lt;br /&gt;
&lt;br /&gt;
write_program_eeprom(address,data);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; to program memory. &amp;lt;b&amp;gt;data&amp;lt;/b&amp;gt; is stored in 16-bit chunks.&lt;br /&gt;
&lt;br /&gt;
write_program_memory(address, dataptr, count);&lt;br /&gt;
* Writes &amp;lt;b&amp;gt;count&amp;lt;/b&amp;gt; bytes of data from &amp;lt;b&amp;gt;dataptr&amp;lt;/b&amp;gt; to &amp;lt;b&amp;gt;address&amp;lt;/b&amp;gt; in program memory.&lt;br /&gt;
* Every fourth byte of data will not be written, this needs to be filled with 0x00.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
We has no circuit.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
===#ROM Directive Examples===&lt;br /&gt;
Writes sine values to ROM addresses starting at 0x1000&lt;br /&gt;
 #rom 0x1000 = {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
    0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
    0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
    0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
    0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
    0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
    0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
    0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
    0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
&lt;br /&gt;
===Creating a look-up table for the sine function using CONST===&lt;br /&gt;
&lt;br /&gt;
*int8 = 8 bit number (1 byte); range 0 to 255 (2-3 digits)&lt;br /&gt;
*int16 = 16 bit number (2 bytes); range 0 to 65535 (4-5 digits)&lt;br /&gt;
*float = 32 bit number (4 bytes); range -1.5x10^45 to 3.4x10^38 (7-8 digits)&lt;br /&gt;
&lt;br /&gt;
With values of sine from 0-89°, we can calculate sine values for all 360°. Below is code storing a table of sine values from 0-89° with a angle resolution of 1° and algorithm for calculating sine values for 90-360°.&lt;br /&gt;
&lt;br /&gt;
 const float sineTable[90] =&lt;br /&gt;
     {0,0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,0.139173,0.156434,&lt;br /&gt;
     0.173648,0.190809,0.207912,0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,&lt;br /&gt;
     0.34202,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.45399,0.469472,0.48481,0.5,&lt;br /&gt;
     0.515038,0.529919,0.544639,0.559193,0.573576,0.587785,0.601815,0.615661,0.62932,0.642788,&lt;br /&gt;
     0.656059,0.669131,0.681998,0.694658,0.707107,0.71934,0.731354,0.743145,0.75471,0.766044,&lt;br /&gt;
     0.777146,0.788011,0.798636,0.809017,0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,&lt;br /&gt;
     0.87462,0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.93358,0.939693,&lt;br /&gt;
     0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,0.97437,0.978148,0.981627,0.984808,&lt;br /&gt;
     0.987688,0.990268,0.992546,0.994522,0.996195,0.997564,0.99863,0.999391,0.999848};&lt;br /&gt;
 &lt;br /&gt;
 //To look up sine values from the table, you could use a function like the following:&lt;br /&gt;
 float sineLookup(index){&lt;br /&gt;
     i = index % 360; //Is there a better way to implement this?&lt;br /&gt;
     if (i &amp;gt;= 0 &amp;amp;&amp;amp; i &amp;lt; 90)&lt;br /&gt;
         return sineTable[i];&lt;br /&gt;
     else if (i &amp;gt;= 90 &amp;amp;&amp;amp; i &amp;lt; 180)&lt;br /&gt;
         return sineTable[179-i];&lt;br /&gt;
     else if (i &amp;gt;= 180 &amp;amp;&amp;amp; i &amp;lt; 270)&lt;br /&gt;
         return -sineTable[180-i];&lt;br /&gt;
     else if (i &amp;gt;= 270 &amp;amp;&amp;amp; i &amp;lt; 360)&lt;br /&gt;
         return -sineTable[359-i];&lt;br /&gt;
     end&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
===Memory Management===&lt;br /&gt;
&lt;br /&gt;
This table stores values as floats and is 360 bytes in size. Since the PIC has 32 KB of program memory, we could theoretically hold a sine lookup table precise to 0.01125° (32000/360 = 88.8x larger size; 1°/88.8 = 0.01125°).&lt;br /&gt;
&lt;br /&gt;
 const int8 sineTable[90] = ...&lt;br /&gt;
&lt;br /&gt;
A table made with int8 values would be able to hold &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;insert table of data types and angle resolution possible&#039;&#039;&lt;br /&gt;
int8, int16, float, double?&lt;br /&gt;
&lt;br /&gt;
===Creating a sine look-up table using EEPROM===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for (i = 0,i &amp;lt; 90, i++)&lt;br /&gt;
data[4]=&lt;br /&gt;
write_program_eeprom(i&amp;gt;&amp;gt;2,&lt;br /&gt;
&lt;br /&gt;
To read, use:&lt;br /&gt;
&lt;br /&gt;
 read_program_eeprom(address)&lt;/div&gt;</summary>
		<author><name>JonathanShih</name></author>
	</entry>
</feed>