#### Equip your Genius

Welcome to the Parallax Discussion Forums, sign-up to participate.

# Boe-Bot + Ping))) Rangefinder - Scan for and Go to Closest Object

Posts: 1,737
edited August 2013 in Learn
Scan For and Go To Closest Object
·
In Ping)))Dar – A Radar Style Display, we used the debug terminal to get an idea of what objects look like when the Boe-Bot scans them with the Ping))) Ultrasonic Rangefinder and Mounting Bracket kits. In this activity, we'll use the same setup along with a program that makes the Boe-Bot scan a field of objects and go to the closest one. Figure 1 shows the Boe-Bot's “scan and go to” sequence as it runs GotoClosestObject.bs2. Here's what it does:
·
······· (The Boe-Bot pauses for 2 seconds after the RESET button on the Board of Education is pressed and released.
······· The Boe-Bot directs the Ping))) Ultrasonic Rangefinder to the right (0°).
······· It scans from right to left (180°) while taking successive distance measurements and saving the angle and distance of the closest measurement it found.
······· The Boe-Bot then points the Ping))) rangefinder in the direction of its closest measurement.
······· The Ping))) is then swept to the right in smaller increments until the object's right edge is detected.
······· The Ping))) is swept to the left (in the same small increments) until the object's left edge is detected.
······· The Boe-Bot calculates the middle of the object and turns in place to face it.
······· The Boe-Bot goes to the object.

View Video Introduction (YouTube)

Download Source Code – Scan For and Go To Closest Object
·
Figure 1 - Finding the Angle that Points Toward the Middle of the Object

Getting Started

This project contains advanced topics, not intended for Boe-Bot beginners.· Before continuing, it is highly recommended you complete the following tasks in order to gain a better understanding on how this application works:
·
······· Complete all activities in What’s a Microcontroller
······· Complete at minimum Chapters 1-4 in Robotics with the Boe-Bot
······· Complete at minimum Chapters 1-3 in Smart Sensors and Applications
······· Download the product documentation and assembly instructions for the PING))) Bracket Kit
······· Complete the Ping)))Dar – A Radar Style Display forum post

Parts Required

(1) Fully assembled and tested Boe-Bot® Robot
(1) Ping))) Ultrasonic Rangefinder
(1) Ping))) Mounting Bracket Kit

Finding, Facing, and Going to the Closest Object

·
Finding the closest object is pretty simple. Start by initializing a word variable, named minDist in GotoClosestObject.bs2, to 65536. Then, repeatedly take distance measurements with the Ping))) rangefinder while sweeping the mounting bracket servo from right to left. Each time the current distance measurement is less than minDist, copy the current distance measurement to minDist, and also copy pingDir, which is the mounting bracket servo control pulse duration to a variable named markDir. When the sweep is done, minDist will store the closest distance, but more importantly, markDir will store the pulse duration that made the mounting bracket servo point the rangefinder at the closest object. As we saw in the previous activity, once the pulse duration to the mounting bracket servo is known, the angle the mounting bracket servo has pointed the rangefinder to can be calculated.

Single_Sweep:
·
· DO UNTIL pingDir >= LimitLeft
··· GOSUB Sweep_Increment
··· GOSUB Get_Ping_Cm
··· IF distance < minDist THEN
····· minDist = distance
····· markDir = pingDir
··· ENDIF
··LOOP
·
· RETURN
·
A quick sweep with fairly large servo increments may not be enough for a heading toward the middle of the closest object. Next, GotoClosestObject.bs2 points the rangefinder in the direction where it took its closest measurement. Then, it scans to the·right until the measured distance is more than 10 cm beyond than the closest distance measurement shown in Figure 3 (a). After that, it scans to the left until the measured distance is 10 cm beyond the closest distance shown in Figure 3 (b). The program marks both these servo pulse durations, and calculates the average of the two. This gives the Boe-Bot's BASIC Stamp a pulse duration to make the mounting bracket servo point the rangefinder to the object about half way between the two edges as shown in Figure 3 (c).
·
Figure 3 - Finding the Angle that Points Toward the Middle of the Object

Although the Ping))) Mounting Bracket servo is now pointing the Ping))) Ultrasonic Rangefinder directly at the object, it's not the right angle to help the Boe-Bot turn to face the object. Figure 4 shows why. Notice that θ1ping-object) is much less than θ2Boe-Bot-object). So, before facing the object, the program has to figure out what θ2 is given θ1 and the object's distance (d), which is (d··θ1) in polar coordinates.

Figure 4 - PULSOUT Duration Argument vs. Rotation Angle

Ping)))Dar.bs2 demonstrated how to make polar to Cartesian coordinate conversions using x = d cos(θ[noparse];)[/noparse] and y = d sin(θ[noparse];)[/noparse]. Assuming the Boe-Bot's continuous rotation servos are mounted so that their output shafts are toward the back of the Boe-Bot, the offset between the front of the Ping))) rangefinder and the Boe-Bot's axis is about 7 cm. If they are mounted with their output shafts toward the front of the Boe-Bot, the offset is more like 5 cm. Assuming 7 cm, after the program calculates the x and y centimeter distances, all it has to do is add 7 cm to the y distance, and those are the x and y distances for θ2. Then, θ2Boe-Bot-Object) can be calculated using the inverse tangent of the (y + 7 cm) ÷ x distances.

Once the program has figured out θ2, all it has to do to is face the object and make the continuous rotation servos cause the Boe-Bot to turn in place for that number of binary radians. One of the calibration programs in this activity involves figuring out the continuous rotation servo PULSOUT Duration arguments that will make the Boe-Bot turn 128 brads (180°) with 128 pulses. The constants that are determined will then be used in GotoClosestObject.bs2 to give the Boe-Bot turn-in-place control in terms of brads.

Software Continuous Rotation Servo Calibration

In Ping)))Dar, you adjusted the Ping))) Mounting Bracket servo's hardware to make sure it points straight forward when it receives PULSOUT 14, 750 signals. You also adjusted LimitLeft and LimitRight CON directives to make sure the mounting bracket servo scanned the Ping))) rangefinder across a 180° field in front of the Boe-Bot. There are two more sets of CON directives that have to be updated, and they will be used in PULSOUT commands that control the continuous rotation servos that turn the Boe-Bot's wheels. These CON directives are FwdLeftFast, FwdRightFast, RotateLeft, and RotateRight. FwdLeftFast and FwdRightFast are used in PULSOUT commands to make the Boe-Bot drive forward at top speed. They have to be adjusted so that they make the Boe-Bot roll straight forward (instead of a curved path that's mostly forward) to make sure the Boe-Bot can roll straight to the object. RotateLeft and RotateRight have to be adjusted so that they make the Boe-Bot turn 180° (128 brads) when 128 pulses are delivered. This adjustment will make it possible for GotoClosestObject.bs2 to turn the Boe-Bot to the correct angle so that it faces the closest object before driving up to it.

CON Directives for Adjusting Boe-Bot Maneuvers

Below are the two PULSOUT commands along with the PAUSE command to send signals to the Boe-Bot's continuous rotation servos that make them turn full speed forward. The number of times a loop repeats these signals dictates how long the servos will turn full speed forward. The speed at which each servo turns is controlled by the PULSOUT commands' Duration arguments, which are 850 and 650 in the example. Since one servo typically turns a little faster than the other at full speed, the 850 or 650 values have to be adjusted to equalize the speeds the wheels turn.

PULSOUT 13, 850

PULSOUT 12, 650
PAUSE 20
The CON directives below make these values adjustable, which is especially useful when they are used more than one place in the program. All you have to do is change a CON directive, and any PULSOUT command that uses the name for Duration argument will automatically be updated. For example, if you change the value of the FwdLeftFast CON directive from 850 to 820, the command PULSOUT BotServoLeft, FwdFastLeft will be changed from PULSOUT 13, 850 to PULSOUT 13, 820. The net effect will be that the left wheel will rotate slower when the program runs.

BotServoLeft ·PIN 13 ··················· ' Boe-Bot servo pins

BotServoRight PIN 12
.
.
.
Center ·······CON 750 ·················· ' Center servo pulse width
FwdLeftFast ··CON 850 ·················· ' Fast settings - straight ahead
FwdRightFast ·CON 650
RotateRight ··CON 758 ·················· ' Boe-Bot rotate right pulse
RotateLeft ···CON 729 ·················· ' Boe-Bot rotate left pulse
.
.
.
· PULSOUT BotServoLeft, RotateRight
· PULSOUT BotServoRight, RotateRight
· PAUSE 20
.
.
.
· PULSOUT BotServoLeft, FwdLeftFast
· PULSOUT BotServoRight, FwdRightFast
· PAUSE 20
.
.
.

Example Program − CalibrateStraightForward.bs2

In this calibration task, you have to observe the Boe-Bot's forward travel and determine if it is tending to curve to either the left or right. Then, adjust the FwdLeftFast or FwdRightFast CON directives to correct any tendency toward traveling in a curve. To make the correction, adjust the CON directive for the faster wheel to make its speed equal to that of the slower wheel.

·
······· Run CalibrateStraightForward.bs2 and watch the Boe-Bot as it travels forward. Does it curve to the left, or right, or is its travel almost perfectly straight?
······· If the Boe-Bot already goes in a straight line (almost no curving whatsoever), skip to the next section: Example Program - Calibrate180DegreeTurns.bs2.
······· If the Boe-Bot curves to the left, the right wheel is going too fast. Try running the program with FwdRightFast set to 660. Still curving left? Try 670 to make it slower still. Still curving left? Try 680. Keep bringing the FwdRightFast value closer to 750 and running and testing the program until it either makes the Boe-Bot travel in a straight line, or it starts curving to the right instead. If the Boe-Bot starts to curve to the right, try a value between the current and previous FwdRightFast settings. Fine tune the value until it makes the Boe-Bot go in the straightest path possible.
······· If the Boe-Bot curves to the right, the left wheel is going too fast. Try running the program with FwdLeftFast set to 840. Still curving right? Try 830 to make it slower still. Still curving right? Try 820. Keep bringing the FwdLeftFast value closer to 750 and running and testing the program until it either makes the Boe-Bot travel in a straight line, or it starts curving to the left instead. If the Boe-Bot starts to curve to the left, try a value between the current and previous FwdLeftFast settings. Fine tune the value until it makes the Boe-Bot go in the straightest path possible.
······· Save your modified program and make a note of your FwdLeftFast and FwdRightFast CON directives so that you can update them in the upcoming navigation program, GotoClosestObject.bs2.

```[color=#008000]' Smart Sensors and Applications - CalibrateStraightForward.bs2[/color]

[color=#008000]' {\$STAMP BS2}[/color]
[color=#008000]' {\$PBASIC 2.5}[/color]

[color=#000000]BoeBotServoL PIN 13[/color]
[color=#000000]BoeBotServoR PIN 12[/color]

[color=#008000]' Adjust these constants until the Boe-Bot goes full speed forward[/color]
[color=#008000]' in a straight line.[/color]

[color=#000000]FwdLeftFast CON 850[/color]
[color=#000000]FwdRightFast CON 650[/color]

[color=#000000]counter VAR Byte[/color]

[color=#020FC0]FOR[/color][color=#000000] counter = 0 [/color][color=#020FC0]TO[/color][color=#000000] 250[/color]
[color=#020FC0]  PULSOUT[/color][color=#000000] BoeBotServoL, FwdLeftFast[/color]
[color=#020FC0]  PULSOUT[/color][color=#000000] BoeBotServoR, FwdRightFast[/color]
[color=#020FC0]  PAUSE[/color][color=#000000] 20[/color]
[color=#020FC0]NEXT[/color]

[color=#020FC0]END[/color]

```

Example Program − Calibrate180DegreeTurns.bs2

This calibration task involves adjusting CON directives for PULSOUT command Duration arguments that will make the Boe-Bot rotate 128 brads (180°) when 128 pulses are sent to its continuous rotation drive servos. These constants will likely be different for left and right rotation, so Calibrate180DegreeTurns.bs2 has separate RotateRight and RotateLeft CON directives. By adjusting the values of the RotateRight and RotateLeft CON directives, you will adjust how far the Boe-Bot rotates left and right when it receives 128 pulses. The goal again is to adjust the constants until the program makes the Boe-Bot execute a 180° right turn that's as close to perfect as you can get it, followed by an equally perfect 180° left turn.

······· Open and run Calibrate180DegreeTurns.bs2 and watch how far the Boe-Bot turns to the left and then to the right. The calibration goal is for it to turn 180° to the right, then 180° to the left.
······· If the Boe-Bot turns more than 180° to the right, reduce the value of the RotateRight CON directive, and re-run the program. If it turns less than 180° to the right, increase the RotateRight CON directive. Repeat until you have tuned it to turn 180° to the right.
······· For tuning left rotation, if the Boe-Bot turns too far, increase the RotateLeft CON directive, or if it doesn't turn far enough, decrease the RotateLeft CON directive.
······· Keep adjusting the RotateRight and RotateLeft CON directives until your Boe-Bot executes perfect (or at least really good) 180° left and right turns.
······· Save your modified program, and be prepared to use those values when you update the constants in GoToClosestObject.bs2.

```[color=#008000]' Smart Sensors and Applications - Calibrate180DegreeTurns.bs2[/color]

[color=#008000]' {\$STAMP BS2}[/color]
[color=#008000]' {\$PBASIC 2.5}[/color]

[color=#000000]BotServoLeft  PIN 13                                                 [/color][color=#008000]' Left drive servo[/color]
[color=#000000]BotServoRight PIN 12                                                 [/color][color=#008000]' Right drive servo[/color]

[color=#000000]RotateRight   CON 765                                               [/color][color=#008000]' Boe-Bot rotate right pulse[/color]
[color=#000000]RotateLeft    CON 735                                               [/color][color=#008000]' Boe-Bot rotate left pulse[/color]

[color=#000000]counter VAR Word[/color]

[color=#020FC0]FOR[/color][color=#000000] counter = 1 [/color][color=#020FC0]TO[/color][color=#000000] 128[/color]
[color=#020FC0]  PULSOUT[/color][color=#000000] BotServoLeft, RotateRight[/color]
[color=#020FC0]  PULSOUT[/color][color=#000000] BotServoRight, RotateRight[/color]
[color=#020FC0]  PAUSE[/color][color=#000000] 20[/color]
[color=#020FC0]NEXT[/color]

[color=#020FC0]FOR[/color][color=#000000] counter = 127 [/color][color=#020FC0]TO[/color][color=#000000] 0[/color]
[color=#020FC0]  PULSOUT[/color][color=#000000] BotServoLeft, RotateLeft[/color]
[color=#020FC0]  PULSOUT[/color][color=#000000] BotServoRight, RotateLeft[/color]
[color=#020FC0]  PAUSE[/color][color=#000000] 20[/color]
[color=#020FC0]NEXT[/color]

[color=#020FC0]END[/color]

```

Going to the Closest Object

Once GotoClosestObject.bs2's CON directives that control the Boe-Bot's servos are updated, it should perform a respectable demo for objects 1 meter away or less. It also has code that deals with the anomalies you experimented with in the Ping)))Dar such as when two objects are so close together that they look like one object in the Ping)))Dar Debug Terminal display. In addition, GoToClosestObject.bs2 has code that can figure out if the closest object is slightly outside its field of detection to the left or right, and it can adjust the Boe-Bot's position and re-scan the object before going straight to it.

Example Program − GoToClosestObject.bs2

As you went through this and Ping)))Dar, you used TestPingDirection.bs2, CalibrateStraightForward.bs2, and Calibrate180DegreeTurns.bs2 to determine values for the calibration constants listed below. GoToClosestObject.bs2 relies on these eight constants to scan a field of objects, determine which one is closest, and accurately turn to face and go to the object. The calibration results for these CON directives have to be updated GotoClosestObject.bs2 before you run it.
········· LimitLeft
········· LimitRight
········· PingDirToAngle
········· ForwardLeftFast
········· ForwardRightFast
········· RotateRight
········· RotateLeft
·
······· IMPORTANT: Make sure to update GoToClosestObject.bs2's CON directives for the eight names listed above with the values you determined as you went through this and the previous activity.
······· Measure the distance from the front of the Ping))) rangefinder to the center of the Boe-Bot's turning axis. It should either be 7 cm or around 5 cm. If it's 5 cm, update the PingAxleOffset CON directive accordingly.
······· Save and run your modified version of GoToClosestObject.bs2.
······· Start by testing it with a single, cylindrical object 1 ft (30 cm) away from the Boe-Bot at various angles, such as 60°, 90°, and 120°.
······· In each case, the Boe-Bot should be able to scan its surroundings, find the object, and go straight to it. If it doesn't succeed, revisit the various calibration instructions in this and the previous activity. Then, use the values you collected, and update the CON directives in GoToClosestObject.bs2 and try again.
······· When the Boe-Bot can reliably go to one object that's 1 ft (30 cm) away, try a variety of other angles and distances. How far out can the Boe-Bot detect and go to an object?
······· Try 1 object 1 ft (30 cm) away from the Boe-Bot at 120° and the other one 2 ft (60 cm) away from the Boe-Bot at 60°. The Boe-Bot should go straight to the one at 120°. Swap the distances and try again; the Boe-Bot should go to the one at 60°.
······· Try two objects 1 ft (30 cm) apart and 1.5 ft (45 cm) from the front of the Boe-Bot. The Boe-Bot will initially think it sees a single object and attempt to go between the two cylinders. As it gets closer, it should detect the gap between them and choose the one it's closest to.
······· Try one object one ft (30 cm) away at 0° and the other object 2 ft (60 cm) away at 180 degrees. The Boe-Bot should discover that the right edge of the object at 0° is outside its field of detection. So it should rotate and re-scan the object, and then go directly to it.

```[color=#020FC0][color=#008000]' -----[noparse][[/noparse] Title ]--------------------------------------------------------------[/color]
[color=#008000]' Smart Sensors and Applications - GoToClosestObject.bs2[/color]
[color=#008000]' Sweep Ping))) Ultrasonic Rangefinder across 180-degrees and find the closest[/color]
[color=#008000]' object.  Then calculate and execute the turn required to face the object.[/color]
[color=#008000]' Travel forward until the object is less than or equal to 5 cm from the front[/color]
[color=#008000]' of the rangefinder.[/color]

[color=#008000]' IMPORTANT: This program has several constants that have to be tuned before[/color]
[color=#008000]'            it will work right.  Follow the instructions in Smart Sensors[/color]
[color=#008000]'            and Applications, Chapter 8, Activity #4 and #5 before you run[/color]
[color=#008000]'            this program![/color]

[color=#008000]' {\$STAMP BS2}                               ' Target device = BASIC Stamp 2[/color]
[color=#008000]' {\$PBASIC 2.5}                              ' Language = PBASIC 2.5[/color]

[color=#008000]' -----[noparse][[/noparse] I/O Definitions ]----------------------------------------------------[/color]

[color=#008000]' Ping))) Ultrasonc Rangefinder and Mounting Bracket[/color]
[color=#000000]PingServo      PIN     14[/color]                    [color=#008000]' Servo that directs Ping))) snsr[/color]
[color=#000000]Ping           PIN     15[/color]                    [color=#008000]' Ping))) sensor signal pin[/color]

[color=#008000]' Boe-Bot servo pins (Left and right are from driver's seat perspective.)[/color]
[color=#000000]BotServoLeft   PIN     13[/color]                    [color=#008000]' Left drive servo[/color]
[color=#000000]BotServoRight  PIN     12[/color]                    [color=#008000]' Right drive servo[/color]

[color=#008000]' -----[noparse][[/noparse] Constants ]----------------------------------------------------------[/color]

[color=#008000]' Ping))) mounting bracket constants[/color]
[color=#000000]LimitLeft      CON     1250[/color] [color=#008000]' Bracket 90-degrees Left[/color]
[color=#000000]LimitRight     CON     250[/color]                  [color=#008000]' Bracket 90-degrees Right[/color]
[color=#000000]Center         CON     750[/color]        [color=#008000]' Center/0-degree pulse duration[/color]
[color=#000000]Increment      CON     15[/color]         [color=#008000]' Increment for pulse sweeping[/color]
[color=#000000]MinSweep       CON     40[/color]         [color=#008000]' Pulses -> 90-degree right[/color]

[color=#008000]' Boe-Bot continuous rotation servo control constants[/color]
[color=#000000]FwdLeftFast    CON     850[/color]                  [color=#008000]' Fast settings - straight ahead[/color]
[color=#000000]FwdRightFast   CON     650[/color]
[color=#000000]RotateRight    CON     765[/color]                  [color=#008000]' Boe-Bot rotate right pulse[/color]
[color=#000000]RotateLeft     CON     735[/color]                  [color=#008000]' Boe-Bot rotate left pulse[/color]
[color=#000000]BtwnPulses     CON     20[/color]                    [color=#008000]' ms between servo pulses[/color]

[color=#008000]' Ping))) Ultrasonic Rangefinder constants[/color]
[color=#000000]CmConstant     CON     2260[/color]       [color=#008000]' Echo time -> cm with **[/color]
[color=#000000]SinCosTo256    CON[/color]             [color=#000000]517[/color]       [color=#008000]' For */ -127..127 -> -256..256[/color]
[color=#000000]Ms20           CON[/color]             [color=#000000]330[/color]       [color=#008000]' 20 ms worth of cm[/color]

[color=#008000]' MSB sign (twos complement)[/color]
[color=#000000]Negative       CON[/color]     [color=#000000]1[/color]          [color=#008000]' Negative sign (bit-15)[/color]
[color=#000000]Positive[/color]                 [color=#000000]CON[/color]     [color=#000000]0[/color]       [color=#008000]' Positive sign (bit-15)[/color]

[color=#008000]' Ping and turning axis geometry[/color]
[color=#000000]PingDirToAngle[/color] [color=#000000]CON[/color]     [color=#000000]8454[/color]       [color=#008000]' Servo pulse to angle ** con[/color]
[color=#000000]PingAxleOffset[/color] [color=#000000]CON[/color]     [color=#000000]7[/color]          [color=#008000]' 7 cm between ping))) and axis[/color]

[color=#008000]' -----[noparse][[/noparse] Variables ]----------------------------------------------------------[/color]

[color=#000000]time           VAR     Word [/color][color=#008000]' Ping))) echo time[/color]
[color=#000000]pingDir        VAR     Word [/color][color=#008000]' Pulse duration -> direction[/color]
[color=#000000]x              VAR     Word [/color][color=#008000]' x coordinate[/color]
[color=#000000]y              VAR     Word [/color][color=#008000]' y coordinate[/color]
[color=#000000]distance       VAR     Time [/color][color=#008000]' Object centimeter distance[/color]
[color=#000000]markDir        VAR     y          [/color][color=#008000]' Pulse points to closest object[/color]
[color=#000000]rightMark      VAR     x          [/color][color=#008000]' Pulse to object's right side[/color]
[color=#000000]leftMark       VAR     pingDir    [/color][color=#008000]' Pulse to object's left side[/color]
[color=#000000]pulses         VAR     x          [/color][color=#008000]' +/- brads to turn toward object[/color]
[color=#000000]PrevDist       VAR     Byte [/color][color=#008000]' Previous distance measurement[/color]
[color=#000000]angle          VAR     Byte [/color][color=#008000]' Servo angle from right in brads[/color]
[color=#000000]counter        VAR     angle      [/color][color=#008000]' Loop counter[/color]
[color=#000000]minDist        VAR     angle      [/color][color=#008000]' Minimum distance measurement[/color]
[color=#000000]sweepInc       VAR     Nib        [/color][color=#008000]' Increment for servo sweep[/color]
[color=#000000]sweepDir       VAR     Bit        [/color][color=#008000]' Increment/decrement pingDir[/color]
[color=#000000]xSign          VAR     Bit        [/color][color=#008000]' Stores sign of x variable[/color]
[color=#000000]ySign          VAR     xSign      [/color][color=#008000]' Stores sign of x variable[/color]
[color=#000000]pSign          VAR     Bit        [/color][color=#008000]' Sign of pulses variable[/color]
[color=#000000]edgesFound     VAR     Bit        [/color][color=#008000]' Navigation flag[/color]

[color=#008000]' -----[noparse][[/noparse] Initialization ]-----------------------------------------------------[/color]

PAUSE[color=#000000] 2000[/color]                                             [color=#008000]' Delay program start by 2 s.[/color]

[color=#008000]' -----[noparse][[/noparse] Main Routine ]-------------------------------------------------------[/color]

GOSUB[color=#000000] Get_Ping_Cm                            [/color][color=#008000]' First distance measurement[/color]

DO UNTIL[color=#000000] distance <= 5                       [/color][color=#008000]' Repeat until distance <= 5 cm[/color]

[color=#000000]  edgesFound = 0                             [/color][color=#008000]' Clear edges found flag[/color]

DO UNTIL[color=#000000] edgesFound = 1                    [/color][color=#008000]' Repeat until edges found = 1[/color]
GOSUB[color=#000000] Face_Closest_Object                [/color][color=#008000]' Find & face closest object[/color]
LOOP

GOSUB[color=#000000] Get_Ping_Cm                          [/color][color=#008000]' Get current distance[/color]

DO UNTIL[color=#000000] distance <= 5                     [/color][color=#008000]' Drive toward object[/color]
[color=#000000]    prevDist = distance MAX 255              [/color][color=#008000]' Current distance -> previous[/color]
GOSUB[color=#000000] Get_Ping_Cm                        [/color][color=#008000]' Get new distance[/color]
PULSOUT[color=#000000] BotServoLeft, FwdLeftFast        [/color][color=#008000]' Boe-Bot forward[/color]
PULSOUT[color=#000000] BotServoRight, FwdRightFast[/color]
PAUSE[color=#000000] BtwnPulses - (distance / Ms20)     [/color][color=#008000]' 20 ms pause between pulses[/color]
IF[color=#000000] distance >= prevDist + 5 [/color]THEN EXIT    [color=#008000]' Exit if distance increasing[/color]
LOOP

LOOP                                         [color=#008000]' Main routine's outermost loop[/color]

END

[color=#008000]' -----[noparse][[/noparse] Subroutines - BoeBot_Turn_Brads ]-----------------------------------[/color]

[color=#008000]' Boe-Bot turns a certain number of binary radians to face an object.[/color]

[color=#000000]BoeBot_Turn_Brads:[/color]

IF[color=#000000] pSign = Positive [/color]THEN
FOR[color=#000000] counter = 0 TO ABS(pulses)[/color]
PULSOUT[color=#000000] BotServoLeft, RotateRight[/color]
PULSOUT[color=#000000] BotServoRight, RotateRight[/color]
PAUSE[color=#000000] BtwnPulses - (distance / Ms20)[/color]
NEXT
ELSE
FOR[color=#000000] counter = 0 TO ABS(pulses)[/color]
PULSOUT[color=#000000] BotServoLeft, RotateLeft[/color]
PULSOUT[color=#000000] BotServoRight, RotateLeft[/color]
PAUSE[color=#000000] BtwnPulses - (distance / Ms20)[/color]
NEXT
ENDIF

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutines - Face_Closest_Object ]----------------------------------[/color]

[color=#008000]' Scan for closest object using a Ping))) rangefinder mounted on a standard[/color]
[color=#008000]' servo.  Locate the middle fo the object, and turn Boe-Bot to face it.[/color]

[color=#000000]Face_Closest_Object:[/color]

[color=#008000]  ' Initialize sweep increment.[/color]
[color=#000000]  sweepInc = Increment[/color]

[color=#008000]  ' Start Servo rotated to the far right.[/color]
[color=#000000]  pingDir = LimitRight[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]

[color=#008000]  ' Make minDist large and sweepDir positive (0).  Single_Sweep sweeps[/color]
[color=#008000]  ' left -> right while measuring object distances and stores the direction[/color]
[color=#008000]  ' of the closest object in markDir.[/color]
[color=#000000]  minDist = 65535[/color]
[color=#000000]  sweepDir = Positive[/color]
GOSUB[color=#000000] Single_Sweep[/color]

[color=#008000]  ' Point the servo in the direction of the closest distance measurement.[/color]
[color=#000000]  pingDir = markDir[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]

[color=#008000]  ' Scan to find object's right side.[/color]
GOSUB[color=#000000] Find_Right_Side[/color]
IF[color=#000000] edgesFound = 0 [/color]THEN RETURN

[color=#008000]  ' Point the servo in the direction of the closest distance measurement.[/color]
[color=#000000]  pingDir = markDir[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]

[color=#008000]  ' Scan to find object's right side.[/color]
GOSUB[color=#000000] Find_Left_Side[/color]
IF[color=#000000] edgesFound = 0 [/color]THEN RETURN

[color=#008000]  ' Average the angles to the object's left and right sides.  That's the[/color]
[color=#008000]  ' middle of the object.  Point rangefinder in that direction.[/color]
[color=#000000]  pingDir = leftMark + rightMark / 2[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]

[color=#008000]  ' At this point, the Ping))) should be pointing directly at the closest[/color]
[color=#008000]  ' object.[/color]

[color=#008000]  ' Calculate the angle to the object's angle in brads, and turn the[/color]
[color=#008000]  ' Boe-Bot to face that angle.[/color]
GOSUB[color=#000000] Turn_Angle_Adjust[/color]
GOSUB[color=#000000] BoeBot_Turn_Brads[/color]

[color=#008000]  ' Face Ping))) rangefinder straight ahead.[/color]
[color=#000000]  pingDir = Center[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutines - Find_Left_Side ]---------------------------------------[/color]

[color=#008000]' Scan left until the measured distance is 10 cm beyond the closest distance,[/color]
[color=#008000]' which is assumed to mean the object's side has been found.[/color]

[color=#008000]' If the object's side has been found within the 180-degree field of vision,[/color]
[color=#008000]' set edgesFound = 1 and store the pulse duration (pingDir) at which the[/color]
[color=#008000]' object was found in the leftMark variable.[/color]

[color=#008000]' If the side was not found by the 180-degree point in the scan, rotate the[/color]
[color=#008000]' Boe-Bot until the edge is found, and then set edgesFound to 0 signifying[/color]
[color=#008000]' that the scan will have to be repeated because the Boe-Bot rotated[/color]
[color=#008000]' to find the side, which would otherwise cause the markDir variable to[/color]
[color=#008000]' store an incorrect value.[/color]

[color=#000000]Find_Left_Side:[/color]

[color=#000000]  sweepDir  = Positive[/color]
[color=#000000]  distance = minDist[/color]
[color=#000000]  sweepInc = 1[/color]

DO UNTIL[color=#000000] distance > minDist + 10[/color]
GOSUB[color=#000000] Sweep_Increment[/color]
GOSUB[color=#000000] Get_Ping_Cm[/color]
IF[color=#000000] pingDir >= LimitLeft - 10 [/color]THEN
[color=#000000]      pingDir = LimitLeft - 50[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]
DO UNTIL[color=#000000] distance > minDist + 10[/color]
PULSOUT[color=#000000] BotServoLeft, RotateLeft[/color]
PULSOUT[color=#000000] BotServoRight, RotateLeft[/color]
GOSUB[color=#000000] Get_Ping_Cm[/color]
PAUSE[color=#000000] 20[/color]
LOOP
[color=#000000]      edgesFound = 0[/color]
RETURN
ENDIF
LOOP
[color=#000000]  leftMark = pingDir[/color]
[color=#000000]  edgesFound = 1[/color]
RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutines - Find_Right_Side ]--------------------------------------[/color]

[color=#008000]' Mirror image of Find_Left_Side.[/color]

[color=#000000]Find_Right_Side:[/color]

[color=#000000]  sweepDir  = Negative[/color]
[color=#000000]  distance = minDist[/color]
[color=#000000]  sweepInc = 1[/color]

DO UNTIL[color=#000000] distance > minDist + 10[/color]
GOSUB[color=#000000] Sweep_Increment[/color]
GOSUB[color=#000000] Get_Ping_Cm[/color]
IF[color=#000000] pingDir <= LimitRight + 10 [/color]THEN
[color=#000000]      pingDir = LimitRight + 50[/color]
GOSUB[color=#000000] Point_At_PingDir[/color]
DO UNTIL[color=#000000] distance > minDist + 10[/color]
PULSOUT[color=#000000] BotServoLeft, RotateRight[/color]
PULSOUT[color=#000000] BotServoRight, RotateRight[/color]
GOSUB[color=#000000] Get_Ping_Cm[/color]
PAUSE[color=#000000] 20[/color]
LOOP
[color=#000000]      edgesFound = 0[/color]
RETURN
ENDIF
LOOP
[color=#000000]  rightMark = pingDir[/color]
[color=#000000]  edgesFound = 1[/color]
RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutine - Get_Ping_Cm ]-------------------------------------------[/color]

[color=#008000]' Gets Ping))) rangefinder measurement and converts time to centimeters.[/color]
[color=#008000]' Distance may be declared as time to save variable space.[/color]

[color=#000000]Get_Ping_Cm:[/color]

PULSOUT[color=#000000] Ping, 5[/color]
PULSIN[color=#000000] Ping, 1, time[/color]
[color=#000000]  distance = time ** CmConstant[/color]

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutines - Point_At_PingDir ]-------------------------------------[/color]

[color=#008000]' Points servo mounted Ping))) rangefinder at an angle determined by the[/color]
[color=#008000]' value of the pingDir variable.[/color]

[color=#000000]Point_At_PingDir:[/color]

FOR[color=#000000] counter = 0 [/color]TO[color=#000000] MinSweep[/color]
PULSOUT[color=#000000] PingServo, pingDir[/color]
PAUSE[color=#000000] BtwnPulses[/color]
NEXT

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutine - Polar_To_Cartesian ]------------------------------------[/color]

[color=#008000]' Calculates x and y (Cartesian coordinates) given distance and angle[/color]
[color=#008000]' (polar coordinates).[/color]

[color=#000000]Polar_To_Cartesian:[/color]

[color=#008000]' Calculate left/right component.[/color]
[color=#000000]  x = COS angle                              [/color][color=#008000]' Polar to Cartesian[/color]
[color=#000000]  xSign = x.BIT15                            [/color][color=#008000]' Store sign bit[/color]
[color=#000000]  x = ABS(x) */ SinCOsTo256                  [/color][color=#008000]' Polar to Cartesian continued[/color]
[color=#000000]  x = distance */ x[/color]
IF[color=#000000] xSign = negative [/color]THEN[color=#000000] x = -x            [/color][color=#008000]' Correct sign with sign bit[/color]

[color=#008000]' Calculate straight ahead component.[/color]
[color=#000000]  y = SIN angle                              [/color][color=#008000]' Polar to Cartesian[/color]
[color=#000000]  ySign = y.BIT15                            [/color][color=#008000]' Store sign bit[/color]
[color=#000000]  y = ABS(y) */ SinCOsTo256                  [/color][color=#008000]' Polar to Cartesian continued[/color]
[color=#000000]  y = distance */ y[/color]
[color=#000000]  IF ySign = negative THEN y = -y            [/color][color=#008000]' Correct sign with sign bit[/color]

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutines - Single_Sweep ]-----------------------------------------[/color]

[color=#008000]' Do one sweep, and find the closest distance measurement and the[/color]
[color=#008000]' pulse value that points the servo in that direction.[/color]

[color=#000000]Single_Sweep:[/color]

DO UNTIL[color=#000000] pingDir >= LimitLeft[/color]
GOSUB[color=#000000] Sweep_Increment[/color]
GOSUB[color=#000000] Get_Ping_Cm[/color]
IF[color=#000000] distance < minDist [/color]THEN
[color=#000000]      minDist = distance[/color]
[color=#000000]      markDir = pingDir[/color]
ENDIF
LOOP

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutine - Sweep_Increment ]---------------------------------------[/color]

[color=#008000]' Increment/decrement the position of the servo that directs the Ping)))[/color]
[color=#008000]' rangefinder. When pingDir goes outside either LimitRight or LimitLeft,[/color]
[color=#008000]' the sweep direction toggles.[/color]

[color=#000000]Sweep_Increment:[/color]

[color=#008000]' Change sweepDir for adding/subtracting increment if at rotation limit.[/color]
IF[color=#000000] pingDir <= LimitRight [/color]THEN
[color=#000000]    sweepDir = Positive[/color]
ELSEIF[color=#000000] pingDir >= LimitLeft [/color]THEN
[color=#000000]    sweepDir = Negative[/color]
ENDIF

[color=#008000]  ' Add/subtract increment to/from pingDir.[/color]
IF[color=#000000] sweepDir = negative [/color]THEN
[color=#000000]    pingDir = pingDir - sweepInc[/color]
ELSEIF[color=#000000] sweepDir = Positive [/color]THEN
[color=#000000]    pingDir = pingDir + sweepInc[/color]
ENDIF

[color=#008000]  ' Send positioning pulse to Ping))) Mounting Bracket servo.[/color]
PULSOUT[color=#000000] PingServo, pingDir[/color]

RETURN

[color=#008000]' -----[noparse][[/noparse] Subroutines - Turn_Angle_Adjust ]------------------------------------[/color]

[color=#008000]' Adjusts required turn angle based on 7 mm offset of Ping))) rangefinder from[/color]
[color=#008000]' Boe-Bot's turning axis.[/color]

[color=#000000]Turn_Angle_Adjust:[/color]

[color=#008000]  ' Get the object's distance at its center.[/color]
GOSUB[color=#000000] Get_Ping_Cm[/color]

[color=#008000]  ' Position servo & calculate angle from far-right in brads.[/color]
[color=#000000]  angle = pingDir - 250 ** PingDirToAngle[/color]

GOSUB[color=#000000] Polar_To_Cartesian[/color]

[color=#008000]  ' Add distance between Ping))) and center of Boe-Bot axis.[/color]
[color=#000000]  y = y + PingAxleOffset[/color]

[color=#008000]  ' Recalculate the turning angle with respect to Boe-Bot's turning axis.[/color]
[color=#000000]  angle = x ATN y[/color]
[color=#000000]  pulses = 64 - angle[/color]
[color=#000000]  pSign = pulses.BIT15[/color]

RETURN
[/color]
```

__________________________________________________ ___________________________
··
(c) 2009·by Parallax Inc - all rights reserved.··

Post Edited By Moderator (Jessica Uelmen (Parallax)) : 8/25/2010 6:07:28 PM GMT
Tagged:

## Comments

• 30 Comments sorted by Date Added Votes
• Posts: 1,737
edited June 2006
Post Edited By Moderator (Jessica Uelmen (Parallax)) : 4/13/2009 5:22:03 PM GMT
• Posts: 5,666
edited June 2006
Andy,

Ran this code myself this afternoon. Very impressive! The Pings))) look like eyes and the Boe-Bot looks smarter than ever in this application. It's very "alive" (though not as much as that Linda Blair head that John was making pop out of the 50-gallon drum last week. . .that thing made me run out of the machine shop).

The simplicity is really nice and it the results are very consistent.

Ken Gracey
Parallax, Inc.
• Posts: 1,737
edited June 2006
Thanks Ken!

I'm glad to hear about the repeatability.· There's a lot more calibration here than there is in most of the other Boe-Bot apps.

I discovered a bug yesterday that you may want to keep in mind if you are doing any demos in the near future. For good performance with the current program/hardware, the maximum distance threshold appears to be 50 cm.

If the closest object is further out than that, the Boe-Bot does not correctly swivel the Ping))) rangefinder to locate the object's left and right sides. So keep the closest object within a 50 cm radius, and it should still work really well. I'll post updated code as soon as I fix the bug.

Andy

Post Edited (Andy Lindsay (Parallax)) : 6/7/2006 11:04:09 PM GMT
• Posts: 118
edited June 2006
i have actally been watiting for andy`s new book.btw when will it be realsed
• Posts: 5,666
edited June 2006
Hey Andy,

Am I supposed to know all of the answers because I work at Parallax?

First I'll set the stage. Today I did a 40-minute presentation (six times) for my son's elementary school. I brought the most amazing set of robots from Parallax (lawnmowers, fish robots, hexcrawler, 10 Boe-Bots, a half-dozen Scribblers) and the best robot videos out there (Mars - Spirit, SumoBots, the "RipSaw", the running gas-powered dog thing, etc) and the kids were going nuts over the whole gig. I even threw some rock music over the videos which caused them to jump up and down like monkeys when they saw the Delta rocket launch.·

But that's·just the background·to my question.

Trying to make the "GoToClosestObject" Ping))) demo even more interesting, I thought I'd use a couple of stuffed animals (a big cow and a small purple thing called "Baloo") instead of wooden blocks. Strangely, the ultrasonic sensor had a fair amount of trouble with them. Sometimes it seemed to not see them at all, and other times it would track them and loose them. The small purple one with less soft areas seemed to work better.

I assume that small furry critters absorb the ultrasonic waves, is that the case?

Ken Gracey
Parallax, Inc.

Post Edited (Ken Gracey (Parallax)) : 6/9/2006 3:42:51 AM GMT
• Posts: 3,045
edited June 2006
Ken -

At the base level ultrasonics are nothing more or less than sound. Sound is reflected by "hard" objects, and absorbed by "soft" objects, regardless of the frequency of the sound.

If you have a room which is too noisy, or has echoes, due to its size or configuration, then carpets, drapes and furniture will all help to ameliorate the problem. So too, "softening" the "hard" ceiling with acoustical tile. All are "soft" objects (comparatively speaking) and all will absorb sound.

I'd love to have some Aero-Gel to play with. I'd bet ultrasonics would pass right through it, as though it weren't even there. Aero-Gel is about 99% air! Speaking of SOFT! Any LLNL or NASA folks out there want to give it a shot, and report back?

Regards,

Bruce Bates

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
<!--StartFragment -->

Post Edited (Bruce Bates) : 6/9/2006 7:48:56 AM GMT
• Posts: 1,737
edited June 2006
Ken,

It'll be interesting to see what the stuffed animals' signatures are with Ping)))Dar - a Radar Style Display, especially compared to a soda can or water bottle. Try taking a screen capture of the Ping)))Dar display with a stuffed animal along with a photo, then replace it with a water bottle and take another screen capture and photo.

The demo is designed for use with cylinders, not blocks. I put one of those i-boxes about that on page 342. I also put a !-box about how important calibration is on page 347. If you have any suggestions about how I can more effectively convey those two important points to the reader, I'll certainly do my best to make it so.

Andy
• Posts: 1,737
edited June 2006
Three more notes:

1) So far, I haven't found background noise to be a problem, and I've done this demo in several really noisy environments. Of course, there are a lot of different flavors of noice, and maybe the grade school environment has one that interferes while trade shows do not.

2) If the stuffed animals were placed more than 50 cm from the front of the Boe-Bot, you may have seen that bug I mentioned earlier. Of course, if it worked with the blocks at the same distance in the same environment, that's probably not it. I'm still working on that bug.

3) Aaach! I just remembered, carpet can be a problem, and I didn't include a warning in the PDF. Yes, in many cases, carpet can look like an array of objects within the 180-degree Ping))) rangefinder's field of detection.· Sorry about that...

Post Edited (Andy Lindsay (Parallax)) : 6/9/2006 6:00:47 PM GMT
• Posts: 57
edited August 2006
Andy,

Brilliant series of projects based around sensors! I can't wait for the new SIC book to come out. The Ping))) Rangefinder has helped me to finally get to grips with ultrasonic sensors and I am waiting for my ordered bracket set to arrive so I can try out the newer programs. I echo the comment that others have made - the Ping))) really looks like eyes and, swivelling around on the bracket, it makes the BOE-Bot 'come alive' as·the robot·resembles a small, curious animal. As 'superworms' posted,·I would be interested to know how far off the book's publication is; will there be a complete kit?

I've also ordered the Sensor Collection as these projects really show some practical uses for Basic Stamps and sensors·in control and monitoring·systems.

Keep up the excellent work and posting the chapters for review.

John

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Manxstamp,
Isle of Man, British Isles
• Posts: 2,224
edited September 2006
I was working on a project based on "go to closest object" and since Brads give me headaches sometimes, I made up a PDF protractor (sp?) that shows brads and degrees (I used this for calibrating some servos to x servo pulses = 90 degrees = 64 brads). I didn't label every 5th degree, but otherwise it should be Postscript accurate, and looks pretty decent on an injket printer.

Thanks again, Mr. Lindsay, for the elegant and incredibly explanatory code projects.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
When the going gets weird, the weird turn pro. -- HST

my site: 1uffakind.com
create bitmap data tool: 1uffakind.com/robots/povBitMapBuilder.php
resistor ladder tool: 1uffakind.com/robots/resistorLadder.php
convert images to ascii art: 1uffakind.com/apptoys/convtoascii/
MC6808/Hero-1 assembler: 1uffakind.com/apptoys/onlinecompilers/MC6800/
• Posts: 2,224
edited September 2008
Andy -- I adapted some of the concepts in "Closest Object" so that one of my 'bots can calculate theta, x pos, y pos in cartesian space based on wheel encoder odometry (works great, and I would never have remembered all my trig w/o your great article).

One thing that I took into account in my code, that I do not find in "Closest Object" is checking for x/y values greater than (abs) -127/+127 before using ATN (to derive angle from a target x/y point).

In my own code, I normalize x/y values before doing ATN; "Closest Object" does not. Wouldn't you get bogus values if the closest target found has a distance of greater than 127 cm? I realize on a table top this highly unlikely, and out-of-bounds values don't matter until target heading calculations are performed in your code... but still. Or am I missing something? In my code·I shift x/y right with rounding until both are ABS <= 127, so I get the best resolution -- my inputs are signed Word x/y values in cm).

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST

1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
When the going gets weird, the weird turn pro. -- HST

my site: 1uffakind.com
create bitmap data tool: 1uffakind.com/robots/povBitMapBuilder.php
resistor ladder tool: 1uffakind.com/robots/resistorLadder.php
convert images to ascii art: 1uffakind.com/apptoys/convtoascii/
MC6808/Hero-1 assembler: 1uffakind.com/apptoys/onlinecompilers/MC6800/
• Posts: 4
edited October 2008
does anyone know how i can convert the GO TO CLOSEST OBJECT code so that the boe bot can avoid the closest object when it comes in range of something like 10 cm or 15 cm, and then it will scan the object and the go in the opposite angle of the ping servo so that instead of going left where the closest object is it will go right where an object is further away? Im going to keep playing with the code but let me know if there is some way to make it work.
• Posts: 1,737
edited October 2008
The third to last line of the code is where the number of pulses the Boe-Bot uses to turn is defined.

pulses = 64 - angle

The angle variable should store a value ranging from 0 to 128. If you swap the 64 and the angle, it will turn the same distance in the opposite direction. That should work really well for 30 degrees or more off center. However, if the object is only one brad off center, that could be a problem since the Boe-Bot would turn one brad in the opposite direction. An IF...THEN statement increasing the pulses value if it's close to 64 would fix that problem.

In the Main Routine, you might need to get rid of the UNTIL distance <= 5, and move GoSUB Get_Ping_Cm just below the DO (that used to have UNTIL next to it). This will cause the Boe-Bot to repeat the check the surroundings and navigate loop periodically.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay

Education Department
Parallax, Inc.
• Posts: 124
edited November 2008
I am trying to modify the original program, the one that just acts as a sort of radar.· Ultimatley what i am trying to do is make it so that the second scan is compared to·the the first scan to detect large amounts of motion.· I need to tie this in so i can point an array of sensors in the direction of the motion.· I had thought about having it detect it in sort of quadrants, but i am open to ideas, because I am really stuck.· Any suggestions are great!· Code is even better : )
• Posts: 502
edited November 2008
Dear Andy,

I thank you for the Excellent code.

Post Edited (MovieMaker) : 11/22/2008 4:51:28 AM GMT
• Posts: 502
edited December 2008
I just tried the program and it worked perfect. It is neat!@

Andy, Mike and ALL of the Parallax Gang, Thanks for making this a nice Holiday Season for me by your EXCELLENT Support!

Post Edited (MovieMaker) : 12/25/2008 4:42:08 PM GMT
• Posts: 25
edited January 2009
Hi everybody, new here. Just got the Boe-Bot for Christmas, and I've been having a blast with it. Just yesterday I got the PING+servo/bracket deal for it, and have been trying to understand it better. However, while everything else has been documented greatly, it seems that the servo with PING has not - I was under the impression that it was all to be combined and explained in the Smart Sensors and Applications book, however only the PING sensor itself is explained there. No mention of the servo with PING, etc. While following the source code attached ina couple of threads is fine, I was just wondering if there will be something published that describes it in more detail?

Thanks, and keep up the good work, the series of manuals/books is really what makes this a great learning experience!

Polbit
• Posts: 5,012
edited January 2009
Take a look in "What's a microcontroller" on the free downloads page for more information. I beliive that there's a full chapter on the subject.

In short though, all you need to do (with a regular BS2) is send a PULSOUT on the correct pin with a value between 500 and 1000. Going outside these values can damage your servo. 750 is approximately the center position (for a standard servo), while 1000 and 500 are left and right (maybe not in that order). The second thing you need to do is to refresh this every 20 ms or so.
• Posts: 490
edited March 2009
Hi·all!

Just like Ping)))Dar, we've updated this project to include a brief video introduction/demonstration for your viewing pleasure.· You can check it out on YouTube here.

Happy Developing!

Jessica

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax, Inc.
Allons-y!
--
@jessicauelmen
• Posts: 99
edited April 2009
I am trying to run the "Scan To and Go To Closest Object" program. I have two questions.

First is the program listed somewhere as a file or I to copy and paste from the thread ? It is long to retype and·not have errors.

Second, in this thread listing of the program·it says to complete chapter 8, activity 4 & 5 of the manual on "Smart Sensors and Applications". My manual does not have a chapter 8. What do I do?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
······ Joe Fishback

-Robots are my friends-
• Posts: 2,224
edited April 2009
The second or third at the top of the thread has a .zip file with all programs so you don't have to cut-and-paste.

"Smart Sensors" can be downloaded here: www.parallax.com/tabid/535/Default.aspx

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST

1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
When the going gets weird, the weird turn pro. -- HST

my site: 1uffakind.com
create bitmap data tool: 1uffakind.com/robots/povBitMapBuilder.php
resistor ladder tool: 1uffakind.com/robots/resistorLadder.php
convert images to ascii art: 1uffakind.com/apptoys/convtoascii/
MC6808/Hero-1 assembler: 1uffakind.com/apptoys/onlinecompilers/MC6800/
• Posts: 1
edited March 2010
I searched a lot of websites and forums to search this code.. But finally i got it at your forum... i would like to thank you all for this...

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
DARRELL
• Posts: 10
edited June 2010
For some reason, this program will not run correctly on my Boe-Bot. I've given it my best shot, but I'm stumped on this one. My calibrated code is attached, and assistance is welcome.

Thanks...
• Posts: 1
edited July 2010
Yea, I can't get mine to work as well.
Here's the source code I used.
Here's a pic of what I edited.
Here's a video of what happens.
Do you HAVE to have the "center" at 750? (mine is at 730 and [noparse][[/noparse]PingDirToAngle CON·· ·9290] using the calibrated values that I came up with.
Robot works fine in Dar mode and finds closest target, then looks at it and goes Bump Bump closer to it then stops.
I've tried from 1 ft. (or even closer) to 1 meter away.

Post Edited (Erik Elmore) : 7/17/2010 10:39:09 AM GMT
• Posts: 2
edited November 2011
I enjoined the Scan For and Go To Closest Object program very much. I must admit it took a bit of tweaking until I was happy with it.
I added another LOOP to the Main Routine so that it would continue its search. The repeating LOOP proved to be quite entertaining.
New Main Routine:

Speaker PIN 5 ' piezo speaker and LED

'
[ Main Routine ]

DO WHILE(1)

GOSUB Get_Ping_Cm ' First distance measurement

DO UNTIL distance <= StopDistance ' Repeat until distance <= 5 cm

edgesFound = 0 ' Clear edges found flag

DO UNTIL edgesFound = 1 ' Repeat until edges found = 1
GOSUB Face_Closest_Object ' Find & face closest object
LOOP

GOSUB Get_Ping_Cm ' Get current distance

DO UNTIL distance <= StopDistance ' Drive toward object
prevDist = distance MAX 255 ' Current distance -> previous
GOSUB Get_Ping_Cm ' Get new distance
PULSOUT BotServoLeft, FwdLeftFast ' Boe-Bot forward
PULSOUT BotServoRight, FwdRightFast
PAUSE BtwnPulses - (distance / Ms20) ' 20 ms pause between pulses
IF distance >= prevDist + 5 THEN EXIT ' Exit if distance increasing
LOOP

LOOP ' Main routine's outermost loop

FREQOUT Speaker, 500, 3500, 3500 ' Stop Beep
PAUSE 1000

FOR counter = 0 TO 20 ' Back up about 10 cm
PULSOUT BotServoLeft, 800
PULSOUT BotServoRight, 700
PAUSE 20
NEXT

FOR counter = 1 TO 120 ' Turn Around
PULSOUT BotServoLeft, RotateRight
PULSOUT BotServoRight, RotateRight
PAUSE 20
NEXT

LOOP ' End of While Loop
END

'
[ Subroutines - BoeBot_Turn_Brads ]
• Posts: 2
edited August 2013
Hey Guys,

Could someone please help me with this.

I ran the ' Smart Sensors and Applications - Ping)))Dar.bs2 code and my Debug terminal doesn't seem to display the objects

instead I just get a X

any help is greatly appreciated

Cheers
• Posts: 22,001
edited August 2013
Ping)))Dar works so there must be a problem with either how you've hooked up the Ping))) or how you've entered the code. It would help for you to give a detailed description of how you have things connected or a schematic. Do check that the program you've got in the Stamp Editor (from here) is an exact copy of the one provided. Does the DEBUG terminal work for other programs?
• Posts: 2
edited August 2013
Thanks Mike for your reply.

I am sure my code is an identical copy of the one provided, I have also changed the limits and recalculated my PingDirToAngle.

As for my wiring, I have followed the instructions carefully.

Here is a picture of my wiring.

I attached the servo to pin 15(X4) and the the Ping Sensor to pin5.

I have also modified the pin numbers in my code.

And Yes, the Debug terminal works fine with all other programs except this one
• Posts: 22,001
edited August 2013
With the switch to the new Parallax website, many links are broken including the ones associated with the PING))). You can replace the "www" with "classic" in the URLs and they still work like this:

PING))) product page
PING))) documentation

Have you tried the simple demo program in the PING))) documentation to verify that it works?

Your picture looks ok although there's this big shadow right where the signal wire connects to the Stamp I/O pin socket. Also, color coding wires really does help. It's important to use black for ground and red for positive supply voltages. Other colors are not so important, but it's helpful to use a different color for each different signal, at least in the same area of a breadboard.
Sign In or Register to comment.