Shop OBEX P1 Docs P2 Docs Learn Events
Serial communcation question — Parallax Forums

Serial communcation question

turbosupraturbosupra Posts: 1,088
edited 2014-09-29 07:17 in Propeller 1
I'd like to detect a carriage return, then send the cached bytes (prior to the carriage return) to a delimiter routine.

So let's say I typed into the Parallax Serial Terminal forum=65 and then a carriage return.

After carriageReturnCheck equaled 13, it would then send "forum=65" to my delimiter routine ... but I don't know how to do the cached bytes storage, stringIn := (stringIn + debug.rx) does not work.

I can post the additional code routines if it would make answer the question easier.

Thanks!
    stringIn := (stringIn + debug.rx)
    carriageReturnCheck := debug.rx
    if (carriageReturnCheck == 13)
      debug.str(string("Carriage return detected"))
      debug.tx(13)
      debug.str(@stringIn)
      debug.tx(13)
      debug.StrIn(@stringIn)
      DelimiterFinder(@stringIn)

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2014-09-25 14:16
    Firstly, your first line clears the input character, so the second line will not see that char, but rather see the next char.

    As a good sample of string manipulation, see Kye's string routines in OBEX.

    You will also have to replace the cr with $0 in the stringIn or you will overrun the buffer until a null is found ( a null=$0 is the string terminator)
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-09-26 06:43
    The rx method returns a single byte, adding simply adds the bytes together: "A" + "B" = $83

    Instead, use an index designator to store each byte in a seperate element of the array: stringIn[0] := debug.rx stores the byte in the first element. Remember that arrays start at 0.
    Use a variable for the index to advance through the array as each byte is received: stringIn[i++] := debug.rx
    The ++ operator increments the index after the byte has been stored, so you need to loop until the byte at the previous index is a carriage return.
      i := 0
      repeat until stringIn[i - 1] == 13
        stringIn[i++] := debug.rx
      stringIn[i - 1] := 0                   ' replace the carriage return with a null
      debug.str(@stringIn)
    
    You of course need to make sure that the array is large enough or have some way of limiting the index or otherwise controlling the length of the string.
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-26 11:05
    Thank you.

    I cannot seem to get this to work, I had to add the rxcheck statement because my cog was hung in the repeat loop ... what am I missing?
      if (debug.rxcheck <> -1) 
          'repeat until stringIn[i - 1] == 13
          
          stringIn[i++] := debug.rx
          debug.str(string("Character is - "))
          debug.str(@stringIn[i])
          debug.tx(13)
          if (@stringIn[i] == 13)           
            stringIn[i - 1] := 0                   ' replace the carriage return with a null          
            'debug.str(@stringIn)
            debug.str(string("Carriage return detected (main)"))
            debug.tx(13)
    
    

    ChrisGadd wrote: »
    The rx method returns a single byte, adding simply adds the bytes together: "A" + "B" = $83

    Instead, use an index designator to store each byte in a seperate element of the array: stringIn[0] := debug.rx stores the byte in the first element. Remember that arrays start at 0.
    Use a variable for the index to advance through the array as each byte is received: stringIn[i++] := debug.rx
    The ++ operator increments the index after the byte has been stored, so you need to loop until the byte at the previous index is a carriage return.
      i := 0
      repeat until stringIn[i - 1] == 13
        stringIn[i++] := debug.rx
      stringIn[i - 1] := 0                   ' replace the carriage return with a null
      debug.str(@stringIn)
    
    You of course need to make sure that the array is large enough or have some way of limiting the index or otherwise controlling the length of the string.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-09-26 11:33
    In the statement "if (@stringIn == 13) you are testing if the address of stringIn is equal to 13. Remove the "@" character.

    EDIT: You are also incrementing i when reading the character, and then referring to stringIn later on. You should either increment i after doing everything else, or use stringIn[i-1] to compensate for having incremented i.
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-29 05:38
    Something still is off. I'm trying to type "bob=100" to test this. It will detect every other character for the "character is - " portion of it and I'm not sure why ... and the incrementing variable I'm not able to display after the carriage return is detected, either.
    if (debug.rxcheck <> -1) 
          debug.str(string("Character detected ", 13))
          stringIn[i] := debug.rx
          debug.str(string("Character is - "))
          debug.str(@stringIn[i])
          debug.tx(13)
          if (stringIn[i] == 13)           
            stringIn[i - 1] := 0                   ' replace the carriage return with a null          
            debug.str(stringIn)
            debug.tx(13)
            debug.str(string("Carriage return detected (main)"))
            debug.tx(13)
    
          i++ 
    

    with the result of

    [code]
    bCharacter detected
    oCharacter is - o
    bCharacter detected
    =Character is - =
    1Character detected
    0Character is - 0
    0Character detected

    Character is -
    ˆP,
  • kuronekokuroneko Posts: 3,623
    edited 2014-09-29 05:44
    PUB RxCheck : rxByte
    {{
       Check if a byte is waiting in the receive buffer and return the byte if one is there,
       does NOT block (never waits).
    
       Parameters: none
       return:     [COLOR="#FF0000"]If no byte, then return(-1).  If byte, then return(byte).[/COLOR]
    
       example usage: serial.RxCheck
    
       expected outcome of example usage call: Return a byte if one is available, but dont wait
                                               for a byte to come in.
    }}
    
    IOW you should remember the character returned in if (debug.rxcheck <> -1), e.g. if ((c := debug.rxcheck) <> -1) and then consume the character, not throw it away.
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-29 05:56
    It appears I was using the byte receive portion incorrectly, this code works better
    receivedByte := debug.RxCheck                                          
        if (receivedByte <> -1) 
          
          debug.str(string("Character detected ", 13))
          stringIn[i] := receivedByte
          debug.str(string("Character is - "))
          debug.str(@stringIn[i])
          debug.tx(13)
          if (stringIn[i] == 13)           
            stringIn[i] := 0                   ' replace the carriage return with a null          
            debug.str(stringIn)
            debug.tx(13)
            debug.str(string("Carriage return detected (main)"))
            debug.tx(13)
            i := 0
    
          i++ 
    

    but the debug.str(stringIn) still prints nonsense to the terminal.
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-29 05:59
    Hey Kuroneko, it is good to see you are still around and helping people, thanks for the response.

    I just read your message after my latest code and I believe I've gotten that part correct. Any idea why I can't write the final value ( debug.str(stringIn) ) as confirmation I've ingested it and stored it in ram?

    kuroneko wrote: »
    PUB RxCheck : rxByte
    {{
       Check if a byte is waiting in the receive buffer and return the byte if one is there,
       does NOT block (never waits).
    
       Parameters: none
       return:     [COLOR="#FF0000"]If no byte, then return(-1).  If byte, then return(byte).[/COLOR]
    
       example usage: serial.RxCheck
    
       expected outcome of example usage call: Return a byte if one is available, but dont wait
                                               for a byte to come in.
    }}
    
    IOW you should remember the character returned in if (debug.rxcheck <> -1), e.g. if ((c := debug.rxcheck) <> -1) and then consume the character, not throw it away.
  • kuronekokuroneko Posts: 3,623
    edited 2014-09-29 05:59
    turbosupra wrote: »
    ... but the debug.str(stringIn) still prints nonsense to the terminal.
    Use debug.str(@stringIn{0}) instead.
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-29 06:20
    That only prints out the first character of my variables address. Is there a way to print out the entire variable value?
  • kuronekokuroneko Posts: 3,623
    edited 2014-09-29 06:35
    Works for me:
    CON
      _clkmode = XTAL1|PLL16X
      _xinfreq = 5_000_000
    
    OBJ
      debug: "FullDuplexSerial"
    
    VAR
      byte  stringIn[32]
      
    PUB null : i | c
    
      debug.start(31, 30, %0000, 115200)
      waitcnt(clkfreq*3 + cnt)
      debug.tx(0)
      
      repeat
        if (c := debug.rxcheck) <> -1                                                   
          stringIn[i] := c                                                              
          if (stringIn[i++] == 13)                                                      
            stringIn[--i] := 0                 ' replace the carriage return with a null          
            [COLOR="#FF0000"]debug.str(@stringIn{0})[/COLOR]                                                     
            debug.tx(13)                                                                
            i := 0                                                                      
    
    DAT
    
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-29 07:00
    You are right, it did work as a stand alone function and then eventually in my code after I fixed my mistakes.

    I did not work in my code at first, but then I noticed you had stringIn defined as a 32bit byte array and I had it as a long.

    Can you explain why you knew to do that so I can understand why that the correct choice over a 32bit long?
  • kuronekokuroneko Posts: 3,623
    edited 2014-09-29 07:06
    turbosupra wrote: »
    ... you had stringIn defined as a 32bit byte array and I had it as a long.
    Make that a byte array holding 32 elements. I could have picked any length, e.g. 42.
    turbosupra wrote: »
    Can you explain why you knew to do that so I can understand why that the correct choice over a 32bit long?
    Strings in SPIN are zero terminated byte arrays. There is nothing else to it. You can use a long array if you want but still have to fill it with bytes e.g.
    VAR
      long  stringIn[16[COLOR="#A9A9A9"]{64 bytes}[/COLOR]]
    
    PUB null
    
      ...
      stringIn.byte[i] := c
      ...
    
  • turbosupraturbosupra Posts: 1,088
    edited 2014-09-29 07:17
    Ok, thank you
Sign In or Register to comment.