my pbasic code
for a school project im trying to build a robot that can find a few tennis balls that are within a two meter radius of itself using the ping)) sonar.· any suggestions or problems brought to my attention will be greatly appreciated.· its my first program so im sure there are some problems.
' {$STAMP BS2}
' {$PBASIC 2.5}
Ping PIN 1
RawDist VAR Word
cm VAR Word
Trigger CON 5
Scale CON $200
RawToCm CON 2257
LMF1 PIN 2
LMF2 PIN 3
RMF1 PIN 4
RMF2 PIN 5
LMR1 PIN 6
LMR2 PIN 7
RMR1 PIN 8
RMR2 PIN 9
OUTPUT 0
OUTPUT 2
OUTPUT 3
OUTPUT 4
OUTPUT 5
OUTPUT 6
OUTPUT 7
OUTPUT 8
OUTPUT 9
OUTPUT 14
OUTPUT 15
Balls VAR Nib
Balls = 0
Grabber PIN 15
Rotator PIN 14
Ball_Sensor PIN 0
Travel_Time VAR Word
Travel_Time = 0
Return_Time VAR Word
Return_Time = 0
Grab_Position VAR Word
Rotate_Position VAR Word
Main:
· DO
· GOSUB Search
· LOOP UNTIL (cm <= 200 AND cm >= 3)
· GOSUB Advance
· GOSUB Retrieve
· GOSUB Retreat
· GOTO Main
Search:
· RMF1 = 1
· RMF2 = 1
· LMR1 = 1
· LMR2 = 1
· PAUSE 100
· GOSUB Get_Sonar
· RETURN
Get_Sonar:
· Ping = 0
· PULSOUT Ping, Trigger
· PULSIN Ping, 1, RawDist
· RawDist = RawDist */ Scale
· RawDist = Rawdist / 2
· cm = RawDist ** RawToCm
· PAUSE 100
· RETURN
Advance:
· DO
· RMF1 = 1
· RMF2 = 1
· LMF1 = 1
· LMF2 = 1
· Travel_Time = Travel_Time + 1
· PAUSE 1000
· GOSUB Get_Sonar
· IF cm < 6 AND cm > 3 THEN RETURN
· IF cm < 3 OR cm > 210 THEN GOTO Retreat
· LOOP WHILE (cm <= 200 AND cm >= 6)
Retrieve:
· DO
··· RMF1 = 1
··· RMF2 = 1
··· LMF1 = 1
··· LMF2 = 1
··· PAUSE 10
· LOOP UNTIL Ball_Sensor = 1
· RMF1 = 1
· RMR1 = 1
· LMF1 = 1
· LMR1 = 1
· PAUSE 1000
· LOW grabber
· LOW rotator
· FOR Grab_Position = 750 TO 1000 STEP 5
··· PULSOUT Grabber, Grab_Position
··· PAUSE 20
· NEXT
· FOR rotate_position = 750 TO 1000
··· PULSOUT Rotator, rotate_position
··· PULSOUT grabber, 1000
··· PAUSE 20
· NEXT
· FOR Grab_Position = 1000 TO 750 STEP 5
··· PULSOUT Grabber, grab_position
··· PULSOUT rotator, 1000
··· PAUSE 20
· NEXT
· FOR rotate_position = 1000 TO 750
··· PULSOUT Rotator, rotate_position
··· PAUSE 20
· NEXT
· Balls = Balls + 1
· RETURN
Retreat:
· DO
· LMF1 = 1
· LMF2 = 1
· RMF2 = 1
· RMF1 = 1
· PAUSE 1000
· Return_Time = Return_Time + 1
· LOOP UNTIL Return_Time = Travel_Time
· PAUSE 2000
· IF Balls = 3 THEN END
· RETURN
' {$STAMP BS2}
' {$PBASIC 2.5}
Ping PIN 1
RawDist VAR Word
cm VAR Word
Trigger CON 5
Scale CON $200
RawToCm CON 2257
LMF1 PIN 2
LMF2 PIN 3
RMF1 PIN 4
RMF2 PIN 5
LMR1 PIN 6
LMR2 PIN 7
RMR1 PIN 8
RMR2 PIN 9
OUTPUT 0
OUTPUT 2
OUTPUT 3
OUTPUT 4
OUTPUT 5
OUTPUT 6
OUTPUT 7
OUTPUT 8
OUTPUT 9
OUTPUT 14
OUTPUT 15
Balls VAR Nib
Balls = 0
Grabber PIN 15
Rotator PIN 14
Ball_Sensor PIN 0
Travel_Time VAR Word
Travel_Time = 0
Return_Time VAR Word
Return_Time = 0
Grab_Position VAR Word
Rotate_Position VAR Word
Main:
· DO
· GOSUB Search
· LOOP UNTIL (cm <= 200 AND cm >= 3)
· GOSUB Advance
· GOSUB Retrieve
· GOSUB Retreat
· GOTO Main
Search:
· RMF1 = 1
· RMF2 = 1
· LMR1 = 1
· LMR2 = 1
· PAUSE 100
· GOSUB Get_Sonar
· RETURN
Get_Sonar:
· Ping = 0
· PULSOUT Ping, Trigger
· PULSIN Ping, 1, RawDist
· RawDist = RawDist */ Scale
· RawDist = Rawdist / 2
· cm = RawDist ** RawToCm
· PAUSE 100
· RETURN
Advance:
· DO
· RMF1 = 1
· RMF2 = 1
· LMF1 = 1
· LMF2 = 1
· Travel_Time = Travel_Time + 1
· PAUSE 1000
· GOSUB Get_Sonar
· IF cm < 6 AND cm > 3 THEN RETURN
· IF cm < 3 OR cm > 210 THEN GOTO Retreat
· LOOP WHILE (cm <= 200 AND cm >= 6)
Retrieve:
· DO
··· RMF1 = 1
··· RMF2 = 1
··· LMF1 = 1
··· LMF2 = 1
··· PAUSE 10
· LOOP UNTIL Ball_Sensor = 1
· RMF1 = 1
· RMR1 = 1
· LMF1 = 1
· LMR1 = 1
· PAUSE 1000
· LOW grabber
· LOW rotator
· FOR Grab_Position = 750 TO 1000 STEP 5
··· PULSOUT Grabber, Grab_Position
··· PAUSE 20
· NEXT
· FOR rotate_position = 750 TO 1000
··· PULSOUT Rotator, rotate_position
··· PULSOUT grabber, 1000
··· PAUSE 20
· NEXT
· FOR Grab_Position = 1000 TO 750 STEP 5
··· PULSOUT Grabber, grab_position
··· PULSOUT rotator, 1000
··· PAUSE 20
· NEXT
· FOR rotate_position = 1000 TO 750
··· PULSOUT Rotator, rotate_position
··· PAUSE 20
· NEXT
· Balls = Balls + 1
· RETURN
Retreat:
· DO
· LMF1 = 1
· LMF2 = 1
· RMF2 = 1
· RMF1 = 1
· PAUSE 1000
· Return_Time = Return_Time + 1
· LOOP UNTIL Return_Time = Travel_Time
· PAUSE 2000
· IF Balls = 3 THEN END
· RETURN
Comments
·· A few tips/notes to get you started...At the beginning of your code, you have a series of constans being defined.· Some are in decimal, some are in hex.· It might help you later if you stick with one format.· Also, you define a bunch of pins as outputs, but this could be done with one DIRS command.· After this you declare a variable (Balls), which would be better to do at the top of the code with the other variable declarations.· Also you don't need to set it to zero, as it is zero by default when declared.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
DIRS = %0000000000001111
... would make P0-P3 outputs (1 makes pin an output) and the rest inputs.· That saves code space versus:
OUTPUT 0
OUTPUT 1
OUTPUT 2
OUTPUT 3
A common mistake for those new to the BASIC Stamp is to do something like this at the top of their program:
INPUT 0
OUTPUT 1
OUTPUT 2
INPUT 3
INPUT 4
INPUT 5
And so on.· Remember that when the BASIC Stamp is reset, all variables (including DIRS) are cleared to zero -- this makes all pins inputs after a reset.· To declare pins as inputs at the beginning of the program is just wasting code space (there are rare occassions when INPUT is used, but they are rare).· DIRS has constituent parts that make things easy.· Let's say you want P0 to be an output, P1 an input, and P2 and P3 to be outputs -- and all other pins are inputs.· All you need is:
DIRA = %1101
You can use DIRB for P4-P7, DIRC for P8-P11, and DIRD for P12-P15.· There are 8-bit versions DIRL (P0-P7) and DIRH (P8-P15) as well.
Another common error with INPUT and OUTPUT is something like this:
OUTPUT 0
HIGH 0
or....
INPUT 15
SERIN 15, Baud, [noparse][[/noparse]cmdVal]
You see, the BASIC Stamp will set the pin direction for most commnads -- the manual (or help file will tell you this).· There is no need to make a pin an output before using HIGH, because the HIGH instruction does that.· Same holds true for SERIN -- that function makes the pin an input.
Okay, hit Section 4 of the BASIC Stamp Syntax and Reference Manual for additional details.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
·· At this point I would recommend reading the "What's a Microcontoller?" text,· a free download in PDF format from our website.· This will help you understand programming the BASIC Stamp.· A link has been posted below.
http://www.parallax.com/dl/docs/books/edu/wamv2_2.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
Let me suggest you download and read through "What's A Microcontroller?" by Jedi master Andy Lindsay.· There is no better way to get started with BASIC Stamp programming than WAM -- a couple hours reading will tie up lots of loose ends for you.
Get it here: http://www.parallax.com/dl/docs/books/edu/wamv2_2.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
' {$STAMP BS2}
' {$PBASIC 2.5}
Ping PIN 1
RawDist VAR Word
cm VAR Word
Trigger CON 5
Scale CON $200
RawToCm CON 2257
main:
· DO
· Ping = 0
· PULSOUT Ping, Trigger
· PULSIN Ping, 1, RawDist
· RawDist = RawDist */ Scale
· RawDist = Rawdist / 2
· cm = RawDist ** RawToCm
· DEBUG cm, CR
· PAUSE 1000
· LOOP
This is part of the code given to me with the instructions from the Ping)).· I am not getting numbers for results.· I am either getting boxes or blanks.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
· DEBUG cm, CR
DEBUG wants to send characters, so you're getting funny boxes and things you don't expect.· What your code should say is:
· DEBUG DEC cm, CR
... which converts the cm value to a string of characters using the DEC modifier.· I've attached the Ping))) demo code for your convenience.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Since the BS2 costs $50, you don't really want to solder it down. Also, do you have a DB-9 on your target board to allow you to reprogram the BS2 in-circuit?
Really -- go to RadioShack and pick up a 24-pin socket. Solder that down.
There are two important advantages to putting a programming port on your board. The first is that it prevents the BASIC Stamp's pins from being damaged from all that pushing it into one socket, then pulling it back out to push it onto another socket. With that kind of setup, it's usually just a matter of time... The second advantage is that you can connect your board to the Debug Terminal for trouble-shooting. Otherwise, trouble-shooting will be much more difficult.
A couple of extra notes:
Even if you do put a programming port on your board, you should still mount a socket on it for the BASIC Stamp.
Before you do your board layout, make sure to test your entire circuit setup on a breadboard, and verify it against your schematic. This will help errors from creeping into your printed circuit board.