Shop OBEX P1 Docs P2 Docs Learn Events
trouble writing radar program with Ping — Parallax Forums

trouble writing radar program with Ping

newbie011newbie011 Posts: 3
edited 2007-07-29 22:48 in BASIC Stamp
I am a new Basic Stamp 2 user and I am attempting to write a simple radar program with my Stamp and a Ping board.· I have used elements from "Ping_Demo.BS2" and I have made alterations to control a piezo speaker.· The problem I am having is the timimg commands from the beep sequence and the Ping control are being compounded and throwing off the Ping timing.· How can I write code to monitor the Ping results and control the speaker?· I am sure the coding is simple but my experience is very limited.

Here is what I have:

' =========================================================================
'
'·· File....... Ping_Demo.BS2
'·· Purpose.... Demo Code for Parallax Ping Sonar Sensor
'·· Author..... Jon Williams -- Parallax, Inc.
'·· E-mail..... jwilliams@parallax.com
'·· Started....
'·· Updated.... 08 JUN 2005
'
'·· {$STAMP BS2}
'·· {$PBASIC 2.5}
'

'
[noparse][[/noparse] I/O Definitions ]
Ping··········· PIN···· 15
Piezo·········· PIN···· 14

'
[noparse][[/noparse] Constants ]
#SELECT $STAMP
· #CASE BS2, BS2E
··· Trigger···· CON···· 5······················ ' trigger pulse = 10 uS
··· Scale······ CON···· $200··················· ' raw x 2.00 = uS
· #CASE BS2SX, BS2P, BS2PX
··· Trigger···· CON···· 13
··· Scale······ CON···· $0CD··················· ' raw x 0.80 = uS
· #CASE BS2PE
··· Trigger···· CON···· 5
··· Scale······ CON···· $1E1··················· ' raw x 1.88 = uS
#ENDSELECT
RawToIn········ CON···· 889···················· ' 1 / 73.746 (with **)
RawToCm········ CON···· 2257··················· ' 1 / 29.034 (with **)
IsHigh········· CON···· 1······················ ' for PULSOUT
IsLow·········· CON···· 0

'
[noparse][[/noparse] Variables ]
rawDist········ VAR···· Word··················· ' raw measurement
inches········· VAR···· Word
cm············· VAR···· Word

'
[noparse][[/noparse] EEPROM Data ]

'
[noparse][[/noparse] Initialization ]
Reset:
· DEBUG CLS,··································· ' setup report screen
······· "Parallax Ping Sonar· ", CR,
······· "=====================", CR,
······· CR,
······· "Time (uS).....······ ", CR,
······· "Inches........······ ", CR,
······· "Centimeters...······ "

'
[noparse][[/noparse] Program Code ]
Main:
· DO
··· GOSUB Get_Sonar···························· ' get sensor value
··· inches = rawDist ** RawToIn················ ' convert to inches
··· cm = rawDist ** RawToCm···················· ' convert to centimeters
··· DEBUG CRSRXY, 15, 3,······················· ' update report screen
········· DEC rawDist, CLREOL,
········· CRSRXY, 15, 4,
········· DEC inches, CLREOL,
········· CRSRXY, 15, 5,
········· DEC cm, CLREOL
··· PAUSE 100

· IF (rawDist < 1000) THEN
··· GOSUB step1
··· ENDIF
· IF (rawDist > 1000) AND (rawDist < 2000) THEN
··· GOSUB step2
··· ENDIF
· IF (rawDist > 2000) AND (rawDist < 3000) THEN
··· GOSUB step3
··· ENDIF
· IF (rawDist > 3000) AND (rawDist < 4000) THEN
··· GOSUB step4
··· ENDIF
· IF (rawDist > 4000) AND (rawDist < 5000) THEN
··· GOSUB step5
··· ENDIF
· IF (rawDist > 5000) AND (rawDist < 6000) THEN
··· GOSUB step6
··· ENDIF
· IF (rawDist > 6000) AND (rawDist < 7000) THEN
··· GOSUB step7
··· ENDIF
· IF (rawDist > 7000) AND (rawDist < 8000) THEN
··· GOSUB step7
··· ENDIF
· IF (rawDist > 8000) AND (rawDist < 9000) THEN
··· GOSUB step8
··· ENDIF
· IF (rawDist > 9000) AND (rawDist < 10000) THEN
··· GOSUB step9
··· ENDIF
· LOOP
· END

Get_Sonar:
· Ping = IsLow································· ' make trigger 0-1-0
· PULSOUT Ping, Trigger························ ' activate sensor
· PULSIN· Ping, IsHigh, rawDist················ ' measure echo pulse
· rawDist = rawDist */ Scale··················· ' convert to uS
· rawDist = rawDist / 2························ ' remove return trip
· RETURN
step1:
· FREQOUT 14, 50, 2000
· PAUSE 50
· GOTO main
step2:
· FREQOUT 14, 50, 2000
· PAUSE 75
· GOTO main
step3:
· FREQOUT 14, 50, 2000
· PAUSE 100
· GOTO main
step4:
· FREQOUT 14, 50, 2000
· PAUSE 150
· GOTO main
step5:
· FREQOUT 14, 50, 2000
· PAUSE 200
· GOTO main
step6:
· FREQOUT 14, 50, 2000
· PAUSE 250
· GOTO main
step7:
· FREQOUT 14, 50, 2000
· PAUSE 300
· GOTO main
step8:
· FREQOUT 14, 50, 2000
· PAUSE 400
· GOTO main
step9:
· FREQOUT 14, 50, 2000
· PAUSE 500
· GOTO main

·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-29 16:54
    The problem is that you're calling step1 through step9 as subroutines, but they don't return ... they jump back to the start of your main loop. Try putting RETURN in place of the GOTO main in each of the routines.
  • newbie011newbie011 Posts: 3
    edited 2007-07-29 17:10
    Mike thanks for the info.· I replaced the GOTO command with RETURN but the PING timimg is still being affected by the timing of the speaker pulse.
  • DufferDuffer Posts: 374
    edited 2007-07-29 17:35
    Since you only have a FREQOUT and a PAUSE cmd in each of the subroutines, have you considered putting the FREQOUT command in each of the IF structures and letting the code fall through to the LOOP statement which takes you back to Main: anyway. That would save you having to do the GOSUB and RETURN.

    Even better might be the use of a SELECT, CASE structure (as above with the FREQOUT and PAUSE following each CASE statement) instead of all the IF clauses. The advantage to the SELECT is that the first "True" hit on a CASE statement executes the code following it and exits the SELECT structure without having to perform the remainder of the CASE tests which follow. Using a series of IF clauses means that all nine test must be performed each time the DO loop is performed. The advantage of the order that you already have is that the closer you are to the object (lower rawDist) the quicker you get in and out of the loop. You might also consider putting a CASE ELSE statement at the end of you CASE statements and before the ENDSELECT to catch and handle out-of-range conditions.

    SELECT
    · CASE (rawDist < 1000)
    · FREQOUT 14, 50, 2000
    ·PAUSE 50

    · CASE (rawDist > 1000) AND (rawDist < 2000)
    · FREQOUT 14, 50, 2000
    · PAUSE 75
    .
    .
    .
    · CASE ELSE
    <Do something if out-of-range>
    ENDSELECT

    If you're still having trouble, it might be because it takes you between 50 and 500 Ms to get through the loop.
    Consider this:

    Duration· VAR Byte········

    SELECT
    · CASE (rawDist < 1000)
    ··Duration = 1······················'replaces Step 1 code

    · CASE (rawDist > 1000) AND (rawDist < 2000)
    · Duration = 2····················· 'replaces Step 2 code
    .
    .
    .
    · CASE ELSE
    <Do something if out-of-range>
    ENDSELECT

    FREQOUT 14, 50, 2000········ 'always the same, regardless of step
    PAUSE Duration * 25··········· 'or some other scaling factor
    LOOP

    OR..................
    Vary the Freq of the FREQOUT instead of the duration and get rid of the PAUSE statement. That would produce nearly the same loop duration in all cases (plus the instruction time associated with the SELECT loop).

    FREQOUT 14, 50, 2000 + (Duration * 25)···· 'or some other scaling factor

    50 Ms + execution time of the SELECT loop (about the same rate that you would have to use if you were updating a servo).


    Steve

    Post Edited (Duffer) : 7/29/2007 6:12:31 PM GMT
  • newbie011newbie011 Posts: 3
    edited 2007-07-29 19:06
    Steve, thanks for the help. I think it's getting closer to functionality. I can't seem to get the "AND" statement to function with the "CASE" command, but it works with the "IF" statements.
  • DufferDuffer Posts: 374
    edited 2007-07-29 22:48
    You can speed up the loop even if you're still using the IF statements by putting a GOTO in each IF clause to keep from having to do the rest of the tests once you get a True condition.

    DO
    IF (rawDist < 1000) THEN
    FREQOUT 14, 50, 2000
    PAUSE 50
    GOTO Endloop
    ENDIF
    .
    .
    .
    .
    IF (rawDist > 9000) AND (rawDist < 10000) THEN
    FREQOUT 14, 50, 2000
    PAUSE 500
    GOTO Endloop
    ENDIF

    Endloop:
    LOOP
Sign In or Register to comment.