Shop OBEX P1 Docs P2 Docs Learn Events
...another dumb question — Parallax Forums

...another dumb question

nondemnondem Posts: 15
edited 2007-12-10 00:10 in BASIC Stamp
I'm struggling with a variable issue. I've read the reference manual and a few things I googled. I'm still not having comprehension.

In a nutshell - I can't figure out how to wait for then accept a variable string from the serial port(of known length in characters NOT binary) then parse that string using the position of individual letters and their values to make decisions.
It's killing me. I'm not Vb guru by any means but I can easily parse a variable string in VB but not in PBASIC.

I've got a .NET application that talks to my BS2 via the serial port. It sends string commands to the BS2 that trigger subroutines.
For example:
I'd send "CB180" to the stamp which is waiting with:
SERIN 16, 16468, [noparse][[/noparse]WAIT("C"),serdata]

The feed that into some Select/Case and/or IF/THEN subs like this:
IF SERDATA(0) = "B" THEN
GOSUB Bearing:
GOTO MAIN:
ENDIF

IF serdata(0) = "D" THEN
GOSUB dt:
GOTO MAIN:
ENDIF

IF serdata(0) = "C" THEN
GOSUB camcontrol:
GOTO MAIN:
ENDIF


I've tried defining "serdata" w/various VAR types. Treating it as an array etc.

so anyway - "In theory" when I send "B180" to the serial port it SHOULD hit this particular if/then:
BEARING:
-
-
-
IF serdata = "B180" THEN
GOSUB TURNRIGHT
GOSUB TURNRIGHT
ENDIF
-
-
-
RETURN

The problem is that I get an "Expected THEN" highlighting the character after the B in B180.

I'm thinking this points to the variable expecting to be one letter long.

Thanks for reading this far [noparse]:)[/noparse]

-Randy

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-08 02:14
    First of all, there are no string variables in PBasic. There are only arrays of characters (bytes). What you probably want is something like this:
    letter var byte
    number var word
    ...
    SERIN 16, 16468, [noparse][[/noparse]WAIT("C"),letter,dec3 number]
    
    


    You'd look at the 2nd letter by testing "IF letter = "B" THEN ..."
    You'd look at the 3 digit value by testing "IF letter = "B" and digit = 180 THEN ..."

    The description of SERIN and SEROUT describe the "formatters" like DEC3.
    There's also some stuff in one of the appendices.
    You can also use the STR formatter to read the next N bytes into a byte array.
    That's more like what you were trying to do, but this may be easier.
  • nondemnondem Posts: 15
    edited 2007-12-08 06:07
    Bingo - once again you saved me hours with your minutes. Thank you!

    So everything is basically working...I'm getting close to having everything set up. VB console-app is working and I've got all the parts to build a power supply that will serve up 1 amp of 5vdc for the cam system using a relay that will be controlled by PIN8.


    www.linearrow.com/consoleBeta.jpg - for a peak.

    I do have one minor annoyance though. Commands generally have to be sent twice to the bot before it actually does something. The command is echo-ing back twice but only the second one triggers anything.
    Any thoughts?

    Here is the (roughly finished) code I'm using in the stamp:
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    pulsecount VAR Byte
    letter VAR Byte
    number VAR Word
    dis VAR Word
    distance VAR Byte

    main:
    'wait for command to be received

    SERIN 16, 16468, [noparse][[/noparse]WAIT("C"),letter, DEC3 number]
    '===============Determine Target of command
    IF letter = "B" THEN
    GOSUB Bearing:
    GOTO MAIN:
    ENDIF

    IF letter = "D" THEN
    GOSUB dt:
    GOTO MAIN:
    ENDIF

    IF letter = "C" THEN
    GOSUB camcontrol:
    GOTO MAIN:
    ENDIF

    '==========================================


    '===================Bearing Commands=======
    bearing:

    IF letter = "B" AND number = 000 THEN
    GOTO main:
    ENDIF
    IF letter = "B" AND number = 045 THEN
    GOSUB TURNRIGHT
    ENDIF
    IF letter = "B" AND number = 090 THEN
    GOSUB turnRIGHT
    GOSUB TURNRIGHT
    ENDIF
    IF letter = "B" AND number = 135 THEN
    GOSUB turnRIGHT
    GOSUB TURNRIGHT
    GOSUB turnRIGHT
    ENDIF
    IF letter = "B" AND number = 180 THEN
    GOSUB turnright
    GOSUB turnright
    GOSUB turnright
    GOSUB TURNRIGHT
    ENDIF
    IF letter = "B" AND number = 225 THEN
    GOSUB TURNLEFT
    GOSUB TURNLEFT
    GOSUB TURNLEFT
    ENDIF
    IF letter = "B" AND number = 270 THEN
    GOSUB TURNLEFT
    GOSUB TURNLEFT
    ENDIF
    IF letter = "B" AND number = 315 THEN
    GOSUB TURNLEFT
    ENDIF
    PAUSE 20

    SEROUT 16, 16468, [noparse][[/noparse]number , " - Bearing Command Received"]
    RETURN

    '===================DISTANCE Commands=======

    dt:

    'start of distance loop
    IF letter = "D" AND number = 001 THEN
    distance = 1
    ENDIF
    IF letter = "D" AND number = 002 THEN
    distance = 2
    ENDIF
    IF letter = "D" AND number = 003 THEN
    distance = 3
    ENDIF
    IF letter = "D" AND number = 004 THEN
    distance = 4
    ENDIF
    IF letter = "D" AND number = 005 THEN
    distance = 5
    ENDIF
    IF letter = "D" AND number = 006 THEN
    distance = 6
    ENDIF
    IF letter = "D" AND number = 007 THEN
    distance = 7
    ENDIF
    IF letter = "D" AND number = 008 THEN
    distance = 8
    ENDIF
    IF letter = "D" AND number = 009 THEN
    distance = 9
    ENDIF
    IF letter = "D" AND number = 010 THEN
    distance = 10
    ENDIF
    distance = distance * 35
    FOR dis = 1 TO distance
    PAUSE 50
    PULSOUT 13, 850
    PULSOUT 12, 650
    PAUSE 20
    NEXT
    PAUSE 20
    SEROUT 16, 16468, [noparse][[/noparse]number , " - Distance Command Received"]

    RETURN



    '===============CAMCONTROL COMMANDS=============
    camcontrol:
    IF letter = "C" AND number = 666 THEN
    HIGH 8

    ENDIF

    IF letter = "C" AND number = 667 THEN
    LOW 8
    ENDIF


    PAUSE 20
    SEROUT 16, 16468, [noparse][[/noparse]number , " - Camera Command Received"]
    GOTO main


    '============================================








    '===============================SUBROUTINES



    backward:

    '___________________________________________________________________
    '
    Straight backward Continous
    DO

    PULSOUT 12, 850
    PULSOUT 13, 650

    PAUSE 20
    LOOP


    '___________________________________________________________________

    RETURN

    turnleft:
    '___________________________________________________________________
    '
    90 degree left
    FOR pulsecount = 1 TO 20

    'PULSOUT 12, 850
    PULSOUT 13, 650

    PAUSE 20
    NEXT



    '___________________________________________________________________

    RETURN



    turnright:
    '___________________________________________________________________
    '
    90 degree right

    FOR pulsecount = 1 TO 20
    PULSOUT 12, 850
    'PULSOUT 13, 650

    PAUSE 20
    NEXT


    '___________________________________________________________________

    RETURN
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-08 06:41
    The programming port (pin "16") always echos back to the PC. That's the way it's built.

    You don't have to test letter again in your subroutines. You can take out the 'letter = "-" and' stuff.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2007-12-08 18:04
    I believe the reason you are having to send the information twice has something to do with the WAIT instruction at 9600 baud. If you drop to 4800 baud you may find it will work just fine. If you prefer to run at 9600 it is possible by using a different format string.

    Stamp:
    sData VAR Byte(4)
    SERIN 16,16468,[noparse][[/noparse]WAIT("C"),STR sData \4\10]

    VB:

    Serialport.Write("C")

    Thread.Sleep(5)

    Serialport.WriteLine("B123")

    I might also change my "wait" character to a character that I know is not going to appear in my data string, maybe WAIT("#") or some other non alphanumeric character.

    Jeff T.

  • nondemnondem Posts: 15
    edited 2007-12-09 20:20
    I'll be removing the lame redundant stuff and streamlining the code. Since with you guys help I've got it working - I'm back to working the "minor annoyances" checklist [noparse]:)[/noparse]

    I'm stuck with minimum 9600 baud for now due to a limitation of my wireless-serial-port hardware. I'm using bluetooth com adapters till I can get some more robust hardware in.

    Everything makes sense except the SERIN 16,16468,[noparse][[/noparse]WAIT("C"),STR sData \4\10] part. Actually I found reference to it but I can't figure out what \4\10 does.
    I mean I see where stringin\10 would load a 10 byte array w/the string received but what does using two(\4\10) do?
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2007-12-10 00:10
    When you read data into an array you can use the special formatter STR. This instruction requires you define the length of the string in other words the number of bytes you wish to place in the array. The first backslash is the number that defines those bytes which in our case is·four· ( \4 ). So if we send the four bytes "B527" from the VB application our array elements will contain sData(0)=B , sData(1)=5 , sData(2)=2 ,sData(3)=7.

    The second backslash \10 is probably not needed in your case but defines a character that terminates the input before the defined length. In other words you could use the same instruction ,·even though you defined a length of four bytes , to recieve three bytes or less.
    Without the termination character if you sent three bytes the SERIN would hang waiting for the fourth byte this would be overcome by sending the terminating character. The terminating character does not have to be 10 (NewLine) , it can be any character you want.

    Jeff T.


    EDIT : I liked the look of the interface BTW, especially the compass

    Post Edited (Unsoundcode) : 12/10/2007 1:05:32 AM GMT
Sign In or Register to comment.