Shop OBEX P1 Docs P2 Docs Learn Events
Do Until I get some new value — Parallax Forums

Do Until I get some new value

SteveWoodroughSteveWoodrough Posts: 190
edited 2008-03-02 22:52 in BASIC Stamp
What is a good technique to accept a value through the serial port, take some action, and continue with that action until I get some new value through the serial port?

Here's my scenario:
Each mouse click in a seprate program sends a value to the BS2

Without the DO Until x<>Y (or Do While x=Y) the I only get one program loop.· With the Do statements, the program "latches" onto the first command and never stops.

Other than a degree in computer science, what am I missing?

THANKS


DO
··· 'accept decimal value in through serial port 16 at 2400,N,8,1
··· SERIN 16, 16780, [noparse][[/noparse]DEC y]
·············· x = y
·· DO UNTIL x <> y
········· IF x = 1 THEN
········· GOSUB Straight
········· ELSEIF x = 2 THEN
········· GOSUB TurnRight
········· ELSEIF x = 3 THEN
········· GOSUB BackUp
········· ELSEIF x = 4 THEN
········· GOSUB TurnLeft
········· ELSE
········· GOSUB Halt
········· ENDIF
········· GOSUB ApplyPulse
·· LOOP
····
LOOP

Comments

  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2008-03-02 05:27
    Hi Steve, if you use the time out function of SERIN there is probably no need for the second DO...LOOP. If you set the time out < 30mS it should still refresh the servos ok

    DO

    SERIN RX,baud,30,Time_out,[noparse][[/noparse]DEC y]

    conditional logic

    LOOP

    Jeff T.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2008-03-02 06:06
    Steve -

    As an alternative to Jeff's method (and with some added coding), here is another method you can try. Currently you have the following in your program:

    DO
    'accept decimal value in through serial port 16 at 2400,N,8,1
    ··· SERIN 16, 16780, [noparse][[/noparse]DEC y]
    ··· X = Y
    · DO UNTIL X <> Y
    ··· ...
    · LOOP
    LOOP

    Have the other program send a leading character, such as "!". Then have the SERIN and the additional code look like this:

    DO····················· 'Infinite loop

    'accept decimal value in through serial port 16 at 2400,N,8,1
    ··· SERIN 16, 16780, [noparse][[/noparse]WAIT ("!"), DEC y]
    ··· X = Y·············· 'Save last Y

    SELECT X············ 'Field value

    ·CASE = 1··········· 'Check value
    ·GOSUB Straight

    ·CASE = 2··········· 'Check value
    ·GOSUB TurnRight

    ·CASE = 3··········· 'Check value
    ·GOSUB BackUp

    ·CASE = 4··········· 'Check value
    ·GOSUB TurnLeft

    ·CASE ELSE
    ·GOSUB Halt

    ·ENDSELECT

    'Select termination Point

    LOOP

    - - - - -

    Just make sure at the top of your program you have included this:

    ' {PBASIC 2.5}

    - - - - -

    I find it quite a bit "cleaner" with SELECT...CASE, but do what makes you feel comfortable.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Programming can't be all that difficult, it's nothing but 1's and 0's

    Post Edited (Bruce Bates) : 3/2/2008 6:22:08 AM GMT
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2008-03-02 22:28
    Bruce,
    Thank You verymuch for your response, but I'm not getting it. I tried it but nothing works.
    My understanding is that the "WAIT" for a ! instruction will cause the stamp program to hold at that line until the stamp gets a ! character. If I only send a ! with each mouse click, won't the program hang?

    I might be asking the stamp to do the impossible...I want to send the stamp a value of 1, 2, 3, 4 or 5 by clicking the mouse in a VB program.
    I want the stamp to take the value sent to it, and execute the corresponding subroutine, and to continue with that executing that subroutine until some other value is sent. As I "talk" this out I need the stamp routine to periodically go back and check if any new data has come in the serial line. Two questions come up in my mind:

    When I'm not clicking the mouse button is a 0 or NULL value being transmitted to the stamp?
    If data is sent to the stamp when it's not "looking" will the data be lost?

    Thanks again for everyone's input!

    Below is the code:

    VB Code:
    Private Sub DataSendButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataSendButton.Click
    Dim send As Integer = Val(TextDataToStamp.Text)
    If _port.IsOpen Then
    _port.WriteLine("!" & vbLf & send)
    End If
    End Sub

    BSCode

    '
    [noparse][[/noparse] Title ]
    '{$STAMP BS2}
    '{$PBASIC 2.5}
    '
    [noparse][[/noparse] I/O Definitions ]

    LeftServo PIN 13 ' Left Servo
    RightServo PIN 12 ' Right Servo

    '
    [noparse][[/noparse] Variables]

    x VAR Word
    y VAR Word
    PulseLeft VAR Word
    PulseRight VAR Word
    '
    [noparse][[/noparse] Constants ]
    pulse CON 15
    '
    [noparse][[/noparse] Initialization ]

    '
    [noparse][[/noparse] Main Routine ]


    DO 'Infinite loop

    'accept decimal value in through serial port 16 at 2400,N,8,1
    SERIN 16, 16780, [noparse][[/noparse]WAIT ("!"), DEC y]

    X = Y 'Save last Y

    SELECT X 'Field value

    CASE = 1 'Check value
    GOSUB Straight

    CASE = 2 'Check value
    GOSUB TurnRight

    CASE = 3 'Check value
    GOSUB BackUp

    CASE = 4 'Check value
    GOSUB TurnLeft

    CASE ELSE
    GOSUB Halt

    ENDSELECT
    'Select termination Point
    GOSUB ApplyPulse
    LOOP



    '+++++++++++SubRoutines+++++++++++++++

    timeout:
    PAUSE 30
    RETURN

    ApplyPulse:

    PULSOUT LeftServo,pulseLeft
    PULSOUT RightServo,pulseRight
    PAUSE pulse ' Constant defined above
    RETURN

    Straight:
    pulseLeft = 850
    pulseRight = 650
    RETURN

    TurnRight:
    pulseLeft = 850
    pulseRight = 850
    RETURN

    TurnLeft:
    pulseLeft = 650
    pulseRight = 650
    RETURN

    BackUp:
    pulseLeft = 650
    pulseRight = 850
    RETURN

    Halt:
    pulseLeft = 750
    pulseRight = 750
    RETURN
  • Tracy AllenTracy Allen Posts: 6,666
    edited 2008-03-02 22:52
    I think that the pause that you have in the applypulse subroutine should be moved up into the SERIN command.
    DO'Infinite loop
    X = Y 'Save last Y
    'accept decimal value in through serial port 16 at 2400,N,8,1   <------- with timeout of length "pulse" milliseconds
    SERIN 16, 16780, pulse, continue, [noparse][[/noparse]DEC y]
    
    IF X<>Y THEN EXIT  ' other code
    
    continue:
    
    SELECT X 'Field value
    
    CASE = 1 'Check value
    GOSUB Straight
    
    CASE = 2 'Check value
    GOSUB TurnRight
    
    CASE = 3 'Check value
    GOSUB BackUp
    
    CASE = 4 'Check value
    GOSUB TurnLeft
    
    CASE ELSE
    GOSUB Halt
    
    ENDSELECT
    'Select termination Point
    GOSUB ApplyPulse
    LOOP
    '  other code on EXIT
    
    
    ApplyPulse:
    PULSOUT LeftServo,pulseLeft
    PULSOUT RightServo,pulseRight
    ' leave out the PAUSE pulse here.   It is rolled into the timeout for SERIN   <---------
    RETURN
    
    



    There is a chance the SERIN will miss an input change or that it will read it incorrectly, so the mouse click might have to try again. It is a workaround. The Stamp does not have a serial buffer to store up incoming asynchronous data. It will only receive while it is sitting at and executing the SERIN command, and the SERIN timeout becomes part of the 20 or 30 millisecond loop that refreshes the servos.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
Sign In or Register to comment.