Professional Documents
Culture Documents
8 Mission Mapping PDF
8 Mission Mapping PDF
In this lab, you will learn more about the Adafruit motor shield and how it can be used to control
a stepper motor. Your work with the IR sensors will also continue as you teach your rover how
to map the terrain surrounding it, equipping it with sufficient knowledge to navigate around
possible obstructions, and finally reach the desired plaques of interest.
Table of Contents
1
2
3
4
5
Reading
1.1
References
Homework and Mission
2.1
Homework
2.2
Mission
2.3
Documentation
Lab Checklist
Parts
How it Works
5.1
General
5.2
Construction
5.3
Unipolar vs. Bipolar
5.4
Movement
5.4.1
Single
5.4.2
Double
5.4.3
Interleave
5.4.4
Microstep
Lab Experiments
6.1
Gyro Calibration
6.2
Horizontal Alignment of the Scan Platform
6.3
Mapping Experiment
6.3.1
Documentation
Software
7.1
Gyro Calibration Application
7.2
Mapping Software Application
7.3
Reading
Most of the material in this document on the SPI subsystem can be found in
Chapter 18 The Serial Peripheral Interface (SPI) of the ATmega328P Datasheet.
We will be looking at stepper motors and the SPI serial communications as they are
implemented by the Arduino and the Adafruit Motor Shield. Here is the motor shield schematic
http://www.ladyada.net/make/mshield/download.html
and here is the pdf documenting the shield and how to control a stepper motor (pages 25 and
26) http://www.robotshop.ca/content/PDF/adafruit-motor-shield-arduino-user-guide.pdf
1.1 References
1. Atmel AVR Micrcontroller Primer:Programming and Interfacing, by Barrett, Section 6.4
DC Motor Speed and Direction Control
2. HSI Stepper Motor Theory and Stepper Motor are good recources, among many on the
2.2
Mission
Before your rovers can travel to points of interest (the plaques), it needs to be able to pick them
out from other terrain features (walls, cabinets, desks, chairs, etc.). At the end of this lab you
should have completed a...
IR Mapping Experiment - the Difference Map
Software with associated documentation to identify targets within the field-of-view of the
rover.
As a necessary precondition for completing these experiments, the scan platform and IR
rangers will need to be aligned horizontally.
2.3
Documentation
Summarize your experimental results and equation(s) in the subsection named IR Sensors
within the Hardware Build section of your Project Document. This subsection should include a
discussion of the modifications you made to the indoor mapping experiment in order to achieve
success on the test site.
Lab Checklist
The checklist is filled in by the instructor at the beginning of next weeks lab.
Horizontal Alignment of the scan platform with tilt calculation
IR Mapping Experiment
Graphical results with comments from running makeMap program are included in the IR
section of the Project Document.
Target Location Algorithm added to the Software Code Section.
Results from running your findObjects software to identify targets within the field-of-
Parts
Solderless breadboard
Sharp
GP2Y0A710YK0F
Long Range IR Sensor
$19.50
Sharp GP2Y0A02YK0F
Medium Range IR
Sensor $12.50
4.7 K resistor
10uF Capacitor
LED
In addition to our essentials, we will need some measuring equipment and supplies to complete
this lab...
Tape Measure
(inches and cm)
Laser Pointer
Level
You will also need your breadboard wire bundle plus half-size breadboard.
Electrical Tape
How it Works
The best discussion on how stepper motors work can be found on Wikipedia under Stepper
motor. To learn how to use these in the Arduino IDE look here. Also see AdaFruit Make it Work
under the Stepper section.
5.1
General
Stepper motors can be salvaged from obsolete disk drives and ink jet printers. The motors from
3.5" floppy motors are not suitable for this lab. Bipolar motors have 4 wires and unipolar motors
have 5,6 or 8. Bipolar motors generally have a larger torque and smaller step angle when
compared to unipolar stepper motors. You can find common phase leads by using a ohmmeter
to measure resistances between leads, common phase leads will have low resistances in
around 30 ohms.
Stepper motors can be broken down into 3 categories.
1. Variable reluctance stepper- magnetic flux seeking the lowest reluctance path through a
magnetic circuit.
2. Permanent magnet stepper- has a cylindrical permanent magnet rotor.
3. The hybrid stepper- combination of variable reluctance and permanent magnet steppers
Source: http://www.stepperboard.com/MotorConnections.htm
5.2
Construction
An inductive motor like our stepper motor has two major components: a stator and a rotor.
The rotor is the magnetic armature of the stepper motor and is the moving part of the stepper
motor. The rotor consists of bearings, magnetic shaft and poles. This cylindrical shaft contains
permanent magnets which interact with the stator. The stator is the external part of the inductive
motor that does not move. The stator contains the bearing housing, the stator coils and the
stator poles. (Follow this link for a disassemble). A stepper motor is a type of motor whose
circular rotation of the rotor is divided into smaller discrete steps. The number of steps a
stepper motor takes in order to make one full rotation of the rotor is fixed and is determined by
the number of poles inside the motor. Each step turns the rotor a certain number of degrees.
Smaller step angles are obtained by adding more poles on both the rotor and stator. Both
unipolar and bipolar stepper motors are constructed this way while the main difference lies in
5.3
Unipolar stepper motors are designed to have a canter tap which is common to two coils
working together. The positive voltage is then applied to the common tap and the nodes a and
b are alternately grounded to produce changes in polarity to the magnetic field. You can check
the direction of the field by using the equation B=IxR (this is greatly simplified for our purposes)
where B is the magnetic field, I point in the direction of positive current flow, and R is in the
direction of where you want to measure the magnetic field at. For example if 1 is positive, a is
grounded, and b is open (high impedance) current flows from 1 to a in Figure 1 and the direction
of the magnetic field flows out at the left end and comes in at the right end (Figure 2 is meant to
clear up which way is north or south. If the magnetic field is outgoing it is south while north is on
the receiving end). If the current flows from 1 to b,while a is high impedance, then the polarity is
reversed.
Figure 1
Figure 2
From:http://www.cs.uiowa.edu/~jones/step/types.html
From:http://en.wikipedia.org/wiki/
File:Dipole_field.svg
A bipolar motor has no center tap and the current must flow from a to b or from b to a. We must
reverse the current in order to reverse the magnetic field as opposed to switching the ground.
This requires a more complex design to handle and is usually left to an H-bridge to configure.
5.4
Movement
The stepping sequence of a bipolar stepping motor can be broken down into:
1. Step mode: Full step (one-phase or two-phase), Half Step (eight-phase), Micro-stepping
(not used in the lab).
2. Misc factors: Power, torque, step angle and accuracy.
The type of stepping sequence that is used is dependent on the type of application of the motor.
5.4.1 Single
This mode refers to the single-coil activation aka the Wave Drive, One-Phase activation of the
motors. See GIF animation. For the ROB-09238 this gives you a step of 1.8o.
5.4.2 Double
This mode refers to the double-coil activation aka the Full Step, Two-Phase activation of the
motors. See GIF animation. For the ROB-09238 this gives you a step of 1.8o.
5.4.3 Interleave
This mode refers to the single-coil/double-coil aka the Half Step activation of the motors. See
GIF animation. For the ROB-09238 this gives you a step of 0.9o.
5.4.4 Microstep
The micro-stepping mode is the most complex of all the stepping modes. That is why some
stepper drivers only offer full and half step modes. Micro-stepping is when the current applied
to each winding is proportional to a mathematical function, providing a fraction of a full step.
The most common divisions are 1/4th, 1/8th, 1/10th, etc. However, there are some drivers that
provide up to 1/256th of a full step. Micro-stepping provides greater resolution and smoother
motor operation. This is very advantageous as it reduces the need for mechanical gearing when
trying to achieve high resolution. However, micro-stepping can affect the repeatability of the
motor. (source: CNC Router Source).
Lab Experiments
2. Place your rover on the raised platform at the front of the lab. Using your level, find a
relatively flat and level part of the floor. After placing your rover at this location, again
using your level, verify that the base of the rover is level to the floor.
3. Using your triangle adjust the stepper motor mount so the shaft of the stepper motor is
perpendicular to the base. This assumes that any adapters you have attached to the
shaft of the stepper motor are also aligned. Verify this alignment for all 360 degrees of
rotation.
4. Using the triangle and level adjust the scan platform/IR sensor so it is perpendicular
to the shaft/mounting adapter of the stepper motor and parallel to the floor for all 360
degrees of rotation. It is critical that the IR sensor not be tilted with respect to the axis of
rotation.
5. Have the rover run the scan platform demonstration sequence from last week.
6. Approximately locate the laser beam's maximum and minimum height from the floor.
7. Place a target at these two locations 4 meters from the rover. You may have to reorient
the rover to be able to locate the targets on the platform.
8. If required, repeat steps 2 through 7, until the laser beam stays approximately level to
the floor during its 360 degree scan.
Once you feel the scan platform is mission ready, program the rover to move one meter and run
the scan platform demonstration sequence from last week. Locate the minimum and maximum
height. Do not move the scan platform by hand - we are trying to replicate the real-world that
the rover will encounter during the mission. Place targets as far away as you can at these two
locations and record the beam height, distance, and the rotation angle from the home position
(straight ahead). Tell your rover to move approximately 1 more meter, and again have the rover
run the scan platform demonstration sequence. Record beam height, distance, and the rotation
angle.
Have the rover move an additional meter and repeat the sequence.
After running these experiments calculate the maximum angle that the floor could be tilted, so
the laser does not hit the floor or go over an 11 inch high target.
Rotation Angle
Distance to Target
Beam Height
Signature/Date
Test 1
Test 2
Using your compass, string, and ruler measure the rotation angle and
distance of the targets relative to the IR sensor(s). Record the location (angle and distance)
of these plaques in your lab notebook. You may also want to take a picture(s) and/or video for
future reference. As you can see in the figure below, the photo makes a nice background for
displaying the results of your mapping experiments.
I recommend running with the laser ON in order to record when the IR is looking at a target.
Download and run the program. Launch the terminal program (warning: opening or closing
the terminal program during a scan will effect your experimental results). You should see the
message "in setup," followed by "press any key to start scan." Press any key to
start the scan.
Record in your lab notebook the steps at which the laser hits a target.
After the scan platform has mapped 180 degrees, spun 360 degrees, and completed the next
180 degree scan, you should see the message "data set complete," followed by "press
any key to start scan." Remove the plaques from the scan area and press any key to
start the second scan.
Stop the program after the scan platform has completed two full mappings as previously defined
(with and without plaques).
Cut and Paste your results into a text file. Import this text file (comma delimited) into an Excel
spreadsheet. Add columns translating test values into distances. For both mappings, add
a column named sample difference and have Excel calculate the difference in the average
distance from each measurement (dn - dn-1). Next add a column named mapping difference and
have Excel calculate the difference in the average distance for each sample angle (with and
without plaques). You are welcome to download my Excel spreadsheet and use it as a template
for recording your data.
6.3.1 Documentation
Document your experimental results and subsequent calculations in the subsection named IR
Sensors within the Hardware Build section of your Project Document.
7 Software
7.1 Gyro Calibration Application
7.2 Mapping Software Application
The following program requires utility functions getRange and ReadADC located in the "Utility
Functions" Section of Lab 4.
/*
*
*
*
*
*
*
*
// 10 rpm
Serial.begin(9600);
Serial.println("in setup");
analogReference(EXTERNAL);
motor.release();
makeMap();
}
void loop()
{
}
/*
* Make a Difference Map
*/
void makeMap()
{
int dn = 0;
tweak();
// take 200 measurements and 199 steps (stops at 179.1 degrees clock-wise)
for (int i = 0; i < 200; i = i++) {
dn = readADC(sensorPin);
map_data[i] = pgm_read_word(&range_data[dn]);
// Serial.println(map_data[i]);
// take 200 measurements and 199 steps (stops at 179.1 degrees clock-wise)
for (int i = 0; i < 200; i = i++) {
dn = readADC(sensorPin);
map_data[i] = map_data[i] - pgm_read_word(&range_data[dn]);
Serial.println(map_data[i]);
motor.step(1, FORWARD, INTERLEAVE); // 0.9 degrees/step
delay(60);
// @ 10 rpm, this should take 15 ms + 45 ms margin
}
// rotate counter clock-wise 399 steps (stops at 180 degrees clock-wise)
// 0.9 degrees/step x 399 steps = - 359.1 degrees
motor.step(399, BACKWARD, INTERLEAVE);
delay(10000);
// @ 10 rpm, this should take 6 seconds + 4 second margin
// take 200 measurements and 199 steps (stops at 359.1 degrees clock-wise)
for (int i = 0; i < 200; i = i++) {
dn = readADC(sensorPin);
map_data[i + 200] = map_data[i + 200] - pgm_read_word(&range_data[dn]);
Serial.println(map_data[i + 200]);
motor.step(1, FORWARD, INTERLEAVE); // 0.9 degrees/step
delay(60);
// @ 10 rpm, this should take 15 ms + 45 ms margin
}
// cancel extra step
motor.step(1, BACKWARD, INTERLEAVE);
Serial.println("difference mapping complete");
}
/*
* Terminal adjust of starting angle
* Enter the plus or minus character (+/-) and the number of steps (n = 1 to 9).
*/
void tweak(){
char ch;
// used by tweak
Serial.println("enter +n, -n, or go where n = 1-9 steps and go = start scan");
while(1)
{
while (Serial.available() <= 1) {}
// do nothing
// send data only when you receive data:
if (Serial.available() > 1) {
// read the incoming byte:
ch = Serial.read();
// Serial.println(ch, HEX);
if ( ch == 0x2d ) {
Serial.print("minus ");
ch = Serial.read();
ch = ch - 0x30;
Serial.println(ch, HEX);
// 0.9 degrees/step x 399 steps = - 359.1 degrees
motor.step(ch, BACKWARD, INTERLEAVE);
} else if ( ch == 0x2b ) {
Serial.print("plus ");
ch = Serial.read();
ch = ch - 0x30;
Serial.println(ch, HEX);
motor.step(ch, FORWARD, INTERLEAVE); // 0.9 degrees/step
} else if (ch == 0x67 ) {
ch = Serial.read();
delay(250);
Serial.println("scanning...");
return;
} else {
ch = Serial.read();
Serial.println("unknown entry");
}
}
}
}
7.3
The following program requires utility functions getRange and ReadADC located in the
shared "Utility Functions" Section of this document.
This software program assumes that makeMap has been called and has generated a 400 entry
array.
// 400 entries x 2 bytes/entry = 800 bytes, ATmega328P has 2,048 bytes of
SRAM
// and 1,024 bytes of EEPROM
int map_data[map_length];
If you simply want to test findObjects add the following array declaration.
int map_data[]=
{-8,14,18,7,18,85,147,200,197,174,55,0,-54,1,-14,10,6,-1,4,6,10,36,49,66,58,135,-110,-3,0,10,1,-1,6,2,2,1,18,53,50,45,43,39,25,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,18,17,20,19,16,16,16,9,13,-3,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,-1,0,0,-1,0,0,0,0,-1,0,0,3,0,31,79,97,100,103,111,118,122,131,137,140,34,7,5,-3,-10,14,-9,7,9,15,0,0,0,0,0,0,0,0,0,0,0,17,42,52,-10,15,25,3,46,12,87,179,224,288,76,108,125,32,0,-1,-7,-12,0,7,-9,-5,0,-11,12,-10,-3,4,1,-2,-14,6,2,12,30,40,-27,5,23,-19,6,5,-15,-46,-17,-97,23,93,32,101,21,3,0,0,0,0,0,0,0,-4,-1,3,29,52,-2,-13,0,83,0,0,0,-2,0,0,0,12,94,-143,-309,-71,-69,-27,37,139,265,148,4,77,197,0,1,0,264,72,0,77,135,243,0,15,11,16,2,-242,320,-205,1,5,8,10,0,-1,-1,0,0,-8,15,9,0,-16,-292,-125,-239,-8,-11,2,0,0,-1,0,40,0,0,-1,82,0,76,206,4,0,2,9,0,0,-2,4,0,-9,6,4,4,-4,1,0,0,0,0,0,0,0,0,0,0,0,0,-20,0,6,2,1,1,0,-7,2,0,1,1,-5,-2,-1,10,14,6,-2,12,7,5,-4,1,1,-16,14,16,0,0,15,8,0,-7,21,0,0,2,0,0,0,0,0,0,0,1,2,-1};
// if the difference is greater than (15), and we're not already recording,
// then start recording plaque length
if((map_data[i]>=sensitivity)&!plaqueDetected){
beginning = i;
// The previous gap count could be moved in code for different effects.
// It is placed here so that it counts the total length of gaps in a
// signal as opposed to any individual gap in a signal ie: for a
// tolerance of 2 10101011 won't pass.
gapCounter = 0;
plaqueDetected=true;
}
if((map_data[i]<sensitivity)&plaqueDetected){
gapCounter++;
// if the value falls below (15) dont count
ending = i - gapCounter;
// the extra gap in the ending of the plaque
if(gapCounter > gapTolerance) {
// only stop after the gap has exceeded
plaqueDetected=false;
// the tolerance
if(ending-beginning >= minWidth){ // if plaque was wide enough count it
p_angle[p_Idx]= (ending + beginning)/2; // save the angle as the
//Serial.print(p_Idx);
// midpoint of the beginning and
end
//Serial.print(": ");
//Serial.println(p_angle[p_Idx]);
p_Idx++;
// move to the next array location
}
}
}
}
verify(p_Idx);
}
// else gapCounter=0; // place the reset to gapCounter here if you'd like
// to clear it after the end of every gap
7.4
// 12 *2 = 24 bytes
7.4.2
Subroutine verify()
7.5.2
Function arcSine()
/*
* Find offset angle (in interleave steps) based on distance-to-target
* ref: http://www.nongnu.org/avr-libc/user-manual/
group__avr__math.html#g98384ad60834911ec93ac5ae1af4cf0a
* asin argument must be between -1 and 1, returned value is between
* -pi and pi (-90 and 90 degrees)
*
* INPUT
* Data
Argument
Description
* Type
Units
* double a_opp
cm
opposide side of a right triangle
*
(typically offset distance)
* double a_hyp
cm
hypotenuse of a right triangle
*
(typically dstance measured by ir ranger)
*
* OUTPUT
* returns angle
steptype
*
* note: if steptype is INTERLEAVE then a step is (0.9 degrees/step),
*
otherwise SINGLE is assumed (1.8 degrees/step).
*/
int arcSine(double a_opp, double a_hyp){
double d_x;
float d_angle;
d_x = a_opp/a_hyp;
if (-1 > d_x || d_x > 1) {
// domain error
digitalWrite(ledPin, HIGH);
Serial.print("domain error x = ");
Serial.println(d_x);
return(-1);
}
d_angle = asin(d_x)/radians_step; // calculate angle in degrees
return int(d_angle);
// convert to steps
7.6
EEPROM Functions
EEPROM.write(address, value)
Parameters
address: the location to write to, starting from 0 (int)
value: the value to write, from 0 to 255 (byte)
Example
#include <EEPROM.h>
void setup()
{
for (int i = 0; i < 512; i++)
EEPROM.write(i, i);
}
void loop()
{
}
EEPROM.read(address)
Parameters
address: the location to read from, starting from 0 (int)
Returns
the value stored in that location (byte)
Example
#include <EEPROM.h>
int a = 0;
int value;
void setup()
{
Serial.begin(9600);
}
void loop()
{
value = EEPROM.read(a);
Serial.print(a);
Serial.print("\t");
Serial.print(value);
Serial.println();
a = a + 1;
if (a == 512)
a = 0;
delay(500);
}