Ping)))Dar Display with ActivityBot and BlocklyProp

This activity features a program that displays what the ActivityBot detects in the BlocklyProp Terminal as it sweeps the Ping))) sensor back and forth. The image below shows an example with a water bottle in the ActivityBot's 180° field of detection along with its signatures displayed in the Terminal:

Experimenting with this program will help you better understand what the ActivityBot can and cannot detect with the Ping))) Ultrasonic Distance Sensor and mounting bracket. This will help you to write better programs that navigate with this object detection system.

The next image shows an ActivityBot assembled with the Ping))) Ultrasonic Distance Sensor and Mounting Bracket Kits. The Mounting Bracket Kit makes it possible for the ActivityBot to swivel the Ping))) sensor and measure object distances across a 180° field in front of it.

Before you Start

This project contains advanced topics. Before continuing, we highly recommend that you complete the following tasks to gain a better understanding of how this program operates:

What's needed

Assembly and Electrical Connections

Follow the instructions in the Ping))) Mounting Bracket Kit documentation for making the mechanical and electrical connections to the servo and Ping))) sensor. When you finish, the servo will connect to P16 on the Activity Board, and the Ping))) sensor will connect to P17.

Polar-to-Cartesian Coordinate Conversion

The Ping)))Dar BlocklyProp program will scan a 180° field in front of the ActivityBot by incrementally rotating the Ping))) mounting bracket and then taking a distance measurement. It will do this rapidly enough that the mounting bracket servo will appear just to be rotating from right to left and back again as it updates the Terminal display.

For each measurement in a given sweep, the information that the program will have to work with is a distance measurement (d) and an angle measurement (θ) as shown in the image below. Given distance and angle coordinates are called polar coordinates. We express coordinates in parentheses like this: (d θ). When telling those coordinates to someone, you would typically say, "d at an angle of theta." The BlocklyProp code will have to convert these polar coordinates to Cartesian (x, y) coordinates to display these measurements graphically in the Terminal. That way, the Terminal set cursor block can be used to graphically display the measurement by positioning the cursor before the Terminal print text block sends an asterisk (“*”).

Calculating the x- and y-axis components given polar coordinates is not difficult with BlocklyProp!   The equations for x and y are below. The x-axis component involves multiplying the distance by the cosine of the angle, and the y-axis component is the distance multiplied by the sine of the angle.

Mounting Bracket Adjustments

Since the object's position is dependent on good distance and angle measurements, it is important to adjust and calibrate your Ping))) mounting bracket system mechanically, so that the program's servo set angle block can sweep it from 0° (to the right) to 180° (to the left). The first adjustment step toward good Ping))) mounting bracket servo angular control is making sure that the Ping))) sensor is mounted so that the servo points it straight ahead when the servo set angle sends 90°.

  • Create a new BlocklyProp project with the ActivityBoard as the board type.
  • Build the following program:

  • Make sure to set the Activity Board's 3-position power switch to position-2.
  • Load the program.
  • Check to see whether the mounting bracket servo points the Ping))) sensor straight ahead on the ActivityBot.
  • If it does, then continue to the “Software Calibration for 180° Sweep” section. Otherwise, keep following the checklist instructions here.
  • Make sure the program continues running for the remaining checklist instructions in this section.
  • Start by removing the screw that connects the servo horn to the output shaft:

  • Pull upward on the Ping))) sensor. The horn, which is attached to the Ping))) sensor with screws should slide up and off the servo's output shaft.
  • Orient the Ping))) sensor so that it is pointing straight ahead as shown above.
  • Slide the servo horn back onto the output shaft.
  • Perfect alignment may not be possible. Choose the closest to ‘straight ahead.’
  • If the teeth on the output shaft do not line up with the servo horn when it is pointing exactly straight ahead, there will be two ways that the servo horn lines up: with the Ping))) pointing slightly to the left, or slightly to the right. Choose the position that is as closest to straight ahead.
  • You will then be able to fine tune straight-ahead by adjusting the screws that attach the servo to the ActivityBot chassis.
  • Twist the screw back in that holds the servo horn to the Ping))) mounting bracket.
  • To adjust for any slight error caused by the output-shaft-to-servo-horn-gear-teeth alignment, start by loosening the screws that attach the servo to the ActivityBot chassis. Now, you will have some wiggle room to rotate the servo's housing slightly to make up for any offset resulting from the alignment of the servo horn and output shaft's teeth.
  • Make sure to re-tighten all the screws when finished.

Building the Ping)))Dar Program

Now that your servo is in the correct position, you will use the concepts from the beginning of this tutorial to create a display in the Terminal window that reflects what the Ping))) sensor “sees” as the servo sweeps it back and forth over a 180° field of detection.

  • Build the program below:

    • The text in the first Terminal print block is “________________________O________________________” - copy this text and paste it into your program.

  • Load the code to your ActivityBot’s EEPROM. Leave the USB cable connected.
  • Observe the Terminal as you try placing a variety of objects at various distances and locations from the ActivityBot in its 180° field of detection.
  • You may notice that if you move objects into enough parts of the ActivityBot’s view, the Terminal display fills up with asterisks.

Using Arrays to Erase Readings from the Previous Sweep

The code above only adds asterisks to the Terminal window. To keep the Terminal from getting cluttered, you will need to remove the asterisks from the last sweep. To do this, you will use 2 arrays - one for x coordinates and one for y coordinates, to hold the position of the asterisks so they can be erased when you add new ones.

  • Add two array initialize blocks to the beginning of your program:

  • Add the following blocks near the end of the program:

  • Load the code to your ActivityBot’s EEPROM. Leave the USB cable connected.
  • Observe the Terminal as you try placing a variety of objects at various distances from the ActivityBot at various locations in its 180° field of detection.

Your Turn – Understanding What the ActivityBot Does and Does Not ‘See’

To understand what your ActivityBot does and does not "see" with the Ping))) sensor, a few experiments are in order. Here are some questions that can be answered with the program, as well as various objects placed in the ActivityBot's field of detection.

  • If you place one object behind another object, can it see the object in back?
  • How far do you have to rotate a flat object before it is no longer visible to the Ping))) sensor?

Start with one or two cylindrical objects about 3 ft (91 cm) apart and 2 ft (61 cm) from the front of the ActivityBot. For best results, use tall cylindrical objects, such as soda cans, water bottles, etc. Sheets of paper can also be conveniently rolled into 8.5 inches (21.5 cm) tall by 2 to 3 inches (5 to 7.5 cm) diameter cylinders with a couple of pieces of tape.

  • As you move the objects closer to each other, how close can they be to each other before they appear to be one object in the Terminal?
  • If you keep the objects the same distance from each other but move them closer to the front of the ActivityBot, is the gap between them detected again at some point?
  • To what extent does setting the increment constant to a smaller value help the ActivityBot detect the gap between objects?