Boe-Bot Maze Navigation with QTIs

Jessica UelmenJessica Uelmen Posts: 490
Boe-Bot Maze Navigation with QTIs
·
Maze navigation is the heart of many robotic competitions, including the Micromouse maze and the Trinity firefighting competitions.· It is considered by most to be the one of the most challenging competitions since it requires a fair amount of work and ingenuity.· This project introduces basic maze navigation logic by using the Boe-Bot® Robot and the QTI Line Follower AppKit to navigate through an electrical tape maze containing 90° left and right turns, T-intersections and even dead ends!


View Video Introduction (YouTube)

Download Source Code – Boe-Bot Maze Navigation

Getting Started

Before continuing, make sure that you have already completed this checklist.· Especially if you have not already completed the Robotics with the Boe-Bot text, do that before you continue here.· It’s a great way to get started with Robotics!
·
······· Complete all activities in Robotics with the Boe-Bot
······· Download the documentation for the QTI Line Follower AppKit and follow all instructions listed
······· Review the How to - Boe-Bot QTI Line Following with 4 QTI Sensors for in-depth information on how the line follower code works.· This will be important when modifying the code for maze navigation.

Parts Required

(1) Boe-Bot® Robot, assembled and tested
The parts below are included in the Boe-Bot Robot kit:
····· (1) Piezospeaker
····· (misc)· Jumper wires
(1) QTI Line Follower AppKit
The parts below are included in the QTI Line Follower AppKit:
····· (4) 3-pin Male-Male Headers
····· (4) QTI Sensor Modules
····· (4) 3/8” 4-40 pan-head screws
····· (4) 7/8” 4-40 pan-head screws
····· (4) 1” round standoffs
····· (4) 1/2" round spacers
····· (4) 10” servo cable extenders

Building the Circuits···········

Follow the instructions included with the QTI Line Follower AppKit.· Or, you can download them here.· Some hardware modifications are needed for this application.· In the AppKit instructions, each QTI is mounted edge to edge, but in this application, more spacing will be required between the QTIs so the Boe-Bot can detect turns and other obstacles.· Use Figure 1 as a guide and mount the QTIs so the two center QTIs are 0.8 cm apart, and the outermost sensors are 2 cm from the center QTIs.
·
Figure 1 – Mounted QTI Sensors

attachment.php?attachmentid=59877

Building the Maze

Figure 2 shows a maze with a variety of obstacles for the Boe-Bot to navigate, including short and long straight tracks, 90° left and right turns, a T-Intersection, and a Dead End.· These obstacles pose a number of navigation challenges that you can solve, and in doing so, improve your Boe-Bot’s performance in larger and more complex mazes.· When constructing your maze, use a large piece of poster board and make sure each lane stripe is 1.5 inches of black vinyl electrical tape thick.· Figure 2 shows the maze designed for this activity (not to scale).
·
Figure 2 – Boe-Bot Electrical Tape Maze

attachment.php?attachmentid=59878

Calibration, Calibration, and More Calibration

Before we begin, you should know that the last program in this project may be larger than the example programs you may have tried in Robotics with the Boe-Bot.· That’s because there are a lot of conditions that have to be taken into account!· This “mini project” demonstrates how to take a complex problem and break it down into small pieces in order to successfully solve it.· In order to do this, we’re going to have to calibrate our Boe-Bot to maneuver through each condition before putting the whole thing together.· This will save us time when troubleshooting if we know that each individual piece works as it should.

attachment.php?attachmentid=74107

Moving Forward

Since the Boe-Bot will need to move slowly at some points in the maze, we’ll have to slow down the servos form the normal 850, 650 PUSLOUT durations.· This will help ensure that QTI readings aren’t missed as the Boe-Bot navigates through the maze, and you can use the same testing procedure introduced in Robotics with the Boe-Bot Chapter 4, Activity #2.· To slow forward movement, remember that a PULSOUT value of 750 stops the servo motors.· So we’ll want to pick values closer to 750 so the Boe-Bot slowly moves forward.· For further explanation, see the Rotational Velocity vs. Pulse Width for Servo graph in Robotics with the Boe-Bot Chapter 3, Activity #4.· Notice how the speed only really starts slowing as the pulses approach 700 from 650 and 800 from 850, so don’t worry if the change from 850 to 840 does not appear to have any effect.· Below is an adaptation of BoeBotForwardTenSeconds.bs2, and can be used to calibrate your Boe-Bot.

[color=#008000]' SlowlyForward.bs2[/color]
[color=#008000]' Calibrate your Boe-Bot to slowly move forward in a straight line.[/color]
 
[color=#008000]' {$STAMP BS2}[/color]
[color=#008000]' {$PBASIC 2.5}[/color]
 
[color=#000000]counter   VAR    Word[/color]
 
[color=#020FC0]FOR[/color][color=#000000] counter = 1 [/color][color=#020FC0]TO[/color][color=#000000] 407[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
[color=#020FC0]NEXT[/color]
 
[color=#020FC0]END[/color]


90° Left Turn Calibration

Once you’ve got the slow-forward code calibrated, the next step is to calibrate 90° turns.· There are a lot of them in the maze, so do a good job here.· It’s simple, and you’ve already calibrated your Boe-Bot to complete one in Robotics with the Boe-Bot Chapter 4, Activity #2…right?· If not, do not proceed until you are done with this important step! Now all we have to do is program the Boe-Bot to turn left when the maze path does.· You can set conditions for the Boe-Bot to follow using SELECT…CASE statements.· That way, if the QTIs are sending readings that the tell the BASIC Stamp the Boe-Bot needs to turn left, the BASIC Stamp can then send pulses to the servos to execute a 90° left turn.

attachment.php?attachmentid=74108
·
Use the sample code below and adjust the values as necessary so your Boe-Bot executes 90° left turns while staying centered on the maze path.

[color=#008000]' MazeNavigation_LeftTurn.bs2[/color]
[color=#008000]' Boe-Bot turns left based on values from the QTIs.[/color]
 
[color=#008000]' {$STAMP BS2}[/color]
[color=#008000]' {$PBASIC 2.5}[/color]
 
[color=#000000]qtis            VAR   Nib                 [/color][color=#008000]' qti black/white states[/color]
[color=#000000]pulseCount      VAR   Byte                [/color][color=#008000]' FOR..NEXT loop counter for turning[/color]
 
[color=#800080]OUTB[/color][color=#000000] = %1111                              [/color][color=#008000]' Set OUTB bits to 1[/color]
 
[color=#020FC0]DO[/color]                                        [color=#008000]' Main DO...LOOP[/color]
  [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                        [/color][color=#008000]' Get QTI states[/color]
 
  [color=#020FC0]SELECT[/color][color=#000000] qtis                             [/color][color=#008000]' Control servo speeds/directions[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0110                            [/color][color=#008000]' Straight ahead[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]CASE[/color][color=#000000] %1110[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] Turn_Left[/color]
    [color=#020FC0]CASE[/color] [color=#020FC0]ELSE[/color]                             [color=#008000]' Do nothing[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 3[/color]
  [color=#020FC0]ENDSELECT[/color]
[color=#020FC0]LOOP[/color]
 
[color=#000000]Check_Qtis:[/color]
[color=#008000]' Checks the state of each QTI Sensor. 0 means white surface, 1 means black surface.  [/color]
  [color=#800080]DIRB[/color][color=#000000] = %1111                            [/color][color=#008000]'[/color] [color=#008000]P7..P4 -> output[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
  [color=#800080]DIRB[/color][color=#000000] = %0000                            [/color][color=#008000]' P7..P4 -> input[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
[color=#000000]  qtis = [/color][color=#800080]INB[/color]                              [color=#008000]' Store QTI outputs in INB[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]Turn_Left:[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 15                [/color][color=#008000]' Go forward a bit so Boe-Bot[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770                       [/color][color=#008000]' stays on course[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 24                [/color][color=#008000]' Turn left, about 90-degrees[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 650[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 650[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
[color=#020FC0]RETURN[/color]


90° Right Turn Calibration

Calibrating your Boe-Bot to execute 90° right turns works the same way as calibrating left turns.· These values probably won’t be a mirror image of left turns, so it’s important to test and find the necessary PULSOUT Duration Values to make the right turns as reliable as the left turns.· Use the sample code below and adjust the values as necessary so your Boe-Bot executes 90° right turns while staying centered on the maze path.

[color=#008000]' MazeNavigation_LeftTurn.bs2[/color]
[color=#008000]' Boe-Bot turns left based on values from the QTIs.[/color]
 
[color=#008000]' {$STAMP BS2}[/color]
[color=#008000]' {$PBASIC 2.5}[/color]
 
 
[color=#000000]qtis            VAR   Nib                 [/color][color=#008000]' qti black/white states[/color]
[color=#000000]pulseCount      VAR   Byte                [/color][color=#008000]' FOR..NEXT loop counter for turning[/color]
 
[color=#800080]OUTB[/color][color=#000000] = %1111                              [/color][color=#008000]' Set OUTB bits to 1[/color]
 
[color=#020FC0]DO[/color]                                        [color=#008000]' Main DO...LOOP[/color]
  [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                        [/color][color=#008000]' Get QTI states[/color]
 
  [color=#020FC0]SELECT[/color][color=#000000] qtis                             [/color][color=#008000]' Control servo speeds/directions[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0110                            [/color][color=#008000]' Straight ahead[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0111[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] Turn_Right[/color]
    [color=#020FC0]CASE[/color] [color=#020FC0]ELSE[/color]                             [color=#008000]' Do nothing[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 3[/color]
  [color=#020FC0]ENDSELECT[/color]
[color=#020FC0]LOOP[/color]
 
[color=#000000]Check_Qtis:[/color]
[color=#008000]' Checks the state of each QTI Sensor. 0 means white surface, 1 means black surface.  [/color]
  [color=#800080]DIRB[/color][color=#000000] = %1111                            [/color][color=#008000]'[/color] [color=#008000]P7..P4 -> output[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
  [color=#800080]DIRB[/color][color=#000000] = %0000                            [/color][color=#008000]' P7..P4 -> input[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
[color=#000000]  qtis = [/color][color=#800080]INB[/color]                              [color=#008000]' Store QTI outputs in INB[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]Turn_Right:[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 15                [/color][color=#008000]' Go forward a bit so Boe-Bot[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770                       [/color][color=#008000]' stays on course[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 24                [/color][color=#008000]' Turn right, about 90-degrees[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 850[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 850[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
[color=#020FC0]RETURN[/color]


T-Intersection Calibration

Alright, now what happens when the Boe-Bot encounters a T-Intersection?· One solution, which we will use here, is to program the Boe-Bot to make a random decision when it reaches the· T-Intersection.· We can do this by generating a pseudo-random number, and then turn left or right based a single bit of that random number (0 or 1).
·
In MazeNavigation_TIntersection.bs2, a pseudo-random number ranging from 0 to 65535 is generated each time through the Main loop using the RANDOM command.· By looking at a single bit of that number, the Boe-Bot can turn left or right depending if the value of that bit is 0 or 1.
·

attachment.php?attachmentid=74109

Using MazeNavigation_TIntersection.bs2, complete the following tests:

······· Run the code, and use the Debug Terminal to verify that you get pseudo random results each time
······· Press the reset button and move the Boe-Bot along a straight track until it reaches a T-Intersection
······· Repeat this process several times and verify that the turn results vary each time the T-Intersection is reached.

[color=#008000]' MazeNavigation_TIntersection.bs2[/color]
[color=#008000]' When all QTI sensors detect a black line, the Boe-Bot randomly decides to turn[/color]
[color=#008000]' left or right.  This codes simulates the decision by printing "Turn Left!" or[/color]
[color=#008000]' "Turn Right!" to the debug terminal.[/color]
 
[color=#008000]' {$STAMP BS2}[/color]
[color=#008000]' {$PBASIC 2.5}[/color]
 
 
[color=#000000]rng             VAR   Word                [/color][color=#008000]' random number[/color]
[color=#000000]turnDecision    VAR   rng.BIT0            [/color][color=#008000]' Bit0 of the random number[/color]
[color=#000000]qtis            VAR   Nib                 [/color][color=#008000]' qti black/white states[/color]
 
[color=#800080]OUTB[/color][color=#000000] = %1111                              [/color][color=#008000]' Set OUTB bits to 1[/color]
[color=#020FC0]DEBUG[/color] [color=#800080]CLS                                  [/color][color=#008000]' Clear the Debug screen[/color]
 
[color=#020FC0]DO                                        [/color][color=#008000]' Main DO...LOOP[/color]
  [color=#020FC0]GOSUB [/color][color=#000000]Check_Qtis                        [/color][color=#008000]' Get QTI states[/color]
  [color=#020FC0]RANDOM [/color][color=#000000]rng                              [/color][color=#008000]' Create random number[/color]
 
  [color=#020FC0]SELECT [/color][color=#000000]qtis                             [/color][color=#008000]' Control servo speeds/directions[/color]
    [color=#020FC0]CASE [/color][color=#000000]%0110                            [/color][color=#008000]' Straight ahead[/color]
      [color=#020FC0]PULSOUT [/color][color=#000000]13, 770[/color]
      [color=#020FC0]PULSOUT [/color][color=#000000]12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]CASE [/color][color=#000000]%1111[/color]
      [color=#020FC0]GOSUB [/color][color=#000000]T_Intersection[/color]
    [color=#020FC0]CASE [/color][color=#000000]ELSE                             [/color][color=#008000]' Do nothing[/color]
      [color=#020FC0]PAUSE [/color][color=#000000]3[/color]
  [color=#020FC0]ENDSELECT[/color]
[color=#020FC0]LOOP[/color]
 
[color=#000000]Check_Qtis:[/color]
[color=#008000]' Checks the state of each QTI Sensor. 0 means white surface, 1 means black surface[/color]
  [color=#800080]DIRB[/color][color=#000000] = %1111                            [/color][color=#008000]' P7..P4 -> output[/color]
  [color=#020FC0]PAUSE [/color][color=#000000]0                                 [/color][color=#008000]' Delay = 230 us[/color]
  [color=#800080]DIRB[/color][color=#000000] = %0000                            [/color][color=#008000]' P7..P4 -> input[/color]
  [color=#020FC0]PAUSE [/color][color=#000000]0                                 [/color][color=#008000]' Delay = 230 us[/color]
[color=#000000]  qtis = [/color][color=#800080]INB[/color]                              [color=#008000]' Store QTI outputs in INB[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]T_Intersection:[/color]
  [color=#020FC0]IF [/color][color=#000000](turnDecision = 0) [/color][color=#020FC0]THEN[/color]
    [color=#020FC0]DEBUG [/color][color=#ff0000]"Turn Right!"[/color][color=#000000], [/color][color=#800080]CR[/color]
    [color=#020FC0]PAUSE [/color][color=#000000]100[/color]
  [color=#020FC0]ELSEIF [/color][color=#000000](turnDecision = 1) [/color][color=#020FC0]THEN[/color]
    [color=#020FC0]DEBUG [/color][color=#ff0000]"Turn Left!"[/color][color=#000000], [/color][color=#800080]CR[/color]
    [color=#020FC0]PAUSE [/color][color=#000000]100[/color]
  [color=#020FC0]ENDIF[/color]
[color=#020FC0]RETURN[/color]


Dead End Navigation and “Artificial Intelligence”

The dead end is another common maze obstacle, and therethththth are a lot of different approaches to solve this problem.· The program below handles it in the following way: tthe Boe-Bot will back up until it reaches the turn that led to the dead end, and then it will execute a 90° turn to get back on the maze path.
·
But what then?· The Boe-Bot still made another turn that brought it to the dead end, and if it makes that turn again, it will return to start instead of continuing to the end.· One way to solve this problem would be to create a new variable.· Let’s call it “AI”. When this variable is equal to 1, the Boe-Bot will ignore the left turn that would take it back to Start.· By creating a new subroutine named “AI_Decision”, the Boe-Bot can execute left turns based on the value of the AI variable.
·
Use the following code to verify that your Boe-Bot can successfully navigate its way out of a dead end.· Remember, some tweaking may be required!
[color=#008000]' MazeNavigation_DeadEnd.bs2[/color]
[color=#008000]' Boe-Bot backs up until it notices a turn and then moves forward again.[/color]
 
[color=#008000]' {$STAMP BS2}[/color]
[color=#008000]' {$PBASIC 2.5}[/color]
 
[color=#000000]qtis            VAR   Nib                 [/color][color=#008000]' qti black/white states[/color]
[color=#000000]AI              VAR   Byte                [/color][color=#008000]' "Artificial Intelligence" remembers dead ends[/color]
[color=#000000]pulseCount      VAR   Byte                [/color][color=#008000]' FOR..NEXT loop counter for turning[/color]
 
[color=#800080]OUTB[/color][color=#000000] = %1111                              [/color][color=#008000]' Set OUTB bits to 1[/color]
 
[color=#000000]DO                                        [/color][color=#008000]' Main DO...LOOP[/color]
  [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                        [/color][color=#008000]' Get QTI states[/color]
 
  [color=#020FC0]SELECT[/color][color=#000000] qtis                             [/color][color=#008000]' Control servo speeds/directions[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0110                            [/color][color=#008000]' Straight ahead[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]CASE[/color][color=#000000] %1110[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] AI_Decision[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0000                            [/color][color=#008000]' Back-up until it sees another turn[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] Dead_End[/color]
    [color=#020FC0]CASE[/color] [color=#020FC0]ELSE[/color]                             [color=#008000]' Do nothing[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 3[/color]
  [color=#020FC0]ENDSELECT[/color]
[color=#020FC0]LOOP[/color]
 
[color=#000000]Check_Qtis:[/color]
[color=#008000]' Checks the state of each QTI Sensor. 0 means white surface, 1 means black surface[/color]
  [color=#800080]DIRB[/color][color=#000000] = %1111                            [/color][color=#008000]' P7..P4 -> output[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
  [color=#800080]DIRB[/color][color=#000000] = %0000                            [/color][color=#008000]' P7..P4 -> input[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
[color=#000000]  qtis = [/color][color=#800080]INB[/color]                              [color=#008000]' Store QTI outputs in INB[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]AI_Decision:[/color]
  [color=#020FC0]IF[/color][color=#000000] (AI = 1) [/color][color=#020FC0]THEN[/color]                        [color=#008000]' If the AI variable is 1, Boe-Bot was in dead end[/color]
    [color=#020FC0]AI[/color][color=#000000] = 0                                [/color][color=#008000]' Set AI variable to 0[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Ignore_Turn                     [/color][color=#008000]' Ignore the turn that leads to Start[/color]
  [color=#020FC0]ELSEIF[/color][color=#000000] (AI = 0) THEN                    [/color][color=#008000]' If the AI variable is 0, Boe-Bot was not in[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Turn_Left                       [/color][color=#008000]' dead end, so it's OK to turn left.[/color]
  [color=#020FC0]ENDIF[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]Ignore_Turn:[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 50[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]Turn_Left:[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 15                [/color][color=#008000]' Go forward a bit so Boe-Bot stays on course.[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
  [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 17                [/color][color=#008000]' Turn left, about 90-degrees[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 650[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 650[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]NEXT[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]Dead_End:[/color]
  [color=#020FC0]DO[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 730[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 770[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]LOOP[/color] [color=#020FC0]UNTIL[/color][color=#000000] (qtis = %0111)[/color]
 
  [color=#020FC0]IF[/color][color=#000000] (qtis = %0111) [/color][color=#020FC0]THEN[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 15[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]NEXT[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 17[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 850[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 850[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]NEXT[/color]
  [color=#020FC0]ENDIF[/color]
[color=#000000]  AI = 1[/color]
[color=#020FC0]RETURN[/color]


Keep the Boe-Bot on Track!

The final calibration step will be to write code that keeps the Boe-Bot centered on the electrical tape, since there are several factors that could knock it off course: the tape not being perfectly straight, slippage during turns, etc.· Keep in mind that line correction can be difficult when navigating through mazes, since there are a lot of different ways that the Boe-Bot can move off track, and each response would be different.· In the solution below, whenever the Boe-Bot detects that it has gone off course, it responds in as follows:

········· Stop
········· Slowly rotate until both middle sensors are back on the line
········· Turn slightly left/right depending which way the Boe-Bot went off track
········· Turn in the other direction slightly to center the Boe-Bot back on the line

This code was taken through several iterations of calibration, testing, recalibration, re-testing, etc.· Since the values may be completely different you may also have to go through several iterations of test and recalibrate.· Keep in mind that these steps are essential for successful line following though the maze, since the center sensors need to be on the line when moving forward.· Use the following steps to make sure the Boe-Bot can stay centered on the maze path:

······· Start with the far left sensor on the electrical tape and see how long it takes the Boe-Bot to center itself on the line
······· If you find that the Boe-Bot doesn’t correct fast enough, try increasing the pulseCount durations in the FOR...NEXT loops
······· On the other hand, if you find the Boe-Bot turns too far, try decreasing the pulseCount durations in the FOR…NEXT loops
······· Repeat with the far right sensor, far left and mid left sensors, and far right and mid right sensors
······· Once those values seem OK, try sliding the poster board to force the Boe-Bot to go off track and see how quickly it reacts


[color=#008000]' MazeNavigation_StayOnStripe.bs2[/color]
[color=#008000]' Calibration program to keep the Boe-Bot on the electrical tape path.[/color]
 
[color=#008000]' {$STAMP BS2}[/color]
[color=#008000]' {$PBASIC 2.5}[/color]
 
[color=#000000]qtis          VAR     Nib                 [/color][color=#008000]' qti black/white states[/color]
[color=#000000]pulseCount    VAR     Word                [/color][color=#008000]' FOR...NEXT loop counter for smooth turning[/color]
 
[color=#800080]OUTB[/color][color=#000000] = %1111                              [/color][color=#008000]' Set OUTB bits to 1[/color]
 
[color=#020FC0]DO[/color]                                        [color=#008000]' Main DO...LOOP[/color]
  [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                        [/color][color=#008000]' Get QTI states[/color]
 
  [color=#020FC0]SELECT[/color][color=#000000] qtis                             [/color][color=#008000]'[/color] [color=#008000]Control servo speeds/directions[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0110                            [/color][color=#008000]'[/color] [color=#008000]Mid Left and Right sensors detected, go forward[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]CASE[/color][color=#000000] %1000                            [/color][color=#008000]' Far Left sensor detected[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] BackOnTrack_OneSensorLeft[/color]
    [color=#020FC0]CASE[/color][color=#000000] %1100                            [/color][color=#008000]' Far and Mid Left sensors detected[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] BackOnTrack_TwoSensorsLeft[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0001                            [/color][color=#008000]' Far Right sensor detected[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] BackOnTrack_OneSensorRight[/color]
    [color=#020FC0]CASE[/color][color=#000000] %0011                            [/color][color=#008000]' Far and Mid Right sensor detected[/color]
      [color=#020FC0]GOSUB[/color][color=#000000] BackOnTrack_TwoSensorsRight[/color]
    [color=#020FC0]CASE[/color] [color=#020FC0]ELSE[/color]                             [color=#008000]' Do nothing[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 3[/color]
  [color=#020FC0]ENDSELECT[/color]
[color=#020FC0]LOOP[/color]
 
[color=#000000]Check_Qtis:[/color]
[color=#008000]' Checks the state of each QTI Sensor. 0 means white surface, 1 means black surface.  [/color]   
  [color=#800080]DIRB[/color][color=#000000] = %1111                            [/color][color=#008000]'[/color] [color=#008000]P7..P4 -> output[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
  [color=#800080]DIRB[/color][color=#000000] = %0000                            [/color][color=#008000]' P7..P4 -> input[/color]
  [color=#020FC0]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
[color=#000000]  qtis = [/color][color=#800080]INB[/color]                              [color=#008000]' Store QTI outputs in INB[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]BackOnTrack_OneSensorLeft:[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
  [color=#020FC0]DO[/color]                                      [color=#008000]' Slowly rotate until the middle[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                      [/color][color=#008000]' QTIs are back on the line[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 740[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]LOOP[/color] [color=#020FC0]UNTIL[/color][color=#000000] (qtis = %0110)[/color]
 
  [color=#020FC0]IF[/color][color=#000000] (qtis = %0110) [/color][color=#020FC0]THEN[/color]                  [color=#008000]' When the middle QTIs are back[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 1 [/color][color=#020FC0]TO[/color][color=#000000] 20              [/color][color=#008000]' on the line, rotate left for[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                     [/color][color=#008000]' 20 pulses and then rotate right[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 740                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
    [color=#020FC0]NEXT[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 10[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]NEXT[/color]
  [color=#020FC0]ENDIF[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]BackOnTrack_TwoSensorsLeft:[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
  [color=#020FC0]DO[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                      [/color][color=#008000]' Slowly rotate until the middle[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                       [/color][color=#008000]' QTIs are back on the line[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 740[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]LOOP[/color] [color=#020FC0]UNTIL[/color][color=#000000] (qtis = %0110)[/color]
 
  [color=#020FC0]IF[/color][color=#000000] (qtis = %0110) [/color][color=#020FC0]THEN[/color]                  [color=#008000]' When the middle QTIs are back[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 1 [/color][color=#020FC0]TO[/color][color=#000000] 20              [/color][color=#008000]' on the line, rotate left for[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                     [/color][color=#008000]' 20 pulses and then rotate right[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
    [color=#020FC0]NEXT[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 10[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]NEXT[/color]
  [color=#020FC0]ENDIF[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]BackOnTrack_OneSensorRight:[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
  [color=#020FC0]DO[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                      [/color][color=#008000]' Slowly rotate until the middle[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 760                       [/color][color=#008000]' QTIs are back on the line[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]LOOP[/color] [color=#020FC0]UNTIL[/color][color=#000000] (qtis = %0110)[/color]
 
  [color=#020FC0]IF[/color][color=#000000] (qtis = %0110) [/color][color=#020FC0]THEN[/color]                  [color=#008000]' When the middle QTIs are back[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 1 [/color][color=#020FC0]TO[/color][color=#000000] 20              [/color][color=#008000]' on the line, rotate right for[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 760                     [/color][color=#008000]' 20 pulses and then rotate left[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
    [color=#020FC0]NEXT[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 TO 10[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]NEXT[/color]
  [color=#020FC0]ENDIF[/color]
[color=#020FC0]RETURN[/color]
 
[color=#000000]BackOnTrack_TwoSensorsRight:[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
  [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
  [color=#020FC0]DO[/color]
    [color=#020FC0]GOSUB[/color][color=#000000] Check_Qtis                      [/color][color=#008000]' Slowly rotate until the middle[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 13, 760                       [/color][color=#008000]' QTIs are back on the line[/color]
    [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750[/color]
    [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
  [color=#020FC0]LOOP[/color] [color=#020FC0]UNTIL[/color][color=#000000] (qtis = %0110)[/color]
 
  [color=#020FC0]IF[/color][color=#000000] (qtis = %0110) [/color][color=#020FC0]THEN[/color]                  [color=#008000]' When the middle QTIs are back[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 1 [/color][color=#020FC0]TO[/color][color=#000000] 20              [/color][color=#008000]' on the line, rotate right for[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 770                     [/color][color=#008000]' 20 pulses and then rotate left[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 750                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
    [color=#020FC0]NEXT[/color]
    [color=#020FC0]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#020FC0]TO[/color][color=#000000] 10[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 13, 750[/color]
      [color=#020FC0]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#020FC0]PAUSE[/color][color=#000000] 20[/color]
    [color=#020FC0]NEXT[/color]
  [color=#020FC0]ENDIF[/color]
[color=#020FC0]RETURN[/color]


▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax Inc.

Post Edited (Jessica Uelmen (Parallax)) : 8/25/2010 6:24:04 PM GMT
358 x 423 - 30K
722 x 444 - 24K
727 x 152 - 25K
727 x 97 - 15K
727 x 188 - 33K
Allons-y!
--
@jessicauelmen

Comments

  • 13 Comments sorted by Date Added Votes
  • Jessica UelmenJessica Uelmen Posts: 490
    edited April 2009 Vote Up0Vote Down
    The Whole Shebang

    Congratulations, you’ve completed the calibration process!· After calibration, the final program may seem long, but it’s really just a compilation of all the short programs we’ve just written and tested. Breaking maze navigation, or and any other robotic problem, down into small pieces and calibrating at each step helps ensure success.· If you develop these habits now, it can save you tremendous amounts of time preparing for your next robotics project or contest entry.
    ··································
    The final code has some extra features to make navigation more reliable.· For example, there’s a Turn_Check subroutine that prevents the Boe-Bot from misinterpreting %0111 or %1110 as a full 90° turn.· It’s true that those QTI patterns do sometimes indicate a turn, but the same patterns can also indicate that the Boe-Bot has just drifted a little to the left or right of the line.· The Turn_Check subroutine figures out whether the Boe-Bot is off course or on a turn by:
    ·
    ········· Moving the Boe-Bot forward for 5 pulses
    ········· Obtaining another QTI reading
    ········· If the sensors still tell Boe-Bot to turn, it will, any other reading returns the program to Main for line adjustment
    ·
    Another extra feature of the final code is that each SELECT…CASE statement in the main routine is sent to a subroutine.· This is because we want the code to execute as quickly as possible.· Each QTI reading is crucial to accurate maze navigation, so the faster the main program executes, the more QTI readings we obtain.· If we put every movement in the main routine, this severely slows down our code, which could cause missed readings in important areas, such as turns or T-intersections.· That’s why the code in the main routine only checks the QTI states, and depending on the result, gets sent to the corresponding subroutine.
    ·
    Before the code below will work on your Boe-Bot, it is essential for you to go through and update all the values you determined in this article’s calibration and testing steps.· When running your Boe-Bot through the maze, you may find that some values need to be adjusted to account for unforeseen obstacles.· That’s OK!· Experiment with the code until your Boe-Bot can consistently navigate through your electrical tape maze.
    [color=#008000]' -----[noparse][[/noparse] Title ]----------------------------------------------------------------------------[/color]
    [color=#008000]' FullMazeNavigation.bs2[/color]
    [color=#008000]' Navigate your Boe-Bot through a "maze" made of electrical tape using the QTI Line[/color]
    [color=#008000]' Follower App Kit.[/color]
     
    [color=#008000]' IMPORTANT: This program has several operations that have to be tuned before it will work[/color]
    [color=#008000]' right! Follow the instructions on forums.parallax.com -> Stamps in Class -> Stamps in[/color]
    [color=#008000]' Class "Mini Projects" -> Boe-Bot Maze Navingation before you run 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] Variables ]------------------------------------------------------------------------[/color]
     
    [color=#000000]rng             VAR   Byte                [/color][color=#008000]' Random number generator variable[/color]
    [color=#000000]pulseCount      VAR   Byte                [/color][color=#008000]' FOR..NEXT loop counter for turning[/color]
    [color=#000000]turnDecision    VAR   rng.BIT0            [/color][color=#008000]' Bit zero of the random number generated[/color]
    [color=#000000]AI              VAR   Bit                 [/color][color=#008000]' "Artificial Intelligence" remembers dead ends[/color]
    [color=#000000]qtis            VAR   Nib                 [/color][color=#008000]' QTI black/white states[/color]
     
    [color=#008000]' -----[noparse][[/noparse] Initialization ]-------------------------------------------------------------------[/color]
     
    [color=#800080]OUTB[/color][color=#000000] = %1111                              [/color][color=#008000]' Set OUTB bits to 1[/color]
    [color=#000000]AI = 0                                    [/color][color=#008000]' Set AI variable to 0[/color]
     
    [color=#0000ff]FREQOUT[/color][color=#000000] 15, 1000, 2000                    [/color][color=#008000]' Battery Tester[/color]
     
    [color=#008000]' -----[noparse][[/noparse] Main Routine ]---------------------------------------------------------------------[/color]
     
    [color=#0000ff]DO[/color]                                        [color=#008000]' Main DO...LOOP[/color]
      [color=#0000ff]RANDOM[/color][color=#000000] rng                              [/color][color=#008000]' Create a random number[/color]
      [color=#0000ff]GOSUB[/color][color=#000000] Check_Qtis                        [/color][color=#008000]' Get QTI states[/color]
      [color=#0000ff]SELECT[/color][color=#000000] qtis[/color]
     
      [color=#0000ff]CASE[/color][color=#000000] %0110                              [/color][color=#008000]'[/color] [color=#008000]Mid Left and Right sensors detected, go forward[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] Forward[/color]
      [color=#0000ff]CASE[/color][color=#000000] %1100                              [/color][color=#008000]' Far and Mid Left sensors detected = off track[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] BackOnTrack_TwoSensorsLeft[/color]
      [color=#0000ff]CASE[/color][color=#000000] %0011                              [/color][color=#008000]' Far and Mid Right sensor detected = off track[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] BackOnTrack_TwoSensorsRight[/color]
      [color=#0000ff]CASE[/color][color=#000000] %1110, %0111                       [/color][color=#008000]' Turn Detected[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] Turn_Check[/color]
      [color=#0000ff]CASE[/color][color=#000000] %1111                              [/color][color=#008000]' All sensors detected = T-Intersection[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] T_Intersection[/color]
      [color=#0000ff]CASE[/color][color=#000000] %0000                              [/color][color=#008000]' No track = dead end[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] Dead_End[/color]
      [color=#0000ff]CASE[/color][color=#000000] %0001                              [/color][color=#008000]' Far Right sensor detected[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] BackOnTrack_OneSensorRight[/color]
      [color=#0000ff]CASE[/color][color=#000000] %1000                              [/color][color=#008000]' Far Left sensor detected[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] BackOnTrack_OneSensorLeft[/color]
      [color=#0000ff]CASE[/color] [color=#0000ff]ELSE[/color]                               [color=#008000]' Any other combination, move forward until[/color]
        [color=#0000ff]PULSOUT[/color][color=#000000] 13, 770                       [/color][color=#008000]' something else is detected.[/color]
        [color=#0000ff]PULSOUT[/color][color=#000000] 12, 730[/color]
        [color=#0000ff]PAUSE[/color][color=#000000] 20[/color]
      [color=#0000ff]ENDSELECT[/color]
    [color=#0000ff]LOOP[/color]
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Check_Qtis ]---------------------------------------------------------[/color]
    [color=#008000]' Checks the state of each QTI Sensor. 0 means white surface, 1 means black surface.[/color]
     
    [color=#000000]Check_Qtis:[/color]
      [color=#800080]DIRB[/color][color=#000000] = %1111                            [/color][color=#008000]' P7..P4 -> output[/color]
      [color=#0000ff]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
      [color=#800080]DIRB[/color][color=#000000] = %0000                            [/color][color=#008000]' P7..P4 -> input[/color]
      [color=#0000ff]PAUSE[/color][color=#000000] 0                                 [/color][color=#008000]' Delay = 230 us[/color]
    [color=#000000]  qtis = [/color][color=#800080]INB[/color]                              [color=#008000]' Store QTI outputs in INB[/color]
    [color=#0000ff]RETURN[/color]
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Forward ]------------------------------------------------------------[/color]
    [color=#008000]' Boe-Bot moves forward.[/color]
     
    [color=#000000]Forward:[/color]
      [color=#0000ff]PULSOUT[/color][color=#000000] 13, 770[/color]
      [color=#0000ff]PULSOUT[/color][color=#000000] 12, 730[/color]
      [color=#0000ff]PAUSE[/color][color=#000000] 20[/color]
    [color=#0000ff]RETURN[/color]
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Turn_Check ]---------------------------------------------------------[/color]
    [color=#008000]' When three sensors are detected, this subroutine checks if there is actually a turn, or[/color]
    [color=#008000]' if the Boe-Bot got off track.[/color]
     
    [color=#000000]Turn_Check:[/color]
      [color=#0000ff]PULSOUT[/color][color=#000000] 13, 750                         [/color][color=#008000]' Stop moving[/color]
      [color=#0000ff]PULSOUT[/color][color=#000000] 12, 750[/color]
     
      [color=#0000ff]FOR[/color][color=#000000] pulseCount = 0 [/color][color=#0000ff]TO[/color][color=#000000] 5                 [/color][color=#008000]' Move forward a bit[/color]
        [color=#0000ff]PULSOUT[/color][color=#000000] 13, 770[/color]
        [color=#0000ff]PULSOUT[/color][color=#000000] 12, 730[/color]
        [color=#0000ff]PAUSE[/color][color=#000000] 20[/color]
      [color=#0000ff]NEXT[/color]
     
      [color=#0000ff]GOSUB[/color][color=#000000] Check_Qtis                        [/color][color=#008000]' Check the new QTI states[/color]
      [color=#0000ff]SELECT[/color][color=#000000] qtis[/color]
     
      [color=#0000ff]CASE[/color][color=#000000] %1110                              [/color][color=#008000]' Left turn is detected[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] AI_Decision[/color]
      [color=#0000ff]CASE[/color][color=#000000] %0111                              [/color][color=#008000]' Right turn is detected[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] Turn_Right[/color]
      [color=#0000ff]CASE[/color] [color=#0000ff]ELSE[/color]                               [color=#008000]' Boe-Bot was off track, return to main program[/color]
        [color=#0000ff]RETURN[/color]
      [color=#0000ff]ENDSELECT[/color]
    [color=#0000ff]RETURN[/color]
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - AI_Decision ]--------------------------------------------------------[/color]
    [color=#008000]' When a left turn is detected, check if the Boe-Bot hit a dead end last.  This will keep[/color]
    [color=#008000]' it from returning to Start.[/color]
     
    [color=#000000]AI_Decision:[/color]
      [color=#0000ff]IF[/color][color=#000000] (AI = 1) [/color][color=#0000ff]THEN[/color]                        [color=#008000]' If the AI variable is 1, Boe-Bot was in dead end[/color]
    [color=#000000]    AI = 0                                [/color][color=#008000]' Set AI variable to 0[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] Ignore_Turn                     [/color][color=#008000]'[/color] [color=#008000]Ignore the turn that leads to Start[/color]
      [color=#0000ff]ELSEIF[/color][color=#000000] (AI = 0) [/color][color=#0000ff]THEN[/color]                    [color=#008000]' If the AI variable is 0, Boe-Bot was not in[/color]
        [color=#0000ff]GOSUB[/color][color=#000000] Turn_Left                       [/color][color=#008000]' dead end, so it's OK to turn left.[/color]
      [color=#0000ff]ENDIF[/color]
    [color=#0000ff]RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Ignore_Turn ]--------------------------------------------------------[/color]
    [color=#008000]' AI variable was 1, so ignore the left turn by going forward for 50 pulses.[/color]
     
    [color=#000000]Ignore_Turn:[/color]
      FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 50[/color]
        PULSOUT[color=#000000] 13, 770[/color]
        PULSOUT[color=#000000] 12, 730[/color]
        PAUSE[color=#000000] 20[/color]
      NEXT
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Turn_Left ]----------------------------------------------------------[/color]
    [color=#008000]' Boe-Bot executes a left turn.[/color]
     
    Turn[color=#000000]_Left:[/color]
      FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 15                [/color][color=#008000]' Go forward a bit so Boe-Bot stays on course.[/color]
        PULSOUT[color=#000000] 13, 770[/color]
        PULSOUT[color=#000000] 12, 730[/color]
        PAUSE[color=#000000] 20[/color]
      NEXT
      FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 17                [/color][color=#008000]' Turn left, about 90-degrees[/color]
        PULSOUT[color=#000000] 13, 650[/color]
        PULSOUT[color=#000000] 12, 650[/color]
        PAUSE[color=#000000] 20[/color]
      NEXT
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Turn_Right ]----------------------------------------------------------[/color]
    [color=#008000]' Boe-Bot executes a right turn.[/color]
     
    [color=#000000]Turn_Right:[/color]
      FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 15                [/color][color=#008000]' Go forward a bit so Boe-Bot stays on course[/color]
        PULSOUT[color=#000000] 13, 770[/color]
        PULSOUT[color=#000000] 12, 730[/color]
       PAUSE[color=#000000] 20[/color]
      NEXT
      FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 17                [/color][color=#008000]' Turn right, about 90-degrees[/color]
        PULSOUT[color=#000000] 13, 850[/color]
        PULSOUT[color=#000000] 12, 850[/color]
        PAUSE[color=#000000] 20[/color]
      NEXT
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - T_Intersection ]-----------------------------------------------------[/color]
    [color=#008000]' Boe-Bot makes a random turn when it comes to a T-Intersection[/color]
     
    [color=#000000]T_Intersection:[/color]
      IF[color=#000000] turnDecision = 0 [/color]THEN                [color=#008000]' If Bit0 is 0 then turn right[/color]
        GOSUB[color=#000000] Turn_Right[/color]
      ELSEIF[color=#000000] turnDecision = 1 [/color]THEN            [color=#008000]' If Bit0 is 1 then turn left[/color]
        GOSUB[color=#000000] Turn_Left[/color]
      ENDIF
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - Dead_End ]-----------------------------------------------------------[/color]
    [color=#008000]' Boe-Bot detects a dead end, backs up, and turns around to get back on track.[/color]
     
    [color=#000000]Dead_End:[/color]
      DO
        GOSUB[color=#000000] Check_Qtis[/color]
        PULSOUT[color=#000000] 13, 730[/color]
        PULSOUT[color=#000000] 12, 770[/color]
        PAUSE[color=#000000] 20[/color]
      LOOP UNTIL[color=#000000] (qtis = %0111)[/color]
     
      IF[color=#000000] (qtis = %0111) [/color]THEN
        PAUSE[color=#000000] 20[/color]
        FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 15[/color]
          PULSOUT[color=#000000] 13, 770[/color]
          PULSOUT[color=#000000] 12, 730[/color]
          PAUSE[color=#000000] 20[/color]
        NEXT
        FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 17[/color]
          PULSOUT[color=#000000] 13, 850[/color]
          PULSOUT[color=#000000] 12, 850[/color]
          PAUSE[color=#000000] 20[/color]
        NEXT
      ENDIF
    [color=#000000]  AI = 1[/color]
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - BackOnTrack_TwoSensorsLeft ]-----------------------------------------[/color]
    [color=#008000]' Boe-Bot is off track.  Boe-Bot slowly rotates until the two middle sensors are detected,[/color]
    [color=#008000]' and then centers itself on the line.[/color]
     
      PULSOUT[color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
      PULSOUT[color=#000000] 12, 750[/color]
      DO
        GOSUB[color=#000000] Check_Qtis                      [/color][color=#008000]' Slowly rotate until the middle[/color]
        PULSOUT[color=#000000] 13, 750                       [/color][color=#008000]' QTIs are back on the line[/color]
        PULSOUT[color=#000000] 12, 740[/color]
        PAUSE[color=#000000] 20[/color]
      LOOP UNTIL[color=#000000] (qtis = %0110)[/color]
     
      IF[color=#000000] (qtis = %0110) [/color]THEN                  [color=#008000]' When the middle QTIs are back [/color]
        FOR[color=#000000] pulseCount = 1 [/color]TO[color=#000000] 20              [/color][color=#008000]' on the line, rotate left for[/color]
          PULSOUT[color=#000000] 13, 750                     [/color][color=#008000]' 20 pulses and then rotate right[/color]
          PULSOUT[color=#000000] 12, 730                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
          PAUSE[color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
        NEXT
        FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 10[/color]
          PULSOUT[color=#000000] 13, 770[/color]
          PULSOUT[color=#000000] 12, 750[/color]
          PAUSE[color=#000000] 20[/color]
        NEXT
      ENDIF
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - BackOnTrack_TwoSensorsRight ]----------------------------------------[/color]
    [color=#008000]' Boe-Bot is off track.  Boe-Bot slowly rotates until the two middle sensors are detected,[/color]
    [color=#008000]' and then centers itself on the line.[/color]
     
      PULSOUT[color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
      PULSOUT[color=#000000] 12, 750[/color]
      DO
        GOSUB[color=#000000] Check_Qtis                      [/color][color=#008000]' Slowly rotate until the middle[/color]
        PULSOUT[color=#000000] 13, 760                       [/color][color=#008000]' QTIs are back on the line[/color]
        PULSOUT[color=#000000] 12, 750[/color]
        PAUSE[color=#000000] 20[/color]
      LOOP UNTIL[color=#000000] (qtis = %0110)[/color]
     
      IF[color=#000000] (qtis = %0110) [/color]THEN                  [color=#008000]' When the middle QTIs are back[/color]
        FOR[color=#000000] pulseCount = 1 [/color]TO[color=#000000] 20              [/color][color=#008000]' on the line, rotate right for[/color]
          PULSOUT[color=#000000] 13, 770                     [/color][color=#008000]' 20 pulses and then rotate left[/color]
          PULSOUT[color=#000000] 12, 750                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
          PAUSE[color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
        NEXT
        FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 10[/color]
          PULSOUT[color=#000000] 13, 750[/color]
          PULSOUT[color=#000000] 12, 730[/color]
          PAUSE[color=#000000] 20[/color]
        NEXT
      ENDIF
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - BackOnTrack_OneSensorLeft ]------------------------------------------[/color]
    [color=#008000]' Boe-Bot is off track.  Boe-Bot slowly rotates until the two middle sensors are detected,[/color]
    [color=#008000]' and then centers itself on the line.[/color]
     
    [color=#000000]BackOnTrack_OneSensorLeft:[/color]
      PULSOUT[color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
      PULSOUT[color=#000000] 12, 750[/color]
      DO                                      [color=#008000]' Slowly rotate until the middle[/color]
        GOSUB[color=#000000] Check_Qtis                      [/color][color=#008000]' QTIs are back on the line[/color]
        PULSOUT[color=#000000] 13, 750[/color]
        PULSOUT[color=#000000] 12, 740[/color]
        PAUSE[color=#000000] 20[/color]
      LOOP UNTIL[color=#000000] (qtis = %0110)[/color]
     
      IF[color=#000000] (qtis = %0110) [/color]THEN                  [color=#008000]' When the middle QTIs are back[/color]
        FOR[color=#000000] pulseCount = 1 [/color]TO[color=#000000] 20              [/color][color=#008000]' on the line, rotate left for[/color]
          PULSOUT[color=#000000] 13, 750                     [/color][color=#008000]' 20 pulses and then rotate right[/color]
          PULSOUT[color=#000000] 12, 740                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
          PAUSE[color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
        NEXT
        FOR[color=#000000] pulseCount = 0 [/color]TO[color=#000000] 10[/color]
          PULSOUT[color=#000000] 13, 770[/color]
          PULSOUT[color=#000000] 12, 750[/color]
          PAUSE[color=#000000] 20[/color]
        NEXT
      ENDIF
    RETURN
     
    [color=#008000]' -----[noparse][[/noparse] Subroutines - BackOnTrack_OneSensorRight ]-----------------------------------------[/color]
    [color=#008000]' Boe-Bot is off track.  Boe-Bot slowly rotates until the two middle sensors are detected,[/color]
    [color=#008000]' and then centers itself on the line.[/color]
     
    [color=#000000]BackOnTrack_OneSensorRight:[/color]
      PULSOUT[color=#000000] 13, 750                         [/color][color=#008000]' Stop[/color]
      PULSOUT[color=#000000] 12, 750[/color]
      DO
        GOSUB[color=#000000] Check_Qtis                      [/color][color=#008000]' Slowly rotate until the middle[/color]
        PULSOUT[color=#000000] 13, 760                       [/color][color=#008000]' QTIs are back on the line[/color]
        PULSOUT[color=#000000] 12, 750[/color]
        PAUSE[color=#000000] 20[/color]
      LOOP UNTIL[color=#000000] (qtis = %0110)[/color]
     
      IF[color=#000000] (qtis = %0110) [/color]THEN                  [color=#008000]' When the middle QTIs are back[/color]
        FOR[color=#000000] pulseCount = 1 [/color]TO[color=#000000] 20              [/color][color=#008000]' on the line, rotate right for[/color]
          PULSOUT[color=#000000] 13, 760                     [/color][color=#008000]' 20 pulses and then rotate left[/color]
          PULSOUT[color=#000000] 12, 750                     [/color][color=#008000]' for 10 pulses to center the Boe-[/color]
          PAUSE[color=#000000] 20                            [/color][color=#008000]' Bot on the line.[/color]
        NEXT
        FOR[color=#000000] pulseCount = 0 TO 10[/color]
          PULSOUT[color=#000000] 13, 750[/color]
          PULSOUT[color=#000000] 12, 730[/color]
          PAUSE[color=#000000] 20[/color]
        NEXT
      ENDIF
    RETURN[/color]
    
    

    Your Turn: Challenge Yourself and Friends!

    Although this code was written specifically for the maze in Figure 2, it can be adapted to a variety of other situations as well as expanded for more complex mazes.· Challenge yourself by creating a random maze and see if you can program your Boe-Bot to get through it!· You can also challenge your friends and see who can best navigate through mazes, or who can do it the fastest. As a final touch, try adding obstacles that can be detected by Whiskers, infrared or photoresistors, and try programming your Boe-Bot to navigate around these obstacles and get back on the maze.
    ·
    _____________________________________________________________________________
    ··
    (c) 2009·by Parallax Inc - all rights reserved.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jessica Uelmen
    Education Department
    Parallax, Inc.

    Post Edited (Jessica Uelmen (Parallax)) : 4/6/2009 8:59:29 PM GMT
    Allons-y!
    --
    @jessicauelmen
  • bomberbomber Posts: 297
    edited September 2011 Vote Up0Vote Down
    Neat! I wonder if this could work on a Stingray....
    " 'I hate my code' is the developers version of 'Do I look fat in this dress?' " Quote by Kelly Sommers
  • PublisonPublison Posts: 9,452
    edited September 2011 Vote Up0Vote Down
    bomber wrote: »
    Neat! I wonder if this could work on a Stingray....

    Sure will! Kye wrote an object that is in the OBEX:

    http://obex.parallax.com/objects/584/

    I believe he used it on his StingRay for a competition.

    EDIT: Yup! Here is the thread:

    http://forums.parallax.com/showthread.php?131242-Parallax-Stringray-Robot-1st-Place-at-Carnegie-Mellon-University-Mobot-Race-2011&highlight=Stingray
    Infernal Machine
  • edited January 2012 Vote Up0Vote Down
    Haw can you differentiate between the dead end and the end both look the same
  • Jessica UelmenJessica Uelmen Posts: 490
    edited January 2012 Vote Up0Vote Down
    Welcome to the forums!

    In this case, there isn't a way to differentiate between the dead end and the end points. The tutorial was meant to be a simple 'starter' tutorial to cover the basics of maze navigation.

    You could put a different tape pattern for the end of the maze so that the robot could be programmed to tell the difference. For example, maybe the end of the maze has a strip of tape that's detected by the outer two QTI sensors. You could then add a CASE statement to end the program if the robot detects that condition.

    Hope this helps!

    Cheers,
    Jessica
    Allons-y!
    --
    @jessicauelmen
  • hulsebothulsebot Posts: 1
    edited February 2012 Vote Up0Vote Down
    Hey,

    I was wondering how could you adjust this program so that you could use it for 3 QTI sensors rather then 4?

    -Debra
  • Jessica UelmenJessica Uelmen Posts: 490
    edited February 2012 Vote Up0Vote Down
    Hi Debra,

    Welcome to the forums!

    If you wanted to use 3 QTI sensors instead, you would want to use a thinner strip of electrical tape and position the sensors so that the robot will move straight forward if the middle sensor is over the line and the left and right sensors are over a white surface. Since you won't easily be able to tell whether the robot needs to adjust itself to keep moving straight or if it's at a left or right turn, you'll also need to take a different approach to the code.

    One approach would be: if the robot detects 0 or 1 cases, you could keep moving forward instead of executing a turn. Then, if the robot detects no line after a few pulses, you know that it was a 90° turn and can execute the movement accordingly. You would then need to make small adjustments to get your robot back on the line.

    There is also a line-following example from Andy using three QTI Sensors instead of four. You can find it here. This is best used for courses with rounded turns, but it should help get you started!

    You'll need to do some experimenting, certainly, but that's part of the fun! Let us know how it goes & if you have any other questions!

    Cheers,
    Jessica
    Allons-y!
    --
    @jessicauelmen
  • sirhulksirhulk Posts: 1
    edited March 2012 Vote Up0Vote Down
    Hi, i am student working with the line follower boe bot. my bot is not doing what it should i did every step above. is there a way to set up lights to each sensor to tell me when it senses black.
  • KendallWeiheKendallWeihe Posts: 1
    edited August 2012 Vote Up0Vote Down
    Hi there,

    I know this thread is semi - old, but this year at my High School I plan on spending an entire year learning this code.

    My question here is: how do you insert the code to tell the Boe-Bot where it has already been. In other words, so it won't back track in the maze?

    As of now, I am only using the basic IR transmitter and receiver to navigate a maze. Last year I used the Line Following kit, but I never got into it enough to be able to code something like my question above. Soon enough though I will have the PING))) Ultra Sonic sensor and several other components, but the gold is in the code. So that's what I want to learn the most.

    All help is appreciated!

    Thanks!

    -Kendall Weihe
  • ercoerco Posts: 17,950
    edited August 2012 Vote Up0Vote Down
    Google "robot maze algorithm"

    Here's one solution that looks promising for line mazes: http://richardvannoy.info/line-maze-algorithm.pdf
    "When you make a thing, a thing that is new, it is so complicated making it that it is bound to be ugly. But those that make it after you, they don’t have to worry about making it. And they can make it pretty, and so everybody can like it when others make it after you."

    - Pablo Picasso
  • sailman58sailman58 Posts: 162
    edited September 2012 Vote Up0Vote Down
    Before I got involved in a lot of other stuff, I was a member of a robotics club where I was the token Boe-Bot in a bunch of Vexs ( also the token senior in a bunch of elementary school kids and parents) but any robot club in a storm! The club leaders started a maze challenge from a Vex website where the maze squares were rotated 45 degrees and the entry/exit points were at the corners of the squares. Just to make life interesting, none of the squares was perfectly laid out so the angles varied quite a bit. If I hadn't been half bald when I started to code for this maze I would have been when I finished! For some reason, the Vex sensors handled the configuration without a problem given the correct coding, but my Boe-Bot would always seem to stumble after handling the first several intersections OK.

    Ron
  • I teach Math and Computer Science, and my students are trying to program our Boe Bot to follow lines for an upcoming competition. They successfully installed 4 QTIs and were able to follow a simple line using the Line Following with Check QTI program. When the kids try to get our Boe Bot to follow more complicated lines, our robot behaves strangely. We set up the program to debug the QTIs and we found that when the robot deviates from the course in a way we didn't anticipate, it is usually the result of the QTIs "seeing" a line that is not actually present. I thought it might have been the material that we are using to prepare for competition, so we made the maze and attempted to follow the directions listed above. For some reason, our QTi's will indicate that a sensor is looking at a line that is not on our white poster board.

    To clarify, if the line is directly under the middle two sensors as configured in the pictures for this activity, instead of the QTIs displaying 0110, sometimes they will display 1110 or 0111 when only the two middle sensors are over the line. For some reason, they will sometimes randomly display 1010, or 1001.

    Has anybody else ever encountered this problem? I know from my past experience in aviation that some aircraft sensors can be tuned to be more sensitive or less sensitive. Is this something that we can do with QTIs? Any advice would be appreciated.
  • edited April 26 Vote Up0Vote Down
    Hello Mr. Reed,

    The first step would be to experiment with the height of the QTIs over the line. Your students might find that there's a sweet spot focal distance that always gets correct measurements.

    Another option is to tune the detection subroutine. Here is how:

    Below is one of the programs from the QTI Line Follower AppKit for Small Robot page's Downloads & Documentation section.

    https://www.parallax.com/product/28108
    https://www.parallax.com/downloads/qti-line-follower-appkit-basic-stamp-example-code

    There are four paragraphs below the code that describe it, then the 5th paragraph explains tuning. A second explanation with some visual aids is in Applied Robotics with the SumoBot, Chapter 3, Activity #4.

    https://www.parallax.com/downloads/applied-robotics-sumobot-text
    ' CheckQtiSubroutine.bs2
    ' Displays QTI sensor states.  0 means white surface, 1 means black.
    
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    qtis VAR Nib                                 ' qti black/white states
    
    OUTB = %1111                                 ' Set OUTB bits to 1
    
    DEBUG CRSRX, 8, "FMMF", CR,                  ' Display bit positions
          CRSRX, 8, "LLRR", CR
    
    DO                                           ' Main DO...LOOP
    
      GOSUB Check_Qtis                           ' Get QTI states
      DEBUG BIN4 ? qtis, CRSRUP                  ' Display QTI states
      PAUSE 100                                  ' 1/10 s delay
    
    LOOP
    
    Check_Qtis:
    
      ' Result -> qtis variable.  0 means white surface, 1 means black surface.
    
      DIRB = %1111                               ' P7..P4 -> output
      PAUSE 0                                    ' Delay = 230 us
      DIRB = %0000                               ' P7..P4  -> input
      PAUSE 0                                    ' Delay = 230 us
      ' PULSOUT UnusedPin, 0                     ' Delays = 208 + (Duration*2) us
      qtis = INB                                 ' Store QTI outputs in INB
    
      RETURN
    

    The Check_Qtis subroutine charges up capacitors in the QTIs with DIRB = %1111, which connects each QTI to the BASIC Stamp's 5 V supply through I/O pins 7...4. The PAUSE 0 command causes a 230 us delay for the capacitors to charge up to some value in the 5 V neighborhood. Then, DIRB = %0000 sets the I/O pins that were charging the QTIs capacitors to inputs. As inputs, the I/O pins have no effect on the QTI circuits, but can monitor for whether the voltage that each QTI circuit applies to each I/O pin has decayed below 1.3 V (binary-0) or is still above 1.3 V (binary 1). Then, qtis = INB copies the binary values for P7, P6, P5, and P4 from the BASIC Stamp's B input register to the qtis variable.

    A white surface reflecting infrared light the QTI emits more intensely makes the phototransistor in a given QTI conduct more current from its capacitor to ground, causing its voltage to decay more rapidly. A black surface reflecting light less causes the phototransistor to conduct less current and drains the capacitor less rapidly.

    The trick to tuning the QTIs is setting the delay between changing I/O to input with DIRB = %0000 and checking their values with qtis = INB. That will give all the QTI's more or less time for their capacitor's to draing through the phototransistors. What we are looking for is a sweet spot delay time that allows QTIs over white to discharge below 1.3 V, but not so long that it allows the QTIS over black to also decay below 1.3 V.

    I added 'PULSOUT UnusedPin, 0 to to that code to make it tunable. For example, assuming nothing else is connected to P11, you could comment the lower of the two PAUSE 0 by putting an apostrophe to its left. Then, uncomment the PULSOUT command by removing its apostrophe, and make it something like PULSOUT 11, 100. This should change the delay from 230 us to 408 us (208 + 200 * 2 us = 408 us).

    I think the best approach would be to first increase PULSOUT duration arguments from 100 up to the point where they are long enough that even the QTIs over black lines report 0. Then, adjust the duration below 100, short enough to make QTIS that are over while surfaces report 1. Finally, set the duration in PULSOUT 11, duration to the half way point between the two values.

    Andy
Sign In or Register to comment.