Shop OBEX P1 Docs P2 Docs Learn Events
IF satement help — Parallax Forums

IF satement help

grasshoppergrasshopper Posts: 438
edited 2008-01-16 15:23 in Propeller 1
'' Propeller "Hello, world input and output"


CON
  _clkmode = xtal1 + pll16x                     ' use external crystal * 16
  _xinfreq = 5_000_000                          ' 5 MHz

obj
SER  : "FullDuplexSerial" 
    
PUB COMPUB    
   ser.start(31, 30, 0, 9600)

   if [color=#990000] ser.rx(string("[noparse][[/noparse]X1]")) then[/color]
   ser.str(string("Hello World "))
   ser.tx(13)                          'line feed
   ser.tx(10)                          'carriage return
   else [color=#990000] goto COMPUB[/color]







Basically i want to pause the code until the serial string [noparse][[/noparse]X1] is recieved then say HELLO WORLD

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-14 19:01
    A lot depends on what other characters you're expecting on the serial input line. If "[noparse][[/noparse]" is always followed by "X1]", then it's easy:
    repeat
       if ser.rx == "[noparse][[/noparse]"
          if ser.rx == "X"
             if ser.rx == "1"
                if ser.rx == "]"
                   ser.str(string("Hello World ",13,10))
    


    This always goes back to waiting for the "[noparse][[/noparse]" if any of the characters are incorrect. There are other, fancier ways of doing this that can do a smarter job of matching strings, but this would do what you asked.
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-14 19:25
    Yes thanks this did work but since i am learning i ask why this is not working?

    '' Propeller "Hello, world input and output"
    
    
    CON
      _clkmode = xtal1 + pll16x                     ' use external crystal * 16
      _xinfreq = 5_000_000                          ' 5 MHz
    
    obj
    SER  : "FullDuplexSerial" 
        
    PUB COMPUB    
      ser.start(31, 30, 0, 9600)
      repeat
       if ser.rx == (@DATAONE)
        ser.str(string("Hello World ",13,10))               ' accept
               
    
    DAT
    
    DATAONE byte "[noparse][[/noparse]X1]"  
    
    
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-14 20:08
    Well, if you want to learn.. Tell me, what do you think this check shall do?
    IF ser.rx == (@DATAONE)
    
  • hippyhippy Posts: 1,981
    edited 2008-01-14 20:09
    You probably need something like ...

    if ser.rx == byte[noparse][[/noparse] @DATAONE ]
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-14 20:10
    I though it would put the pointer at this (@DATAONE) address and if is true "[noparse][[/noparse]X1]" then complete the if statement.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-14 20:27
    You can't make that kind of assumption.

    Only some programming languages have the ability to work with strings of characters as basic values. Spin is not one of these. There is some minimal support in the compiler for string and floating point constants and some simple string operations (equality testing, length, and copying) implemented as efficient function/procedure calls, but that's it.
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-14 20:30
    You are surely aware you will have to know - in all cases - what "it" will do..
    So you say: "---"it" would put the pointer at this (@DATAONE) address..."
    A better way to say this would be: " ... look at the memory cells pointed to by the pointer..."
    You say:"... and if is true "[noparse][[/noparse]X1]" then complete the if statement."
    A better way to say this would be: ".. and if those memory cells are equal to the bytes read in by the serial routine...."

    Is this what you think?
    It "yes", I shall tell you in the next posting why it is not so with SPIN...
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-14 20:43
    Yes this is what I was thinking. Ok, now that I am embarrassed will you tell me why? I have been reading other postings and cant seem to figure it out.

    I really want to have a "serial data table" that I can look up when data is sent to the propeller via a computer. Once i find a specific match in the table i can execute code for that table.
    Any help is appreciated even if I get embarrassed [noparse]:)[/noparse]
  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-14 20:57
    Spin works well with 8, 16, and 32 integers and you can easily take 1 to 4 input characters and convert them to integers, then look that up in a table. For example:
    pub matchIt | name, t
       name := 0
       repeat until ser.rx == "[noparse][[/noparse]"  ' wait for opening bracket
       repeat until (t := ser.rx) == "]"
          name := name << 8 + t  ' pack the characters into a long
       result := 0
       repeat while t := table[noparse][[/noparse] result++ ]   ' check for end of table
          if name == t   ' look for a match in the table
             return  ' if a match, return zero-based index in table
       return -1 ' indicate unknown
    
    


    dat
    table         long  "X" << 8 + "1"  ' zero padded with LSB the last character
            long  0     ' marks end of table
    
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-14 21:16
    Mike did very advanced stuff here... We shall keep it simpler at the beginning:
    (a) You have called a routine here, "rx". First find out as precise as possible what this routine delivers as a result! Is it a "string"? A pointer to a string? A number? What is the eaning of that number?

    This can be difficult sometimes! The best way is to look into the object where that routine is defined! There are generally coments that tell you, but sometimes you have to look through its very code....

    (b) You use an "operator", "==". What does the manual tell you what it does, again: What it "precisely" does...

    Can you now put those things together? If not - after having done your "homework" (a) and (b) - call here again smile.gif
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-14 21:21
    Mike the code look great but i am still a bit confused. here is what i understand from what you posted from line 1 - finish
    1. "name" and "t" are variables (of what data type i do not know) in a pub called matchit (i understand naming a pub)
    2. name alwys = 0
    3. repeat until "[noparse][[/noparse]" is captured from serial port. (i understand this)
    4. load into memory "name" until "]" is received or name is larger than 8? (kind of foggy here)
    5. result = 0 (i think it returns a 0 to the pub)
    6. repeat ehile t := table ( looking up the table for matches?)
    7. the rest i am lost on.
    if i find a match what then??
    i still need to send through the serial port "hello world for X1 and say bye world for X2 etc...??

    Thanks in advance.
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-14 21:30
    deSilva said...


    (a) You have called a routine here, "rx". First find out as precise as possible what this routine delivers as a result! Is it a "string"? A pointer to a string? A number? What is the eaning of that number?

    --- I thought it to be a string but maybe a number not sure
    deSilva said...

    [noparse][[/noparse]quote](b) You use an "operator", "==". What does the manual tell you what it does, again: What it "precisely" does...

    --- == is boolean: is equal

    I still need to do my homework... i will call many many more times [noparse]:)[/noparse]
  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-14 22:07
    1. "name" and "t" are variables (of what data type i do not know) in a pub called matchit (i understand naming a pub)
    Read the documentation on PRI / PUB. You'll see that local variables are all longs.
    2. name alwys = 0
    No. Look at the repeat loop
    3. repeat until "[noparse][[/noparse]" is captured from serial port. (i understand this)
    4. load into memory "name" until "]" is received or name is larger than 8? (kind of foggy here)
    Look up the "<<" operator. Work through an example on paper.
    5. result = 0 (i think it returns a 0 to the pub)
    Look up the unary "++" operator. Again, work through an example on paper.
    6. repeat ehile t := table ( looking up the table for matches?)
    You can put an assignment statement in parentheses and the value assigned is used. Here it's the result of ser.rx.
    7. the rest i am lost on.
    Again, you'll learn a lot working through an example on paper. I usually make columns for each variable and
    step through each statement (or part of a statement) on each row, writing down what changes.
    if i find a match what then??
    This subroutine returns the number of the table entry where there was a match (0 to n) or -1 if there was no match.
    In your main program, you'd have something like:
    repeat
       case matchIt
          -1: exit
          0: ' here's the first choice
          1: ' now the second choice
    
    
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-14 23:27
    i understand most of this now. However i poss a new question. What if i wanted to store the data coming in through the serial port and send it through another serial port. For example i list in my table with [noparse][[/noparse]X1] and so on to [noparse][[/noparse]X9]. if non are listed then i pass the serial data through a different serial port. any ideas?
  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-14 23:45
    You can certainly do that.· I suggest that you get something working and gain some experience with the language (Spin) and the programming environment (Propeller Tool and the Propeller).· Basically, what you want to do is create a buffer in which you store all the incoming characters until you either get a successful match or an unsuccessful one.· If successful, you do whatever action is called for and clear the buffer.· If unsuccessful (something unknown between brackets), you retransmit the buffer, then clear it.· Think about how you might do that, but get something going first.
    ·
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-15 17:21
    I would love to learn more but i am not sure where to start. I need to get this programed soon. I have about 3 weeks before my project is due. Can you point me in the right direction on this BUFFER. I do understand your code more and appreciate your guidance.
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-15 17:57
    Here is what i have done so far

    '' Propeller "Hello, world input and output"
    
    
    CON
      _clkmode = xtal1 + pll16x                             ' use external crystal * 16
      _xinfreq = 5_000_000                                  ' 5 MHz
    
    obj
    SER           : "256_FullDuplexSerial"
    
    PUB START
        ser.start(31, 30, 0, 9600)                          'INPUT PORT
        repeat
          MatchIt
          SendIt
        
    PUB SendIt
        CASE MatchIt
          0: ser.str(string("NO COMMAND"))
          1: ser.str(string("X1"))
          2: ser.str(string("X2"))
          3: ser.str(string("X3"))
         10: PassIt
          
    PUB MatchIt | name, t 
        name := 0
        repeat until ser.rx == "[noparse][[/noparse]"                          ' wait for opening bracket
        repeat until (t := ser.rx) == "]"
          name := name << 8 + t                             ' pack the characters into a long
        result := 0
        repeat while t := table[noparse][[/noparse] result++ ]                 ' check for end of table
          if name == t                                      ' look for a match in the table
             return                                         ' if a match, return zero-based index in table
        return 10                                           ' indicate unknown
          
    PUB PassIt | str
    
      SER.start(0,1, 0, 9600)                               'OUTPUT PORT
       repeat 
        str := name
        if str <> 0
          SER.tx(str)
       
    dat
    table   long  "X" << 8 + "1"                            ' zero padded with LSB the last character
            long  "X" << 8 + "2"                            ' zero padded with LSB the last character
            long  "X" << 8 + "3"                            ' zero padded with LSB the last character
            long  "X" << 8 + "4"                            ' zero padded with LSB the last character 
            long  0                                         ' marks end of table
      
    
    



    But the name needs to be global variable i think. Alos why do i have to input the commands twice before it will send it back through the port?
  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-15 19:23
    You have to input the commands twice because you call MatchIt twice (once in Start and once again in SendIt).
    PassIt won't work the way you've done it (you're reinitializing the serial port rather than setting up a new one).

    1) You need two separate serial ports, one for input and one for your output. You can declare multiple instances
    of the serial object. Keep SER as one name and maybe use OUTPUT as the other. The OUTPUT.start call needs to
    be in your START routine so that it's only called once during initialization.

    2) Sure, make "name" a global variable (in a VAR section ... declare it as a long). To transmit it, use the following:
    PRI sendName   ' use the implicit result variable as a temporary value
       result := name   ' the first character is in the high order byte
       OUTPUT.tx("[noparse][[/noparse]")   ' send the opening bracket
       repeat until result == 0   ' stop when there are no more characters
          if (result >> 24) <> 0   ' don't send a zero byte
             OUTPUT.tx(result >> 24)   ' send the leading character of the name
          result := result << 8   ' shift the next character into position
       OUTPUT.tx("]")   ' send the closing bracket
    
    

    Post Edited (Mike Green) : 1/15/2008 7:31:19 PM GMT
  • Mike CookMike Cook Posts: 829
    edited 2008-01-16 00:13
    Grasshopper,

    Take a look at the attached *.spin code, probably not the best example, but works for what I need it to do. Demonstrates receiving a 'canned' string and then acting upon what was received.

    Please remember I code for a 'relaxation hobby' like some that play Xbox or whatever as a relaxation!

    Always learning!

    Hope this helps,

    Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike
  • grasshoppergrasshopper Posts: 438
    edited 2008-01-16 15:23
    Thanks ill take a look.
Sign In or Register to comment.