Shop OBEX P1 Docs P2 Docs Learn Events
Multiple Tasks in a Do...Loop — Parallax Forums

Multiple Tasks in a Do...Loop

surfline27surfline27 Posts: 8
edited 2011-11-13 18:04 in Robotics
Hi there,

I'm using the Boe-Bot kit with Basic Stamp Editor to complete a "mission" which is to make the Boe-Bot navigate through an obstacle course (which is a white floor surrounded by black spray paint as a border) and stop when it detects a bright light near it using the phototransistor (like a desk lamp pointing downwards). I have used whiskers, IR sensors and a phototransistor.

My problem is that I have all the stuff I need each part to do its task but I'm having trouble putting it all together in one Do...Loop statement

For example to go through the course I would make it:

1. Check ambient light (before the Do...Loop statement)
2. Check IR sensors (for sensing black)
3. Check whiskers (for objects in the way)
4. And then start moving through the course

I tried this:

(Check Ambient light)
Do
IF...Then... (for IR sensors with a bunch of ElseIf statements in it for the left and right sensors)
ElseIf...Then...(whiskers with a bunch of ElseIf statements in it for the left and right whiskers)
ElseIf...Then...(checking for the desk lamp)
EndIf

(code for moving forward)
Loop

But it doesn't do all the tasks....it will detect the black with the IR sensors and avoid it but if one of the whiskers is hit, it won't do anything about it (it will keep moving forward).

How do I put it all together in the Do...Loop statement so it can perform whatever task is needed?


Any help would be appreciated

Comments

  • ercoerco Posts: 20,255
    edited 2011-11-11 17:17
    Should be very possible. You should attach your exact code with comments for help.
  • surfline27surfline27 Posts: 8
    edited 2011-11-11 18:07
    This is the code:

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    
    
    irDetectLeft VAR Bit ' Variable Declarations
    irDetectRight VAR Bit
    pulseLeft VAR Word
    pulseRight VAR Word
    pulseCount VAR Byte
    Initial_Light_Level VAR Word
    Other_Ligh_Level VAR Word
    
    
    HIGH 6 ' 1 Set P6 high to start charging
    PAUSE 1 ' 2 Wait for cap to charge
    RCTIME 6, 1, Initial_Light_Level ' 3 P6->input, measure decay time
    
    DO
    
    FREQOUT 8, 1, 38500 ' Check IR Detectors
    irDetectLeft = IN9
    FREQOUT 2, 1, 38500
    irDetectRight = IN0
    
    
    
    '------IR SENSORS-------------------------------------------------------------------
    IF (irDetectLeft = 1) AND (irDetectRight = 1) THEN
    HIGH 10
    HIGH 1
    pulseLeft = 700
    pulseRight = 850
    ELSEIF (irDetectRight = 1) THEN
    LOW 10
    HIGH 1
    pulseLeft = 710
    pulseRight = 650
    ELSEIF (irDetectLeft = 1) THEN
    HIGH 10
    LOW 1
    pulseLeft = 850
    pulseRight = 790
    ELSEIF (irDetectLeft = 0) AND (irDetectRight = 0)  THEN
    LOW 10
    LOW 1
    pulseLeft = 800
    pulseRight = 650
    
    '-----WHISKERS-----------------------------------------------------------------
    ELSEIF (IN7 = 0) AND (IN11 = 0) THEN ' Both whiskers detect obstacle
    HIGH 10
    HIGH 1
    FOR pulseCount = 0 TO 10     ' Back up
    pulseLeft = 700
    pulseRight = 850
    PAUSE 20
    NEXT
    RETURN
    FOR pulseCount = 0 TO 8       ' Left
    pulseLeft = 650
    pulseRight = 650
    PAUSE 20
    NEXT
    RETURN                         ' Left
    FOR pulseCount = 0 TO 8
    pulseLeft = 650
    pulseRight = 650
    PAUSE 20
    NEXT
    RETURN
    
    
    ELSEIF (IN7 = 0) THEN ' Left whisker contacts
    HIGH 10
    LOW 1
    FOR pulseCount = 0 TO 10       ' Back up
    pulseLeft = 700
    pulseRight = 850
    PAUSE 20
    NEXT
    RETURN
    FOR pulseCount = 0 TO 8           ' Right
    pulseLeft = 850
    pulseRight = 850
    PAUSE 20
    NEXT
    RETURN
    
    
    ELSEIF (IN11 = 0) THEN ' Right whisker contacts
    LOW 10
    HIGH 1
    FOR pulseCount = 0 TO 10        ' Back up
    pulseLeft = 700
    pulseRight = 850
    PAUSE 20
    NEXT
    RETURN
    FOR pulseCount = 0 TO 8          ' Left
    pulseLeft = 650
    pulseRight = 650
    PAUSE 20
    NEXT
    RETURN
    
    ELSEIF (IN7 = 1) AND (IN11 = 1) THEN
    pulseLeft = 800
    pulseRight= 650
    ENDIF
    
    PULSOUT 13,pulseLeft
    PULSOUT 12,pulseRight
    PAUSE 15
    
    LOOP
    
    

    The part that I haven't finished yet is to check for the desk lamp light at the end
  • SRLMSRLM Posts: 5,045
    edited 2011-11-11 19:49
    I would suggest recoding with a state machine. In embedded systems (aka, BS2 stuff) the standard way to do lots of concurrent tasks with a single threaded processor is to use one or more state machines. A google search for "PBASIC state machine" turns up lots of nice examples. You'll probably also want to learn how to draw out the graphical representation of a state machine as well.
  • ercoerco Posts: 20,255
    edited 2011-11-11 20:16
    I think you need an ENDIF or two in there. I'd ENDIF before WHISKERS and start a new IF check at WHISKERS. I'd also use ENDIF before you look for ambient light, and use a new IF check for that.
  • surfline27surfline27 Posts: 8
    edited 2011-11-12 18:12
    If I put them in two separate If...Then... statements then the whiskers one works (because I changed to subroutines) but the IR sensors go crazy (LEDs blinking rapidly and bot shaking like crazy) if it detects the edge...it won't turn away from it.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    
    
    irDetectLeft VAR Bit ' Variable Declarations
    irDetectRight VAR Bit
    pulseLeft VAR Word
    pulseRight VAR Word
    pulseCount VAR Byte
    Initial_Light_Level VAR Word
    Other_Ligh_Level VAR Word
    
    
    HIGH 6 ' 1 Set P6 high to start charging
    PAUSE 1 ' 2 Wait for cap to charge
    RCTIME 6, 1, Initial_Light_Level ' 3 P6->input, measure decay time
    
    DO
    
    FREQOUT 12, 1, 38500 ' Check IR Detectors
    irDetectLeft = IN14
    FREQOUT 2, 1, 38500
    irDetectRight = IN0
    
    
    '------[ IR SENSORS ]-------------------------------------------------------------------
    IF (irDetectLeft = 1) AND (irDetectRight = 1) THEN
    HIGH 15
    HIGH 1
    pulseLeft = 700
    pulseRight = 850
    ELSEIF (irDetectRight = 1) THEN
    LOW 15
    HIGH 1
    pulseLeft = 710
    pulseRight = 650
    ELSEIF (irDetectLeft = 1) THEN
    HIGH 15
    LOW 1
    pulseLeft = 850
    pulseRight = 790
    ELSE
    LOW 15
    LOW 1
    pulseLeft = 800
    pulseRight = 650
    ENDIF
    
    
    '-----[ WHISKERS ]-----------------------------------------------------------------
    IF (IN7 = 0) AND (IN11 = 0) THEN ' Both whiskers detect obstacle
    HIGH 15
    HIGH 1
    GOSUB Back_Up ' Back up & U-turn (left twice)
    GOSUB Turn_Left
    GOSUB Turn_Left
    GOSUB Turn_Left
    GOSUB Turn_Left
    ELSEIF (IN7 = 0) THEN ' Left whisker contacts
    HIGH 15
    LOW 1
    GOSUB Back_Up ' Back up & turn right
    GOSUB Turn_Right
    ELSEIF (IN11 = 0) THEN ' Right whisker contacts
    LOW 15
    HIGH 1
    GOSUB Back_Up ' Back up & turn left
    GOSUB Turn_Left
    ELSE ' Both whiskers 1, no contacts
    LOW 15
    LOW 1
    GOSUB Forward_Pulse ' Apply a forward pulse
    ENDIF ' and check again
    
    PULSOUT 13,pulseLeft
    PULSOUT 12,pulseRight
    PAUSE 15
    
    LOOP
    
    
    
    
    ' -----[ WHISKER Subroutines ]--------------------------------------------------------
    Forward_Pulse: ' Send a single forward pulse.
    PULSOUT 13,800
    PULSOUT 12,650
    PAUSE 20
    RETURN
    Turn_Left: ' Left turn, about 90-degrees.
    FOR pulseCount = 0 TO 10
    PULSOUT 13, 650
    PULSOUT 12, 650
    PAUSE 20
    NEXT
    RETURN
    Turn_Right:
    FOR pulseCount = 0 TO 10 ' Right turn, about 90-degrees.
    PULSOUT 13, 850
    PULSOUT 12, 850
    PAUSE 20
    NEXT
    RETURN
    Back_Up: ' Back up.
    FOR pulseCount = 0 TO 10
    PULSOUT 13, 700
    PULSOUT 12, 850
    PAUSE 20
    NEXT
    RETURN
    
    
  • ercoerco Posts: 20,255
    edited 2011-11-12 19:42
    Your whiskers subroutines each send a single pulse, which isn't enough. Try sending a group of pulses (dunno, a loop of a hundred to start) and see the difference.
  • surfline27surfline27 Posts: 8
    edited 2011-11-13 12:58
    Ok so I finally got both the IR Sensors and Whiskers to work by using the same subroutines for both. The other problem I have is making the bot stop when it reaches the light which I am having trouble with writing the code.

    This is how it looks so far after changing some stuff:
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    
    
    irDetectLeft VAR Bit ' Variable Declarations
    irDetectRight VAR Bit
    pulseLeft VAR Word
    pulseRight VAR Word
    pulseCount VAR Byte
    tLeft VAR Word
    
    
    
    
    PWM 6, 80, 1                              ' Charge cap to 3.59 V
    RCTIME 6, 1,tLeft
    PAUSE 100
    
    
    DO UNTIL tLeft = 0
    
    
    FREQOUT 12, 1, 38500 ' Check IR Detectors
    irDetectLeft = IN14
    FREQOUT 2, 1, 38500
    irDetectRight = IN0
    
    
    '------[ IR SENSORS ]-------------------------------------------------------------------
    IF (irDetectLeft = 1) AND (irDetectRight = 1) THEN
    HIGH 15
    HIGH 1
    GOSUB Back_Up
    ELSEIF (irDetectRight = 1) THEN
    LOW 15
    HIGH 1
    GOSUB Turn_Left
    ELSEIF (irDetectLeft = 1) THEN
    HIGH 15
    LOW 1
    GOSUB Turn_Right
    ELSE
    LOW 15
    LOW 1
    GOSUB Forward_Pulse
    ENDIF
    
    
    '-----[ WHISKERS ]-----------------------------------------------------------------
    IF (IN7 = 0) AND (IN11 = 0) THEN ' Both whiskers detect obstacle
    HIGH 15
    HIGH 1
    GOSUB Back_Up ' Back up & U-turn (left twice)
    GOSUB Turn_Left
    GOSUB Turn_Left
    GOSUB Turn_Left
    GOSUB Turn_Left
    ELSEIF (IN7 = 0) THEN ' Left whisker contacts
    HIGH 15
    LOW 1
    GOSUB Back_Up ' Back up & turn right
    GOSUB Turn_Right
    ELSEIF (IN11 = 0) THEN ' Right whisker contacts
    LOW 15
    HIGH 1
    GOSUB Back_Up ' Back up & turn left
    GOSUB Turn_Left
    ELSE ' Both whiskers 1, no contacts
    LOW 15
    LOW 1
    GOSUB Forward_Pulse ' Apply a forward pulse
    ENDIF ' and check again
    
    PULSOUT 13,pulseLeft
    PULSOUT 12,pulseRight
    PAUSE 15
    
    
    
    LOOP
    
    
    
    
    ' -----[ WHISKER Subroutines ]--------------------------------------------------------
    Forward_Pulse: ' Send a single forward pulse.
    PULSOUT 13,800
    PULSOUT 12,650
    PAUSE 20
    RETURN
    Turn_Left: ' Left turn, about 90-degrees.
    FOR pulseCount = 0 TO 10
    PULSOUT 13, 650
    PULSOUT 12, 650
    PAUSE 20
    NEXT
    RETURN
    Turn_Right:
    FOR pulseCount = 0 TO 10 ' Right turn, about 90-degrees.
    PULSOUT 13, 850
    PULSOUT 12, 850
    PAUSE 20
    NEXT
    RETURN
    Back_Up: ' Back up.
    FOR pulseCount = 0 TO 10
    PULSOUT 13, 700
    PULSOUT 12, 850
    PAUSE 20
    NEXT
    RETURN
    
    
    
  • surfline27surfline27 Posts: 8
    edited 2011-11-13 14:07
    Ok I finally got everything to work properly.

    Thanks for all your help guys.
  • FranklinFranklin Posts: 4,747
    edited 2011-11-13 16:22
    Ok I finally got everything to work properly.
    Great, now you should turn off the unsolved tag to let others know it is solved.
  • surfline27surfline27 Posts: 8
    edited 2011-11-13 17:55
    Franklin wrote: »
    Great, now you should turn off the unsolved tag to let others know it is solved.

    How do I turn it off?
  • FranklinFranklin Posts: 4,747
    edited 2011-11-13 18:01
    Edit the top post and change it there. I don't use those tags so I have never had to do that, but I know it can be done. If you can't figure it out I'm sure there will be someone here that can explain it better.Also welcome to the forums.
  • ercoerco Posts: 20,255
    edited 2011-11-13 18:04
    Yes by all means, congrats & welcome, surfline27!
Sign In or Register to comment.