<?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=RenYu</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=RenYu"/>
	<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php/Special:Contributions/RenYu"/>
	<updated>2026-05-14T11:03:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17775</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17775"/>
		<updated>2010-03-18T17:12:39Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Fluff_Bot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel.&lt;br /&gt;
&lt;br /&gt;
Some videos:&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=jAqSzvoKiLE Fluffbot with seal casing 1]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=utZnFJuoLag Fluffbot seal-on-land]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=BIMgh9eEPQ4 Fluffbot seal-in-water]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Xc-FJgjFg50 Fluffbot seal-on-ice]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=-XoxQAQtva4 Fluffbot seal-on-land reverse]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=fzAgX4L4gHU Fluffbot bottom view of momentum and steering wheel]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=3X7MnW4_8FM Fluffbot with seal casing 2]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=H4ZJ47V_QE4 Fluffbot with seal casing 3]&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
[[image:2010-25-Johnson-Pentelovitch-Yu.jpg|thumb|400pix|right|Johnson - Pentelovitch - Yu]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Fluffbot_Concept.jpg|thumb|700pix|right|Fluffbot Motion]]&lt;br /&gt;
&lt;br /&gt;
Instead of using motors to directly drive its motion forward, Fluffbot uses the basic principal of conservation of angular momentum. When an object with a high moment of inertia is accelerated about an axis, angular momentum in the direction of motion is immediately created. When this happens, angular momentum in the opposing direction is also produced. The resulting motion from this &amp;quot;reaction&amp;quot; momentum can be transferred to ground through a rigid fixture, or this resulting motion could be controlled and channeled into a desirable form as shown with Fluffbot.&lt;br /&gt;
&lt;br /&gt;
When the large flywheel on Fluffbot accelerates clockwise in the horizontal plane, the body attempts to conserve the zero angular momentum of the system by rotating around the same axis in a counter clockwise direction. Motion forward or backward by Fluffbot is made possible by the steering of the front wheel. There are three conditions for the steering wheel to be in, and three corresponding effects:&lt;br /&gt;
&lt;br /&gt;
1) Wheel is aligned straight ahead - In this scenario, friction between the front wheel and the the ground prevent any rotation along the robot&#039;s main axis of rotation. Any acceleration of the momentum wheel in this arrangement will result in no movement of Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) Wheel is turned to the left - When the momentum wheel accelerates in a clockwise direction, the chassis will attempt to rotate to the left. Because the front wheel is turned to the left, a portion of this rotation will be allowed to occur around a pivot point perpendicular to the direction the wheel is pointed. This gives the overall effect of turning Fluffbot to the left and moving it slightly forward. If the momentum wheel were to accelerate in the opposite direction (counter clockwise) while the front wheel is steering left, the result would be to turn Fluffbot to the right and send in moving backward.&lt;br /&gt;
&lt;br /&gt;
3) Wheel is turned to the right - This exhibits the same behavior as when the front wheel is turned to the left, however, the direction of rotation for the momentum wheel and the chassis are reversed.&lt;br /&gt;
&lt;br /&gt;
In order to control the motion of Fluffbot and to send it in a straight direction, the momentum wheel accelerates back and forth sinusoidally as the front wheel turns left to right with the same sinusoid. To reverse the direction that Fluffbot travels, simply put the front wheels control wave 180˚ out of phase with the control wave for the momentum wheel. Fluffbot is also able to steer left and right by controlling the amplitude and range of the front steering wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:Uncovered_Bot.jpg|thumb|right|Inside Fluff Bot]]&lt;br /&gt;
The Fluffbot has all of its circuitry and mechanical components confined to a single chassis. The chassis is an arrow shape and is mounted on three wheels attached to the bottom of the chassis. The two rear wheels are fixed, while the front wheel is free to rotate and is mounted on a fork and coupled to a servo, which controls its turning angle. A momentum wheel is fixed underneath the center of the chassis to a motor which is mounted on top. All circuitry and power sources are mounted on the top of the chassis as well.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the Fluffbot is designed for minimum chassis weight and maximum torque generated by the momentum wheel. The momentum wheel is mounted directly in the center of the three wheels so that the torque is distributed evenly. The wheels use press-fit ball bearings mounted on fixed axles to achieve minimum friction when rolling. The front-wheel fork is mounted to the chassis through a ball bearing to reduce frictional force on the servo motor. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Motors:&#039;&#039;&#039; Futaba S3004 standard ball bearing RC servo motor, Mechatronics Lab - Pittman GM8712G708-R3 Motor 19.5:1 gear head, Mechatronics Lab&lt;br /&gt;
*&#039;&#039;&#039;Wheels:&#039;&#039;&#039; Machined from Aluminum 2&amp;quot; 6061 rod, McMaster part# 8974K711&lt;br /&gt;
*&#039;&#039;&#039;Momentum Wheel:&#039;&#039;&#039; Machined from 6&amp;quot; Aluminum 6061 rod, machine shop stock&lt;br /&gt;
*&#039;&#039;&#039;Tires:&#039;&#039;&#039; Shop Stock rubber wheel coverings&lt;br /&gt;
*&#039;&#039;&#039;Wheel Fork:&#039;&#039;&#039; Machined from aluminum 6061 rod, McMaster part# 8974K711&lt;br /&gt;
*&#039;&#039;&#039;Wheel Fork Bearing:&#039;&#039;&#039; Steel, flanged open ball bearing, 1/4&amp;quot; ID, 11/16&amp;quot; OD, McMaster part# 6383K213&lt;br /&gt;
*&#039;&#039;&#039;RC Servo-Shaft Coupler:&#039;&#039;&#039; Split clamp to Futaba S3004 coupler, ServoCity.com&lt;br /&gt;
*&#039;&#039;&#039;Chassis:&#039;&#039;&#039; laser cut from 1/4 inch 12&amp;quot;x12&amp;quot; clear acrylic&lt;br /&gt;
*&#039;&#039;&#039;Axels:&#039;&#039;&#039; 1/4&amp;quot; tapered dowels&lt;br /&gt;
*&#039;&#039;&#039;Wheel Bearings:&#039;&#039;&#039; 3 x Open steel ball bearings, 1/4&amp;quot; ID, 7/8&amp;quot; OD, 1/4&amp;quot; thickness, McMaster part# 6383K14&lt;br /&gt;
*&#039;&#039;&#039;Fasteners:&#039;&#039;&#039; 10-32 set screw for securing the momentum wheel to the motor, 4-40 round-head screws for securing motor to the chassis&lt;br /&gt;
*&#039;&#039;&#039;Velcro:&#039;&#039;&#039; To attach battery packs and housing to the chassis&lt;br /&gt;
*&#039;&#039;&#039;Adhesives:&#039;&#039;&#039; Acrylic Epoxy for Servo Holder, Superglue for rear wheel mounts&lt;br /&gt;
*&#039;&#039;&#039;Power Source:&#039;&#039;&#039; 2 x 9.6 V, 2200 mAh, NI-MH, Powerizer rechargeable battery &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a sheet of 1/4 inch clear Acrylic. It needed to be large enough to hold the motors, two batteries, and two circuit boards. In order to reduce the weight of the design, the base was cut into a triangle with wheels to be placed at each corner. Four small holes were cut at the front and at the middle of the base to allow the motor to be secured, and one larger hole was cut for a bearing to be pressed into place for the front steering wheel. [[Media:Dimensioned_Drawing_of_Chassis.pdf|Dimensioned Drawing of Chassis]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Steering Assembly ====&lt;br /&gt;
&lt;br /&gt;
[[image:Servo_and_Fork_Detail.jpg|thumb|right|RC Servo Attachment and Front Wheel Fork]]&lt;br /&gt;
&lt;br /&gt;
The front wheel was attached to the steering servo through a machined aluminum fork. The fork design was used (as opposed to a one-sided mount) so that the axis of rotation for the front wheel could be directly centered above the centerline of the wheel with relative ease.&lt;br /&gt;
&lt;br /&gt;
The Futaba RC servo used for steering the front wheel was held in place by the servo-shaft coupler and by two pieces of acrylic. The servo was light enough that it could be supported by only the coupler. Two vertical pieces of acrylic prevented the servo from rotating as it turned the front wheel. A small piece of electrical tape kept the servo from backing off of the coupler while Fluffbot was operating. [[Media:Dimensioned_Drawing_of_Steering_Fork.pdf|Dimensioned Drawing of Steering Fork]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Momentum Wheel ====&lt;br /&gt;
&lt;br /&gt;
[[image:Momentum_Wheel.jpg|thumb|right|Angular Momentum Wheel]]&lt;br /&gt;
The momentum wheel is design specifically to increase the torque on the body. This was done by machining the wheel so that there was more weight on the outside of the wheel. The momentum wheel is made from Aluminum 6061. The shaft in the center of the momentum wheel connects to the shaft of the motor using a set screw. The motor connector shaft and the momentum wheel were made as one piece to increase rigidity and assure that the momentum wheel would be perfectly parallel to the chassis. The momentum wheel weighs about 1.3 lbs, which makes the torque on the motor above its maximum continuous torque rating. We felt that this would be alright because the motor is not running continuously at a high speed, but rather is accelerating and decelerating sinusoidally. The motor is also not running at maximum rpm.&lt;br /&gt;
[[Media:Momentum_Wheel_Dimensioned_Drawing.pdf|Dimensioned Drawing of Momentum Wheel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Wheels ====&lt;br /&gt;
[[Image:RY_NP_TJ_Wheel_with_Bearing.jpg|thumb|right|Wheel with Ball Bearing]]&lt;br /&gt;
The wheels we used were specially machined out of Aluminum 6061 to fit treaded rubber tires we found in the machine shop. Aluminum was used instead of preformed plastic wheels because we could precisely machine the wheels to fit the design of the Fluffbot, rather than needing to design the Fluffbot around the wheels we had available. The wheels were designed to fit ____ ball bearings. The ball bearings were press fit into the center of the wheel. We used ball bearings so that the wheels would spin with minimal friction and thus less energy would be required to move the Fluffbot. [[Media:Dimensioned_Drawing_of_Wheels.pdf|Dimensioned Drawing of Wheels&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Battery and Electronics ====&lt;br /&gt;
&lt;br /&gt;
The batteries and circuit boards were attached to the top of the chassis using Velcro. The configuration of the batteries as well as the placement of the circuit boards are intentional, concentrating the majority of the weight around the center of hte momentum wheel and also so that different housing (read: stuffed animals) could be easily placed around the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Fluffy Housing ====&lt;br /&gt;
&lt;br /&gt;
[[Image:Fluffbot_with_Seal_Housing.jpg|thumb|right|Fluffy Housing]]&lt;br /&gt;
The Fluffbot receives its name from the fluffy stuffed animals that ride atop it and that the Fluffbot imitates by its motion. For this version of the Fluffbot a seal was used to house the mechanical structure and electronics. The seal is split in two and attached to the chassis by Velcro. There is a piece of sheet metal that is bent and attached with Velcro to the upper part of the seal so that it will maintain its structure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Mechanical Debugging ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bearings are coming out of rear wheels:&#039;&#039;&#039; Re-machine wheels using a boring bar for the through-hole for the bearings. While boring   out hole, check dimensions of the bearing being used and take small cuts, measuring after each pass, to assure that the hole diameter precisely matches that of the bearing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Servo comes loose from servo coupler:&#039;&#039;&#039; Machine a set screw hole through the part of the coupler connecting to the servo and add a set screw to keep the servo in place&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
[[image:Fluffbot_Circuit_Boards.jpg |thumb|300px|Fluffbot Circuitry|right]]&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
Due to the short amount of time in which the Fluffbot was designed, built and programmed, there was not enough time for optimization and iteration. Thus, there are many areas in which the Fluffbot could be improved with future work. &lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. this could be accomplished by adding encoders to the front wheel to determine the distance the Fluffbot has moved from its initial position. It would then be possible to map the Fluffbot&#039;s trajectory as well as collect data about its speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
By adding optical sensors to the Fluffbot we could program it to automatically avoid obstacles. This would most likely use an override function that would supersede the command coming from the user.&lt;br /&gt;
&lt;br /&gt;
==== High Torque Servos ====&lt;br /&gt;
High torque servos would enable the Fluffbot to move more quickly because the front wheel would be able to turn at a higher frequency. &lt;br /&gt;
&lt;br /&gt;
==== Hand-held Controller ====&lt;br /&gt;
By linking the control of the Fluffbot to a handheld controller a user could more easily interact with the Fluffbot and control it because they wouldn&#039;t need to be staring at a GUI on a computer to control its behavior. &lt;br /&gt;
&lt;br /&gt;
==== Wall-Riding ====&lt;br /&gt;
The initial scope of the project included giving the robot the ability to ride on a vertical wall. While this was not a possibility for us in the time frame allotted, a future team may be able to build on our design to enable dynamic motion using a momentum wheel along a vertical surface. This may be possible by using neodymium wheels to attach the robot to a metal wall.&lt;br /&gt;
&lt;br /&gt;
==== Housing ====&lt;br /&gt;
The Fluffbot does not currently have a housing that protects the electronics on the chassis. A housing would allow for easy attachment and detachment of various animal shells and would also prevent the stuffed animals from contacting the hot electronics and making them heat up even faster. Air vents could also be added to the housing to allow for heat to dissipate from the electronics.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17774</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17774"/>
		<updated>2010-03-18T17:11:58Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Fluff_Bot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel.&lt;br /&gt;
&lt;br /&gt;
Some videos:&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=jAqSzvoKiLE Fluffbot with seal casing 1]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=utZnFJuoLag Fluffbot seal-on-land]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=BIMgh9eEPQ4 Fluffbot seal-in-water]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Xc-FJgjFg50 Fluffbot seal-on-ice]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=-XoxQAQtva4 Fluffbot seal-on-land reverse]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=fzAgX4L4gHU Fluffbot bottom view of momentum and steering wheel]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=3X7MnW4_8FM Fluffbot with seal casing 2]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=H4ZJ47V_QE4 Fluffbot with seal casing 3]&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
[[image:2010-25-Johnson-Pentelovitch-Yu.jpg|thumb|400pix|right|Johnson - Pentelovitch - Yu]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Fluffbot_Concept.jpg|thumb|700pix|right|Fluffbot Motion]]&lt;br /&gt;
&lt;br /&gt;
Instead of using motors to directly drive its motion forward, Fluffbot uses the basic principal of conservation of angular momentum. When an object with a high moment of inertia is accelerated about an axis, angular momentum in the direction of motion is immediately created. When this happens, angular momentum in the opposing direction is also produced. The resulting motion from this &amp;quot;reaction&amp;quot; momentum can be transferred to ground through a rigid fixture, or this resulting motion could be controlled and channeled into a desirable form as shown with Fluffbot.&lt;br /&gt;
&lt;br /&gt;
When the large flywheel on Fluffbot accelerates clockwise in the horizontal plane, the body attempts to conserve the zero angular momentum of the system by rotating around the same axis in a counter clockwise direction. Motion forward or backward by Fluffbot is made possible by the steering of the front wheel. There are three conditions for the steering wheel to be in, and three corresponding effects:&lt;br /&gt;
&lt;br /&gt;
1) Wheel is aligned straight ahead - In this scenario, friction between the front wheel and the the ground prevent any rotation along the robot&#039;s main axis of rotation. Any acceleration of the momentum wheel in this arrangement will result in no movement of Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) Wheel is turned to the left - When the momentum wheel accelerates in a clockwise direction, the chassis will attempt to rotate to the left. Because the front wheel is turned to the left, a portion of this rotation will be allowed to occur around a pivot point perpendicular to the direction the wheel is pointed. This gives the overall effect of turning Fluffbot to the left and moving it slightly forward. If the momentum wheel were to accelerate in the opposite direction (counter clockwise) while the front wheel is steering left, the result would be to turn Fluffbot to the right and send in moving backward.&lt;br /&gt;
&lt;br /&gt;
3) Wheel is turned to the right - This exhibits the same behavior as when the front wheel is turned to the left, however, the direction of rotation for the momentum wheel and the chassis are reversed.&lt;br /&gt;
&lt;br /&gt;
In order to control the motion of Fluffbot and to send it in a straight direction, the momentum wheel accelerates back and forth sinusoidally as the front wheel turns left to right with the same sinusoid. To reverse the direction that Fluffbot travels, simply put the front wheels control wave 180˚ out of phase with the control wave for the momentum wheel. Fluffbot is also able to steer left and right by controlling the amplitude and range of the front steering wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:Uncovered_Bot.jpg|thumb|right|Inside Fluff Bot]]&lt;br /&gt;
The Fluffbot has all of its circuitry and mechanical components confined to a single chassis. The chassis is an arrow shape and is mounted on three wheels attached to the bottom of the chassis. The two rear wheels are fixed, while the front wheel is free to rotate and is mounted on a fork and coupled to a servo, which controls its turning angle. A momentum wheel is fixed underneath the center of the chassis to a motor which is mounted on top. All circuitry and power sources are mounted on the top of the chassis as well.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the Fluffbot is designed for minimum chassis weight and maximum torque generated by the momentum wheel. The momentum wheel is mounted directly in the center of the three wheels so that the torque is distributed evenly. The wheels use press-fit ball bearings mounted on fixed axles to achieve minimum friction when rolling. The front-wheel fork is mounted to the chassis through a ball bearing to reduce frictional force on the servo motor. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Motors:&#039;&#039;&#039; Futaba S3004 standard ball bearing RC servo motor, Mechatronics Lab - Pittman GM8712G708-R3 Motor 19.5:1 gear head, Mechatronics Lab&lt;br /&gt;
*&#039;&#039;&#039;Wheels:&#039;&#039;&#039; Machined from Aluminum 2&amp;quot; 6061 rod, McMaster part# 8974K711&lt;br /&gt;
*&#039;&#039;&#039;Momentum Wheel:&#039;&#039;&#039; Machined from 6&amp;quot; Aluminum 6061 rod, machine shop stock&lt;br /&gt;
*&#039;&#039;&#039;Tires:&#039;&#039;&#039; Shop Stock rubber wheel coverings&lt;br /&gt;
*&#039;&#039;&#039;Wheel Fork:&#039;&#039;&#039; Machined from aluminum 6061 rod, McMaster part# 8974K711&lt;br /&gt;
*&#039;&#039;&#039;Wheel Fork Bearing:&#039;&#039;&#039; Steel, flanged open ball bearing, 1/4&amp;quot; ID, 11/16&amp;quot; OD, McMaster part# 6383K213&lt;br /&gt;
*&#039;&#039;&#039;RC Servo-Shaft Coupler:&#039;&#039;&#039; Split clamp to Futaba S3004 coupler, ServoCity.com&lt;br /&gt;
*&#039;&#039;&#039;Chassis:&#039;&#039;&#039; laser cut from 1/4 inch 12&amp;quot;x12&amp;quot; clear acrylic&lt;br /&gt;
*&#039;&#039;&#039;Axels:&#039;&#039;&#039; 1/4&amp;quot; tapered dowels&lt;br /&gt;
*&#039;&#039;&#039;Wheel Bearings:&#039;&#039;&#039; 3 x Open steel ball bearings, 1/4&amp;quot; ID, 7/8&amp;quot; OD, 1/4&amp;quot; thickness, McMaster part# 6383K14&lt;br /&gt;
*&#039;&#039;&#039;Fasteners:&#039;&#039;&#039; 10-32 set screw for securing the momentum wheel to the motor, 4-40 round-head screws for securing motor to the chassis&lt;br /&gt;
*&#039;&#039;&#039;Velcro:&#039;&#039;&#039; To attach battery packs and housing to the chassis&lt;br /&gt;
*&#039;&#039;&#039;Adhesives:&#039;&#039;&#039; Acrylic Epoxy for Servo Holder, Superglue for rear wheel mounts&lt;br /&gt;
*&#039;&#039;&#039;Power Source:&#039;&#039;&#039; 2 x 9.6 V, 2200 mAh, NI-MH, Powerizer rechargeable battery &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a sheet of 1/4 inch clear Acrylic. It needed to be large enough to hold the motors, two batteries, and two circuit boards. In order to reduce the weight of the design, the base was cut into a triangle with wheels to be placed at each corner. Four small holes were cut at the front and at the middle of the base to allow the motor to be secured, and one larger hole was cut for a bearing to be pressed into place for the front steering wheel. [[Media:Dimensioned_Drawing_of_Chassis.pdf|Dimensioned Drawing of Chassis]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Steering Assembly ====&lt;br /&gt;
&lt;br /&gt;
[[image:Servo_and_Fork_Detail.jpg|thumb|right|RC Servo Attachment and Front Wheel Fork]]&lt;br /&gt;
&lt;br /&gt;
The front wheel was attached to the steering servo through a machined aluminum fork. The fork design was used (as opposed to a one-sided mount) so that the axis of rotation for the front wheel could be directly centered above the centerline of the wheel with relative ease.&lt;br /&gt;
&lt;br /&gt;
The Futaba RC servo used for steering the front wheel was held in place by the servo-shaft coupler and by two pieces of acrylic. The servo was light enough that it could be supported by only the coupler. Two vertical pieces of acrylic prevented the servo from rotating as it turned the front wheel. A small piece of electrical tape kept the servo from backing off of the coupler while Fluffbot was operating. [[Media:Dimensioned_Drawing_of_Steering_Fork.pdf|Dimensioned Drawing of Steering Fork]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Momentum Wheel ====&lt;br /&gt;
&lt;br /&gt;
[[image:Momentum_Wheel.jpg|thumb|right|Angular Momentum Wheel]]&lt;br /&gt;
The momentum wheel is design specifically to increase the torque on the body. This was done by machining the wheel so that there was more weight on the outside of the wheel. The momentum wheel is made from Aluminum 6061. The shaft in the center of the momentum wheel connects to the shaft of the motor using a set screw. The motor connector shaft and the momentum wheel were made as one piece to increase rigidity and assure that the momentum wheel would be perfectly parallel to the chassis. The momentum wheel weighs about 1.3 lbs, which makes the torque on the motor above its maximum continuous torque rating. We felt that this would be alright because the motor is not running continuously at a high speed, but rather is accelerating and decelerating sinusoidally. The motor is also not running at maximum rpm.&lt;br /&gt;
[[Media:Momentum_Wheel_Dimensioned_Drawing.pdf|Dimensioned Drawing of Momentum Wheel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Wheels ====&lt;br /&gt;
[[Image:RY_NP_TJ_Wheel_with_Bearing.jpg|thumb|right|Wheel with Ball Bearing]]&lt;br /&gt;
The wheels we used were specially machined out of Aluminum 6061 to fit treaded rubber tires we found in the machine shop. Aluminum was used instead of preformed plastic wheels because we could precisely machine the wheels to fit the design of the Fluffbot, rather than needing to design the Fluffbot around the wheels we had available. The wheels were designed to fit ____ ball bearings. The ball bearings were press fit into the center of the wheel. We used ball bearings so that the wheels would spin with minimal friction and thus less energy would be required to move the Fluffbot. [[Media:Dimensioned_Drawing_of_Wheels.pdf|Dimensioned Drawing of Wheels&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Battery and Electronics ====&lt;br /&gt;
&lt;br /&gt;
The batteries and circuit boards were attached to the top of the chassis using Velcro. The configuration of the batteries as well as the placement of the circuit boards are intentional, concentrating the majority of the weight around the center of hte momentum wheel and also so that different housing (read: stuffed animals) could be easily placed around the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Fluffy Housing ====&lt;br /&gt;
&lt;br /&gt;
[[Image:Fluffbot_with_Seal_Housing.jpg|thumb|right|Fluffy Housing]]&lt;br /&gt;
The Fluffbot receives its name from the fluffy stuffed animals that ride atop it and that the Fluffbot imitates by its motion. For this version of the Fluffbot a seal was used to house the mechanical structure and electronics. The seal is split in two and attached to the chassis by Velcro. There is a piece of sheet metal that is bent and attached with Velcro to the upper part of the seal so that it will maintain its structure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Mechanical Debugging ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bearings are coming out of rear wheels:&#039;&#039;&#039; Re-machine wheels using a boring bar for the through-hole for the bearings. While boring   out hole, check dimensions of the bearing being used and take small cuts, measuring after each pass, to assure that the hole diameter precisely matches that of the bearing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Servo comes loose from servo coupler:&#039;&#039;&#039; Machine a set screw hole through the part of the coupler connecting to the servo and add a set screw to keep the servo in place&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
[[image:Fluffbot_Circuit_Boards.jpg |thumb|300px|Fluffbot Circuitry|right]]&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
Due to the short amount of time in which the Fluffbot was designed, built and programmed, there was not enough time for optimization and iteration. Thus, there are many areas in which the Fluffbot could be improved with future work. &lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. this could be accomplished by adding encoders to the front wheel to determine the distance the Fluffbot has moved from its initial position. It would then be possible to map the Fluffbot&#039;s trajectory as well as collect data about its speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
By adding optical sensors to the Fluffbot we could program it to automatically avoid obstacles. This would most likely use an override function that would supersede the command coming from the user.&lt;br /&gt;
&lt;br /&gt;
==== High Torque Servos ====&lt;br /&gt;
High torque servos would enable the Fluffbot to move more quickly because the front wheel would be able to turn at a higher frequency. &lt;br /&gt;
&lt;br /&gt;
==== Hand-held Controller ====&lt;br /&gt;
By linking the control of the Fluffbot to a handheld controller a user could more easily interact with the Fluffbot and control it because they wouldn&#039;t need to be staring at a GUI on a computer to control its behavior. &lt;br /&gt;
&lt;br /&gt;
==== Wall-Riding ====&lt;br /&gt;
The initial scope of the project included giving the robot the ability to ride on a vertical wall. While this was not a possibility for us in the time frame allotted, a future team may be able to build on our design to enable dynamic motion using a momentum wheel along a vertical surface. This may be possible by using neodymium wheels to attach the robot to a metal wall.&lt;br /&gt;
&lt;br /&gt;
==== Housing ====&lt;br /&gt;
The Fluffbot does not currently have a housing that protects the electronics on the chassis. A housing would allow for easy attachment and detachment of various animal shells and would also prevent the stuffed animals from contacting the hot electronics and making them heat up even faster. Air vents could also be added to the housing to allow for heat to dissipate from the electronics.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17773</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17773"/>
		<updated>2010-03-18T17:09:41Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Fluff_Bot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel.&lt;br /&gt;
&lt;br /&gt;
Some videos:&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=fzAgX4L4gHU Fluffbot bottom view of momentum and steering wheel]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=BIMgh9eEPQ4 Fluffbot seal-in-water]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Xc-FJgjFg50 Fluffbot seal-on-ice]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=-XoxQAQtva4 Fluffbot seal-on-land reverse]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=utZnFJuoLag Fluffbot seal-on-land]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=jAqSzvoKiLE Fluffbot with seal casing 1]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=3X7MnW4_8FM Fluffbot with seal casing 2]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=H4ZJ47V_QE4 Fluffbot with seal casing 3]&lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
[[image:2010-25-Johnson-Pentelovitch-Yu.jpg|thumb|400pix|right|Johnson - Pentelovitch - Yu]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Fluffbot_Concept.jpg|thumb|700pix|right|Fluffbot Motion]]&lt;br /&gt;
&lt;br /&gt;
Instead of using motors to directly drive its motion forward, Fluffbot uses the basic principal of conservation of angular momentum. When an object with a high moment of inertia is accelerated about an axis, angular momentum in the direction of motion is immediately created. When this happens, angular momentum in the opposing direction is also produced. The resulting motion from this &amp;quot;reaction&amp;quot; momentum can be transferred to ground through a rigid fixture, or this resulting motion could be controlled and channeled into a desirable form as shown with Fluffbot.&lt;br /&gt;
&lt;br /&gt;
When the large flywheel on Fluffbot accelerates clockwise in the horizontal plane, the body attempts to conserve the zero angular momentum of the system by rotating around the same axis in a counter clockwise direction. Motion forward or backward by Fluffbot is made possible by the steering of the front wheel. There are three conditions for the steering wheel to be in, and three corresponding effects:&lt;br /&gt;
&lt;br /&gt;
1) Wheel is aligned straight ahead - In this scenario, friction between the front wheel and the the ground prevent any rotation along the robot&#039;s main axis of rotation. Any acceleration of the momentum wheel in this arrangement will result in no movement of Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) Wheel is turned to the left - When the momentum wheel accelerates in a clockwise direction, the chassis will attempt to rotate to the left. Because the front wheel is turned to the left, a portion of this rotation will be allowed to occur around a pivot point perpendicular to the direction the wheel is pointed. This gives the overall effect of turning Fluffbot to the left and moving it slightly forward. If the momentum wheel were to accelerate in the opposite direction (counter clockwise) while the front wheel is steering left, the result would be to turn Fluffbot to the right and send in moving backward.&lt;br /&gt;
&lt;br /&gt;
3) Wheel is turned to the right - This exhibits the same behavior as when the front wheel is turned to the left, however, the direction of rotation for the momentum wheel and the chassis are reversed.&lt;br /&gt;
&lt;br /&gt;
In order to control the motion of Fluffbot and to send it in a straight direction, the momentum wheel accelerates back and forth sinusoidally as the front wheel turns left to right with the same sinusoid. To reverse the direction that Fluffbot travels, simply put the front wheels control wave 180˚ out of phase with the control wave for the momentum wheel. Fluffbot is also able to steer left and right by controlling the amplitude and range of the front steering wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:Uncovered_Bot.jpg|thumb|right|Inside Fluff Bot]]&lt;br /&gt;
The Fluffbot has all of its circuitry and mechanical components confined to a single chassis. The chassis is an arrow shape and is mounted on three wheels attached to the bottom of the chassis. The two rear wheels are fixed, while the front wheel is free to rotate and is mounted on a fork and coupled to a servo, which controls its turning angle. A momentum wheel is fixed underneath the center of the chassis to a motor which is mounted on top. All circuitry and power sources are mounted on the top of the chassis as well.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the Fluffbot is designed for minimum chassis weight and maximum torque generated by the momentum wheel. The momentum wheel is mounted directly in the center of the three wheels so that the torque is distributed evenly. The wheels use press-fit ball bearings mounted on fixed axles to achieve minimum friction when rolling. The front-wheel fork is mounted to the chassis through a ball bearing to reduce frictional force on the servo motor. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Motors:&#039;&#039;&#039; Futaba S3004 standard ball bearing RC servo motor, Mechatronics Lab - Pittman GM8712G708-R3 Motor 19.5:1 gear head, Mechatronics Lab&lt;br /&gt;
*&#039;&#039;&#039;Wheels:&#039;&#039;&#039; Machined from Aluminum 2&amp;quot; 6061 rod, McMaster part# 8974K711&lt;br /&gt;
*&#039;&#039;&#039;Momentum Wheel:&#039;&#039;&#039; Machined from 6&amp;quot; Aluminum 6061 rod, machine shop stock&lt;br /&gt;
*&#039;&#039;&#039;Tires:&#039;&#039;&#039; Shop Stock rubber wheel coverings&lt;br /&gt;
*&#039;&#039;&#039;Wheel Fork:&#039;&#039;&#039; Machined from aluminum 6061 rod, McMaster part# 8974K711&lt;br /&gt;
*&#039;&#039;&#039;Wheel Fork Bearing:&#039;&#039;&#039; Steel, flanged open ball bearing, 1/4&amp;quot; ID, 11/16&amp;quot; OD, McMaster part# 6383K213&lt;br /&gt;
*&#039;&#039;&#039;RC Servo-Shaft Coupler:&#039;&#039;&#039; Split clamp to Futaba S3004 coupler, ServoCity.com&lt;br /&gt;
*&#039;&#039;&#039;Chassis:&#039;&#039;&#039; laser cut from 1/4 inch 12&amp;quot;x12&amp;quot; clear acrylic&lt;br /&gt;
*&#039;&#039;&#039;Axels:&#039;&#039;&#039; 1/4&amp;quot; tapered dowels&lt;br /&gt;
*&#039;&#039;&#039;Wheel Bearings:&#039;&#039;&#039; 3 x Open steel ball bearings, 1/4&amp;quot; ID, 7/8&amp;quot; OD, 1/4&amp;quot; thickness, McMaster part# 6383K14&lt;br /&gt;
*&#039;&#039;&#039;Fasteners:&#039;&#039;&#039; 10-32 set screw for securing the momentum wheel to the motor, 4-40 round-head screws for securing motor to the chassis&lt;br /&gt;
*&#039;&#039;&#039;Velcro:&#039;&#039;&#039; To attach battery packs and housing to the chassis&lt;br /&gt;
*&#039;&#039;&#039;Adhesives:&#039;&#039;&#039; Acrylic Epoxy for Servo Holder, Superglue for rear wheel mounts&lt;br /&gt;
*&#039;&#039;&#039;Power Source:&#039;&#039;&#039; 2 x 9.6 V, 2200 mAh, NI-MH, Powerizer rechargeable battery &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a sheet of 1/4 inch clear Acrylic. It needed to be large enough to hold the motors, two batteries, and two circuit boards. In order to reduce the weight of the design, the base was cut into a triangle with wheels to be placed at each corner. Four small holes were cut at the front and at the middle of the base to allow the motor to be secured, and one larger hole was cut for a bearing to be pressed into place for the front steering wheel. [[Media:Dimensioned_Drawing_of_Chassis.pdf|Dimensioned Drawing of Chassis]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Steering Assembly ====&lt;br /&gt;
&lt;br /&gt;
[[image:Servo_and_Fork_Detail.jpg|thumb|right|RC Servo Attachment and Front Wheel Fork]]&lt;br /&gt;
&lt;br /&gt;
The front wheel was attached to the steering servo through a machined aluminum fork. The fork design was used (as opposed to a one-sided mount) so that the axis of rotation for the front wheel could be directly centered above the centerline of the wheel with relative ease.&lt;br /&gt;
&lt;br /&gt;
The Futaba RC servo used for steering the front wheel was held in place by the servo-shaft coupler and by two pieces of acrylic. The servo was light enough that it could be supported by only the coupler. Two vertical pieces of acrylic prevented the servo from rotating as it turned the front wheel. A small piece of electrical tape kept the servo from backing off of the coupler while Fluffbot was operating. [[Media:Dimensioned_Drawing_of_Steering_Fork.pdf|Dimensioned Drawing of Steering Fork]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Momentum Wheel ====&lt;br /&gt;
&lt;br /&gt;
[[image:Momentum_Wheel.jpg|thumb|right|Angular Momentum Wheel]]&lt;br /&gt;
The momentum wheel is design specifically to increase the torque on the body. This was done by machining the wheel so that there was more weight on the outside of the wheel. The momentum wheel is made from Aluminum 6061. The shaft in the center of the momentum wheel connects to the shaft of the motor using a set screw. The motor connector shaft and the momentum wheel were made as one piece to increase rigidity and assure that the momentum wheel would be perfectly parallel to the chassis. The momentum wheel weighs about 1.3 lbs, which makes the torque on the motor above its maximum continuous torque rating. We felt that this would be alright because the motor is not running continuously at a high speed, but rather is accelerating and decelerating sinusoidally. The motor is also not running at maximum rpm.&lt;br /&gt;
[[Media:Momentum_Wheel_Dimensioned_Drawing.pdf|Dimensioned Drawing of Momentum Wheel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Wheels ====&lt;br /&gt;
[[Image:RY_NP_TJ_Wheel_with_Bearing.jpg|thumb|right|Wheel with Ball Bearing]]&lt;br /&gt;
The wheels we used were specially machined out of Aluminum 6061 to fit treaded rubber tires we found in the machine shop. Aluminum was used instead of preformed plastic wheels because we could precisely machine the wheels to fit the design of the Fluffbot, rather than needing to design the Fluffbot around the wheels we had available. The wheels were designed to fit ____ ball bearings. The ball bearings were press fit into the center of the wheel. We used ball bearings so that the wheels would spin with minimal friction and thus less energy would be required to move the Fluffbot. [[Media:Dimensioned_Drawing_of_Wheels.pdf|Dimensioned Drawing of Wheels&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Battery and Electronics ====&lt;br /&gt;
&lt;br /&gt;
The batteries and circuit boards were attached to the top of the chassis using Velcro. The configuration of the batteries as well as the placement of the circuit boards are intentional, concentrating the majority of the weight around the center of hte momentum wheel and also so that different housing (read: stuffed animals) could be easily placed around the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Fluffy Housing ====&lt;br /&gt;
&lt;br /&gt;
[[Image:Fluffbot_with_Seal_Housing.jpg|thumb|right|Fluffy Housing]]&lt;br /&gt;
The Fluffbot receives its name from the fluffy stuffed animals that ride atop it and that the Fluffbot imitates by its motion. For this version of the Fluffbot a seal was used to house the mechanical structure and electronics. The seal is split in two and attached to the chassis by Velcro. There is a piece of sheet metal that is bent and attached with Velcro to the upper part of the seal so that it will maintain its structure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Mechanical Debugging ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bearings are coming out of rear wheels:&#039;&#039;&#039; Re-machine wheels using a boring bar for the through-hole for the bearings. While boring   out hole, check dimensions of the bearing being used and take small cuts, measuring after each pass, to assure that the hole diameter precisely matches that of the bearing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Servo comes loose from servo coupler:&#039;&#039;&#039; Machine a set screw hole through the part of the coupler connecting to the servo and add a set screw to keep the servo in place&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
[[image:Fluffbot_Circuit_Boards.jpg |thumb|300px|Fluffbot Circuitry|right]]&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
Due to the short amount of time in which the Fluffbot was designed, built and programmed, there was not enough time for optimization and iteration. Thus, there are many areas in which the Fluffbot could be improved with future work. &lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. this could be accomplished by adding encoders to the front wheel to determine the distance the Fluffbot has moved from its initial position. It would then be possible to map the Fluffbot&#039;s trajectory as well as collect data about its speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
By adding optical sensors to the Fluffbot we could program it to automatically avoid obstacles. This would most likely use an override function that would supersede the command coming from the user.&lt;br /&gt;
&lt;br /&gt;
==== High Torque Servos ====&lt;br /&gt;
High torque servos would enable the Fluffbot to move more quickly because the front wheel would be able to turn at a higher frequency. &lt;br /&gt;
&lt;br /&gt;
==== Hand-held Controller ====&lt;br /&gt;
By linking the control of the Fluffbot to a handheld controller a user could more easily interact with the Fluffbot and control it because they wouldn&#039;t need to be staring at a GUI on a computer to control its behavior. &lt;br /&gt;
&lt;br /&gt;
==== Wall-Riding ====&lt;br /&gt;
The initial scope of the project included giving the robot the ability to ride on a vertical wall. While this was not a possibility for us in the time frame allotted, a future team may be able to build on our design to enable dynamic motion using a momentum wheel along a vertical surface. This may be possible by using neodymium wheels to attach the robot to a metal wall.&lt;br /&gt;
&lt;br /&gt;
==== Housing ====&lt;br /&gt;
The Fluffbot does not currently have a housing that protects the electronics on the chassis. A housing would allow for easy attachment and detachment of various animal shells and would also prevent the stuffed animals from contacting the hot electronics and making them heat up even faster. Air vents could also be added to the housing to allow for heat to dissipate from the electronics.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17566</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17566"/>
		<updated>2010-03-18T03:22:52Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Parts List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Fluff_Bot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//insert team picture&lt;br /&gt;
[[image:2010-25-Johnson-Pentelovitch-Yu.jpg|thumb|400pix|right|Johnson - Pentelovitch - Yu]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Fluffbot_Concept.jpg|thumb|700pix|right|Fluffbot Motion]]&lt;br /&gt;
&lt;br /&gt;
Instead of using motors to directly drive its motion forward, Fluffbot uses the basic principal of conservation of angular momentum. When an object with a high moment of inertia is accelerated about an axis, angular momentum in the direction of motion is immediately created. When this happens, angular momentum in the opposing direction is also produced. The resulting motion from this &amp;quot;reaction&amp;quot; momentum can be transferred to ground through a rigid fixture, or this resulting motion could be controlled and channeled into a desirable form as shown with Fluffbot.&lt;br /&gt;
&lt;br /&gt;
When the large flywheel on Fluffbot accelerates clockwise in the horizontal plane, the body attempts to conserve the zero angular momentum of the system by rotating around the same axis in a counter clockwise direction. Motion forward or backward by Fluffbot is made possible by the steering of the front wheel. There are three conditions for the steering wheel to be in, and three corresponding effects:&lt;br /&gt;
&lt;br /&gt;
1) Wheel is aligned straight ahead - In this scenario, friction between the front wheel and the the ground prevent any rotation along the robot&#039;s main axis of rotation. Any acceleration of the momentum wheel in this arrangement will result in no movement of Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) Wheel is turned to the left - When the momentum wheel accelerates in a clockwise direction, the chassis will attempt to rotate to the left. Because the front wheel is turned to the left, a portion of this rotation will be allowed to occur around a pivot point perpendicular to the direction the wheel is pointed. This gives the overall effect of turning Fluffbot to the left and moving it slightly forward. If the momentum wheel were to accelerate in the opposite direction (counter clockwise) while the front wheel is steering left, the result would be to turn Fluffbot to the right and send in moving backward.&lt;br /&gt;
&lt;br /&gt;
3) Wheel is turned to the right - This exhibits the same behavior as when the front wheel is turned to the left, however, the direction of rotation for the momentum wheel and the chassis are reversed.&lt;br /&gt;
&lt;br /&gt;
In order to control the motion of Fluffbot and to send it in a straight direction, the momentum wheel accelerates back and forth sinusoidally as the front wheel turns left to right with the same sinusoid. To reverse the direction that Fluffbot travels, simply put the front wheels control wave 180˚ out of phase with the control wave for the momentum wheel. Fluffbot is also able to steer left and right by controlling the amplitude and range of the front steering wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:Uncovered_Bot.jpg|thumb|right|Inside Fluff Bot]]&lt;br /&gt;
The Fluffbot has all of its circuitry and mechanical components confined to a single chassis. The chassis is an arrow shape and is mounted on three wheels attached to the bottom of the chassis. The two rear wheels are fixed, while the front wheel is free to rotate and is mounted on a fork and coupled to a servo, which controls its turning angle. A momentum wheel is fixed underneath the center of the chassis to a motor which is mounted on top. All circuitry and power sources are mounted on the top of the chassis as well.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the Fluffbot is designed for minimum chassis weight and maximum torque generated by the momentum wheel. The momentum wheel is mounted directly in the center of the three wheels so that the torque is distributed evenly. The wheels use press-fit ball bearings mounted on fixed axles to achieve minimum friction when rolling. The front-wheel fork is mounted to the chassis through a ball bearing to reduce frictional force on the servo motor. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Mechatronics Lab - Pittman GM8712G708-R3 Motor 19.5:1 gear head, Mechatronics Lab&lt;br /&gt;
*Wheels: Machined from Aluminum 2&amp;quot; 6061 rod stock&lt;br /&gt;
*Momentum Wheel: Machined from 6&amp;quot; Aluminum 6061 rod stock&lt;br /&gt;
*Tires: Shop Stock rubber wheel coverings&lt;br /&gt;
*Wheel Fork: Machined from aluminum 6061 rod stock&lt;br /&gt;
*RC Servo-Shaft Coupler: Split clamp to Futaba S3004 coupler, ServoCity.com&lt;br /&gt;
*Chassis: laser cut from 1/4 inch 12&amp;quot;x12&amp;quot; clear acrylic&lt;br /&gt;
*Axels: 1/4&amp;quot; tapered dowels&lt;br /&gt;
*Bearings: _______&lt;br /&gt;
*Fasteners: 10-32 set screw for securing the momentum wheel to the motor, 4-40 round-head screws for securing motor to the chassis&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chassis&lt;br /&gt;
*Adhesives: Acrylic Epoxy for Servo Holder, Superglue for rear wheel mounts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a sheet of 1/4 inch clear Acrylic. It needed to be large enough to hold the motors, two batteries, and two circuit boards. In order to reduce the weight of the design, the base was cut into a triangle with wheels to be placed at each corner. Four small holes were cut at the front and at the middle of the base to allow the motor to be secured, and one larger hole was cut for a bearing to be pressed into place for the front steering wheel. [[Media:Dimensioned_Drawing_of_Chassis.pdf|Dimensioned Drawing of Chassis]]&lt;br /&gt;
&lt;br /&gt;
==== Steering Assembly ====&lt;br /&gt;
&lt;br /&gt;
[[image:Servo_and_Fork_Detail.jpg|thumb|right|RC Servo Attachment and Front Wheel Fork]]&lt;br /&gt;
&lt;br /&gt;
The front wheel was attached to the steering servo through a machined aluminum fork. The fork design was used (as opposed to a one-sided mount) so that the axis of rotation for the front wheel could be directly centered above the centerline of the wheel with relative ease.&lt;br /&gt;
&lt;br /&gt;
The Futaba RC servo used for steering the front wheel was held in place by the servo-shaft coupler and by two pieces of acrylic. The servo was light enough that it could be supported by only the coupler. Two vertical pieces of acrylic prevented the servo from rotating as it turned the front wheel. A small piece of electrical tape kept the servo from backing off of the coupler while Fluffbot was operating. [[Media:Dimensioned_Drawing_of_Steering_Fork.pdf|Dimensioned Drawing of Steering Fork]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Momentum Wheel ====&lt;br /&gt;
&lt;br /&gt;
[[image:Momentum_Wheel.jpg|thumb|right|Angular Momentum Wheel]]&lt;br /&gt;
The momentum wheel is design specifically to increase the torque on the body. This was done by machining the wheel so that there was more weight on the outside of the wheel. The momentum wheel is made from Aluminum 6061. The shaft in the center of the momentum wheel connects to the shaft of the motor using a set screw. The motor connector shaft and the momentum wheel were made as one piece to increase rigidity and assure that the momentum wheel would be perfectly parallel to the chassis. The momentum wheel weighs about 1.3 lbs, which makes the torque on the motor above its maximum continuous torque rating. We felt that this would be alright because the motor is not running continuously at a high speed, but rather is accelerating and decelerating sinusoidally. The motor is also not running at maximum rpm.&lt;br /&gt;
[[Media:Momentum_Wheel_Dimensioned_Drawing.pdf|Dimensioned Drawing of Momentum Wheel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Wheels ====&lt;br /&gt;
[[Image:RY_NP_TJ_Wheel_with_Bearing.jpg|thumb|right|Wheel with Ball Bearing]]&lt;br /&gt;
The wheels we used were specially machined out of Aluminum 6061 to fit treaded rubber tires we found in the machine shop. Aluminum was used instead of preformed plastic wheels because we could precisely machine the wheels to fit the design of the Fluffbot, rather than needing to design the Fluffbot around the wheels we had available. The wheels were designed to fit ____ ball bearings. The ball bearings were press fit into the center of the wheel. We used ball bearings so that the wheels would spin with minimal friction and thus less energy would be required to move the Fluffbot. [[Media:Dimensioned_Drawing_of_Wheels.pdf|Dimensioned Drawing of Wheels&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Battery and Electronics ====&lt;br /&gt;
&lt;br /&gt;
The batteries and circuit boards were attached to the top of the chassis using Velcro. The configuration of the batteries as well as the placement of the circuit boards are meant so that a most of the weight on the chassis would be centered around the center of the momentum wheel and also so that we could easily place different housings (read: stuffed animals) around the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Mechanical Debugging ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bearings are coming out of rear wheels:&#039;&#039;&#039; Re-machine wheels using a boring bar for the through-hole for the bearings. While boring   out hole, check dimensions of the bearing being used and take small cuts, measuring after each pass, to assure that the hole diameter precisely matches that of the bearing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Servo comes loose from servo coupler:&#039;&#039;&#039; Machine a set screw hole through the part of the coupler connecting to the servo and add a set screw to keep the servo in place&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
[[image:Fluffbot_Circuit_Boards.jpg |thumb|300px|Fluffbot Circuitry|right]]&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17565</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=17565"/>
		<updated>2010-03-18T03:20:54Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Parts List */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Fluff_Bot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//insert team picture&lt;br /&gt;
[[image:2010-25-Johnson-Pentelovitch-Yu.jpg|thumb|400pix|right|Johnson - Pentelovitch - Yu]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Fluffbot_Concept.jpg|thumb|700pix|right|Fluffbot Motion]]&lt;br /&gt;
&lt;br /&gt;
Instead of using motors to directly drive its motion forward, Fluffbot uses the basic principal of conservation of angular momentum. When an object with a high moment of inertia is accelerated about an axis, angular momentum in the direction of motion is immediately created. When this happens, angular momentum in the opposing direction is also produced. The resulting motion from this &amp;quot;reaction&amp;quot; momentum can be transferred to ground through a rigid fixture, or this resulting motion could be controlled and channeled into a desirable form as shown with Fluffbot.&lt;br /&gt;
&lt;br /&gt;
When the large flywheel on Fluffbot accelerates clockwise in the horizontal plane, the body attempts to conserve the zero angular momentum of the system by rotating around the same axis in a counter clockwise direction. Motion forward or backward by Fluffbot is made possible by the steering of the front wheel. There are three conditions for the steering wheel to be in, and three corresponding effects:&lt;br /&gt;
&lt;br /&gt;
1) Wheel is aligned straight ahead - In this scenario, friction between the front wheel and the the ground prevent any rotation along the robot&#039;s main axis of rotation. Any acceleration of the momentum wheel in this arrangement will result in no movement of Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) Wheel is turned to the left - When the momentum wheel accelerates in a clockwise direction, the chassis will attempt to rotate to the left. Because the front wheel is turned to the left, a portion of this rotation will be allowed to occur around a pivot point perpendicular to the direction the wheel is pointed. This gives the overall effect of turning Fluffbot to the left and moving it slightly forward. If the momentum wheel were to accelerate in the opposite direction (counter clockwise) while the front wheel is steering left, the result would be to turn Fluffbot to the right and send in moving backward.&lt;br /&gt;
&lt;br /&gt;
3) Wheel is turned to the right - This exhibits the same behavior as when the front wheel is turned to the left, however, the direction of rotation for the momentum wheel and the chassis are reversed.&lt;br /&gt;
&lt;br /&gt;
In order to control the motion of Fluffbot and to send it in a straight direction, the momentum wheel accelerates back and forth sinusoidally as the front wheel turns left to right with the same sinusoid. To reverse the direction that Fluffbot travels, simply put the front wheels control wave 180˚ out of phase with the control wave for the momentum wheel. Fluffbot is also able to steer left and right by controlling the amplitude and range of the front steering wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:Uncovered_Bot.jpg|thumb|right|Inside Fluff Bot]]&lt;br /&gt;
The Fluffbot has all of its circuitry and mechanical components confined to a single chassis. The chassis is an arrow shape and is mounted on three wheels attached to the bottom of the chassis. The two rear wheels are fixed, while the front wheel is free to rotate and is mounted on a fork and coupled to a servo, which controls its turning angle. A momentum wheel is fixed underneath the center of the chassis to a motor which is mounted on top. All circuitry and power sources are mounted on the top of the chassis as well.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the Fluffbot is designed for minimum chassis weight and maximum torque generated by the momentum wheel. The momentum wheel is mounted directly in the center of the three wheels so that the torque is distributed evenly. The wheels use press-fit ball bearings mounted on fixed axles to achieve minimum friction when rolling. The front-wheel fork is mounted to the chassis through a ball bearing to reduce frictional force on the servo motor. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Mechatronics Lab - Pittman _____ Motor ____ gear head, Mechatronics Lab&lt;br /&gt;
*Wheels: Machined from Aluminum 2&amp;quot; 6061 rod stock&lt;br /&gt;
*Momentum Wheel: Machined from 6&amp;quot; Aluminum 6061 rod stock&lt;br /&gt;
*Tires: Shop Stock rubber wheel coverings&lt;br /&gt;
*Wheel Fork: Machined from aluminum 6061 rod stock&lt;br /&gt;
*RC Servo-Shaft Coupler: Split clamp to Futaba S3004 coupler, ServoCity.com&lt;br /&gt;
*Chassis: laser cut from 1/4 inch 12&amp;quot;x12&amp;quot; clear acrylic&lt;br /&gt;
*Axels: 1/4&amp;quot; tapered dowels&lt;br /&gt;
*Bearings: _______&lt;br /&gt;
*Fasteners: 10-32 set screw for securing the momentum wheel to the motor, 4-40 round-head screws for securing motor to the chassis&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chassis&lt;br /&gt;
*Adhesives: Acrylic Epoxy for Servo Holder, Superglue for rear wheel mounts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a sheet of 1/4 inch clear Acrylic. It needed to be large enough to hold the motors, two batteries, and two circuit boards. In order to reduce the weight of the design, the base was cut into a triangle with wheels to be placed at each corner. Four small holes were cut at the front and at the middle of the base to allow the motor to be secured, and one larger hole was cut for a bearing to be pressed into place for the front steering wheel. [[Media:Dimensioned_Drawing_of_Chassis.pdf|Dimensioned Drawing of Chassis]]&lt;br /&gt;
&lt;br /&gt;
==== Steering Assembly ====&lt;br /&gt;
&lt;br /&gt;
[[image:Servo_and_Fork_Detail.jpg|thumb|right|RC Servo Attachment and Front Wheel Fork]]&lt;br /&gt;
&lt;br /&gt;
The front wheel was attached to the steering servo through a machined aluminum fork. The fork design was used (as opposed to a one-sided mount) so that the axis of rotation for the front wheel could be directly centered above the centerline of the wheel with relative ease.&lt;br /&gt;
&lt;br /&gt;
The Futaba RC servo used for steering the front wheel was held in place by the servo-shaft coupler and by two pieces of acrylic. The servo was light enough that it could be supported by only the coupler. Two vertical pieces of acrylic prevented the servo from rotating as it turned the front wheel. A small piece of electrical tape kept the servo from backing off of the coupler while Fluffbot was operating. [[Media:Dimensioned_Drawing_of_Steering_Fork.pdf|Dimensioned Drawing of Steering Fork]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Momentum Wheel ====&lt;br /&gt;
&lt;br /&gt;
[[image:Momentum_Wheel.jpg|thumb|right|Angular Momentum Wheel]]&lt;br /&gt;
The momentum wheel is design specifically to increase the torque on the body. This was done by machining the wheel so that there was more weight on the outside of the wheel. The momentum wheel is made from Aluminum 6061. The shaft in the center of the momentum wheel connects to the shaft of the motor using a set screw. The motor connector shaft and the momentum wheel were made as one piece to increase rigidity and assure that the momentum wheel would be perfectly parallel to the chassis. The momentum wheel weighs about 1.3 lbs, which makes the torque on the motor above its maximum continuous torque rating. We felt that this would be alright because the motor is not running continuously at a high speed, but rather is accelerating and decelerating sinusoidally. The motor is also not running at maximum rpm.&lt;br /&gt;
[[Media:Momentum_Wheel_Dimensioned_Drawing.pdf|Dimensioned Drawing of Momentum Wheel]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Wheels ====&lt;br /&gt;
[[Image:RY_NP_TJ_Wheel_with_Bearing.jpg|thumb|right|Wheel with Ball Bearing]]&lt;br /&gt;
The wheels we used were specially machined out of Aluminum 6061 to fit treaded rubber tires we found in the machine shop. Aluminum was used instead of preformed plastic wheels because we could precisely machine the wheels to fit the design of the Fluffbot, rather than needing to design the Fluffbot around the wheels we had available. The wheels were designed to fit ____ ball bearings. The ball bearings were press fit into the center of the wheel. We used ball bearings so that the wheels would spin with minimal friction and thus less energy would be required to move the Fluffbot. [[Media:Dimensioned_Drawing_of_Wheels.pdf|Dimensioned Drawing of Wheels&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Battery and Electronics ====&lt;br /&gt;
&lt;br /&gt;
The batteries and circuit boards were attached to the top of the chassis using Velcro. The configuration of the batteries as well as the placement of the circuit boards are meant so that a most of the weight on the chassis would be centered around the center of the momentum wheel and also so that we could easily place different housings (read: stuffed animals) around the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Mechanical Debugging ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bearings are coming out of rear wheels:&#039;&#039;&#039; Re-machine wheels using a boring bar for the through-hole for the bearings. While boring   out hole, check dimensions of the bearing being used and take small cuts, measuring after each pass, to assure that the hole diameter precisely matches that of the bearing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Servo comes loose from servo coupler:&#039;&#039;&#039; Machine a set screw hole through the part of the coupler connecting to the servo and add a set screw to keep the servo in place&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
[[image:Fluffbot_Circuit_Boards.jpg |thumb|300px|Fluffbot Circuitry|right]]&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Fluff_bot_PIC_Code.zip&amp;diff=16866</id>
		<title>File:Fluff bot PIC Code.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Fluff_bot_PIC_Code.zip&amp;diff=16866"/>
		<updated>2010-03-16T04:08:58Z</updated>

		<summary type="html">&lt;p&gt;RenYu: uploaded a new version of &amp;quot;Image:Fluff bot PIC Code.zip&amp;quot;: PIC32 code for the Fluffbot, ME333 Winter 2010 project.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PIC C Code for Fluffbot, an ME333 Winter 2010 Final Project.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16865</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16865"/>
		<updated>2010-03-16T04:06:44Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Parts List (Digikey Part Number) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16864</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16864"/>
		<updated>2010-03-16T04:06:04Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics On Fluffbot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16863</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16863"/>
		<updated>2010-03-16T04:05:23Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]] + PIC USB cable&lt;br /&gt;
*[[XBee Interface Board|XBee Interface Board]] (2)&lt;br /&gt;
*[[PIC RS232| RS232 cable]]&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An XBee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics At Computer====&lt;br /&gt;
The second XBee Interface Board is connected to a computer using the RS232 cable. This enables the user to communicate wirelessly in real-time to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16862</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16862"/>
		<updated>2010-03-16T04:01:19Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee Interface Board]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics On Fluffbot====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An Xbee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16861</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16861"/>
		<updated>2010-03-16T03:59:51Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee Interface Board]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|400px|Electronics Block Diagram|right]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Electronics on Fluffbot&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An Xbee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16860</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16860"/>
		<updated>2010-03-16T03:59:09Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee Interface Board]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|300px|Electronics Block Diagram|right]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Electronics on Fluffbot&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An Xbee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16859</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16859"/>
		<updated>2010-03-16T03:57:25Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Controls angle of the steering wheel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee Interface Board]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|right|Electronics Block Diagram]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Electronics on Fluffbot&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An Xbee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====3) Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16858</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16858"/>
		<updated>2010-03-16T03:56:53Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee Interface Board]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|right|Electronics Block Diagram]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Electronics on Fluffbot&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An Xbee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
*Seal on land (medium amplitude, high frequency)&lt;br /&gt;
*Seal in water (low amplitude, medium frequency)&lt;br /&gt;
*Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
*Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
*Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
*Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
*Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
*Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
*Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
*Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change direction parameters:&lt;br /&gt;
*From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
*In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
*The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16857</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16857"/>
		<updated>2010-03-16T03:54:12Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee Interface Board]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
*Protoboard/breadboard&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:Fluffbot_Electronics_Block_Diagram.jpg |thumb|right|Electronics Block Diagram]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Electronics on Fluffbot&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A 24V DC motor is used to control the momentum wheel. A RCservo motor is used to control the steering angle. An Xbee Board is used to communicate between the Fluffbot and a PC.&lt;br /&gt;
&lt;br /&gt;
The electronics block diagram (right picture) shows how each circuitry block connects to each other. The following links illustrate how each individual circuitry block is built:&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM78L05.html#Overview LM7805 5V regulator circuitry].&lt;br /&gt;
*[http://www.national.com/mpf/LM/LM338.html#Overview LM338T adjustable voltage regulator circuitry] for 18V and 3.3V.&lt;br /&gt;
*[http://www.datasheetcatalog.org/datasheet/SGSThomsonMicroelectronics/mXxwur.pdf L298N H-bridge circuitry].&lt;br /&gt;
*[http://hades.mech.northwestern.edu/images/f/fd/Motor_Encoder_circuit.pdf LS7083 decoder circuitry]. Note that our circuitry for the H-bridge is not the same as the one at this link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
----&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
----&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
----&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Fluffbot_Electronics_Block_Diagram.jpg&amp;diff=16856</id>
		<title>File:Fluffbot Electronics Block Diagram.jpg</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Fluffbot_Electronics_Block_Diagram.jpg&amp;diff=16856"/>
		<updated>2010-03-16T03:44:21Z</updated>

		<summary type="html">&lt;p&gt;RenYu: Electronics block diagram for Fluffbot, ME333 Winter 2010 project.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Electronics block diagram for Fluffbot, ME333 Winter 2010 project.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16855</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16855"/>
		<updated>2010-03-16T03:40:35Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Parts List (Digikey Part Number) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*[[XBee Interface Board|Xbee communication Boad]] (2)&lt;br /&gt;
*LM7805C 5V regulator (2)&lt;br /&gt;
*0.33uF capacitor&lt;br /&gt;
*0.01uF capacitor&lt;br /&gt;
*LM338T Adjustable voltage regulator (2)&lt;br /&gt;
*5k potentiometer (2)&lt;br /&gt;
*120 ohm resistor (2)&lt;br /&gt;
*0.1uF capacitor (6)&lt;br /&gt;
*1uF capacitor (2)&lt;br /&gt;
*L298N H-bridge&lt;br /&gt;
*14N002 diodes (4)&lt;br /&gt;
*LS7083 Decoder&lt;br /&gt;
*100k ohm resistor&lt;br /&gt;
*Pittman GM8712G708-R3 24V motor&lt;br /&gt;
*Futaba S3004 RCservo motor&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
----&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
----&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
----&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16845</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16845"/>
		<updated>2010-03-15T08:55:55Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them: [[Media:Fluff_bot_PIC_Code.zip|PIC code]], [[Media:Fluffbot_Processing.zip‎|Processing code]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
----&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
----&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
----&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Fluffbot_Processing.zip&amp;diff=16844</id>
		<title>File:Fluffbot Processing.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Fluffbot_Processing.zip&amp;diff=16844"/>
		<updated>2010-03-15T08:54:48Z</updated>

		<summary type="html">&lt;p&gt;RenYu: Processing code for Fluffbot, an ME333 Winter 2010 Final Project.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Processing code for Fluffbot, an ME333 Winter 2010 Final Project.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16843</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16843"/>
		<updated>2010-03-15T08:50:14Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
There is a PIC32 code, compiled using MPLAB, as well as a Processing code. Download them [[Media:Fluff_bot_PIC_Code.zip|here]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
----&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
----&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
----&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=File:Fluff_bot_PIC_Code.zip&amp;diff=16842</id>
		<title>File:Fluff bot PIC Code.zip</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=File:Fluff_bot_PIC_Code.zip&amp;diff=16842"/>
		<updated>2010-03-15T08:50:03Z</updated>

		<summary type="html">&lt;p&gt;RenYu: PIC C Code for Fluffbot, an ME333 Winter 2010 Final Project.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;PIC C Code for Fluffbot, an ME333 Winter 2010 Final Project.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16841</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16841"/>
		<updated>2010-03-15T08:40:31Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
----&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
----&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
----&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16840</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16840"/>
		<updated>2010-03-15T08:39:32Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* 1) Sets motion parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16839</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16839"/>
		<updated>2010-03-15T08:36:59Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* 1) Sets motion parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;\t&amp;gt;i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/t&amp;gt;ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16838</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16838"/>
		<updated>2010-03-15T08:36:07Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* 1) Sets motion parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly.&lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16837</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16837"/>
		<updated>2010-03-15T08:33:39Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====1) Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
ii. Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
iii. Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly. &lt;br /&gt;
&lt;br /&gt;
====2) Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
ii. Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
iii. Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
iv. Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
The angle of the steering wheel determines whether the Fluffbot is going forward or reverse, and turning left or right.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
i. Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
ii. Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
iii. Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change direction parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
i. From a computer, using a Processing GUI, the user chooses between forward, reverse, left, or right. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
ii. In the PIC code: the UART 2 interrupt handler receives the instructions, and changes the phase and middle_servo.&lt;br /&gt;
&lt;br /&gt;
iii. The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s direction accordingly.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16836</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16836"/>
		<updated>2010-03-15T08:28:04Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code does three things:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are three motion styles to choose from:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
2) Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
3) Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;There are four motion directions to choose from:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
1) Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
2) Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
3) Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps to change motion parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude, frequency, phase, and/or middle_servo.&lt;br /&gt;
&lt;br /&gt;
3) The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly. &lt;br /&gt;
&lt;br /&gt;
====Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code controls acceleration with four steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
2) Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
3) Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
4) Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16835</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16835"/>
		<updated>2010-03-15T08:21:21Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motion styles to choose from:&lt;br /&gt;
&lt;br /&gt;
1) Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
2) Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
3) Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
There are four motion directions to choose from: &lt;br /&gt;
&lt;br /&gt;
1) Forward. Momentum wheel acceleration and steering wheel angle out of phase by 180 degrees. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by pi/2.&lt;br /&gt;
&lt;br /&gt;
2) Reverse. Momentum wheel acceleration and steering wheel angle in phase phase. Equivalently (and as in the code), the steering wheel angle leads the momentum wheel speed by 3*pi/2.&lt;br /&gt;
&lt;br /&gt;
3) Left, and 4) right. The variable middle_servo changes, so that the steering wheel angle changes about an angle leftwards or rightwards.&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
&lt;br /&gt;
1) From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude, frequency, phase, and/or middle_servo.&lt;br /&gt;
&lt;br /&gt;
3) The function setAnimalParameters() takes this new information, and changes Fluffbot&#039;s motion accordingly. &lt;br /&gt;
&lt;br /&gt;
====Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
1) Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
2) Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
3) Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
4) Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16834</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16834"/>
		<updated>2010-03-15T08:08:15Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motions to choose from:&lt;br /&gt;
&lt;br /&gt;
1) Seal on land (medium amplitude, high frequency)&lt;br /&gt;
&lt;br /&gt;
2) Seal in water (low amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
3) Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
&lt;br /&gt;
1) From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
&lt;br /&gt;
2) In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency accordingly.&lt;br /&gt;
&lt;br /&gt;
3) The function setAnimalParameters() takes this new amplitude and frequency information, and changes Fluffbot&#039;s motion.&lt;br /&gt;
&lt;br /&gt;
====Controls acceleration and direction of the momentum wheel====&lt;br /&gt;
The momentum wheel accelerates in a sinusoidal motion. The PIC controls uses PD control to control the acceleration. (You&#039;ll see in the code that we use speed control, but controlling speed will effectively control acceleration.)&lt;br /&gt;
&lt;br /&gt;
The code controls acceleration with four steps:&lt;br /&gt;
&lt;br /&gt;
1) Sets a target speed &amp;quot;set_speed&amp;quot;, based on a sinusoid generated in the setAnimalParameters() function.&lt;br /&gt;
&lt;br /&gt;
2) Gets actual speed data from encoders on the momentum wheel motor, with the getActualSpeed() function.&lt;br /&gt;
&lt;br /&gt;
3) Calculates the error between set speed and actual speed, with the calculateError() function.&lt;br /&gt;
&lt;br /&gt;
4) Sets PWM to help decrease the error, with the setPWM() function.&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16833</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16833"/>
		<updated>2010-03-15T07:54:42Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
&lt;br /&gt;
2) Controls (speed and thus) acceleration and direction of the momentum wheel.&lt;br /&gt;
&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motions to choose from:&lt;br /&gt;
1) Seal on land (medium amplitude, high frequency)&lt;br /&gt;
2) Seal in water (low amplitude, medium frequency)&lt;br /&gt;
3) Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
1) From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
2) In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency accordingly.&lt;br /&gt;
3) The function setAnimalParameters() takes this new amplitude and frequency information, and changes Fluffbot&#039;s motion.&lt;br /&gt;
&lt;br /&gt;
====Controls (speed and thus) acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16832</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16832"/>
		<updated>2010-03-15T07:53:45Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* PIC Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
&lt;br /&gt;
The code does three things:&lt;br /&gt;
1) Sets motion parameters. &lt;br /&gt;
2) Controls (speed and thus) acceleration and direction of the momentum wheel.&lt;br /&gt;
3) Controls angle of the steering wheel.&lt;br /&gt;
&lt;br /&gt;
====Sets motion parameters====&lt;br /&gt;
Depending on the &amp;quot;type&amp;quot; of seal chosen, Fluffbot exhibits different styles of motion. The styles of motion are changed by changing the maximum angle of the steering wheel (amplitude) and by changing the rate at which the momentum wheel and steering wheel change direction (frequency).&lt;br /&gt;
&lt;br /&gt;
There are three motions to choose from:&lt;br /&gt;
1) Seal on land (medium amplitude, high frequency)&lt;br /&gt;
2) Seal in water (low amplitude, medium frequency)&lt;br /&gt;
3) Seal on ice (high amplitude, medium frequency)&lt;br /&gt;
&lt;br /&gt;
Steps to change motion parameters:&lt;br /&gt;
1) From a computer, using a Processing GUI, the user chooses between seal on land, in water, and on ice. The users choices are transmitted wirelessly to the Fluffbot.&lt;br /&gt;
2) In the PIC code: the UART 2 interrupt handler receives the instructions, and changes amplitude and frequency accordingly.&lt;br /&gt;
3) The function setAnimalParameters() takes this new amplitude and frequency information, and changes Fluffbot&#039;s motion.&lt;br /&gt;
&lt;br /&gt;
====Controls (speed and thus) acceleration and direction of the momentum wheel====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Controls angle of the steering wheel====&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16831</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16831"/>
		<updated>2010-03-15T07:22:40Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics in The Head Segment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
There are two PIC files used in this robotic snake, SnakeServos.c and main.h, which are shown below. main.h sets up  the default parameters used in SnakeServos.c. The microcontroller controls the RC servos and receives data from a computer via serial communication.&lt;br /&gt;
&lt;br /&gt;
The main purpose of SnakeServos.c is to calculate the motion profile of the servos, and send a corresponding signal to each of the servos every 20 ms.  The code for this is found in the &amp;lt;tt&amp;gt;ISR_20MS&amp;lt;/tt&amp;gt; function in the code which is run every 20ms.&lt;br /&gt;
&lt;br /&gt;
A secondary function is to update the parameters that affect the motion of the snake.  The code for this can be found in the &amp;lt;tt&amp;gt;ISR_USART_RX&amp;lt;/tt&amp;gt; function, which is run every time a byte is received on the USART&#039;s receive buffer.&lt;br /&gt;
&lt;br /&gt;
====Servo Control Details====&lt;br /&gt;
The main function of the PIC microcontroller is to control multiple RC servos (seven in our case). See [[RC Servo Theory]] for a discussion of the control signal for an RC servo. The RC servo expects a pulse every 20ms, so a timer called Timer1 is set up to overflow every 20 ms and trigger an interrupt. When the interrupt is triggered, the counter for Timer1 is set to the value held by the constant &amp;lt;tt&amp;gt;TMR1_20MS&amp;lt;/tt&amp;gt; (defined as &amp;lt;tt&amp;gt;15536&amp;lt;/tt&amp;gt;), which will cause Timer1 to overflow 20 ms later and re-trigger the interrupt. &lt;br /&gt;
&lt;br /&gt;
As shown in the RC Servo Theory, the width of the high pulse determines the angle of the servo. As a result, the pulse width corresponding to the desired angle for each servo motor is calculated and the corresponding timer value is stored in an array called &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt;. At the beginning of the interrupt, all the pins connected to the servos are set high. For the RC servos used in this project, the maximum pulse width can be 2.25 ms; therefore, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; only needs to be polled for 2.25 ms. &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt; is a constant corresponding to the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; 2.25 ms after the interrupt begins and is defined as &amp;lt;tt&amp;gt;15536 + 6250&amp;lt;/tt&amp;gt;. While &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is less than this variable, the counter is compared sequentially to the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array plus 15536 (15536 must be added because the Timer1 started counting at 15536 instead of 0).  Since the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array corresponds to the pulse widths of the servos, when the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is greater than a value in &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; plus 15536, the corresponding pin is set low. After the sequence is complete, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is polled again and the process repeats until 2.25 ms have elapsed, which corresponds to when Timer1 is greater than &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt;. After all the servo signals have been sent, the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array are updated to prepare for the next 20ms interrupt. &lt;br /&gt;
&lt;br /&gt;
Although polling the timer to control the length of a pulse has a lower resolution than using an interrupt (see [http://peshkin.mech.northwestern.edu/pic/code/RCservoSoft/RCservoSoft.c RCservoSoft.c]), it allows one to add and remove servos more easily and not have to decrease the frequency of the servo signal pulse train. With a 40MHz clock and seven servos, the resolution for the pulse was about 8us, which was sufficient for this project.&lt;br /&gt;
&lt;br /&gt;
====Serial Communication Details====&lt;br /&gt;
The PIC communicates serially with a XBee radio to a PC with a XBee radio. As shown in the code, the serial communication allows the user to change the speed, the amplitude and period of the sine wave, and the direction (forward, reverse, left and right) of the robotic snake. When a byte is received in the UART receive buffer, a high-priority interrupt is triggered.  The received byte is put into a switch-case statement, and the corresponding parameters are updated.&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16830</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16830"/>
		<updated>2010-03-15T07:21:17Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Electronics in Each Body Segment */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics Description====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics in The Head Segment====&lt;br /&gt;
[[image:PICBoard_schematic_HLS.jpg|thumb|right|The Mainboard Schematic]]&lt;br /&gt;
[[image:PICBoard_HLS.jpg|thumb|right|The Electronics in the Head]]&lt;br /&gt;
&lt;br /&gt;
The PIC18F4520 Prototyping Board designed by Professor Peshkin was used.  Schematics of the board can be found here: [[Main_Page#PIC_18F4520_prototyping_board|18F4520_prototyping_board]].  The only change applied to the board was to replace the 20MHz clock with a 40MHz clock. This allowed the microcontroller to perform calculations faster, improving the resolution of the servo signal.  The ribbon cable was connected to the ground and port D pins on the PIC.&lt;br /&gt;
&lt;br /&gt;
An [[XBee_radio_communication_between_PICs|XBee radio]] was used to communicate between the microcontroller and the PC. The wiring diagram shows a schematic for the Xbee connection with the PIC. The [[XBee_radio_communication_between_PICs#XBee_Interface_Module|XBee Interface Board]] was used to provide a robust mechanical mount for the radio, as well as supply the 3.3V needed by the XBee.  On the PC side, another XBee interface board was plugged into the FTDI USB-Serial converter. Other than this, no special electronics were needed for the XBee radio.  The radio simply acted as a serial cable replacement  The snake was controlled by sending commands with a terminal program. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
There are two PIC files used in this robotic snake, SnakeServos.c and main.h, which are shown below. main.h sets up  the default parameters used in SnakeServos.c. The microcontroller controls the RC servos and receives data from a computer via serial communication.&lt;br /&gt;
&lt;br /&gt;
The main purpose of SnakeServos.c is to calculate the motion profile of the servos, and send a corresponding signal to each of the servos every 20 ms.  The code for this is found in the &amp;lt;tt&amp;gt;ISR_20MS&amp;lt;/tt&amp;gt; function in the code which is run every 20ms.&lt;br /&gt;
&lt;br /&gt;
A secondary function is to update the parameters that affect the motion of the snake.  The code for this can be found in the &amp;lt;tt&amp;gt;ISR_USART_RX&amp;lt;/tt&amp;gt; function, which is run every time a byte is received on the USART&#039;s receive buffer.&lt;br /&gt;
&lt;br /&gt;
====Servo Control Details====&lt;br /&gt;
The main function of the PIC microcontroller is to control multiple RC servos (seven in our case). See [[RC Servo Theory]] for a discussion of the control signal for an RC servo. The RC servo expects a pulse every 20ms, so a timer called Timer1 is set up to overflow every 20 ms and trigger an interrupt. When the interrupt is triggered, the counter for Timer1 is set to the value held by the constant &amp;lt;tt&amp;gt;TMR1_20MS&amp;lt;/tt&amp;gt; (defined as &amp;lt;tt&amp;gt;15536&amp;lt;/tt&amp;gt;), which will cause Timer1 to overflow 20 ms later and re-trigger the interrupt. &lt;br /&gt;
&lt;br /&gt;
As shown in the RC Servo Theory, the width of the high pulse determines the angle of the servo. As a result, the pulse width corresponding to the desired angle for each servo motor is calculated and the corresponding timer value is stored in an array called &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt;. At the beginning of the interrupt, all the pins connected to the servos are set high. For the RC servos used in this project, the maximum pulse width can be 2.25 ms; therefore, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; only needs to be polled for 2.25 ms. &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt; is a constant corresponding to the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; 2.25 ms after the interrupt begins and is defined as &amp;lt;tt&amp;gt;15536 + 6250&amp;lt;/tt&amp;gt;. While &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is less than this variable, the counter is compared sequentially to the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array plus 15536 (15536 must be added because the Timer1 started counting at 15536 instead of 0).  Since the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array corresponds to the pulse widths of the servos, when the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is greater than a value in &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; plus 15536, the corresponding pin is set low. After the sequence is complete, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is polled again and the process repeats until 2.25 ms have elapsed, which corresponds to when Timer1 is greater than &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt;. After all the servo signals have been sent, the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array are updated to prepare for the next 20ms interrupt. &lt;br /&gt;
&lt;br /&gt;
Although polling the timer to control the length of a pulse has a lower resolution than using an interrupt (see [http://peshkin.mech.northwestern.edu/pic/code/RCservoSoft/RCservoSoft.c RCservoSoft.c]), it allows one to add and remove servos more easily and not have to decrease the frequency of the servo signal pulse train. With a 40MHz clock and seven servos, the resolution for the pulse was about 8us, which was sufficient for this project.&lt;br /&gt;
&lt;br /&gt;
====Serial Communication Details====&lt;br /&gt;
The PIC communicates serially with a XBee radio to a PC with a XBee radio. As shown in the code, the serial communication allows the user to change the speed, the amplitude and period of the sine wave, and the direction (forward, reverse, left and right) of the robotic snake. When a byte is received in the UART receive buffer, a high-priority interrupt is triggered.  The received byte is put into a switch-case statement, and the corresponding parameters are updated.&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16829</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16829"/>
		<updated>2010-03-15T07:19:41Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Parts List (Digikey Part Number) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Introduction to the PIC32|PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC&lt;br /&gt;
&lt;br /&gt;
====Electronics in Each Body Segment====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics in The Head Segment====&lt;br /&gt;
[[image:PICBoard_schematic_HLS.jpg|thumb|right|The Mainboard Schematic]]&lt;br /&gt;
[[image:PICBoard_HLS.jpg|thumb|right|The Electronics in the Head]]&lt;br /&gt;
&lt;br /&gt;
The PIC18F4520 Prototyping Board designed by Professor Peshkin was used.  Schematics of the board can be found here: [[Main_Page#PIC_18F4520_prototyping_board|18F4520_prototyping_board]].  The only change applied to the board was to replace the 20MHz clock with a 40MHz clock. This allowed the microcontroller to perform calculations faster, improving the resolution of the servo signal.  The ribbon cable was connected to the ground and port D pins on the PIC.&lt;br /&gt;
&lt;br /&gt;
An [[XBee_radio_communication_between_PICs|XBee radio]] was used to communicate between the microcontroller and the PC. The wiring diagram shows a schematic for the Xbee connection with the PIC. The [[XBee_radio_communication_between_PICs#XBee_Interface_Module|XBee Interface Board]] was used to provide a robust mechanical mount for the radio, as well as supply the 3.3V needed by the XBee.  On the PC side, another XBee interface board was plugged into the FTDI USB-Serial converter. Other than this, no special electronics were needed for the XBee radio.  The radio simply acted as a serial cable replacement  The snake was controlled by sending commands with a terminal program. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
There are two PIC files used in this robotic snake, SnakeServos.c and main.h, which are shown below. main.h sets up  the default parameters used in SnakeServos.c. The microcontroller controls the RC servos and receives data from a computer via serial communication.&lt;br /&gt;
&lt;br /&gt;
The main purpose of SnakeServos.c is to calculate the motion profile of the servos, and send a corresponding signal to each of the servos every 20 ms.  The code for this is found in the &amp;lt;tt&amp;gt;ISR_20MS&amp;lt;/tt&amp;gt; function in the code which is run every 20ms.&lt;br /&gt;
&lt;br /&gt;
A secondary function is to update the parameters that affect the motion of the snake.  The code for this can be found in the &amp;lt;tt&amp;gt;ISR_USART_RX&amp;lt;/tt&amp;gt; function, which is run every time a byte is received on the USART&#039;s receive buffer.&lt;br /&gt;
&lt;br /&gt;
====Servo Control Details====&lt;br /&gt;
The main function of the PIC microcontroller is to control multiple RC servos (seven in our case). See [[RC Servo Theory]] for a discussion of the control signal for an RC servo. The RC servo expects a pulse every 20ms, so a timer called Timer1 is set up to overflow every 20 ms and trigger an interrupt. When the interrupt is triggered, the counter for Timer1 is set to the value held by the constant &amp;lt;tt&amp;gt;TMR1_20MS&amp;lt;/tt&amp;gt; (defined as &amp;lt;tt&amp;gt;15536&amp;lt;/tt&amp;gt;), which will cause Timer1 to overflow 20 ms later and re-trigger the interrupt. &lt;br /&gt;
&lt;br /&gt;
As shown in the RC Servo Theory, the width of the high pulse determines the angle of the servo. As a result, the pulse width corresponding to the desired angle for each servo motor is calculated and the corresponding timer value is stored in an array called &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt;. At the beginning of the interrupt, all the pins connected to the servos are set high. For the RC servos used in this project, the maximum pulse width can be 2.25 ms; therefore, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; only needs to be polled for 2.25 ms. &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt; is a constant corresponding to the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; 2.25 ms after the interrupt begins and is defined as &amp;lt;tt&amp;gt;15536 + 6250&amp;lt;/tt&amp;gt;. While &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is less than this variable, the counter is compared sequentially to the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array plus 15536 (15536 must be added because the Timer1 started counting at 15536 instead of 0).  Since the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array corresponds to the pulse widths of the servos, when the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is greater than a value in &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; plus 15536, the corresponding pin is set low. After the sequence is complete, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is polled again and the process repeats until 2.25 ms have elapsed, which corresponds to when Timer1 is greater than &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt;. After all the servo signals have been sent, the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array are updated to prepare for the next 20ms interrupt. &lt;br /&gt;
&lt;br /&gt;
Although polling the timer to control the length of a pulse has a lower resolution than using an interrupt (see [http://peshkin.mech.northwestern.edu/pic/code/RCservoSoft/RCservoSoft.c RCservoSoft.c]), it allows one to add and remove servos more easily and not have to decrease the frequency of the servo signal pulse train. With a 40MHz clock and seven servos, the resolution for the pulse was about 8us, which was sufficient for this project.&lt;br /&gt;
&lt;br /&gt;
====Serial Communication Details====&lt;br /&gt;
The PIC communicates serially with a XBee radio to a PC with a XBee radio. As shown in the code, the serial communication allows the user to change the speed, the amplitude and period of the sine wave, and the direction (forward, reverse, left and right) of the robotic snake. When a byte is received in the UART receive buffer, a high-priority interrupt is triggered.  The received byte is put into a switch-case statement, and the corresponding parameters are updated.&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16828</id>
		<title>Conservation of Angular Momentum Locomotion Robot (Fluffbot)</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=Conservation_of_Angular_Momentum_Locomotion_Robot_(Fluffbot)&amp;diff=16828"/>
		<updated>2010-03-15T07:16:54Z</updated>

		<summary type="html">&lt;p&gt;RenYu: New page: right  == Overview ==  Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the an...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[image:Snake_Robot_1.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Flufbot uses conservation of angular momentum to move forward or backward, by controlling the acceleration of a momentum wheel and the angle of a steering wheel. &lt;br /&gt;
&lt;br /&gt;
==Team Members==&lt;br /&gt;
&lt;br /&gt;
//insert team picture[[image:Team23_Members.jpg|thumb|400pix|right|Hwang-Long-Smart]]&lt;br /&gt;
&lt;br /&gt;
*Tyler Johnson - Mechanical Engineer - Class 2011&lt;br /&gt;
*Noah Pentelovitch - Mechanical Engineer - Class 2010&lt;br /&gt;
*Ren Chung (RC) Yu - Electrical Engineer - Class 2010&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Concept Overview ==&lt;br /&gt;
&lt;br /&gt;
[[image:Serpentine_curves.jpg|thumb|300pix|right|Serpentine Curves]]&lt;br /&gt;
&lt;br /&gt;
Real snake motion does not follow specified equations. However, research has proven that the serpentine motion of a snake can be modeled with the following equations (Saito etal, 72-73):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x(s)= \int_{0}^{s} \cos (\zeta_\sigma) d\sigma&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;y(s)= \int_{0}^{s} \sin (\zeta_\sigma) d\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\zeta_\sigma= a \cos (b\sigma) +c\sigma &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where the parameters &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; determine the shape of the serpentine motion. The graph shows how the parameters influence the serpentine curve. Basically, &#039;&#039;a&#039;&#039; changes the appearance of the curve, &#039;&#039;b&#039;&#039; changes the number of phases, and &#039;&#039;c&#039;&#039; changes the direction.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The serpentine curve can be modeled with a snake like robot by changing the relative angles between the snake robot segments using the following formula with the number of segments (n):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\phi_i = \alpha sin(\omega t +(i-1)\beta ) + \gamma, \left ( i=1, ..., n-1 \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;amp;alpha; , &amp;amp;beta; , and &amp;amp;gamma; are parameters used to characterize the serpentine curve and are dependent on &#039;&#039;a&#039;&#039;, &#039;&#039;b&#039;&#039;, and &#039;&#039;c&#039;&#039; as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha = a \left | \sin \left ( \frac{\beta}{2} \right ) \right | &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta = \frac{b}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\gamma = -\frac{c}{n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The equations above for &amp;amp;phi;&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,&amp;amp;alpha;,&amp;amp;beta;, and &amp;amp;gamma; were used in this snake like robot as shown in the [[Robot Snake#PIC Code|code section]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Mechanical Design ==&lt;br /&gt;
[[image:FullSnake.jpg|thumb|right|The Snake]]&lt;br /&gt;
The robotic snake consists of a head segment and several body segments. The head segment houses the onboard microcontroller and xBee radio. The body segments house the servo motors and the batteries required to power each motor.  As the snake is designed to be modular, there is no limit to the number of body segments.  More segments will allow it to move more smoothly, while fewer segments will be easier to control.   For this design, seven body segments were used due to material limitations.&lt;br /&gt;
&lt;br /&gt;
Mechanically, the snake is designed to move in a serpentine motion, imitating the motion of a real snake.  As discussed above, real snakes move with anisotropic coefficients of friction. It is difficult to locate materials with this property, but passive wheels satisfy the friction requirements. The friction will be lower in the direction of rolling, thus providing the required difference in friction. The only problem with this approach is that the wheel may slide in the normal direction if the weight applied to the wheel is not sufficient. &lt;br /&gt;
&lt;br /&gt;
===Parts List===&lt;br /&gt;
&lt;br /&gt;
*Motors: Futaba S3004 standard ball bearing RC servo motor, Tower Hobbies LXZV41 $12.99&lt;br /&gt;
*Wheels: McMasterCarr Acetal Pulley for Fibrous Rope for 1/4&amp;quot; Rope Diameter, 3/4&amp;quot; OD McMasterCarr 8901T11 $1.66&lt;br /&gt;
*O-Rings (Tires): McMasterCarr Silicone O-Ring AS568A Dash Number 207, Packs of 50 McMasterCarr 9396K209 $7.60/50&lt;br /&gt;
*PVC Pipe: McMasterCarr Sewer &amp;amp; Drain Thin-Wall PVC Pipe Non-Perforated, 3&amp;quot; X 4-1/2&#039; L, Light Green McMasterCarr 2426K24 $7.06&lt;br /&gt;
*1/8th inch plastic for chassis: (Shop Stock) or McMasterCarr Polycarbonate Sheet 1/8&amp;quot; Thick, 12&amp;quot; X 12&amp;quot;, Clear, McMasterCarr, 8574K26 $6.32&lt;br /&gt;
*Dowel Pins: 1&amp;quot; long, 1/4&amp;quot; diameter &lt;br /&gt;
*Sheet Metal:  For the connecting segments&lt;br /&gt;
*Fasteners: Screws for the servos and chassis, washers for the standoffs&lt;br /&gt;
*Standoffs: Used 1&amp;quot; and 1/2&amp;quot; to achieve a level snake&lt;br /&gt;
*Velcro: To attach battery packs and housing to the chasis&lt;br /&gt;
*Ball caster: For the head&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Body Segments ===&lt;br /&gt;
[[image:Chasis.jpg|thumb|right|A Single Chasis Without a Servo]]&lt;br /&gt;
&lt;br /&gt;
Each of the body segments are identical and includes a chassis, a servo, a connector, standoffs and two passive wheels as can be seen in the picture. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=wBcJkNHEaAs Video of 3 body segments moving]&lt;br /&gt;
&lt;br /&gt;
==== Chassis ====&lt;br /&gt;
&lt;br /&gt;
The base of the chassis is made from a thin (approx. 1/8th inch) piece of polycarbonate. The chassis must be wide enough to hold a servo motor with a AAA battery pack on each side and long enough for the servo and a standoff (the connection for the previous segment). The polycarbonate was cut into a rectangle to meet the specifications for our servo motor.  Five holes were then drilled in the rectangle, four to mount the servo and one for the standoff.  The holes are drilled to allow the servo to be located in the center of the chassis. &lt;br /&gt;
&lt;br /&gt;
==== Connector ====&lt;br /&gt;
&lt;br /&gt;
A connector was machined to attach to the servo horn of one body segment and to attach to the next segment&#039;s standoff. The length of this connector is about 3 inches and is just long enough to prevent collision between segments.  A shorter beam allows for greater torque.  This connection needs to be as tight as possible and the beam must be mounted perpendicular to the chassis.   &lt;br /&gt;
&lt;br /&gt;
[[image:ChasisUnderside.jpg|thumb|right|The Underside of a Chassis]]&lt;br /&gt;
&lt;br /&gt;
====Standoffs ====&lt;br /&gt;
&lt;br /&gt;
Standoffs were used to attach the servo to the chassis and to attach the connector to the chassis. Two standoffs (1 in and 1/2 in) and several washers were used to make the connector parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
==== Passive Wheels ====&lt;br /&gt;
[[image:Wheel.jpg|thumb|left|A Passive Wheel on the Dowel Pin]]&lt;br /&gt;
Passive wheels were mounted to the bottom of the chassis. Each wheel was made of a 3/4 inch pulley and an o-ring. The o-ring was used to increase friction with the ground.  The wheels have been set on polished metal dowel pins which allow the wheels to rotate more freely than when placed on wooden dowels.  The dowel pin axles were mounted (hot glue works but is not very strong) in the center of the segment. The center of the segment is not the center of the polycarbonate rectangle. Instead, the entire segment length is the distance from the standoff on one chassis to the center of the servo horn on the other. In this project, the length of the connector was made to be about half the length of the segment. Therefore, the wheels were placed at the same location as the stand off as can be seen in the image. The wheels are held in place with zip ties. &lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fully Assembled Body Segment ====&lt;br /&gt;
[[image:BuiltChasis.jpg|thumb|right|A Chassis Built Showing a Standoff and Batteries]]&lt;br /&gt;
[[image:BuiltChasis2_MLS.jpg|thumb|right|Chassis with Batteries Removed]]&lt;br /&gt;
A fully assembled chassis has a mounted servo and is connected to a segment on either side.  AAA batteries packs were attached to the sides of the motor with velcro to allow easy removal. The small electronic circuit board for each segment was mounted on the front of the motor to allow easy access to the switch.  (See Electronic Design for more information on the circuit board and batteries)&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Head Segment ===&lt;br /&gt;
[[image:BallCaster.jpg|thumb|left|The Ball Caster Under the Front Segment]]&lt;br /&gt;
&lt;br /&gt;
The head segment is similar to the body segments except that it contains a PCB board with a PIC instead of a servo motor. The head segment is the same width but slightly longer than the body segment.  A ball caster was added to the front of the segment to help support the extra length and help the wheels stay on the ground.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Protection and Visual Appeal  ====&lt;br /&gt;
[[image:Housing.jpg|thumb|right|One Segment of the Housing]]&lt;br /&gt;
&lt;br /&gt;
As a final step, housing for each segment was created from 3&amp;quot; PVC pipe.  The pipe was cut into segments the same length as the chassis. The bottom of the pipe was cut off, allowing it to sit flat on the chassis. The housing provides a protective covering for the servo, batteries and electronics.  The pipe was attached with velcro straps which mounted under the chassis.  This housing can be easily removed to debug and to change batteries.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Debugging ===&lt;br /&gt;
&lt;br /&gt;
Wheels come off the ground:  Add washers to the standoffs to force the chassis to be parallel to the ground.&lt;br /&gt;
&lt;br /&gt;
Wheels slide, but do not roll:  Increase frictionby either adding weight to the segment or changing the &amp;quot;tires&amp;quot; (the o-ring).&lt;br /&gt;
&lt;br /&gt;
The segments slip when the servo rotates:  Tighten the screws for the connector standoffs, both above the beam and below the chassis.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Electronics ==&lt;br /&gt;
====Parts List (Digikey Part Number)====&lt;br /&gt;
&lt;br /&gt;
*[[Using the PIC32MX Series |PIC32 NU32 Board]]&lt;br /&gt;
*Oscillator: 40MHz Oscillator (X225-ND)&lt;br /&gt;
*RC Servo (see mechanical design) preferably high-torque &lt;br /&gt;
*10 wire IDC ribbon cable&lt;br /&gt;
*10 pos IDC cable socket (ASC10G): 1 per segment&lt;br /&gt;
*10 pos IDC cable header (A26267-ND): 1 per segment&lt;br /&gt;
*3 pos AAA battery holder (BH3AAA-W-ND): 1 per segment&lt;br /&gt;
*2 pos AAA battery holder (BH2AAA-W-ND): 1 per segment&lt;br /&gt;
*475 Ohm resistors (transmission line termination)&lt;br /&gt;
*Various switches to turn power electronics and the motors on/off&lt;br /&gt;
*Standard Protoboard, to mount connector from ribbon cable, and switches for each motor&lt;br /&gt;
*Xbee radio pair and PC &lt;br /&gt;
&lt;br /&gt;
====Electronics in Each Body Segment====&lt;br /&gt;
[[image:RibbonCable_schematic_HLS.jpg|thumb|right|Ribbon Cable Schematic]][[image:ServoBoard_schematic_HLS.jpg|thumb|right|ServoBoard Schematic]][[image:ServoBoard_Hooked_up_HLS.jpg|thumb|right|A Complete Circuit Board on the Snake]]&lt;br /&gt;
&lt;br /&gt;
The each segment of the snake contains a Futaba Standard RC Servo.  Each servo has 3 wires: power, ground, and signal.  The signal generated by the microcontroller is carried by the IDC ribbon cable, and each servo board taps into a single signal line and the reference ground line as shown in the ribbon cable schematic.  Each segment of the snake contains a small circuit board (ServoBoard Schematic) which has a connector for the ribbon cable, a switch to control the power, and a power indicator LED.  Because of the length of the ribbon cable, each signal line must be terminated with a 475 ohm resistor to prevent reflected &amp;quot;ghost&amp;quot; signals from interfering with the original signal.&lt;br /&gt;
&lt;br /&gt;
Each servo board also has its own power supply of 5 AAA cells, which gives each servo 7.5V.  Although the servos are only rated for 6V, 7.5V was used because more torque was needed.  The current drain (up to 500mA) caused the voltage across the cells to drop due to the high internal resistance of the alkaline cells.  NiMH rechargeable cells are more capable of handling high current draw applications, but are also much more expensive and can take several hours to charge.&lt;br /&gt;
&lt;br /&gt;
The robot snake can run for about 1 hour on the alkaline cells, after which the servos no longer have enough torque to generate the serpentine motion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Electronics in The Head Segment====&lt;br /&gt;
[[image:PICBoard_schematic_HLS.jpg|thumb|right|The Mainboard Schematic]]&lt;br /&gt;
[[image:PICBoard_HLS.jpg|thumb|right|The Electronics in the Head]]&lt;br /&gt;
&lt;br /&gt;
The PIC18F4520 Prototyping Board designed by Professor Peshkin was used.  Schematics of the board can be found here: [[Main_Page#PIC_18F4520_prototyping_board|18F4520_prototyping_board]].  The only change applied to the board was to replace the 20MHz clock with a 40MHz clock. This allowed the microcontroller to perform calculations faster, improving the resolution of the servo signal.  The ribbon cable was connected to the ground and port D pins on the PIC.&lt;br /&gt;
&lt;br /&gt;
An [[XBee_radio_communication_between_PICs|XBee radio]] was used to communicate between the microcontroller and the PC. The wiring diagram shows a schematic for the Xbee connection with the PIC. The [[XBee_radio_communication_between_PICs#XBee_Interface_Module|XBee Interface Board]] was used to provide a robust mechanical mount for the radio, as well as supply the 3.3V needed by the XBee.  On the PC side, another XBee interface board was plugged into the FTDI USB-Serial converter. Other than this, no special electronics were needed for the XBee radio.  The radio simply acted as a serial cable replacement  The snake was controlled by sending commands with a terminal program. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PIC Code ==&lt;br /&gt;
There are two PIC files used in this robotic snake, SnakeServos.c and main.h, which are shown below. main.h sets up  the default parameters used in SnakeServos.c. The microcontroller controls the RC servos and receives data from a computer via serial communication.&lt;br /&gt;
&lt;br /&gt;
The main purpose of SnakeServos.c is to calculate the motion profile of the servos, and send a corresponding signal to each of the servos every 20 ms.  The code for this is found in the &amp;lt;tt&amp;gt;ISR_20MS&amp;lt;/tt&amp;gt; function in the code which is run every 20ms.&lt;br /&gt;
&lt;br /&gt;
A secondary function is to update the parameters that affect the motion of the snake.  The code for this can be found in the &amp;lt;tt&amp;gt;ISR_USART_RX&amp;lt;/tt&amp;gt; function, which is run every time a byte is received on the USART&#039;s receive buffer.&lt;br /&gt;
&lt;br /&gt;
====Servo Control Details====&lt;br /&gt;
The main function of the PIC microcontroller is to control multiple RC servos (seven in our case). See [[RC Servo Theory]] for a discussion of the control signal for an RC servo. The RC servo expects a pulse every 20ms, so a timer called Timer1 is set up to overflow every 20 ms and trigger an interrupt. When the interrupt is triggered, the counter for Timer1 is set to the value held by the constant &amp;lt;tt&amp;gt;TMR1_20MS&amp;lt;/tt&amp;gt; (defined as &amp;lt;tt&amp;gt;15536&amp;lt;/tt&amp;gt;), which will cause Timer1 to overflow 20 ms later and re-trigger the interrupt. &lt;br /&gt;
&lt;br /&gt;
As shown in the RC Servo Theory, the width of the high pulse determines the angle of the servo. As a result, the pulse width corresponding to the desired angle for each servo motor is calculated and the corresponding timer value is stored in an array called &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt;. At the beginning of the interrupt, all the pins connected to the servos are set high. For the RC servos used in this project, the maximum pulse width can be 2.25 ms; therefore, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; only needs to be polled for 2.25 ms. &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt; is a constant corresponding to the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; 2.25 ms after the interrupt begins and is defined as &amp;lt;tt&amp;gt;15536 + 6250&amp;lt;/tt&amp;gt;. While &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is less than this variable, the counter is compared sequentially to the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array plus 15536 (15536 must be added because the Timer1 started counting at 15536 instead of 0).  Since the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array corresponds to the pulse widths of the servos, when the value of &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is greater than a value in &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; plus 15536, the corresponding pin is set low. After the sequence is complete, &amp;lt;tt&amp;gt;Timer1&amp;lt;/tt&amp;gt; is polled again and the process repeats until 2.25 ms have elapsed, which corresponds to when Timer1 is greater than &amp;lt;tt&amp;gt;TMR1_2point25MS&amp;lt;/tt&amp;gt;. After all the servo signals have been sent, the values in the &amp;lt;tt&amp;gt;RCservo&amp;lt;/tt&amp;gt; array are updated to prepare for the next 20ms interrupt. &lt;br /&gt;
&lt;br /&gt;
Although polling the timer to control the length of a pulse has a lower resolution than using an interrupt (see [http://peshkin.mech.northwestern.edu/pic/code/RCservoSoft/RCservoSoft.c RCservoSoft.c]), it allows one to add and remove servos more easily and not have to decrease the frequency of the servo signal pulse train. With a 40MHz clock and seven servos, the resolution for the pulse was about 8us, which was sufficient for this project.&lt;br /&gt;
&lt;br /&gt;
====Serial Communication Details====&lt;br /&gt;
The PIC communicates serially with a XBee radio to a PC with a XBee radio. As shown in the code, the serial communication allows the user to change the speed, the amplitude and period of the sine wave, and the direction (forward, reverse, left and right) of the robotic snake. When a byte is received in the UART receive buffer, a high-priority interrupt is triggered.  The received byte is put into a switch-case statement, and the corresponding parameters are updated.&lt;br /&gt;
&lt;br /&gt;
====SnakeServos.c====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
Andy Long, Clara Smart, and Michael Hwang&#039;s snake robot code.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;18f4520.h&amp;gt;&lt;br /&gt;
#device high_ints=TRUE        // this allows raised priority interrupts, which we need&lt;br /&gt;
#fuses HS,NOLVP,NOWDT,NOPROTECT&lt;br /&gt;
#use delay(clock=40000000)&lt;br /&gt;
#use rs232(baud=9600, UART1) &lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;main.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Put your desired high duration here; &lt;br /&gt;
3200 is center  &lt;br /&gt;
1000 is 90 deg right &lt;br /&gt;
5400 is 90 deg left&lt;br /&gt;
*/&lt;br /&gt;
int16 RCservo[7];  &lt;br /&gt;
&lt;br /&gt;
//use volatile keyword to avoid problems with optimizer&lt;br /&gt;
volatile float a = A_DEFAULT;&lt;br /&gt;
volatile float b = B_DEFAULT;&lt;br /&gt;
volatile float c = C_DEFAULT;&lt;br /&gt;
&lt;br /&gt;
volatile float alpha;&lt;br /&gt;
volatile float gamma;&lt;br /&gt;
volatile float beta;&lt;br /&gt;
volatile float speed = 0;&lt;br /&gt;
volatile float prev_speed = SPEED_DEFAULT;&lt;br /&gt;
float t = 0; &lt;br /&gt;
&lt;br /&gt;
#INT_TIMER1 // designates that this is the routine to call when timer1 overflows&lt;br /&gt;
//generates servo signals&lt;br /&gt;
void ISR_20MS(){&lt;br /&gt;
   volatile unsigned int16 time;&lt;br /&gt;
   set_timer1(TMR1_20MS);		//set timer to trigger an interrupt 20ms later&lt;br /&gt;
   SET_ALL_SERVOS(0b11111111);	//begin pulse for servo signal&lt;br /&gt;
   time=get_timer1();			//poll timer&lt;br /&gt;
   while(time &amp;lt; TMR1_2point25MS){	//end this loop after 2.25 ms&lt;br /&gt;
      if (time &amp;gt; (RCservo[0] + TMR1_20MS)){	&lt;br /&gt;
         output_low(SERVO_0);	//end the pulse when time is up&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[1] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_1);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[2] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_2);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[3] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_3);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[4] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_4);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[5] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_5);&lt;br /&gt;
      }&lt;br /&gt;
      if (time &amp;gt; (RCservo[6] + TMR1_20MS)){&lt;br /&gt;
         output_low(SERVO_6);&lt;br /&gt;
      }&lt;br /&gt;
      time=get_timer1();	//poll timer&lt;br /&gt;
   }&lt;br /&gt;
   SET_ALL_SERVOS(0);	//set all servos low in case some pins are still high&lt;br /&gt;
&lt;br /&gt;
    //3200 is center  //1000 is 90 deg right // 5400 is 90 deg left&lt;br /&gt;
   /*&lt;br /&gt;
   add value of sine wave with phase offset ((alpha*sin(t + X*beta), &lt;br /&gt;
   3200 for servo center position,&lt;br /&gt;
   an adjustment value to compensate for offsets when mounting servo horn (SERVO_X_ADJ),&lt;br /&gt;
   and bias (gamma) for turning.&lt;br /&gt;
   */&lt;br /&gt;
   RCservo[0]=(int16)(alpha*sin(t) + 3200 + SERVO_3_ADJ + gamma); &lt;br /&gt;
   RCservo[1]=(int16)(alpha*sin(t + 1*beta) + 3200 + SERVO_4_ADJ + gamma);&lt;br /&gt;
   RCservo[2]=(int16)(alpha*sin(t + 2*beta) + 3200 + gamma + SERVO_5_ADJ);&lt;br /&gt;
   RCservo[3]=(int16)(alpha*sin(t + 3*beta) + 3200 + gamma + SERVO_6_ADJ);&lt;br /&gt;
   RCservo[4]=(int16)(alpha*sin(t + 4*beta) + 3200 + gamma + SERVO_7_ADJ);&lt;br /&gt;
   RCservo[5]=(int16)(alpha*sin(t + 5*beta) + 3200 + gamma + SERVO_8_ADJ);&lt;br /&gt;
   RCservo[6]=(int16)(alpha*sin(t + 6*beta) + 3200 + gamma + SERVO_9_ADJ);&lt;br /&gt;
&lt;br /&gt;
   t+= speed;	//increment time, wrap around if necessary to prevent overflow&lt;br /&gt;
   if (t &amp;gt; 2*pi){&lt;br /&gt;
      t = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else if (t &amp;lt; 0){&lt;br /&gt;
      t = 2*pi;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#INT_RDA HIGH    //High-Priority Interrupt triggered by USART Rx&lt;br /&gt;
//parameter update&lt;br /&gt;
void ISR_USART_RX(){&lt;br /&gt;
   char input;&lt;br /&gt;
   if (kbhit()){&lt;br /&gt;
      input = getc();&lt;br /&gt;
      switch(input){&lt;br /&gt;
         case &#039;w&#039;: //accelerate&lt;br /&gt;
            speed += 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;s&#039;: //decelerate&lt;br /&gt;
            speed -= 0.002;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;x&#039;: //pause motion&lt;br /&gt;
            prev_speed = speed;&lt;br /&gt;
            speed = 0;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;z&#039;: //resume motion&lt;br /&gt;
            speed = prev_speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;c&#039;: //reverse speed&lt;br /&gt;
            speed = -speed;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;a&#039;: //increase left turn rate&lt;br /&gt;
            c -= 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;d&#039;: //increase right turn rate&lt;br /&gt;
            c += 1000;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;f&#039;: //set turn rate to 0&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma = 0;&lt;br /&gt;
         case &#039;t&#039;: //increase amplitude&lt;br /&gt;
            a += 10; &lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;g&#039;: //decrease amplitude&lt;br /&gt;
            a -= 10;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;y&#039;: //increase phases in body&lt;br /&gt;
            b += 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;h&#039;: //decrease phases in body&lt;br /&gt;
            b -= 0.1;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;1&#039;: //preset 1&lt;br /&gt;
            a = A_DEFAULT;&lt;br /&gt;
            b = B_default;&lt;br /&gt;
            c = C_default;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;  &lt;br /&gt;
         case &#039;2&#039;:  //preset 2&lt;br /&gt;
            a = 1400;&lt;br /&gt;
            b = 2*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;&lt;br /&gt;
         case &#039;3&#039;:  //preset 3&lt;br /&gt;
            a = 1000;&lt;br /&gt;
            b = 5*pi;&lt;br /&gt;
            c = C_DEFAULT;&lt;br /&gt;
            gamma=-c/num_segments;&lt;br /&gt;
            beta=b/num_segments;&lt;br /&gt;
            alpha=a*abs(sin(beta));&lt;br /&gt;
            speed=SPEED_DEFAULT;&lt;br /&gt;
            break;              &lt;br /&gt;
         default:&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
	//load default values&lt;br /&gt;
   a = A_DEFAULT;&lt;br /&gt;
   b = B_default;&lt;br /&gt;
   c = C_default;&lt;br /&gt;
   gamma=-c/num_segments;&lt;br /&gt;
   beta=b/num_segments;&lt;br /&gt;
   alpha=a*abs(sin(beta));&lt;br /&gt;
   speed=0;&lt;br /&gt;
   &lt;br /&gt;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 );       &lt;br /&gt;
   set_timer1(0);&lt;br /&gt;
   &lt;br /&gt;
   enable_interrupts(INT_TIMER1);	//enable Timer1 interrupt&lt;br /&gt;
   enable_interrupts(INT_RDA);		//enable USART receive interrupt&lt;br /&gt;
   enable_interrupts(GLOBAL);&lt;br /&gt;
      &lt;br /&gt;
   while (TRUE) {     &lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===main.h===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#ifndef __MAIN_H__&lt;br /&gt;
#define __MAIN_H__&lt;br /&gt;
&lt;br /&gt;
#define SET_ALL_SERVOS(x) output_d(x)&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This chart matches the pin on the PIC to the wire on the ribbon cable&lt;br /&gt;
PIN WIRE IN USE&lt;br /&gt;
--- ---- -------&lt;br /&gt;
RD0  2&lt;br /&gt;
RD1  3      *&lt;br /&gt;
RD2  4      *&lt;br /&gt;
RD3  5      *&lt;br /&gt;
RD4  6      *&lt;br /&gt;
RD5  7      *&lt;br /&gt;
RD6  8      *&lt;br /&gt;
RD7  9      *&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
#define SERVO_3_ADJ 0&lt;br /&gt;
#define SERVO_4_ADJ 300&lt;br /&gt;
#define SERVO_5_ADJ (-150)&lt;br /&gt;
#define SERVO_6_ADJ 75&lt;br /&gt;
#define SERVO_7_ADJ (-200)&lt;br /&gt;
#define SERVO_8_ADJ 100&lt;br /&gt;
#define SERVO_9_ADJ (-150)&lt;br /&gt;
&lt;br /&gt;
#define SERVO_0 PIN_D1&lt;br /&gt;
#define SERVO_1 PIN_D2&lt;br /&gt;
#define SERVO_2 PIN_D3&lt;br /&gt;
#define SERVO_3 PIN_D4&lt;br /&gt;
#define SERVO_4 PIN_D5&lt;br /&gt;
#define SERVO_5 PIN_D6&lt;br /&gt;
#define SERVO_6 PIN_D7&lt;br /&gt;
&lt;br /&gt;
#define A_DEFAULT 1300&lt;br /&gt;
#define B_DEFAULT 3*pi&lt;br /&gt;
#define C_DEFAULT 0&lt;br /&gt;
&lt;br /&gt;
#define SPEED_DEFAULT 0.05&lt;br /&gt;
#define OMEGA_DEFAULT 1&lt;br /&gt;
#define num_segments 8&lt;br /&gt;
&lt;br /&gt;
#define TMR1_20MS 15536&lt;br /&gt;
#define TMR1_2point25MS 15536 + 6250&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Overall, the robotic snake was successful. &lt;br /&gt;
&lt;br /&gt;
Initially, the mechanical design included a single wheel mounted in the center of the pvc pipe. However, the motion of the snake was very difficult to control because the robotic snake became unstable very easily. As a result, the chassis was built to include two wheels, as discussed in the mechanical design section, in order to provide stability which made the robot easier to control. &lt;br /&gt;
&lt;br /&gt;
Wireless control from a laptop allowed easy demonstration of the snakes capabilities, and allowed others to easily control its movement.&lt;br /&gt;
&lt;br /&gt;
The final robotic snake can be seen in action here. &lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=Sb8WqaLX1Vo Video of the robot snake without housing]&lt;br /&gt;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake with housing]&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
The robotic snake was developed within five weeks, and proved to be a very successful demo. There are many options that could be researched and developed to add to this robot and discussed below.&lt;br /&gt;
&lt;br /&gt;
==== Position Sensors ====&lt;br /&gt;
Sensors could be added to the robot to allow it to know its position. This could be accomplished with a combination of encoders on a segment. Most likely, the middle segment should be used since it would be the approximate center of gravity. Knowledge of the position of the center of gravity would potentially the robotic snake to be sent to different locations or navigate (using dead reckoning) through a pre-determined obstacle course or maze.  The information from encoders could be sent to a computer to observe different snakelike motions with different parameters.&lt;br /&gt;
&lt;br /&gt;
==== Obstacle Avoidance ====&lt;br /&gt;
With optical sensors on the head of the snake, the robot would be able to sense an obstacle and either overide the wireless command and avoid it, or stop completely, and wait for further commands.&lt;br /&gt;
&lt;br /&gt;
==== Power Supply ====&lt;br /&gt;
Currently, 5 AAA batteries are required for each servo, meaning that this robot requires many batteries. As a result, a different power supply could be investigated.&lt;br /&gt;
&lt;br /&gt;
====High Torque Servos====&lt;br /&gt;
The servos in the snake have a large load but do not need to move very quickly, so high torque servos could be used instead of standard servos.  This would also prolong the battery life because the servos would be operating in a more efficient range.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
Ma, Shugen. &amp;quot;Analysis of creeping locomotion of a snake-like robot.&amp;quot; &#039;&#039;Advanced Robotics&#039;&#039; Vol 15, No 2 (2001): 205-6.&lt;br /&gt;
&lt;br /&gt;
Saito, Fukaya, Iwasaki. &amp;quot;Serpentine Locomotion with Robotic Snakes&amp;quot;. &#039;&#039;IEEE Control Systems Magazine&#039;&#039; (Feb 2002): 66, 72-73.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=ME_333_final_projects&amp;diff=16827</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=16827"/>
		<updated>2010-03-15T07:00:07Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Conservation of Angular Momentum Locomotion Robot (Fluffbot) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the &#039;&#039;&#039;[[ME 333 end of course schedule]]&#039;&#039;&#039;.  &lt;br /&gt;
&lt;br /&gt;
Final projects for ME 333 in years 2000-2007 can be found&lt;br /&gt;
&#039;&#039;&#039;[http://lims.mech.northwestern.edu/~design/mechatronics/ here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ME 333 Final Projects 2010 ==&lt;br /&gt;
&lt;br /&gt;
=== [[Sample Project Title]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
You can copy and paste this wiki code to start your wiki page (but don&#039;t erase this code).  Then replace this text with your own.  A few sentences describing what your project does, with a link to a youtube video.  Look at other final project wiki pages for ideas, but see [[ME 333 end of course schedule]] for more information on what should be included on your wiki page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Conservation of Angular Momentum Locomotion Robot (Fluffbot)]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
Cute fluffy robot that uses conservation of angular momentum to move forward and backward. The robot&#039;s momentum wheel accelerates in the floor-plane. The robot&#039;s net angular momentum must remain zero-- a steering wheel guides the Fluffbot to accelerate in the opposite direction. This moves the robot forward in a curved path. The momentum wheel and steering wheel then change direction of acceleration. This repeated process moves the Fluffbot forward in a sinusoidal path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Differential Drive Mobile Robot]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
The goal of this project was to create a small differential drive mobile robot that would act as a low cost replacement for the popular E-Puck Robot.  The robot uses hybrid stepper motors to allow it to track its position through odometry, has a laser cut acrylic chassis for easy replication and replacement, and a 1500 mAh, 13.2V battery pack for long run time.  The robot also uses the NU32 board for its control logic and a XBee chip for communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Ferrofluid Art Display]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Place holder text for caption .|right]]&lt;br /&gt;
&lt;br /&gt;
A little blurb about our Ferrofluid Art Display will go here. Just a few sentences talking about blah blah lkasjdfal hfalsdjh.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Can Launching Fridge]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:27_Fridge.jpg|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
The goal of the can launching fridge was to create a fridge that would, when initiated by either a remote control or a wired push button, automatically load, aim, and fire a can to multiple predetermined locations. The fridge uses a combination of stepper motors, a DC motor, and solenoids to create the ultimate mix of convenience, fun, and refreshment. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[High Speed Motor Control]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:2dofArmSetUp.jpg|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
The project suggested was to design a system for high speed motor control using the PIC 32. To demonstrate the motor control, a two degree of freedom (2-DOF) parallelogram robot arm was designed to follow paths specified in a MATLAB gui.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ME 333 Final Projects 2009 ==&lt;br /&gt;
&lt;br /&gt;
=== [[Mozart&#039;s Right Hand]] ===&lt;br /&gt;
[[Image:mrh_box.JPG|thumb|150px|Mozart&#039;s Right Hand|right]]&lt;br /&gt;
Mozart&#039;s Right Hand is a musical instrument capable of playing two full octaves of the [http://en.wikipedia.org/wiki/Diatonic_scale Diatonic Scale.]  The user wears a glove on his right hand and uses motions of the hand and fingers to create different notes that are played with a speaker.  The pitch of the note is controlled by the orientation of the user&#039;s hand as he rotates it ether from the wrist, the elbow, or the shoulder.  The LCD on the front of the box tells the user the pitch that corresponds to his or her current hand orientation.  When the user touches together his thumb and index finger, the speaker plays the tone.  A [http://www.youtube.com/watch?v=vec-W4QeHQU video] of Mozart&#039;s Right Hand in action is available on YouTube.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chosen the OUTSTANDING PROJECT by the students of ME 333.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Persistence-of-Vision Display]] ===&lt;br /&gt;
[[Image:Persistence of Vison Display|right|thumb|150px]]&lt;br /&gt;
This is a fully customizable display implemented using the concept of Persistence of Vision. User-specified images (and even moving images) were displayed by rotating a column of LEDs at speeds faster than 300rpm. Each individual LED was modeled as a row of pixels. Conversely, the rotational position of the panel of LEDs represented the pixel columns of the display; the time interval and rotational speed determined the width of the pixel columns. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Rock Paper Scissors Machine]] ===&lt;br /&gt;
[[Image:rps whole thing.JPG|thumb|150px|Rock Paper Scissors Machine|right]]&lt;br /&gt;
A machine that will play a fully functioning, intuitive game of [http://en.wikipedia.org/wiki/Rock-paper-scissors Rock/Paper/Scissors] (abbreviated as RPS) with a user. The machine is represented by a human-like hand, capable of seperate and independant wrist, arm, finger and thumb motion. The players&#039; hand goes into a glove equipped with flex sensors, which wirelessly transmits data to the machine based on what the player chose. The machine then reads this data, randomly chooses a throw of its own, and displays what the machine threw, what the human threw, total win/loss/tie info, and winner/loser both on an [http://en.wikipedia.org/wiki/Lcd LCD] screen and in the form of a thumbs up/down/side motion. Video of the machine in action can be found [http://www.youtube.com/watch?v=xbLNBSTTrcE here.]&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Three-speaker Chladni Patterns]] ===&lt;br /&gt;
[[Image:chladni_660hz|right|thumb|150px]]&lt;br /&gt;
This project uses three speakers to generate shapes on a circular aluminum plate depending on which frequency the speakers are playing at. Once the speakers hit a resonant frequency of the plate, salt migrates to the nodes (zero amplitude) regions of the plate to form distinct patterns.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Basketball]] ===&lt;br /&gt;
[[Image:Mechatronics2009Bball|right|thumb|150px]]&lt;br /&gt;
This project consists of a throwing arm propelled by a Pittman motor is mounted on a turntable and throws the ball into the &amp;quot;hoop.&amp;quot; The hoop is wrapped in reflective tape and an IR emitter, receiver pair is used to sense where the IR is reflected most (the hoop with highly reflective tape). An ultrasonic sensor then pings the hoop for the distance of the hoop. With this information, the arm is able to &amp;quot;make a basket.&amp;quot; A video can be found [http://www.youtube.com/watch?v=Y466dzP-qiY here].&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Robot Drummer]] ===&lt;br /&gt;
[[Image:Robot_Drummer.jpg|thumb|400pix|right|Robot Drummer]]&lt;br /&gt;
The Robot Drummer is a device that demonstrates high-speed motor control by being able to drum when given commands.  Through an RS232 cable, Matlab sends commands to a &amp;quot;master&amp;quot; PIC.  The master then sends the commands to two &amp;quot;slave&amp;quot; PICs through I2C communication.  The slaves take the commands and implement PID control of the motors.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Automated Fish Refuge]] ===&lt;br /&gt;
[[Image:Entire Fish Refuge|right|thumb|200px]]&lt;br /&gt;
The automated fish refuge allows for the controlled movement of a fish refuge with the goal of recording specific behavior.  The mechanical design is completely adjustable and allows adjustable degrees of oscillating movement and orientation of the refuge.  The program is primarily in MATLAB for ease of use and the velocity profile can be a sine, square, triangle, or any function that the user inputs. [http://www.youtube.com/watch?v=wGOKujMhN88 Check out the video!]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Marionette]] ===&lt;br /&gt;
[[Image: MarionettePicForIntro.JPG|right|thumb]] The Marionette Project focused on using RC Servos to make a puppet that would do a dance with the press of a button.  There were 5 different dances programmed for the marionette, showcasing different styles of movement.  The movement had 2 degrees of freedom thanks to using 5 bar linkages and 2 RC servos for each arm.  Two more RC Servos were used on the back of the marionette to create the appearance of leg movement.  The movements included a Hula dance, Jumping Jacks, and even some moves right out of Saturday Night Fever.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Monkeybot]] ===&lt;br /&gt;
[[Image:monkeybot_pic|thumb|right|200px|Monkeybot]]&lt;br /&gt;
The monkeybot is a swinging robot capable of moving side to side and climbing.  It consists of a two link, double pendulum system with an electro-magnet on each end.  At the pivot is a DC motor, which provides an input torque and allows the swinging system to gain energy and climb.  Check out the video of the monkeybot climbing [http://www.youtube.com/watch?v=TA2VcH_GDJ0 here] and a later brachiation video [http://www.youtube.com/watch?v=0hfwJEVQyeQ&amp;amp;feature=related here].&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[PPOD-mini:  6-DOF Shaker]] ===&lt;br /&gt;
[[Image:PPOD_mini.JPG|thumb|200x200 px|right|PPOD-mini 6-DOF Shaker]]&lt;br /&gt;
The PPOD-mini is a miniaturized version of the Programmable Part-feeding Oscillatory Device ([http://lims.mech.northwestern.edu/projects/frictioninducedforcefields/index.htm PPOD]) found in the Laboratory for Intelligent Mechanical Systems (LIMS) at Northwestern. The PPOD-mini utilizes six speakers that act like actuators. The speakers are connected to a acrylic plate via flexures of tygon and iron. In its current implementation, the phase of the speakers can be controlled independently, giving the device six degrees of freedom. The movement of objects placed on the acrylic plate can be controlled by changing the phases of the speakers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Automated Xylophone]] ===&lt;br /&gt;
[[Image:AutomatedXylophonePicture1.jpg|thumb|200x200 px|right|Automated Xylophone]]&lt;br /&gt;
The Automated Xylophone controls several solenoids which hit various pitches on an actual xylophone based on the note selected.  The device has two main modes: using the keypad, a user can choose to either play notes in real time or store songs to be played back later.  A video of the Automated Xylophone playing in real time mode can be found [http://www.youtube.com/watch?v=_ubpAEyq9kg here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Vision-based Cannon]] ===&lt;br /&gt;
[[Image:SM_Gun_Camera_PIC_Setup.JPG|thumb|200x200 px|right|Vision-based Cannon]]&lt;br /&gt;
This project uses a webcam and Matlab to analyze an image and direct a modified USB Missile Launcher to fire at targets found in the image.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&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. [[Media:MT_MS_AZ_TrackerVideo.mp4|See Spot Run.]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chosen the OUTSTANDING PROJECT by the students of ME 333.&#039;&#039;&#039;&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;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake]&lt;br /&gt;
&lt;br /&gt;
Featured on [http://blog.makezine.com/archive/2009/03/well_documented_robotic_snake.html Makezine.com].&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_system.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>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=ME_333_final_projects&amp;diff=16824</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=16824"/>
		<updated>2010-03-15T06:50:30Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* ME 333 Final Projects 2010 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the &#039;&#039;&#039;[[ME 333 end of course schedule]]&#039;&#039;&#039;.  &lt;br /&gt;
&lt;br /&gt;
Final projects for ME 333 in years 2000-2007 can be found&lt;br /&gt;
&#039;&#039;&#039;[http://lims.mech.northwestern.edu/~design/mechatronics/ here]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ME 333 Final Projects 2010 ==&lt;br /&gt;
&lt;br /&gt;
=== [[Sample Project Title]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
You can copy and paste this wiki code to start your wiki page (but don&#039;t erase this code).  Then replace this text with your own.  A few sentences describing what your project does, with a link to a youtube video.  Look at other final project wiki pages for ideas, but see [[ME 333 end of course schedule]] for more information on what should be included on your wiki page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Conservation of Angular Momentum Locomotion Robot (Fluffbot)]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
You can copy and paste this wiki code to start your wiki page (but don&#039;t erase this code).  Then replace this text with your own.  A few sentences describing what your project does, with a link to a youtube video.  Look at other final project wiki pages for ideas, but see [[ME 333 end of course schedule]] for more information on what should be included on your wiki page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [[Differential Drive Mobile Robot]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
The goal of this project was to create a small differential drive mobile robot that would act as a low cost replacement for the popular E-Puck Robot.  The robot uses hybrid stepper motors to allow it to track its position through odometry, has a laser cut acrylic chassis for easy replication and replacement, and a 1500 mAh, 13.2V battery pack for long run time.  The robot also uses the NU32 board for its control logic and a XBee chip for communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Ferrofluid Art Display]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Persistence of Vison Display|thumb|150px|Place holder text for caption .|right]]&lt;br /&gt;
&lt;br /&gt;
A little blurb about our Ferrofluid Art Display will go here. Just a few sentences talking about blah blah lkasjdfal hfalsdjh.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Can Launching Fridge]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:27_Fridge.jpg|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
&lt;br /&gt;
fridge info&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[High Speed Motor Control]] ===&lt;br /&gt;
&lt;br /&gt;
[[Image:2dofArmSetUp.jpg|thumb|150px|Project photo caption.|right]]&lt;br /&gt;
The project suggested was to design a system for high speed motor control using the PIC 32. To demonstrate the motor control, a two degree of freedom (2-DOF) parallelogram robot arm was designed to follow paths specified in a MATLAB gui.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ME 333 Final Projects 2009 ==&lt;br /&gt;
&lt;br /&gt;
=== [[Mozart&#039;s Right Hand]] ===&lt;br /&gt;
[[Image:mrh_box.JPG|thumb|150px|Mozart&#039;s Right Hand|right]]&lt;br /&gt;
Mozart&#039;s Right Hand is a musical instrument capable of playing two full octaves of the [http://en.wikipedia.org/wiki/Diatonic_scale Diatonic Scale.]  The user wears a glove on his right hand and uses motions of the hand and fingers to create different notes that are played with a speaker.  The pitch of the note is controlled by the orientation of the user&#039;s hand as he rotates it ether from the wrist, the elbow, or the shoulder.  The LCD on the front of the box tells the user the pitch that corresponds to his or her current hand orientation.  When the user touches together his thumb and index finger, the speaker plays the tone.  A [http://www.youtube.com/watch?v=vec-W4QeHQU video] of Mozart&#039;s Right Hand in action is available on YouTube.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chosen the OUTSTANDING PROJECT by the students of ME 333.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Persistence-of-Vision Display]] ===&lt;br /&gt;
[[Image:Persistence of Vison Display|right|thumb|150px]]&lt;br /&gt;
This is a fully customizable display implemented using the concept of Persistence of Vision. User-specified images (and even moving images) were displayed by rotating a column of LEDs at speeds faster than 300rpm. Each individual LED was modeled as a row of pixels. Conversely, the rotational position of the panel of LEDs represented the pixel columns of the display; the time interval and rotational speed determined the width of the pixel columns. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Rock Paper Scissors Machine]] ===&lt;br /&gt;
[[Image:rps whole thing.JPG|thumb|150px|Rock Paper Scissors Machine|right]]&lt;br /&gt;
A machine that will play a fully functioning, intuitive game of [http://en.wikipedia.org/wiki/Rock-paper-scissors Rock/Paper/Scissors] (abbreviated as RPS) with a user. The machine is represented by a human-like hand, capable of seperate and independant wrist, arm, finger and thumb motion. The players&#039; hand goes into a glove equipped with flex sensors, which wirelessly transmits data to the machine based on what the player chose. The machine then reads this data, randomly chooses a throw of its own, and displays what the machine threw, what the human threw, total win/loss/tie info, and winner/loser both on an [http://en.wikipedia.org/wiki/Lcd LCD] screen and in the form of a thumbs up/down/side motion. Video of the machine in action can be found [http://www.youtube.com/watch?v=xbLNBSTTrcE here.]&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Three-speaker Chladni Patterns]] ===&lt;br /&gt;
[[Image:chladni_660hz|right|thumb|150px]]&lt;br /&gt;
This project uses three speakers to generate shapes on a circular aluminum plate depending on which frequency the speakers are playing at. Once the speakers hit a resonant frequency of the plate, salt migrates to the nodes (zero amplitude) regions of the plate to form distinct patterns.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Basketball]] ===&lt;br /&gt;
[[Image:Mechatronics2009Bball|right|thumb|150px]]&lt;br /&gt;
This project consists of a throwing arm propelled by a Pittman motor is mounted on a turntable and throws the ball into the &amp;quot;hoop.&amp;quot; The hoop is wrapped in reflective tape and an IR emitter, receiver pair is used to sense where the IR is reflected most (the hoop with highly reflective tape). An ultrasonic sensor then pings the hoop for the distance of the hoop. With this information, the arm is able to &amp;quot;make a basket.&amp;quot; A video can be found [http://www.youtube.com/watch?v=Y466dzP-qiY here].&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Robot Drummer]] ===&lt;br /&gt;
[[Image:Robot_Drummer.jpg|thumb|400pix|right|Robot Drummer]]&lt;br /&gt;
The Robot Drummer is a device that demonstrates high-speed motor control by being able to drum when given commands.  Through an RS232 cable, Matlab sends commands to a &amp;quot;master&amp;quot; PIC.  The master then sends the commands to two &amp;quot;slave&amp;quot; PICs through I2C communication.  The slaves take the commands and implement PID control of the motors.&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Automated Fish Refuge]] ===&lt;br /&gt;
[[Image:Entire Fish Refuge|right|thumb|200px]]&lt;br /&gt;
The automated fish refuge allows for the controlled movement of a fish refuge with the goal of recording specific behavior.  The mechanical design is completely adjustable and allows adjustable degrees of oscillating movement and orientation of the refuge.  The program is primarily in MATLAB for ease of use and the velocity profile can be a sine, square, triangle, or any function that the user inputs. [http://www.youtube.com/watch?v=wGOKujMhN88 Check out the video!]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Marionette]] ===&lt;br /&gt;
[[Image: MarionettePicForIntro.JPG|right|thumb]] The Marionette Project focused on using RC Servos to make a puppet that would do a dance with the press of a button.  There were 5 different dances programmed for the marionette, showcasing different styles of movement.  The movement had 2 degrees of freedom thanks to using 5 bar linkages and 2 RC servos for each arm.  Two more RC Servos were used on the back of the marionette to create the appearance of leg movement.  The movements included a Hula dance, Jumping Jacks, and even some moves right out of Saturday Night Fever.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Monkeybot]] ===&lt;br /&gt;
[[Image:monkeybot_pic|thumb|right|200px|Monkeybot]]&lt;br /&gt;
The monkeybot is a swinging robot capable of moving side to side and climbing.  It consists of a two link, double pendulum system with an electro-magnet on each end.  At the pivot is a DC motor, which provides an input torque and allows the swinging system to gain energy and climb.  Check out the video of the monkeybot climbing [http://www.youtube.com/watch?v=TA2VcH_GDJ0 here] and a later brachiation video [http://www.youtube.com/watch?v=0hfwJEVQyeQ&amp;amp;feature=related here].&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[PPOD-mini:  6-DOF Shaker]] ===&lt;br /&gt;
[[Image:PPOD_mini.JPG|thumb|200x200 px|right|PPOD-mini 6-DOF Shaker]]&lt;br /&gt;
The PPOD-mini is a miniaturized version of the Programmable Part-feeding Oscillatory Device ([http://lims.mech.northwestern.edu/projects/frictioninducedforcefields/index.htm PPOD]) found in the Laboratory for Intelligent Mechanical Systems (LIMS) at Northwestern. The PPOD-mini utilizes six speakers that act like actuators. The speakers are connected to a acrylic plate via flexures of tygon and iron. In its current implementation, the phase of the speakers can be controlled independently, giving the device six degrees of freedom. The movement of objects placed on the acrylic plate can be controlled by changing the phases of the speakers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Automated Xylophone]] ===&lt;br /&gt;
[[Image:AutomatedXylophonePicture1.jpg|thumb|200x200 px|right|Automated Xylophone]]&lt;br /&gt;
The Automated Xylophone controls several solenoids which hit various pitches on an actual xylophone based on the note selected.  The device has two main modes: using the keypad, a user can choose to either play notes in real time or store songs to be played back later.  A video of the Automated Xylophone playing in real time mode can be found [http://www.youtube.com/watch?v=_ubpAEyq9kg here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [[Vision-based Cannon]] ===&lt;br /&gt;
[[Image:SM_Gun_Camera_PIC_Setup.JPG|thumb|200x200 px|right|Vision-based Cannon]]&lt;br /&gt;
This project uses a webcam and Matlab to analyze an image and direct a modified USB Missile Launcher to fire at targets found in the image.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&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. [[Media:MT_MS_AZ_TrackerVideo.mp4|See Spot Run.]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chosen the OUTSTANDING PROJECT by the students of ME 333.&#039;&#039;&#039;&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;
&lt;br /&gt;
[http://www.youtube.com/watch?v=r_GOOFLnI6w Video of the robot snake]&lt;br /&gt;
&lt;br /&gt;
Featured on [http://blog.makezine.com/archive/2009/03/well_documented_robotic_snake.html Makezine.com].&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_system.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>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16161</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16161"/>
		<updated>2010-02-16T06:25:50Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
The PIC32 communicates with the 23K256 through sending a series of 8 bit commands. To understand the 23K256 operations more thoroughly, consult the 23K256 datasheet. But basically, the PIC tells the 23K256 what mode to operate in, whether it is reading or writing, what address to use, and the data to store.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements to your MPLAB project; instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier. The code here has the PIC send data to store in the external RAM, and read the data back from the external RAM. It does this for the three modes available for the 23K256 external ram chip: byte mode, page mode, and sequential mode.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
       &lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
4. To see that the PIC32 and the external RAM are operating correctly, you can observe the communication lines. You should be able to see data, similar to that described in this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
&lt;br /&gt;
5. You can also choose to view the data being sent and read through UART on the PC. You can also set up the LEDs on the PIC32 board to indicate whether the correct data is sent and received. You can do this by adding some code. First, add these two lines somewhere before the main loop:&lt;br /&gt;
&lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
  void Delayms( unsigned t);&lt;br /&gt;
&lt;br /&gt;
Then, configure UART2, adding this code to the start of the main loop:&lt;br /&gt;
&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
    &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
  &lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
 &lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality&lt;br /&gt;
&lt;br /&gt;
Next, add this code to the bottom of the infinite while loop:&lt;br /&gt;
&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD. If data read not equal data sent, LED will be OFF&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
&lt;br /&gt;
Finally, add this to the very bottom of the main file:&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16160</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16160"/>
		<updated>2010-02-16T06:23:11Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
The PIC32 communicates with the 23K256 through sending a series of 8 bit commands. To understand the 23K256 operations more thoroughly, consult the 23K256 datasheet. But basically, the PIC tells the 23K256 what mode to operate in, whether it is reading or writing, what address to use, and the data to store.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements to your MPLAB project; instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier. The code here has the PIC send data to store in the external RAM, and read the data back from the external RAM. It does this for the three modes available for the 23K256 external ram chip: byte mode, page mode, and sequential mode.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
       &lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
4. To see that the PIC32 and the external RAM are operating correctly, you can observe the communication lines. You should be able to see data, similar to that described in this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
&lt;br /&gt;
5. You can also choose to view the data being sent and read through UART on the PC. You can do this by adding some code. First, add these two lines somewhere before the main loop:&lt;br /&gt;
&lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
  void Delayms( unsigned t);&lt;br /&gt;
&lt;br /&gt;
Then, configure UART2, adding this code to the start of the main loop:&lt;br /&gt;
&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
    &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
  &lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
 &lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality&lt;br /&gt;
&lt;br /&gt;
Next, add this code to the bottom of the infinite while loop:&lt;br /&gt;
&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
&lt;br /&gt;
Finally, add this to the very bottom of the main file:&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16159</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16159"/>
		<updated>2010-02-16T06:20:11Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements to your MPLAB project; instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier. The code here has the PIC send data to store in the external RAM, and read the data back from the external RAM. It does this for the three modes available for the 23K256 external ram chip: byte mode, page mode, and sequential mode.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
       &lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
4. To see that the PIC32 and the external RAM are operating correctly, you can observe the communication lines. You should be able to see data, similar to that described in this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
&lt;br /&gt;
5. You can also choose to view the data being sent and read through UART on the PC. You can do this by adding some code. First, add these two lines somewhere before the main loop:&lt;br /&gt;
&lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
  void Delayms( unsigned t);&lt;br /&gt;
&lt;br /&gt;
Then, configure UART2, adding this code to the start of the main loop:&lt;br /&gt;
&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
    &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
  &lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
 &lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality&lt;br /&gt;
&lt;br /&gt;
Next, add this code to the bottom of the infinite while loop:&lt;br /&gt;
&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
&lt;br /&gt;
Finally, add this to the very bottom of the main file:&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16158</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16158"/>
		<updated>2010-02-16T06:19:45Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements to your MPLAB project; instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier. The code here has the PIC send data to store in the external RAM, and read the data back from the external RAM. It does this for the three modes available for the 23K256 external ram chip: byte mode, page mode, and sequential mode.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
       &lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
4. To see that the PIC32 and the external RAM are operating correctly, you can observe the communication lines. You should be able to see data, similar to that described in this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
&lt;br /&gt;
5. You can also choose to view the data being sent and read through UART on the PC. You can do this by adding some code. First, add these two lines somewhere before the main loop:&lt;br /&gt;
&lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
  void Delayms( unsigned t);&lt;br /&gt;
&lt;br /&gt;
Then, configure UART2, adding this code to the start of the main loop:&lt;br /&gt;
&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
    &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
  &lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
 &lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality&lt;br /&gt;
&lt;br /&gt;
Next, add this code to the bottom of the infinite while loop:&lt;br /&gt;
&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
&lt;br /&gt;
Finally, add this to the very bottom of the main fale:&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16157</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16157"/>
		<updated>2010-02-16T06:17:23Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements to your MPLAB project; instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier. The code here has the PIC send data to store in the external RAM, and read the data back from the external RAM. It does this for the three modes available for the 23K256 external ram chip: byte mode, page mode, and sequential mode.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
       &lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
4. To see that the PIC32 and the external RAM are operating correctly, you can observe the communication lines. You should be able to see data, similar to that described in this microchip documentation http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
&lt;br /&gt;
5. You can also choose to view the data being sent and read through UART on the PC. You can do this by adding some code. First, configure UART2, adding this code to the start of the main loop:&lt;br /&gt;
&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
    &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
  &lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
 &lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16156</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16156"/>
		<updated>2010-02-16T06:11:22Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements, instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16155</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16155"/>
		<updated>2010-02-16T06:11:05Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements, instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
  &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16154</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16154"/>
		<updated>2010-02-16T06:07:56Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements, instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
 &lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t);&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
   &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
 &lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
 &lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality &lt;br /&gt;
 &lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
 &lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
 &lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
 &lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
 &lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
 &lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
 &lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
 &lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
 &lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
 &lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
      &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16153</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16153"/>
		<updated>2010-02-16T06:06:52Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements, instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
 &lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t);&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD |  UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
   &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS  | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
&lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
&lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality &lt;br /&gt;
&lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
&lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
&lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
&lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
&lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
&lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
&lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
&lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
&lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
&lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
      &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16152</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16152"/>
		<updated>2010-02-16T06:06:27Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements, instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
 // Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
 // WDT OFF&lt;br /&gt;
 // Other options are don&#039;t care&lt;br /&gt;
 //&lt;br /&gt;
 #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
 #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
 &lt;br /&gt;
 #define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
 &lt;br /&gt;
 void Delayms( unsigned t);&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
   &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
&lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
&lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality &lt;br /&gt;
&lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
&lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
&lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
&lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
&lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
&lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
&lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
 accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
&lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
&lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
&lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
 /************************************************************&lt;br /&gt;
 ...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
 ************************************************************/   &lt;br /&gt;
      &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 void Delayms( unsigned t)&lt;br /&gt;
 // This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
 {&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
 } // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16151</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16151"/>
		<updated>2010-02-16T06:05:40Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and download &amp;quot;AN1277 Source Code&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
2. Add the PIC32 files and other requirements, instructions here [http://hades.mech.northwestern.edu/index.php/HelloWorld_PIC32].&lt;br /&gt;
&lt;br /&gt;
3. Edit the main.c file you downloaded from step 1 to match usage for the PIC32 board. The original code is also edited make testing easier.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;plib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;HardwareProfile.h&amp;quot; &lt;br /&gt;
 #include &amp;quot;SRAMDriver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // Configuration Bit settings&lt;br /&gt;
 // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)&lt;br /&gt;
 // PBCLK = 40 MHz&lt;br /&gt;
// Primary Osc w/PLL (XT+,HS+,EC+PLL)&lt;br /&gt;
// WDT OFF&lt;br /&gt;
// Other options are don&#039;t care&lt;br /&gt;
//&lt;br /&gt;
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF&lt;br /&gt;
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1&lt;br /&gt;
&lt;br /&gt;
#define DESIRED_BAUDRATE       (9600)      // The desired BaudRate&lt;br /&gt;
&lt;br /&gt;
void Delayms( unsigned t);&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   mInitAllLEDs();&lt;br /&gt;
   int pbClk = SYSTEMConfigPerformance(SYS_FREQ);&lt;br /&gt;
   &lt;br /&gt;
   #define config1    UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN&lt;br /&gt;
   &lt;br /&gt;
   // define setup Configuration 2 for OpenUARTx&lt;br /&gt;
      // IrDA encoded UxTX idle state is &#039;0&#039;&lt;br /&gt;
      // Enable UxRX pin&lt;br /&gt;
      // Enable UxTX pin&lt;br /&gt;
      // Interrupt on transfer of every character to TSR &lt;br /&gt;
      // Interrupt on every char received&lt;br /&gt;
      // Disable 9-bit address detect&lt;br /&gt;
      // Rx Buffer Over run status bit clear&lt;br /&gt;
   #define config2      UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR&lt;br /&gt;
&lt;br /&gt;
   // Open UART2 with config1 and config2&lt;br /&gt;
   OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);   // calculate actual BAUD generate value.&lt;br /&gt;
      //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE&lt;br /&gt;
&lt;br /&gt;
   putsUART2(&amp;quot;Init Done\r\n&amp;quot;);&lt;br /&gt;
   //While loop to test LED functionality &lt;br /&gt;
&lt;br /&gt;
   unsigned char ReadVal,Cnt;&lt;br /&gt;
   unsigned char RandomSendData;&lt;br /&gt;
   unsigned char SRAMBufPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufCheckPage[SRAMPageSize];&lt;br /&gt;
   unsigned char SRAMBufSeq[10];&lt;br /&gt;
   unsigned char SRAMBufCheckSeq[10];&lt;br /&gt;
   &lt;br /&gt;
   // Configure the device for maximum performance but do not change the PBDIV&lt;br /&gt;
   // Given the options, this function will change the flash wait states, RAM&lt;br /&gt;
   // wait state and enable prefetch cache but will not change the PBDIV.&lt;br /&gt;
   // The PBDIV value is already set via the pragma FPBDIV option above..&lt;br /&gt;
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);&lt;br /&gt;
   &lt;br /&gt;
   InitSRAM();&lt;br /&gt;
&lt;br /&gt;
   while(1)&lt;br /&gt;
   {&lt;br /&gt;
      &lt;br /&gt;
   //Byte Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMByteMode);&lt;br /&gt;
&lt;br /&gt;
      //Write random byte to 0x0010 memory location of SRAM&lt;br /&gt;
      RandomSendData = rand();&lt;br /&gt;
      SRAMWriteByte(0x00,0x10,RandomSendData);&lt;br /&gt;
&lt;br /&gt;
      //Read 0x0010 memory location of SRAM&lt;br /&gt;
      ReadVal = SRAMReadByte(0x00,0x10);&lt;br /&gt;
&lt;br /&gt;
   //Page Mode&lt;br /&gt;
      SRAMWriteStatusReg(SRAMPageMode);&lt;br /&gt;
      memset(SRAMBufPage,0,sizeof(SRAMBufPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckPage,0,sizeof(SRAMBufCheckPage));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
&lt;br /&gt;
      //Write 32bytes from SRAMBuf array to first page of SRAM&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufPage[Cnt] = (rand());&lt;br /&gt;
      }   &lt;br /&gt;
      SRAMWritePage(0x00,0x20,SRAMBufPage);&lt;br /&gt;
      &lt;br /&gt;
      //Read 32bytes from SRAMBuf array from first page of SRAM      &lt;br /&gt;
      SRAMReadPage(0x00,0x20,SRAMBufCheckPage);&lt;br /&gt;
      &lt;br /&gt;
   //Sequential Mode&lt;br /&gt;
      memset(SRAMBufSeq,0,sizeof(SRAMBufSeq));   //Reset SRAMBuf location to 0x00 value&lt;br /&gt;
      memset(SRAMBufCheckSeq,0,sizeof(SRAMBufCheckSeq));   //Reset SRAMBufCheckSeq location to 0x00 value&lt;br /&gt;
&lt;br /&gt;
      //Write 10bytes from SRAMBuf to SRAM starting from 0x0010 memory location&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++)&lt;br /&gt;
      {&lt;br /&gt;
         SRAMBufSeq[Cnt] =(rand());&lt;br /&gt;
      }&lt;br /&gt;
      SRAMWriteStatusReg(SRAMSeqMode);&lt;br /&gt;
      &lt;br /&gt;
      SRAMWriteSeq(0x10,0x10,SRAMBufSeq,10);&lt;br /&gt;
      &lt;br /&gt;
      //Read 10bytes starting from 0x1010 memory location of SRAM and store it to SRAMBuf array      &lt;br /&gt;
      SRAMReadSeq(0x10,0x10,SRAMBufCheckSeq,10);&lt;br /&gt;
&lt;br /&gt;
/************************************************************&lt;br /&gt;
This &amp;quot;TESTER&amp;quot; section lets you view results via UART or test &lt;br /&gt;
accuracy of data transfer through the LEDS on the PIC32 board&lt;br /&gt;
************************************************************/   &lt;br /&gt;
   //VIEW RESULTS THROUGH UART&lt;br /&gt;
&lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nBYTE MODE: &amp;quot;);&lt;br /&gt;
      printf(&amp;quot;BYTE MODE: Data Sent / Data Read = %d / %d\r\n&amp;quot;, RandomSendData, ReadVal);&lt;br /&gt;
&lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nPAGE MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufPage[Cnt], SRAMBufCheckPage[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //Sequential Mode results&lt;br /&gt;
      printf(&amp;quot;\r\nSEQUENTIAL MODE: &amp;quot;);&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){&lt;br /&gt;
         printf(&amp;quot;Data Sent / Data Read = %d / %d\r\n&amp;quot;, SRAMBufSeq[Cnt], SRAMBufCheckSeq[Cnt]);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   //TEST RESULTS THROUGH LEDS ON PIC32 BOARD&lt;br /&gt;
&lt;br /&gt;
      //Byte Mode results&lt;br /&gt;
      if(ReadVal==RandomSendData){&lt;br /&gt;
            mLED_0_On();&lt;br /&gt;
         }&lt;br /&gt;
         else{&lt;br /&gt;
          mLED_0_Off();&lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
      //Page Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;32;Cnt++){ &lt;br /&gt;
            if(SRAMBufPage[Cnt]==SRAMBufCheckPage[Cnt]){&lt;br /&gt;
               mLED_1_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_1_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //Sequential Mode results&lt;br /&gt;
      for(Cnt = 0;Cnt&amp;lt;sizeof(SRAMBufSeq);Cnt++){ &lt;br /&gt;
            if(SRAMBufSeq[Cnt]==SRAMBufCheckSeq[Cnt]){&lt;br /&gt;
               mLED_2_On();&lt;br /&gt;
            }         &lt;br /&gt;
            else{&lt;br /&gt;
             mLED_2_Off();&lt;br /&gt;
             break;&lt;br /&gt;
          }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
      Delayms(1000);&lt;br /&gt;
/************************************************************&lt;br /&gt;
...end of &amp;quot;TESTER&amp;quot; section.&lt;br /&gt;
************************************************************/   &lt;br /&gt;
      &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Delayms( unsigned t)&lt;br /&gt;
// This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ&lt;br /&gt;
{&lt;br /&gt;
    OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);&lt;br /&gt;
    while (t--)&lt;br /&gt;
    {  // t x 1ms loop&lt;br /&gt;
        WriteTimer1(0);&lt;br /&gt;
        while (ReadTimer1() &amp;lt; SYS_FREQ/256/1000);&lt;br /&gt;
   }&lt;br /&gt;
   CloseTimer1();&lt;br /&gt;
} // Delayms&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16150</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16150"/>
		<updated>2010-02-16T05:54:32Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
1. Go to this link [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1824&amp;amp;appnote=en542689] and&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
	<entry>
		<id>https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16149</id>
		<title>PIC32MX: SPI External RAM</title>
		<link rel="alternate" type="text/html" href="https://hades.mech.northwestern.edu//index.php?title=PIC32MX:_SPI_External_RAM&amp;diff=16149"/>
		<updated>2010-02-16T05:53:26Z</updated>

		<summary type="html">&lt;p&gt;RenYu: /* Circuit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Original Assignment ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not erase this section!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your assignment is to interface to the SPI 23K256 SRAM chip.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This page will guide you how to interface the PIC32 board with the 23K256 external RAM using SPI.&lt;br /&gt;
&lt;br /&gt;
== Circuit ==&lt;br /&gt;
&lt;br /&gt;
Circuit diagram showing PIC32 connected to external RAM 23K256. The circuit is an edited version of a circuit from this microchip documentation [http://ww1.microchip.com/downloads/en/AppNotes/01277A.pdf].&lt;br /&gt;
[[Image:External_Ram_PIC32_SPI.png]]&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
&lt;br /&gt;
Where possible, make it a single piece of well-commented cut-and-pastable code, or at least make each function that way, so others can easily copy it.  Most comments should be in the code itself; outside the code (on the wiki) should only be explanatory comments that are too cumbersome to include in the code.&lt;/div&gt;</summary>
		<author><name>RenYu</name></author>
	</entry>
</feed>