Code help
Hello, I am currently trying to interface two ping sonar sensors with two futaba servo motors. The end product should basically be a vehicle that can navigate obstacles. anyways the problem is my robot seems to want to do the jig and the wheels move for maybe a quarter second and then stop and then move and so the robot basically does nothing but spaz and waddle along. I have tested both sonars independently from the motors and the readings from them are fine. I have also run the motors in a simple do loop and they run fine. So there must be something wrong with my code. I would greatly appreciate if someone could look over my code and tell me if there appears to be a problem. THANKS!!
' {$STAMP BS2}
' {$PBASIC 2.5}
' -----[noparse][[/noparse] I/O Definitions ]-------------------------------------------------
ping1 PIN 1
ping2 PIN 2
clock PIN 3
ToServo1 PIN 14
ToServo2 PIN 15
' -----[noparse][[/noparse] Constants ]-------------------------------------------------------
Trigger CON 5 ' trigger pulse = 10 uS
Scale CON $2 ' raw x 2.00 = uS
RawToCm CON 2257 ' 1 / 29.034 (with **)
IsHigh CON 1 ' for PULSOUT
IsLow CON 0
Halt2 CON 763
Halt1 CON 760
Full2 CON 723
Full1 CON 805
Back2 CON 803
Back1 CON 715
' -----[noparse][[/noparse] Variables ]-------------------------------------------------------
rawDist VAR Word ' raw measurement
rawDist2 VAR Word
cm VAR Word
cm2 VAR Word
Left1 VAR Word
Right2 VAR Word
' -----[noparse][[/noparse] Main ]-----------------------------------------------------------
DO
GOSUB ReadPING1
GOSUB ReadPING2
GOSUB DetermineNextMove
LOOP
'-----[noparse][[/noparse] Subroutines ]---------------------------------------------------
ReadPING1:
ping1 = IsLow
PULSOUT ping1, Trigger ' activate sensor
PULSIN ping1, IsHigh, rawDist ' measure echo pulse
rawDist = rawDist * Scale ' convert to uS
rawDist = rawDist / 2 ' remove return trip
cm = rawDist ** RawToCm ' convert to centimeters
RETURN
ReadPING2:
ping2 = IsLow ' make trigger 0-1-0
PULSOUT ping2, Trigger ' activate sensor
PULSIN ping2, IsHigh, rawDist2 ' measure echo pulse
rawDist2 = rawDist2 * Scale ' convert to uS
rawDist2 = rawDist2 / 2 ' remove return trip
cm2 = rawDist2 ** RawToCm ' convert to centimeters
RETURN
DetermineNextMove:
IF (cm > 100 AND cm2 > 100) THEN
GOSUB Both_full
ELSEIF cm < 15 THEN
GOSUB GETOUTOFTHECORNER1
ELSEIF cm2 < 15 THEN
GOSUB GETOUTOFTHECORNER2
ELSEIF cm > cm2 THEN
GOSUB Go_left
ELSEIF cm < cm2 THEN
GOSUB Go_Right
ENDIF
RETURN
Both_full:
PULSOUT ToServo1, Full1 'sends fullspeed pulse
PULSOUT ToServo2, Full2 'sends fullspeed pulse
PAUSE 10
RETURN
Go_left:
Left1 = cm - cm2
Left1 = Left1 / 2
Left1 = Full1 - Left1
PULSOUT ToServo1, Left1 'sends left turn pulse
PULSOUT ToServo2, Full2 'sends fullspeed pulse
PAUSE 20
RETURN
Go_right:
Right2 = cm2 - cm
Right2 = Right2 / 2
Right2 = Full2 + Right2
PULSOUT ToServo1, Full1 'sends fullspeed pulse
PULSOUT ToServo2, Right2 'sends right turn pulse
PAUSE 20
RETURN
GETOUTOFTHECORNER1:
PULSOUT ToServo1, Full1
PULSOUT ToServo2, Back2
PAUSE 300
RETURN
GETOUTOFTHECORNER2:
PULSOUT ToServo1, Back1
PULSOUT ToServo2, Full2
PAUSE 300
RETURN

Comments
Your reading of each PING will take up to about 20ms, that's 40ms for the two of them. On top of that, you have a pause of 20ms in most of the movement subroutines which adds up to at least 60ms total per cycle. Add some milliseconds for the statements themselves to execute and you've got probably 70-75ms in most movement cycles.
Solutions:
1) Read only one PING per cycle through the main loop. Alternate them. Their readings won't change particularly quickly, so it won't matter.
2) Use the raw PING data to set the PAUSE delay. On a BS2, the width of the pulse is measured in 2us units. Divide it by 500 to get milliseconds and subtract from 20 to get the PAUSE delay like: PAUSE 20 - raw/500.
3) Use www.emesystems.com and the "app-notes" link at the bottom of the page. You'll get a nice discussion of a variety of information including information on PBasic statement execution time. You can use this to adjust the PAUSE value downwards to compensate for the statement execution time in your program.
do
readping1
determinenextstep
readping2
determinenextstep
loop
2) The motors will continue to be jerky until you reduce the PAUSE times as I suggested. They may still be jerky when the PINGs don't see an obstacle. (When they're at maximum range, the time is close to 20ms.)
'
[noparse][[/noparse] Main ]
GOSUB ReadPING2
DO
I think it's time to use DEBUG to make sure various values (like cm and cm2) are what you expect them to be. It may be that there's just too much code executed each time through the loop and it's taking too long. Use the EmeSystems website information to estimate how long your various statements take. I would try the various motion subroutines to see if they actually move the BoeBot the way you expect, particularly Go_right and Go_left. I would rethink DetermineNextMove to make sure it's doing what you want.
When I have a complex program that doesn't do what I expect, I do what I've outlined ... Use some kind of DEBUG statement to make sure what's going on is what I think is supposed to happen. I also test small parts of the actual program, calling small subroutines from a modified main loop to make sure they're doing what they're supposed to be doing.
'
[noparse][[/noparse] Main ]
GOSUB ReadPing2
DO
GOSUB Readping1
GOSUB Go_right
Pausebreak= rawDist/500
GOSUB ReadPING2
Pausebreak= rawDist2/500
LOOP
still choppy with Go_left Both_full or Go_right.
it was working before with the same code except with only the options of both full go left and go right in the determine next move routine and then for some reason it just stopped all of a sudden and started moving choppy and acting unpredictably. is it possible that my computer may be corrupting the micro controller in some way?? It was not doing anything like this before all we did was add two more possible subroutines to determine next move in order to try and make the movement smoother. I have tried simply removing those newer routines and it doesn't make any difference. It worked before as I said when the code was downloaded from my project partners computer. so what was working before does not work now and i have checked my connections I wonder if my computer has somehow damaged the micro controller..[noparse]:([/noparse] that would very unfortunate. Although I have tried using a test for my sonars and it works and when I use a separate program consisting of just motor commands in a loop the motors run fine too.
I still think your program is running out of available time to produce servo control pulses. As I said, you have only about 20ms available between pulses to the servos and you're trying to do a lot in that time. That's one of the common causes for jerky servo movement.