QTI line sensors for a SUMO
We've been having problems with our line sensors, two bots have not been changing their activity when they cross the line. The line test shows that both sensors are functioning as they should. Everything else is working. What are some possible causes? We've made sure that all of the wires are connected as they should be.
Comments
There could be an error in your code, if you post it as an attachment we can take a quick look at it and see if there are any errors.
-- Jessica
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jessica Uelmen
Education Department
Parallax Inc.
'
[noparse][[/noparse] Title ]
' Mini Sumo 5.1 : Basic Competition Program
' {$STAMP BS2}
'
[noparse][[/noparse] I/O Definitions ]
LMotor CON 13 ' left servo motor
RMotor CON 12 ' right servo motor
LLineSnsPwr CON 10 ' left line sensor power
LLineSnsIn CON 9 ' left line sensor input
RLineSnsPwr CON 7 ' right line sensor power
RLineSnsIn CON 8 ' right line sensor input
LfIrOut CON 4 ' left IR LED output
LfIrIn VAR IN11 ' left IR sensor input
RtIrOut CON 15 ' right IR LED output
RtIrIn VAR IN14 ' right IR sensor input
Speaker CON 1 ' piezo speaker
StartLED CON 0 ' display start delay
'
[noparse][[/noparse] Constants ]
LFwdFast CON 1000 ' left motor forward; fast
LFwdSlow CON 800 ' left motor forward; slow
LStop CON 750 ' left motor stop
LRevSlow CON 700 ' left motor reverse; slow
LRevFast CON 500 ' left motor reverse; fast
RFwdFast CON 500 ' right motor forward; fast
RFwdSlow CON 700 ' right motor forward; slow
RStop CON 750 ' right motor stop
RRevSlow CON 800 ' right motor reverse; slow
RRevFast CON 1000 ' right motor reverse; fast
'
[noparse][[/noparse] Variables ]
leftSense VAR Word ' left sensor raw reading
rightSense VAR Word ' right sensor raw reading
blackThresh VAR Word ' QTI black threshold setting
lineBits VAR Nib ' decoded sensors value
lineLeft VAR lineBits.BIT1
lineRight VAR lineBits.BIT0
irBits VAR Nib ' storage for IR target data
irLeft VAR irBits.BIT1
irRight VAR irBits.BIT0
lastIr VAR Nib ' info from last reading
pulses VAR Byte ' counter for motor control
temp VAR Byte
'
[noparse][[/noparse] EEPROM Data ]
RunStatus DATA $00 ' run status
'
[noparse][[/noparse] Initialization ]
Run_Check: ' user Reset button as On-Off
READ RunStatus, temp ' read current status
temp = ~temp ' invert status
WRITE RunStatus, temp ' save status for next reset
IF (temp = 0) THEN Set_Threshold ' run now?
END ' -- no ... next time
' Sets black threshold to 1/4 the average of the two sensor readings.
' SumoBot must be placed over black playing surface before this code runs.
Set_Threshold: ' set QTI black threshold
GOSUB Read_Line_Sensors
blackThresh = (leftSense / 8) + (rightSense / 8)
Start_Delay: ' mandatory five second delay
FOR temp = 1 TO 5
HIGH StartLED ' show active
PAUSE 900
INPUT StartLED ' blink each second
FREQOUT Speaker, 100, 2500, 3000 ' beep each second
NEXT
GOTO Lunge ' start aggressive!
'
[noparse][[/noparse] Main Code ]
Main:
GOSUB Read_Line_Sensors
' If not on the Shikiri line (border), continue to look for opponent,
' otherwise, spin back toward center and resume search
BRANCH lineBits, [noparse][[/noparse]Search_For_Opponent, Spin_Left, Spin_Right, About_Face]
' --[noparse][[/noparse] Border Avoidance ]--
Spin_Left: ' right sensor was active
FOR pulses = 1 TO 20
PULSOUT LMotor, LRevFast
PULSOUT RMotor, RFwdFast
PAUSE 20
NEXT
lastIr = %00 ' clear scan direction
GOTO Lunge
Spin_Right: ' left sensor was active
FOR pulses = 1 TO 20
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
lastIr = %00
GOTO Lunge
About_Face: ' both sensors on Shikiri line
FOR pulses = 1 TO 10 ' back up from edge
PULSOUT LMotor, LRevFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
FOR pulses = 1 TO 30 ' turn around
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
lastIr = %00
GOTO Lunge
' --[noparse][[/noparse] IR Processing ]--
Search_For_Opponent:
GOSUB Read_IR_Sensors
' If opponent is not in view, scan last known direction. Turn toward
' opponent if seen by one "eye" -- if both, lunge forward
BRANCH irBits, [noparse][[/noparse]Scan, Follow_Right, Follow_Left, Lunge]
Scan:
BRANCH lastIR, [noparse][[/noparse]Move_Fwd, Scan_Right, Scan_Left]
Move_Fwd:
GOSUB Creep_Forward
GOTO Main
Scan_Right: ' spin right, slow
FOR pulses = 1 TO 5
PULSOUT LMotor, LFwdSlow
PULSOUT RMotor, RRevSlow
PAUSE 20
NEXT
GOSUB Creep_Forward ' keep moving
GOTO Main
Scan_Left: ' spin left, slow
FOR pulses = 1 TO 5
PULSOUT LMotor, LRevSlow
PULSOUT RMotor, RFwdSlow
PAUSE 20
NEXT
GOSUB Creep_Forward
GOTO Main
Follow_Right: ' spin right, fast
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevSlow
lastIR = irBits ' save last direction found
GOTO Main
Follow_Left: ' spin left, fast
PULSOUT LMotor, LRevSlow
PULSOUT RMotor, RFwdFast
lastIR = irBits
GOTO Main
Lunge: ' locked on -- go get him!
FOR pulses = 1 TO 15
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RFwdFast
GOSUB Read_Line_Sensors
IF (lineBits = %11) THEN Match_Over ' in sight and we're on the line
NEXT
GOTO Main
' If SumoBot can see the opponent with both "eyes" and both QTIs are
' detecting the border, we must have pushed the opponent out.
Match_Over:
FOR pulses = 1 TO 10 ' stop motors
PULSOUT LMotor, LStop
PULSOUT RMotor, RStop
PAUSE 20
NEXT
INPUT LMotor
INPUT RMotor
FOR temp = 1 TO 10 ' make some noise
HIGH StartLED
FREQOUT Speaker, 100, 2500, 3000 ' beep
INPUT StartLED ' blink LED
PAUSE 100
NEXT
DIRS = $0000 ' disable all outputs
GOTO Run_Check ' reset for next round
'
[noparse][[/noparse] Subroutines ]
Read_Line_Sensors:
HIGH LLineSnsPwr ' activate sensors
HIGH RLineSnsPwr
HIGH LLineSnsIn ' discharge QTI caps
HIGH RLineSnsIn
PAUSE 1
RCTIME LLineSnsIn, 1, leftSense ' read left sensor
RCTIME RLineSnsIn, 1, rightSense ' read right sensor
LOW LLineSnsPwr ' deactivate sensors
LOW RLineSnsPwr
' convert readings to bits
lineBits = %00
LOOKDOWN leftSense, >=[noparse][[/noparse]blackThresh, 0], lineLeft
LOOKDOWN rightSense, >=[noparse][[/noparse]blackThresh, 0], lineRight
RETURN
Read_IR_Sensors:
FREQOUT LfIrOut, 1, 38500 ' modulate left IR LED
irLeft = ~LfIrIn ' read input (1 = target)
FREQOUT RtIrOut, 1, 38500 ' modulate right IR LED
irRight = ~RtIrIn ' read input (1 = target)
RETURN
Creep_Forward:
FOR pulses = 1 TO 10
PULSOUT LMotor, LFwdSlow
PULSOUT RMotor, RFwdSlow
PAUSE 20
NEXT
RETURN
'
[noparse][[/noparse] Title ]
' zippy_sumobot.bs2
' {$STAMP BS2}
' This program controls a Parallax MiniSumo Bot equipped with 2 QTI line
' sensors and 2 IR-based object detectors.
' This program is based on the Parallax published program
' Mini Sumo 5.1 : Basic Competition Program
' The main logic is different.
' The robot will go forward unless it detects another robot to the
' right or left, in which case it turns in the appropriate direction.
'
' When it detects the white line at the edge of the sumo ring, the
' robot will back up, turn to the right a bit, and continue forward
' again.
' The robot does not stop at the end of the match, it keeps going forever.
'
[noparse][[/noparse] I/O Definitions ]
LMotor CON 13 ' left servo motor
RMotor CON 12 ' right servo motor
LLineSnsPwr CON 10 ' left line sensor power
LLineSnsIn CON 9 ' left line sensor input
RLineSnsPwr CON 7 ' right line sensor power
RLineSnsIn CON 8 ' right line sensor input
LfIrOut CON 4 ' left IR LED output
LfIrIn VAR IN11 ' left IR sensor input
RtIrOut CON 15 ' right IR LED output
RtIrIn VAR IN14 ' right IR sensor input
Speaker CON 1 ' piezo speaker
StartLED CON 0 ' display start delay
'
[noparse][[/noparse] Constants ]
LFwdFast CON 1000 ' left motor forward; fast
LFwdSlow CON 800 ' left motor forward; slow
LStop CON 750 ' left motor stop
LRevSlow CON 700 ' left motor reverse; slow
LRevFast CON 500 ' left motor reverse; fast
RFwdFast CON 500 ' right motor forward; fast
RFwdSlow CON 700 ' right motor forward; slow
RStop CON 750 ' right motor stop
RRevSlow CON 800 ' right motor reverse; slow
RRevFast CON 1000 ' right motor reverse; fast
BackupTime CON 20 ' len time robot backs up
TurnTime CON 20 ' len time robot turns rt
'
[noparse][[/noparse] Variables ]
leftSense VAR Word ' left sensor raw reading
rightSense VAR Word ' right sensor raw reading
blackThresh VAR Word ' QTI black threshold setting
lineBits VAR Nib ' decoded sensors value
lineLeft VAR lineBits.BIT1
lineRight VAR lineBits.BIT0
irBits VAR Nib ' storage for IR target data
irLeft VAR irBits.BIT1
irRight VAR irBits.BIT0
lastIr VAR Nib ' info from last reading
pulses VAR Byte ' counter for motor control
temp VAR Byte
'
[noparse][[/noparse] EEPROM Data ]
RunStatus DATA $00 ' run status
'
[noparse][[/noparse] Initialization ]
Run_Check: ' user Reset button as On-Off
READ RunStatus, temp ' read current status
temp = ~temp ' invert status
WRITE RunStatus, temp ' save status for next reset
IF (temp = 0) THEN Set_Threshold ' run now?
END ' -- no ... next time
' Sets black threshold to 1/4 the average of the two sensor readings.
' SumoBot must be placed over black playing surface before this code runs.
Set_Threshold: ' set QTI black threshold
GOSUB Read_Line_Sensors
blackThresh = (leftSense / 8) + (rightSense / 8)
Start_Delay: ' mandatory five second delay
FOR temp = 1 TO 5
HIGH StartLED ' show active
PAUSE 900
INPUT StartLED ' blink each second
FREQOUT Speaker, 100, 2500, 3000 ' beep each second
NEXT
'
[noparse][[/noparse] Main Code ]
Main:
GOSUB Read_Line_Sensors
' If either sensor is on the line...
IF ( (lineLeft = 1) OR (lineRight = 1)) THEN White_Line
' ...else check IR sensors
GOSUB Read_IR_Sensors
' Determine direction to go, depending on what was detected
BRANCH irBits, [noparse][[/noparse] Forward_Pulse, Right_Pulse, Left_Pulse, Forward_Pulse]
'
[noparse][[/noparse] Subroutines ]
Read_Line_Sensors:
HIGH LLineSnsPwr ' activate sensors
HIGH RLineSnsPwr
HIGH LLineSnsIn ' discharge QTI caps
HIGH RLineSnsIn
PAUSE 1
RCTIME LLineSnsIn, 1, leftSense ' read left sensor
RCTIME RLineSnsIn, 1, rightSense ' read right sensor
LOW LLineSnsPwr ' deactivate sensors
LOW RLineSnsPwr
' convert readings to bits
lineBits = %00
LOOKDOWN leftSense, >=[noparse][[/noparse]blackThresh, 0], lineLeft
LOOKDOWN rightSense, >=[noparse][[/noparse]blackThresh, 0], lineRight
RETURN
Read_IR_Sensors:
FREQOUT LfIrOut, 1, 38500 ' modulate left IR LED
irLeft = ~LfIrIn ' read input (1 = target)
FREQOUT RtIrOut, 1, 38500 ' modulate right IR LED
irRight = ~RtIrIn ' read input (1 = target)
RETURN
White_Line:
GOSUB Backward
GOSUB Right_Turn
GOTO Main
Right_Turn:
FOR pulses = 1 TO TurnTime
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
RETURN
Backward:
FOR pulses = 1 TO BackupTime
PULSOUT LMotor, LRevFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
RETURN
Forward_Pulse:
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RFwdFast
GOTO Main
Left_Pulse:
PULSOUT LMotor, LRevFast
PULSOUT RMotor, RFwdFast
GOTO Main
Right_Pulse:
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevFast
GOTO Main
' SumoBot-5.1-Basic-Competition-Program.BS2
' {$STAMP BS2}
' {$PBASIC 2.5}
'
[noparse][[/noparse] I/O Definitions ]
LMotor PIN 13 ' left servo motor
RMotor PIN 12 ' right servo motor
LLinePwr PIN 10 ' left line sensor power
LLineIn PIN 9 ' left line sensor input
RLinePwr PIN 7 ' right line sensor power
RLineIn PIN 8 ' right line sensor input
LfIrOut PIN 4 ' left IR LED output
LfIrIn PIN 11 ' left IR sensor input
RtIrOut PIN 15 ' right IR LED output
RtIrIn PIN 14 ' right IR sensor input
Speaker PIN 1 ' piezo speaker
StartLED PIN 0 ' display start delay
'
[noparse][[/noparse] Constants ]
LFwdFast CON 1000 ' left motor fwd; fast
LFwdSlow CON 800 ' left motor fwd; slow
LStop CON 750 ' left motor stop
LRevSlow CON 700 ' left motor rev; slow
LRevFast CON 500 ' left motor rev; fast
RFwdFast CON 500 ' right motor fwd; fast
RFwdSlow CON 700 ' right motor fwd; slow
RStop CON 750 ' right motor stop
RRevSlow CON 800 ' right motor rev; slow
RRevFast CON 1000 ' right motor rev; fast
'
[noparse][[/noparse] Variables ]
lLine VAR Word ' left sensor raw reading
rLine VAR Word ' right sensor raw reading
blackThresh VAR Word ' QTI black threshold
lineBits VAR Nib ' decoded sensors value
lbLeft VAR lineBits.BIT1
lbRight VAR lineBits.BIT0
irBits VAR Nib ' IR readings (l & r)
irLeft VAR irBits.BIT1
irRight VAR irBits.BIT0
lastIr VAR Nib ' info from last reading
pulses VAR Byte ' counter for motor control
temp VAR Byte
'
[noparse][[/noparse] EEPROM Data ]
RunStatus DATA $00 ' run status
'
[noparse][[/noparse] Initialization ]
Reset:
READ RunStatus, temp ' read current status
temp = ~temp ' invert status
WRITE RunStatus, temp ' save for next reset
IF (temp > 0) THEN END ' okay to run?
' Sets black threshold to 1/4 the average of the two sensor readings.
' SumoBot must be placed over black playing surface before this code runs.
Set_Threshold: ' set QTI black threshold
GOSUB Read_Line_Sensors
blackThresh = (lLine / 10) + (rLine / 10)
LOW LMotor ' make more pins outputs
LOW RMotor
Start_Delay: ' five second delay
FOR temp = 1 TO 5
HIGH StartLED ' show active
PAUSE 900
INPUT StartLED ' blink each second
FREQOUT Speaker, 100, 2500, 3000 ' beep each second
NEXT
GOTO Lunge ' start aggressive!
'
[noparse][[/noparse] Program Code ]
Main:
GOSUB Read_Line_Sensors
' If not on the Shikiri line (border), continue to look for opponent,
' otherwise, spin back toward center and resume search
BRANCH lineBits, [noparse][[/noparse]Search_For_Opponent, Spin_Left, Spin_Right, About_Face]
' --[noparse][[/noparse] Border Avoidance ]--
Spin_Left: ' right sensor was active
FOR pulses = 1 TO 20
PULSOUT LMotor, LRevFast
PULSOUT RMotor, RFwdFast
PAUSE 20
NEXT
lastIr = %00 ' clear scan direction
GOTO Lunge
Spin_Right: ' left sensor was active
FOR pulses = 1 TO 20
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
lastIr = %00
GOTO Lunge
About_Face: ' both sensors on Shikiri
FOR pulses = 1 TO 10 ' back up from edge
PULSOUT LMotor, LRevFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
FOR pulses = 1 TO 30 ' turn around
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevFast
PAUSE 20
NEXT
lastIr = %00
GOTO Lunge
' --[noparse][[/noparse] IR Processing ]--
Search_For_Opponent:
GOSUB Read_IR_Sensors
' If opponent is not in view, scan last known direction. Turn toward
' opponent if seen by one "eye" -- if both, lunge forward
BRANCH irBits, [noparse][[/noparse]Scan, Follow_Right, Follow_Left, Lunge]
Scan:
BRANCH lastIR, [noparse][[/noparse]Move_Fwd, Scan_Right, Scan_Left]
Move_Fwd:
GOSUB Creep_Forward
GOTO Main
Scan_Right: ' spin right, slow
FOR pulses = 1 TO 5
PULSOUT LMotor, LFwdSlow
PULSOUT RMotor, RRevSlow
PAUSE 20
NEXT
GOSUB Creep_Forward ' keep moving
GOTO Main
Scan_Left: ' spin left, slow
FOR pulses = 1 TO 5
PULSOUT LMotor, LRevSlow
PULSOUT RMotor, RFwdSlow
PAUSE 20
NEXT
GOSUB Creep_Forward
GOTO Main
Follow_Right: ' spin right, fast
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RRevSlow
lastIR = irBits ' save last direction found
GOTO Main
Follow_Left: ' spin left, fast
PULSOUT LMotor, LRevSlow
PULSOUT RMotor, RFwdFast
lastIR = irBits
GOTO Main
Lunge: ' locked on -- go get him!
FOR pulses = 1 TO 25
PULSOUT LMotor, LFwdFast
PULSOUT RMotor, RFwdFast
GOSUB Read_Line_Sensors
IF (lineBits = %11) THEN Match_Over ' in sight, we're on the line
NEXT
GOTO Main
' If SumoBot can see the opponent with both "eyes" and both QTIs are
' detecting the border, we must have pushed the opponent out.
Match_Over:
FOR pulses = 1 TO 10 ' stop motors
PULSOUT LMotor, LStop
PULSOUT RMotor, RStop
PAUSE 20
NEXT
INPUT LMotor
INPUT RMotor
FOR temp = 1 TO 10 ' make some noise
HIGH StartLED
FREQOUT Speaker, 100, 2500, 3000 ' beep
INPUT StartLED ' blink LED
PAUSE 100
NEXT
DIRS = $0000 ' disable all outputs
GOTO Reset ' reset for next round
'
[noparse][[/noparse] Subroutines ]
Read_Line_Sensors:
HIGH LLinePwr ' activate sensors
HIGH RLinePwr
HIGH LLineIn ' discharge caps
HIGH RLineIn
PAUSE 1
RCTIME LLineIn, 1, lLine ' read left sensor
RCTIME RLineIn, 1, rLine ' read right sensor
LOW LLinePwr ' deactivate sensors
LOW RLinePwr
' convert readings to bits
LOOKDOWN lLine, >=[noparse][[/noparse]1000, 0], lbLeft ' 0 = black, 1 = line
LOOKDOWN rLine, >=[noparse][[/noparse]1000, 0], lbRight
RETURN
Read_IR_Sensors:
FREQOUT LfIrOut, 1, 38500 ' modulate left IR LED
irLeft = ~LfIrIn ' read input (1 = target)
FREQOUT RtIrOut, 1, 38500 ' modulate right IR LED
irRight = ~RtIrIn ' read input (1 = target)
RETURN
Creep_Forward:
FOR pulses = 1 TO 20
PULSOUT LMotor, LFwdSlow
PULSOUT RMotor, RFwdSlow
PAUSE 20
NEXT
RETURN