trouble writing radar program with Ping
newbie011
Posts: 3
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
·
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
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
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