LEARN.PARALLAX.COM
Published on LEARN.PARALLAX.COM (https://learn.parallax.com)
Home > QTI Line Following ActivityBot with BlocklyProp

QTI Line Following ActivityBot with BlocklyProp

This tutorial shows you how to add an array of four QTI sensors to your ActivityBot.  These sensors can differentiate between dark and light surfaces. With a BlocklyProp program, your ActivityBot robot can use the QTI sensors to follow a black electrical tape line on a light background.

Before you start

This is a bonus tutorial to follow BlocklyProp Robotics with the ActivityBot.

What’s needed

  • A fully built and tested ActivtiyBot (#32500) or ActivityBot 360° (#32600)
  • A QTI Line Follower AppKit (#28108)
  • A 3/4 inch black line on a white surface. Options
    • Print out this line-following tracks PDF on an inkjet or laser printer and copy paper (NOT with photo printing paper and ink)
    • Make a track on white poster board, foamcore board, or a smooth, light floor with black electrical tape

After you finish

You will be ready to combine QTI line following with other sensors for more advanced projects, like ActivityBot 360° Line Following with Color Sensing.

Build the QTI Line Follower

Each QTI sensor is connected to a post that is mounted on the underside of the chassis.  This positions the sensors right above the ground surface.

  • Assemble the QTI sensors and mount them to the underside of the ActivityBot chassis:

Each QTI sensor needs to connect to to 5 V power, a Propeller I/O pin, and ground. For this, you will use the four 3-pin headers from the kit to build ports on the breadboard for each sensor.

  • Build the header circuits as shown in the schematic and wiring diagram below. The 3-pin headers and jumper wires are in your QTI Line Follower kit.
  • Remember, DON’T use the 20 k-ohm resistors on P14 and P15 with the AB360°; they are for ActivityBot robots with External Encoders Only (EEO!).

  • Plug a 3-pin extension cable into each QTI sensor.  Match the color of the wires to the B R W (black, red, white) labels on the sensor.

  • Connect the extension cable from each QTI sensor and to its header circuit on the breadboard. Match the color of the wires to the diagram below.   Take your time!

Once you have made all the connections, it is time to test them before trying line-following.

Test the QTI Sensors

Now it is time to test the QTI sensors. 

  • In BlocklyProp Solo, make a new project for your board.
  • Build the block of code shown below. It fetches the output state of each sensor with a “QTIs” function, then displays the results in the Terminal.

  • Then, build the QTIs function shown below.  (This function will also be used for line-following later.)

The white paper will reflect infrared light, while the black line will absorb it. Each QTI sensor emits infrared light, then looks for a reflection.  When a QTI sensor is over a black line, it will return a “1” and when it is over a white surface, it will return a “0.”

  • Position your robot over the black line on your track.  The QTI sensors directly over the line should return a 1, and those over a white area should return a 0.
  • Move the robot around slightly to test each QTI sensor.
  • If the sensors don’t see the line, try the following adjustments: 
    • Double-check all of your wiring connections to make sure the sensors are properly connected to power, ground, and each I/O pin.
    • Try replacing the jumper wire connecting to 5 V with a 220 ohm resistor. This makes the QTIs less bright, which might be overwhelming with a shiny line or shiny paper.
    • Try removing the Nylon spacers from one of the sensor’s posts. If this improves performance, remove it from the rest of the posts.

How the QTIs Function Works

The QTIs function starts by setting the I/O pin states for all four QTI sensors to HIGH, with the direction OUT.  This causes each QTI sensor to turn on its infrared LED. The pulse-out PIN 26 pulse length µs 230 block keeps the LEDs on for just a  230 microsecond flash. (We could not use the pause block here, because its shortest duration is 1 millisecond, which is 1000 microseconds). 

After that, the I/O pin directions are set to IN (input) for another 230 microseconds.  Each QTI sensor is looking for its infrared flash’s reflection, and reports I/O pin as a zero if the reflection is seen and a 1 if it is not. 

Then, the states of the four I/O pins are saved in the item variable as a four-digit binary number. So, each time through the drive routine’s loop, the QTIs function updates the item variable before it gets used for navigation with the switch…case block.

Program for Line-Following

Now that you know your QTI sensors are wired properly, it’s time to build the line-following code. It is long, so let’s build it a few sections at a time. 

You can download the code,  but you should still read what’s happening below so you know what sections to enable, and how it works.

Project29631-QTI-Line-Follow.svg

  • Save your project, then disable the repeat forever test code section with the Terminal print statements in it.
  • At the top of your project, add the blocks shown below to initialize your robot and also a set of variables.
  • Remember to choose ActivityBot or ActivityBot 360° to match the robot you have!

  • Keep the function QTIs section in place, and don’t disable it. 

Instead of displaying the sensor states, we’ll now use that 4-bit binary number to make navigation decisions.   The item variable plugs into a switch…case block with nine different case options, shown in the table.  The binary number determines the right and left variable values. Those variables will help adjust the robot drive values to keep your ActivityBot on the black line.

binary   left = right = behavior
1000 16 32 pivot left
1100 32 48 sharp left
1110 48 64 left
0100 64 64 slight left
0110 64 64 forward
0010 64 64 slight right
0111 64 48 right
0011 48 32 sharp right
0001 32 16 pivot right
  • Add a repeat forever block for the driving routine.
  • First thing inside the loop, add a run function “QTIs” block.
  • Then, add a switch…case block with nine cases. Use item for the variable.
  • Fill in each case using the binary values and the values for the left and right variables shown in the table above, and the screencapture below.

  • The switch…case statement has nine options, but a 4-bit binary number can go up to 16.  We’ll need to add default code that will run if item is not equal to one of the defined nine cases.
  • In the switch…case block’s default section, add the if…do…else if… code shown below. Comparing leftPrev and rightPrev gives a hint of where the line was on the last trip through the loop, so it can now choose an appropriate default behavior.

  • Add these next blocks below the switch…case block, but still inside the repeat forever loop.

Here, the values of left and right from the switch…case block factor into the driveRight and driveLeft variables that actually set each wheel’s speed. By adjusting the initial value of scale at the top of the code. you can fine-tune the robot’s performance.  Finally, just before the pause block, the values of left and right are saved in leftPrev and rightPrev before the loop repeats.

  • Save your project, and load the code to your robot’s EEPROM.
  • Place your robot on its track and put the power switch in position 2. Your ActivityBot should follow the black line.

Fine Tuning Performance

There are several places you can make adjustments to the code to fine-tune your robot’s line-following performance.  Use Save As to make copies of your project before experimenting with the adjustments.

  • Try adjusting the initial value of scale and reloading the code to see how it affects the robot’s behavior.
  • Try adjusting the ticks per second in the robot set acceleration for speed block.

If you take a look at the values assigned to the left and right variables for each case, you can see a pattern.

  • Try adjusting the pattern of values for the left and right variables, such as starting at 0 instead of 16, or gradually increasing up to 96 instead of 64.

 

Line Following using Arrays

Now that you are sure your line follower is working well, try experimenting with arrays as another approach to building your BlocklyProp program.  Think of an array as a numbered list of data elements. Your code can refer to a particular data element by its list number.    Now, imagine your list numbering uses binary numbers instead of decimal numbers. 

Remember the table of wheel speeds from the previous page?  The binary numbers created by the QTI sensors can be used as array list numbers, and the left and right wheel speed values can be used as array elements.

binary left = right = behavior
1000 16 32 pivot left
1100 32 48 sharp left
1110 48 64 left
0100 56 64 slight left
0110 64 64 forward
0010 64 56 slight right
0111 64 48 right
0011 48 32 sharp right
0001 32 16 pivot right

The binary numbers in the column above represent the output of the four QTI sensors – but binary is also a way to represent an integer. The next table shows each of the binary numbers and their decimal equivalents:

binary decimal left = right = behavior
1000 8 16 32 pivot left
1100 12 32 48 sharp left
1110 14 48 64 left
0100 4 56 64 slight left
0110 6 64 64 forward
0010 2 64 56 slight right
0111 7 64 48 right
0011 3 48 32 sharp right
0001 1 32 16 pivot right

 

Next, we will sort the table by the decimal representation of the QTI sensors’ output, and leave blanks for the in-between numbers:

binary decimal left = right = behavior
  0 0 0  
0001 1 32 16 pivot right
0010 2 64 56 slight right
0011 3 48 32 sharp right
0100 4 56 64 slight left
  5 0 0  
0110 6 64 64 forward
0111 7 64 48 right
1000 8 16 32 pivot left
  9 0 0  
  10 0 0  
  11 0 0  
1100 12 32 48 sharp left
  13 0 0  
1110 14 48 64 left
  15 0 0  

Then, let’s turn these into lists, filling in the blanks with zeros:

  • Left = 0,32,64,48,56,0,64,64,16,0,0,0,32,0,48,0
  • Right = 0,16,56,32,64,0,64,48,32,0,0,0,48,0,64,0

These values can then be used to fill an array for each side, left and right:

Now, instead of the large switch…case block – you can use the array values. You will add an if…do block to handle the cases that have been filled with zeros by using the leftPrev and rightPrev variables:

Try this

With shorter code, it’s easier to customize the behavior of the robot. For example, you can add an else if that looks for all four of the QTI sensors to read 1 (binary 1111, or decimal 15), and when they do, have the robot stop or turncompletely around:

  • Create a shape like this at the end of your line:

  • Have your robot stop, beep, and then turn completely around when it encounters the “end of the line” by adding an else if to the if…do block in your code:

 

DISCUSSION FORUMS | PARALLAX INC. STORE

About | Terms of Use | Feedback: learn@parallax.com | Copyright©Parallax Inc. 2024


Source URL:https://learn.parallax.com/courses/qti-line-following-activitybot-with-blocklyprop/
Links