Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Demo Board ultrasonic two servo object avoidance — Parallax Forums

Propeller Demo Board ultrasonic two servo object avoidance

t1000cct1000cc Posts: 4
edited 2011-12-01 01:13 in Propeller 1
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.?ui=2&ik=905dcdc7e4&view=att&th=133a8a23000fbe2d&attid=0.1&disp=inline&realattid=1385571608685445120-1&zw

Comments

  • Christof Eb.Christof Eb. Posts: 1,237
    edited 2011-11-30 08:35
    Hi t1000cc,
    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
  • t1000cct1000cc Posts: 4
    edited 2011-11-30 20:26
    this code will only turn one servo at a time, i had a code that turned both servos at once but my gf deleted it from the computer. now i am stuck with this.

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2011-11-30 21:23
    Use one of the servo controller objects from the Propeller Object Exchange. Here's one that uses a cog, is written in Spin, and controls two servos. There are others. There's a Propeller-based servo controller board that controls up to 16 servos. Most of the code that makes it work is in a servo controller object that can actually control up to 32 servos, also in the Object Exchange.

    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.
  • t1000cct1000cc Posts: 4
    edited 2011-11-30 22:51
    Here is a new approach i have been trying...

    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!
  • t1000cct1000cc Posts: 4
    edited 2011-12-01 01:13
    okay, so i got both servos to turn the same way with this code....

    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....
Sign In or Register to comment.