Shop OBEX P1 Docs P2 Docs Learn Events
pbasic question — Parallax Forums

pbasic question

AnnoyingAnnoying Posts: 50
edited 2009-09-15 21:51 in BASIC Stamp
this problem seems really simple but I can't find the answer in pbasic tutorials:
I want a sequence of actions to take place once a condition is met. this code sequence is not valid: IF (condition)THEN DO UNTIL ...THEN DO UNTIL ...THEN DO UNTIL... etc.· do you know what code would accomplish this? Thanks.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-14 23:13
    Is this what you want to do?
    IF {condition} THEN
       DO
       UNTIL {condition}
       DO
       UNTIL {condition}
       DO
       UNTIL {condition}
    ENDIF
    


    Remember that this is PBasic 2.5 and you'll need the proper directive at the beginning of your program.
  • AnnoyingAnnoying Posts: 50
    edited 2009-09-15 00:20
    thank you so much, I guess I shouldn't have written the "THEN" over and over again! I have one more question I was wondering if you could answer:
    the motor on one robot turns as it should in the first loop, and I want it to immediately turn off once y2 < 1930. for some reason the PULSOUT 3, 750
    following this loop does not cause the motor to stop turning. it stops turning after like 30 seconds...


    IF y2 >3120 THEN

    DO UNTIL y2 <1930


    PULSOUT 3, 1000
    PAUSE 20
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), ' Wait for start character
    y2.HIGHBYTE, y2.LOWBYTE] ' Get y-axis word

    LOOP

    PAUSE 5
    PULSOUT 3, 750
    PAUSE 1

    DO UNTIL y1 > 3116
    PULSOUT 3, 750
    etc.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-15 00:36
    How about comments describing what you're attempting to do? I really don't understand what your program does.

    Is the SERIN all on one line? You've put a comment after part of the SERIN and continued the SERIN on a 2nd line.
    In any event, putting a SERIN like this in a movement loop won't work since a servo motor expects a control pulse every 20ms. If it doesn't get a control pulse, it shuts down until it sees another pulse. That causes jerky movement at best.

    The single PULSOUT 3,750 won't stop the motor. The motor needs to see a series of 1.5ms (PULSOUT 3,750) pulses roughly every 20ms. It shouldn't take 30 seconds to stop the motor if it's getting a series of 1.5ms pulses.

    If the 2nd DO loop is like the 1st and the Stamp doesn't see serial data for periods of time, the servo will shut down which may allow it to coast for a while. Still, 30 seconds seems like a lot. Can't tell without more of the program.
  • AnnoyingAnnoying Posts: 50
    edited 2009-09-15 01:01
    so I am transmitting accelerometer values from one robot to the other through the RF Transmitter/Receiver and the motors alternate turning based on these values. here is the code for one robot:

    '{$STAMP BS2}
    '{$PBASIC 2.5}

    y1 VAR Word
    y2 VAR Word



    Main:
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]


    IF y2 >3120 THEN

    DO UNTIL y2 <1930


    PULSOUT 3, 1000
    PAUSE 20
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]

    LOOP



    DO UNTIL y1 > 3116
    PULSOUT 3, 750
    PULSOUT 15, 1200
    SEROUT 15, 16468, [noparse][[/noparse] "!", y1.HIGHBYTE, y1.LOWBYTE]
    PULSIN 5, 1, y1
    PAUSE 10
    LOOP


    DO UNTIL y2 > 3120
    PULSOUT 3, 1000
    PAUSE 20
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]

    LOOP



    DO UNTIL y1 < 1880
    PULSOUT 3, 750
    PULSOUT 15, 1200
    SEROUT 15, 16468, [noparse][[/noparse] "!", y1.HIGHBYTE, y1.LOWBYTE]
    PULSIN 5,1, y1
    PAUSE 10
    LOOP

    ENDIF


    GOTO Main


    It works at first and then gets weird...

    thanks.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-15 01:55
    One thing I notice is that y1 is initially undefined although it would be initialized to zero when the Stamp is reset.

    What's hooked to pin 5?

    I'd shorten the PAUSE 20. Try PAUSE 10. 20ms is about the limit between servo control pulses and the SERIN will take some time.

    The transmitting robot is transmitting more often than the receiving robot can receive.· Maybe the delay in the transmit loop should be larger than that in the receive loop.· The receiver will wait for the data to be received.
    ·
  • AnnoyingAnnoying Posts: 50
    edited 2009-09-15 18:46
    the accelerometer is hooked to pin 5. I changed the code so there is a longer delay in the transmit loop...I think it works better but still not quite. I have it printing "loop one" in the debug window for the first loop and then "loop two" in the next loop. for some reason it stops printing "loop one" when it should and it's out of the loop, but it doesn't print "loop two" until 15 seconds later, and hence the motor doesn't stop on time because it isn't in that loop. here's the code:


    '{$STAMP BS2}
    '{$PBASIC 2.5}

    y1 VAR Word
    y2 VAR Word



    Main:
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]


    IF y2 >3120 THEN

    DO UNTIL y2 <1930


    PULSOUT 3, 1000
    PAUSE 10
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]
    DEBUG "loop one"
    LOOP


    PULSIN 5, 1, y1

    DO UNTIL y1 > 3100
    DEBUG "loop two"
    PULSOUT 3, 750
    PULSOUT 15, 1200
    SEROUT 15, 16468, [noparse][[/noparse] "!", y1.HIGHBYTE, y1.LOWBYTE]
    PULSIN 5, 1, y1
    PAUSE 30
    LOOP


    DO UNTIL y2 > 3120
    PULSOUT 3, 1000
    PAUSE 10
    PULSOUT 2, 1200
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]

    LOOP



    DO UNTIL y1 < 1880
    PULSOUT 3, 750
    PULSOUT 15, 1200
    SEROUT 15, 16468, [noparse][[/noparse] "!", y1.HIGHBYTE, y1.LOWBYTE]
    PULSIN 5,1, y1
    PAUSE 30
    LOOP

    ENDIF


    GOTO Main
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-15 19:48
    At the very least, reduce the PAUSE 30 to PAUSE 15 or less. The data transmission takes around 5 to 6ms just by itself.

    What you're trying to do is, unfortunately, very problematic with an unassisted Stamp because, when the Stamp is waiting for input data, it's not keeping track of the time and the servo control pulses have to be produced roughly every 20ms. The only good timekeeping mechanism available here is the PAUSE statement and, when the Stamp is paused, it can't listen to the serial input line and will miss anything that comes in. You have some advantage in that the information is repeated so, if you miss one value, you will catch the next one.

    You might consider using a ServoPAL which would allow the Stamp to only have to do something with the servo when the setting changes. See: www.parallax.com/tabid/768/txtSearch/servopal/List/0/SortField/4/Default.aspx
  • AnnoyingAnnoying Posts: 50
    edited 2009-09-15 20:35
    changing to PAUSE 15 didn't help. I'm still confused--do you know why it would take so long to enter the next loop after leaving the first one? I'm new to this and really confused about the timing.
    maybe this is obvious but I'm actually using motors controlled through the HB-25 motor controller, so would the ServoPAL be able to be used with it?
    thanks again!
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-15 20:50
    If you're using an HB-25, then you only need to output a control pulse when you want the motor speed to change (same as with a ServoPAL). In fact, you could move the PULSOUT 3,... to before the DO. You wouldn't need a PAUSE in the SERIN loops (or the SEROUT loops even ... the rate of pulse outputs from the accelerometer would set the maximum rate of transmissions).

    IF ...
       PULSOUT 3,1000
       DO
       UNTIL
       PULSOUT 3,750
       DO
       UNTIL
       PULSOUT 3,1000
       DO
       UNTIL
       PULSOUT 3,750
       DO
       UNTIL
    ENDIF
    


    By the way, why are you doing a PULSOUT to the receiver? That can damage the receiver's output pin.
  • AnnoyingAnnoying Posts: 50
    edited 2009-09-15 21:51
    in the documentation for the parallax RF receiver, it says to send a sync pulse to initiate communication between RF modules and gives that PULSOUT code. It actually didn't seem to matter either way so I got rid of it. but the single PULSOUT line above the loops does not work. is this the code that you had in mind?

    '{$STAMP BS2}
    '{$PBASIC 2.5}

    y1 VAR Word
    y2 VAR Word



    Main:

    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]


    IF y2 >3120 THEN

    PULSOUT 3, 1000

    DO UNTIL y2 <1930

    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]

    LOOP


    PULSIN 5, 1, y1
    PULSOUT 3, 750

    DO UNTIL y1 > 3100
    SEROUT 15, 16468, [noparse][[/noparse] "!", y1.HIGHBYTE, y1.LOWBYTE]
    PULSIN 5, 1, y1

    LOOP

    PULSOUT 3, 1000
    DO UNTIL y2 > 3120
    SERIN 2, 16468, [noparse][[/noparse]WAIT("!"), y2.HIGHBYTE, y2.LOWBYTE]

    LOOP


    PULSOUT 3, 750
    DO UNTIL y1 < 1880
    SEROUT 15, 16468, [noparse][[/noparse] "!", y1.HIGHBYTE, y1.LOWBYTE]
    PULSIN 5,1, y1
    LOOP

    ENDIF


    GOTO Main
Sign In or Register to comment.