Shop OBEX P1 Docs P2 Docs Learn Events
Help need with Ping))) or IR object detection — Parallax Forums

Help need with Ping))) or IR object detection

ScorpioScorpio Posts: 6
edited 2012-04-26 10:10 in Accessories
Hi everyone,
I am designing my boe bot go race around a circuit. The circuit has borders on the outside and the inside so the boe bot can remain within those borders (using QTIs).
The main problem I am having is detecting and avoiding the objects. I'm using the Ping Dar (without the mounting bracket and servo) to detect and avoid the objects.
Since I do not have a mounting bracket and servo, I made the boe bot partially turn left then center then to the right to obtain the largest distance. However, when the
boe bot detects the object, it continuously goes left center , center - right and it never seems to go the direction with the longest distance.
My other alternative is to use the IR setup to detect and avoid the objects, but I know the other boe bots will use IR jammers to interfere with my bot's detection. I attempted
to incorporate the IR Roaming with IR sniffer provided in the Robotics book. However, the boe bot simply stops and makes a sound when it dectects IR interference, which is
not efficient enough for the race (The bot would be forever stopping )
Can anyone kindly help me with fixing the Ping Dar code or finding a method using IRs that cannot be easily disrupt by jammers?

Here is my code for the Ping Dar )))..I used the RoamingWithPING.bs2 as a guideline.
The code is not complete. I am trying to get the Ping Dar to work.

Your speedy and favorable response will be greatly appreciated.
Scorpio
' {$STAMP BS2}                            ' Target device = BASIC Stamp 2
' {$PBASIC 2.5}                           ' Language = PBASIC 2.5

' -----[ I/O Definitions & Constants ]-------------------------------------------------
Ping            PIN     15              ' PING))) Sensor
Piezo           PIN     3               ' Piezo Speaker


' -----[ Variables ]------------------------------------------------------------------------


pulseCount      VAR   Byte                ' FOR..NEXT loop counter for turning
qtis            VAR   Nib                 ' QTI black/white states
LastMove        VAR   Nib                 'Remembers the last move boe bot made
                                          'LastMove: 2-forward, 6-forward and left, 3-forward and right

Turn            VAR     Nib             ' Current Task

pulseLeft VAR Word
pulseRight VAR Word


distance        VAR     Word            ' Current Distance Of Object
oldDistance     VAR     Word            ' Old Distance Value
attempt         VAR     Word            ' Keeps count of the number of attempts made
counter         VAR     Word            ' PING))) Cycle Counter



' -----[ Initialization ]-------------------------------------------------------------------

OUTB = 11                              ' Set OUTB bits to 1
FREQOUT Piezo, 1000, 2000                    ' Battery Tester
LastMove = 2  'Forward
distance = 30



' -----[ Main Routine ]---------------------------------------------------------------------
'Main:
DO                                        ' Main DO...LOOP
  ' Get QTI states
  DIRB = 11                            ' P7..P4 -> output
  PAUSE 0                                 ' Delay = 230 us
  DIRB = 00                            ' P7..P4 -> input
  PAUSE 0                                 ' Delay = 230 us
  qtis = INB                              ' Store QTI outputs in INB


  SELECT qtis

  CASE 00
  GOSUB Ping_Out                           ' PING)))-- Scan For objects in pathway
  IF (distance > 30) THEN
    GOSUB Forward               ' If Yes Go Forward
  ELSE
    GOSUB Decide_Turn
  ENDIF


  ENDSELECT

  PULSOUT 13,pulseLeft ' Apply the pulses.
  PULSOUT 12,pulseRight

  PAUSE 15

LOOP

' -----[ Subroutines - Turn_Check ]---------------------------------------------------------
Ping_Out:                               ' PING)))

  LOW Ping                              ' Force PING))) Line Low
  PULSOUT Ping, 5                       ' Activate PING))) Pulse
  PULSIN  Ping, 1, distance             ' Receive Return Pulse

  distance = distance ** 2257           ' Calculate Distance In cm

  RETURN


'NOTE: THE SUBROUTINES CONTAIN ALL POSSIBLE MANEUVERS FOR THE BOE BOT SERVOS
'      SOME MAY NOT BE USED IN THE PARTICULAR PROGRAM



' -----[ Subroutines - Forward ]---------------------------------------------------------
Forward:
 pulseLeft = 850
 pulseRight = 663

  RETURN

' -----[ Subroutines - Rotate_Left ]---------------------------------------------------------
Rotate_Left:


  pulseLeft = 650
  pulseRight = 650
  RETURN

' -----[ Subroutines - Rotate_Right ]---------------------------------------------------------
Rotate_Right:


  pulseLeft = 850
  pulseRight = 850
  RETURN


' -----[ Subroutines - Backup ]---------------------------------------------------------
Backup:

    PULSOUT 13, 650              ' Left Servo Backup Pulse Value
    PULSOUT 12, 850             ' Right Servo Backup Pulse Value

  RETURN




Stop_Moving:
  PULSOUT 13, 750
  PULSOUT 12, 750
RETURN

Decide_Turn:

  oldDistance = 30                      ' Current Old Distance Values
  Turn = 0

  GOSUB Stop_Moving

  FOR pulseCount = 0 TO 10
    LOW Ping
    PULSOUT 13,650      'Turns Boe Bot to the left
    PULSOUT 12,650

    PAUSE 20            ' Refresh Delay
 NEXT
 PULSOUT Ping, 5                     ' Activate PING)))
    PULSIN  Ping, 1, distance           ' Receive Distance Value
 distance = distance ** 2257           ' Calculate Distance In cm
  IF distance > oldDistance THEN        ' Is distance > Last Clear Path
   oldDistance = distance              ' Update oldDistance Value
    Turn = 0
  ENDIF

  FOR pulseCount = 0 TO 10
    PULSOUT 13,850      'Turns Boe Bot to the right to return to center
    PULSOUT 12,850
  NEXT

  FOR pulseCount = 0 TO 10
    LOW Ping
    PULSOUT 13,850      'Turns Boe Bot to the Right
    PULSOUT 12,850

    PAUSE 20            ' Refresh Delay
  NEXT
 PULSOUT Ping, 5                     ' Activate PING)))
    PULSIN  Ping, 1, distance           ' Receive Distance Value
 distance = distance ** 2257           ' Calculate Distance In cm
  IF distance > oldDistance THEN        ' Is distance > Last Clear Path
   oldDistance = distance              ' Update oldDistance Value
    Turn = 1
  ENDIF

  FOR pulseCount = 0 TO 10
    PULSOUT 13,650      'Turns Boe Bot to the left to return to center
    PULSOUT 12,650
  NEXT

  ON Turn GOSUB Task0, Task1

  distance = 50

  RETURN

Task0:
'Furthest distance dectected on the left
  FOR pulseCount = 0 TO 10
    PULSOUT 13,650      'Turns Boe Bot to the left to return to center
    PULSOUT 12,650
  NEXT

Task1:
'Furthest distance dectected on the left
  FOR pulseCount = 0 TO 10
    PULSOUT 13,850      'Turns Boe Bot to the left to return to center
    PULSOUT 12,850
  NEXT




Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-04-25 15:07
    On a cursory scan of your program, you've got lots of places (at least 6) where you have loops (like Task0 and Task1) that rapidly output servo control pulses with no PAUSE. The servos will not respond to these rapid pulses and may just vibrate a little without moving. Fix those first by inserting a PAUSE 17 in the loop and see (and report) what happens.
  • ScorpioScorpio Posts: 6
    edited 2012-04-25 18:33
    Ok. Thanks alot..I will insert the pauses and give u an update.
  • ScorpioScorpio Posts: 6
    edited 2012-04-25 19:09
    Ok...I have made as much adjustments as recommended.When the bot detects the object, it will do the scan then decide which path to take. However, the bot sometimes still continues to rotate left to right continuously. I have also realised that when the bot bot moving forward kinda slow although I have it to move at max speed.
    Here is the updated source code.
    ' {$STAMP BS2}                            ' Target device = BASIC Stamp 2
    ' {$PBASIC 2.5}                           ' Language = PBASIC 2.5
    
    ' -----[ I/O Definitions & Constants ]-------------------------------------------------
    Ping            PIN     15              ' PING))) Sensor
    Piezo           PIN     3               ' Piezo Speaker
    
    
    ' -----[ Variables ]------------------------------------------------------------------------
    
    
    pulseCount      VAR   Byte                ' FOR..NEXT loop counter for turning
    qtis            VAR   Nib                 ' QTI black/white states
    LastMove        VAR   Nib                 'Remembers the last move boe bot made
                                              'LastMove: 2-forward, 6-forward and left, 3-forward and right
    
    Turn            VAR     Nib             ' Current Task
    
    pulseLeft VAR Word
    pulseRight VAR Word
    
    
    distance        VAR     Word            ' Current Distance Of Object
    oldDistance     VAR     Word            ' Old Distance Value
    attempt         VAR     Word            ' Keeps count of the number of attempts made
    counter         VAR     Word            ' PING))) Cycle Counter
    
    
    
    ' -----[ Initialization ]-------------------------------------------------------------------
    
    OUTB = 11                              ' Set OUTB bits to 1
    FREQOUT Piezo, 1000, 2000                    ' Battery Tester
    LastMove = 2  'Forward
    distance = 30
    
    
    
    ' -----[ Main Routine ]---------------------------------------------------------------------
    Main:
    DO                                        ' Main DO...LOOP
      ' Get QTI states
      DIRB = 11                            ' P7..P4 -> output
      PAUSE 0                                 ' Delay = 230 us
      DIRB = 00                            ' P7..P4 -> input
      PAUSE 0                                 ' Delay = 230 us
      qtis = INB                              ' Store QTI outputs in INB
    
    
      SELECT qtis
    
      CASE 00
      GOSUB Ping_Out                           ' PING)))-- Scan For objects in pathway
      IF (distance > 30) THEN
        GOSUB Forward               ' If Yes Go Forward
      ELSE
        GOSUB Decide_Turn
      ENDIF
    
    
      ENDSELECT
    
      PULSOUT 13,pulseLeft ' Apply the pulses.
      PULSOUT 12,pulseRight
    
      PAUSE 17
    
    LOOP
    
    ' -----[ Subroutines - Turn_Check ]---------------------------------------------------------
    Ping_Out:                               ' PING)))
    
      LOW Ping                              ' Force PING))) Line Low
      PULSOUT Ping, 5                       ' Activate PING))) Pulse
      PULSIN  Ping, 1, distance             ' Receive Return Pulse
      distance = distance ** 2257           ' Calculate Distance In cm
      RETURN
    
    
    ' -----[ Subroutines - Forward ]---------------------------------------------------------
    Forward:
      pulseLeft = 850
      pulseRight = 663
      PAUSE 17
    RETURN
    
    ' -----[ Subroutines - Rotate_Left ]---------------------------------------------------------
    Rotate_Left:
      pulseLeft = 650
      pulseRight = 650
      PAUSE 17
    RETURN
    
    ' -----[ Subroutines - Rotate_Right ]---------------------------------------------------------
    Rotate_Right:
      pulseLeft = 850
      pulseRight = 850
      PAUSE 17
    RETURN
    
    ' -----[ Subroutines - Backup ]---------------------------------------------------------
    Backup:
        PULSOUT 13, 650              ' Left Servo Backup Pulse Value
        PULSOUT 12, 850             ' Right Servo Backup Pulse Value
        PAUSE 17
    RETURN
    
    Stop_Moving:
      PULSOUT 13, 750
      PULSOUT 12, 750
      PAUSE 17
    RETURN
    
    Decide_Turn:
    
      oldDistance = 30                      ' Current Old Distance Values
      Turn = 0
    
      GOSUB Stop_Moving
    
      FOR pulseCount = 0 TO 10
        LOW Ping
        PULSOUT 13,650      'Turns Boe Bot to the left
        PULSOUT 12,650
        PAUSE 17            ' Refresh Delay
      NEXT
    
      PULSOUT Ping, 5                     ' Activate PING)))
      PULSIN  Ping, 1, distance           ' Receive Distance Value
      distance = distance ** 2257           ' Calculate Distance In cm
      IF distance > oldDistance THEN        ' Is distance > Last Clear Path
        oldDistance = distance              ' Update oldDistance Value
        Turn = 0
      ENDIF
    
      FOR pulseCount = 0 TO 10
        PULSOUT 13,850      'Turns Boe Bot to the right to return to center
        PULSOUT 12,850
        PAUSE 17
      NEXT
    
      FOR pulseCount = 0 TO 10
        LOW Ping
        PULSOUT 13,850      'Turns Boe Bot to the Right
        PULSOUT 12,850
        PAUSE 17            ' Refresh Delay
      NEXT
    
      PULSOUT Ping, 5                     ' Activate PING)))
      PULSIN  Ping, 1, distance           ' Receive Distance Value
      distance = distance ** 2257           ' Calculate Distance In cm
      IF distance > oldDistance THEN        ' Is distance > Last Clear Path
       oldDistance = distance              ' Update oldDistance Value
        Turn = 1
      ENDIF
    
      FOR pulseCount = 0 TO 10
        PULSOUT 13,650      'Turns Boe Bot to the left to return to center
        PULSOUT 12,650
        PAUSE 17
      NEXT
    
      ON Turn GOSUB Task0, Task1
    
      distance = 50
      RETURN
    
    Task0:
    'Furthest distance dectected on the left
      FOR pulseCount = 0 TO 10
        PULSOUT 13,650      'Turns Boe Bot to the left to return to center
        PULSOUT 12,650
        PAUSE 17
      NEXT
      RETURN
    
    Task1:
    'Furthest distance dectected on the left
      FOR pulseCount = 0 TO 10
        PULSOUT 13,850      'Turns Boe Bot to the left to return to center
        PULSOUT 12,850
        PAUSE 17
      NEXT
      RETURN
    
  • Mike GreenMike Green Posts: 23,101
    edited 2012-04-25 21:05
    Between the ENDSELECT and the LOOP, you're outputting only a single pulse to each servo. Is that what you really want to do? I can't rewrite your program for you ... it's too complicated. You're going to have to go through it carefully and examine each place where you want to move the servos. You need to produce a servo pulse about every 20ms and produce the pulses long enough for the servos to move the distance you want. 11 pulses about once every 20ms will take somewhere on the order of 1/4 second. Is that what you need? If you don't produce a servo pulse within about 30ms, the servo will turn off until the next pulse comes in. This will produce jerky movement at best. The PING requires up to about 20ms to take a reading. There's really not enough time for the PING to do its thing, make some decisions, and operate the servo all in a simple loop. That's partly why most PING BoeBot programs stop moving briefly when making distance measurements.

    You might consider getting a ServoPal which will take over the production of the servo pulses and relieve the tight timing constraints on your program.
  • ScorpioScorpio Posts: 6
    edited 2012-04-25 22:10
    Ok..Thanks for the help.. I'll go through the code carefully and see what is going wrong and use your advice to improve it..If I am unsuccessful, I will have to resort to the QTI's and IR combination. BTW, is there a way where I can avoid IR jamming?. I was thinking about sending a PWM signal from my IR LEDs, but the problem is, I not sure how to get it done.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-04-26 07:06
    "avoid IR jamming" ... probably not. The IR signal is already modulated at 38KHz and the IR detectors are tuned roughly to 38KHz and will reject other frequencies. You could try getting IR detectors designed for other frequencies like 36KHz or 40KHz and modifying your program's FREQOUT statement to match. That won't eliminate the interference, but it may reduce it. DigiKey and Mouser carry equivalent IR detectors to the Panasonic PNA4601M that Parallax uses. Vishay makes a whole line of detectors for different frequencies. The pin connections are different though, so you have to pay attention to the diagram on the datasheet for the device you're using.
  • ScorpioScorpio Posts: 6
    edited 2012-04-26 08:51
    I was considering getting IR Dectectors to operate at different frequencies, but I dont have access to any at the moment and my presentation is due tomorrow..lol..Are they any IR detectors in any household electronic devices that operates at different frequencies besides the 38KHz?
    I also have a BPW77NA Phototransistor http://www.vishay.com/docs/81527/bpw77n.pdf. Can this also be used to detect 36Khz or 40Khz IR signals?
  • Mike GreenMike Green Posts: 23,101
    edited 2012-04-26 09:40
    Most household remotes use 38KHz. I wouldn't know what the exceptions are. Unfortunately, you can't use a phototransistor for what you want. Modulated IR is used to avoid interference from room lighting, both 60Hz from fluorescents and higher frequencies from compact fluorescents. The Stamp is incapable of filtering this out by itself and it's incapable of detecting modulated IR by itself. Things like the QTI sensor use unmodulated IR and IR phototransistors because the distances are short and the environment (usually under the robot) is partly shielded from ambient light.
  • ScorpioScorpio Posts: 6
    edited 2012-04-26 10:10
    Oh ok..I understand what you are saying..Thanks for the help. I will have to play around some more with the PING code or use the IR code instead.
Sign In or Register to comment.