Shop OBEX P1 Docs P2 Docs Learn Events
If loop — Parallax Forums

If loop

In the snippet, when I type in "ledoff", the led goes off. Then I type in "ledon" to turn the led on, nothing happens. It seems like the elseif is not being invoked. I tried using the case method, I had no success. I am not sure what I am doing wrong with the if / elseif loop. Need some help.

Thanks
Ray

    repeat
        term.fstr0(string("What do you need."))
        get_str(BUF_SIZE-2)
        term.fstr1(string("%s"),@buffer)
        term.fstr0(string("\r"))

        if (buffer := "ledoff")
           pinl(38)
        elseif (buffer := "ledon")
           pinh(38)

Comments

  • JonnyMacJonnyMac Posts: 9,716
    edited 2026-03-07 19:57

    You're not showing the code for get_str() -- you should allow others to be able to run your code.

    A few errors:
    1. The := operator is for assignments; the == operator is for testing equality
    2. There is no string type in Spin so you cannot use ==, anyway.
    3. You need @ to point to a string buffer

    Spin has as built-in function called strcomp() that lets us check for matching strings. Give this a try.

      repeat
        term.fstr0(string("What do you need."))
        get_str(BUF_SIZE-2)
        term.fstr1(string("%s"),@buffer)
        term.fstr0(string("\r"))
    
        if (strcomp(@buffer, @"ledoff"))
          pinl(38)
        elseif (strcomp(@buffer, @"ledoff"))
          pinh(38)
    

    TIP: If you use an IO pin in more than one place you should give it a name so that editing your programs will be easier. I know you're just getting started, but this good habit will save you a lot of trouble later.

  • RsadeikaRsadeika Posts: 3,895

    OK, that did the trick. Since I plan to add other choices, would using case be a better option. I would need an example of how I would implement that in my code.

    In this program I used get_str(), how would that be used if the code were placed in the jm_fullduplexserial object.

    I am thinking that for other people just getting started maybe this program would be beneficial.

    '' test_term.spin2
    ''
    
    CON
        CLK_FREQ = 200_000_000
        MS_001 = CLK_FREQ / 1_000
        US_001 = CLK_FREQ / 1_000_000
    
        _clkfreq = CLK_FREQ
    
    
    con {terminal}
    
        BR_TERM = 115_200
        BUF_SIZE = 32
    
    
    
    obj
    
        term : "jm_fullduplexserial"
    
    var
    
        byte buffer[BUF_SIZE]
    
    
    PUB main()
    
       setup()
       term.rxflush()
       term.rx()
    
       term.tx(term.CLS)
       ''waitms(1000)
    
    
        term.fstr0(string("Enter your name: "))
        get_str(BUF_SIZE-2)
        term.fstr1(string("%s"),@buffer)
        term.fstr1(string("\r\rHello,%s,good luck\r"),@buffer)
        waitms(500)
    
        repeat
            term.fstr0(string("What do you need."))
            get_str(BUF_SIZE-2)
            term.fstr1(string("%s"),@buffer)
            term.fstr0(string("\r"))
    
            if (strcomp(@buffer, @"ledoff"))
               pinl(38)
            elseif (strcomp(@buffer, @"ledon"))
               pinh(38)
    
    
       ''repeat
        ''waitct(0)
    
    
       repeat
    
    
    pub setup()
        term.tstart(BR_TERM)
    
    pub get_str(maxlen) : len | k
        bytefill(@buffer, 0, BUF_SIZE)
        term.rxflush()
        repeat
            k := term.rx()
            case k
                31..127 :
                    if(len < maxlen)
                        buffer[len++] := k
                term.BKSP :
                        if (len > 0)
                            buffer[--len] := 0
             term.CR :
                buffer[len] := 0
                return
    
    
    
    
    
  • JonnyMacJonnyMac Posts: 9,716
    edited 2026-03-08 03:08

    I am thinking that for other people just getting started maybe this program would be beneficial.

    In my opinion, string processing is not a beginner topic with the Propeller, but if want to do it I'll share my experience (as I'm sure others will, too). What I share comes from real-world (i.e., commercial) projects. Some of the tricks I'll show I used in a P2-based coprocessor system for a medical device. The main computer sends string commands to the P2 which turns those into IO signals and low-level things that the PC can't do on its own (servos, LED brightness, etc.).

    Since I plan to add other choices, would using case be a better option.

    You can't use case directly with strcomp(). What you can do, though -- and this is what I do in programs that use single string commands -- is convert the string to an index value that can be used with case. This may be a little advanced, so I'll explain it piece-by-piece.

    Step 1. Move your command strings to a list. It is very important that each string have just ONE terminating zero -- except the last which needs one extra zero for the search/indexing method.

      s_Commands            byte
      s_LedOff              byte    "ledoff", 0
      s_LedOn               byte    "ledon",  0
      s_Flash               byte    "flash",  0
      s_Help                byte    "help",   0
      EndOfList             byte    0
    

    Technically, you don't need to give each string a name, but I like to do it for flexibility.

    The next step is to take the string provided by a user and compare it to items in the command list. This uses another string function in Spin called strsize() which returns the length of a string.

    pub str_to_idx(p_str, p_list) : idx | len
    
      repeat 
        len := strsize(p_list)
        if (len > 0)                                                ' more strings?
          if (strcomp(p_str, p_list))                               ' match?
            return idx                                              '  return list index
          else
            p_list += len + 1                                       ' skip unmatched string
            ++idx                                                   ' update index
        else
          return -1                                                 ' string not in list
    

    This is a little tricky -- but only a little. Once you understand it you'll appreciate what it saves you when searching through a list of 20 strings versus a giant stack of if-else clauses. Note, too, that it's atomic which means you can use it with different lists within the same program, and they can be of any length.

    Okay, here's how it works. We pass a pointer to our string (input command from user) and a pointer to our command list. There is an unconstrained loop inside this code so that we can process the whole list without having to know how many items it has. To do that we use strsize() at the top of the list. If that is greater than zero there are still strings to process; if not we return -1 to tell the caller that string was not found. Let's assume we have a string. We use strcomp() with the list pointer. If there is a match we return the current index. Remember, the return variable (idx) is automatically set to 0 when we call this method so we don't have to initialize it manually. Let's say that the string isn't a match. We jump over it by adding the length of the current string plus one to the list pointer. Again, the plus one gets us past the current string. We also update the index when skipping a unmatched string.

    Now we can use case to process the string index.

    pub process_command(cmd)
    
      case cmd
        0     : pinlow(LED)
        1     : pinhigh(LED)
        2     : flash_led()
        3     : term.str(@s_HelpMenu)
        other : term.fstr0("\rInvalid command  \r")
    

    Remember that the position of the command string in the list determines its list index. When I build systems using this code I put frequently-used commands at the top of the list.

    Okay, take a breath and dive in. The attached program works. If you read this through a couple times and experiment with the code it will begin to make sense (again, this is not a beginner topic). I love using string commands. Long term, you'll want to get into a string parser where you can enter a complex string, break it into it's constituent parts, and then operate on them. That's a lot of fun.

Sign In or Register to comment.