Propeller Demo Board ultrasonic two servo object avoidance
t1000cc
Posts: 4
Hello, i have a Propeller Demo Board and 2 parallax continuous servos and a parallax ultrasonic range finder. i am trying to make an object avoidance bot in spin, however i cant find any code to help me at this time. i have code to operate the servos and a code to operate the ping sensor. what i need is a spin code that has 2 continuous servos a ping sensor from parallax all controlled by the Propeller Demo Board. here is the bot. i dont care if the code is in spin, i will use c,12block, or any code that will work with the parallax stuff.
Comments
my personal approach would be, that I would start to experiment with these components. First perhaps a small routine, that starts one motor, thats turn to the left, then the other, thats turn the other direction. Then you can try to display the output of ping via the serial line. The ping sensor gives you a distance only it will need to be turned to know where there in an object.
Have fun, Christof
CON
_clkmode = xtal1 + pll8x
_xinfreq = 10_000_000
VAR
byte counter
long Pause, Pulsout
OBJ
Debug: "FullDuplexSerialPlus"
PUB BothServosThreeSeconds
Debug.start(31, 30, 0, 9600)
Pause := clkfreq/1_000
Pulsout := clkfreq/500_000
dira[0..1]~~
outa[0..1]~
repeat counter from 1 to 122
outa[1]~~
waitcnt(Pulsout * 850 + cnt)
outa[1]~
outa[0]~~
waitcnt(Pulsout * 650 + cnt)
outa[0]~
waitcnt(Pause * 20 + cnt)
repeat counter from 1 to 122
outa[1]~~
waitcnt(Pulsout * 650 + cnt)
outa[1]~
outa[0]~~
waitcnt(Pulsout * 850 + cnt)
outa[0]~
waitcnt(Pause * 20 + cnt)
I think that this example code i am using is malfunctioning due to the debug function...
i have the ping sensor working great, outputting in the serial for two ping sensors. its get both servos to turn at once which is giving me problems. I am very exp with the arduino and could complete this project in 30mins with its C based lang. i am also good with the bs2 (Basic Stamp) and could complete it in 45mins. This propeller demo board is unlike anything i have used before. i could really use a code that operates 2 servos at the same time, the rest i can probably figure out. Thanx
If you don't have it already, here's the PING))) demo object.
Typically what you do is have a main program that reads first one PING))), then the other, does some decision making, then sends a pulse width to the servo controller object for each servo. The servo controller object takes care of producing the servo pulses every 20ms so the main program doesn't have to bother with it. That's the beauty of having multiple processors ... they can do two (or more) things at the same time and easily talk to one another. The part of the servo controller object that you call executes in the main cog along with your main program. When you initialize the servo control object, it starts up a 2nd cog that waits for a servo pulse width to be supplied, then starts issuing pulses as requested.
CON
leftpin = 0
rightpin = 1
pingpin = 2
VAR
LONG stack[30]
BYTE direction
OBJ
ping : "ping"
PUB pushRobot
dira[leftpin] := dira[rightpin] := 1
cognew(checkping, @stack)
REPEAT
case direction
1:
outa[leftpin]~~
outa[rightpin]~
2:
outa[leftpin]~
outa[rightpin]~~
3:
outa[leftpin] := outa[rightpin] := 1
4:
outa[leftpin] := outa[rightpin] := 0
PUB checkping | leftdistance, rightdistance
repeat
IF (ping.Millimeters(pingpin) < 10)
leftdistance := ping.Millimeters(pingpin)
rightdistance := ping.Millimeters(pingpin)
IF (leftdistance > rightdistance)
direction := 1
ELSE
direction := 2
ELSE
direction := 3
The OBJ ping is the ping.spin included with the PING)) object.
however i have not got it to work yet.
here is my "ping" ......
CON
TO_IN = 73_746 ' Inches
TO_CM = 29_034
' Centimeters
PUB Ticks(Pin) : Microseconds | cnt1, cnt2
''Return Ping)))'s one-way ultrasonic travel time in microseconds
outa[2]~ ' Clear I/O Pin
dira[2]~~ ' Make Pin Output
outa[2]~~ ' Set I/O Pin
outa[2]~ ' Clear I/O Pin (> 2 µs pulse)
dira[2]~ ' Make I/O Pin Input
waitpne(0, |< 2, 0) ' Wait For Pin To Go HIGH
cnt1 := cnt ' Store Current Counter Value
waitpeq(0, |< 2, 0) ' Wait For Pin To Go LOW
cnt2 := cnt ' Store New Counter Value
Microseconds := (||(cnt1 - cnt2) / (clkfreq / 1_000_000)) >> 1 ' Return Time in µs
PUB Inches(Pin) : Distance
''Measure object distance in inches
Distance := Ticks(2) * 1_000 / TO_IN ' Distance In Inches
PUB Centimeters(Pin) : Distance
''Measure object distance in centimeters
Distance := Millimeters(2) / 10 ' Distance In Centimeters
PUB Millimeters(Pin) : Distance
''Measure object distance in millimeters
Distance := Ticks(2) * 10_000 / TO_CM ' Distance In Millimeters
Thanx so much for the replies, it is a great help!
CON
_clkmode = xtal1 + pll8x
_xinfreq = 5_000_000
VAR
byte counter
long Pause, Pulsout
OBJ
Debug: "FullDuplexSerialPlus"
PUB BothServosThreeSeconds
Debug.start(31, 30, 0, 9600)
Pause := clkfreq/1_000
Pulsout := clkfreq/500_000
dira[0..1]~~
outa[0..1]~
Debug.str(string("Program Running!"))
repeat counter from 1 to 122
outa[1]~~
waitcnt(Pulsout * 900 + cnt)
outa[1]~
outa[0]~~
waitcnt(Pulsout * 500 + cnt)
outa[0]~
waitcnt(Pause * 20 + cnt)
However, i have noticed that this code only works 50% of the time. i am thinking that it may be due to the power supply i am using. i have to load the code and it turns both servos the same direction for the given counter. but if i want to test it again i have to load it more than once. on the first attempt to reload the bot will pulse both servos for a fraction of a second over and over... i am more than confused to say the least....