Shop OBEX P1 Docs P2 Docs Learn Events
Storing and Using Byte Received with FullDuplexSerial — Parallax Forums

Storing and Using Byte Received with FullDuplexSerial

coryco2coryco2 Posts: 107
edited 2013-07-30 09:37 in Propeller 1
I am trying to understand how to utilize the Rx functions of FullDuplexSerial in order to receive different-length strings of bytes of data and store them in byte-sized variables for use in other methods.

I started with this
repeat

     ReceivedByte[0] := serial.rx
     ReceivedByte[1] := serial.rx
     ReceivedByte[2] := serial.rx
     ReceivedByte[3] := serial.rx
     ReceivedByte[4] := serial.rx
     ReceivedByte[5] := serial.rx
     ReceivedByte[6] := serial.rx
     ReceivedByte[7] := serial.rx
     ReceivedByte[8] := serial.rx
     ReceivedByte[9] := serial.rx
     ReceivedByte[10] := serial.rx
     ReceivedByte[11] := serial.rx
     ReceivedByte[12] := serial.rx
     ReceivedByte[13] := serial.rx
     ReceivedByte[14] := serial.rx
     ReceivedByte[15] := serial.rx  

Which was fine, except for all 16 bytes of the buffer had to be filled before the code continued. Some of the strings I want to receive are less than 16 bytes, and the code just waited and started filling the leftover bytes with the next incoming string, which just made a mess. I tried substituting serial.rxcheck, but was uncertain how to use it--would I have to add an IFstatement after every line to see if a -1 was returned instead of a data byte, and then jump to the code that uses the variables and pass the byte number of the highest non -1 received byte? And flush the Rx buffer above that somehow to get rid of the stale data? I don't grasp how to do this efficiently.

What I am looking to do is to have an Rx loop that will receive from 1 to 16 bytes of data, assigning the value of each byte to a separate variable, and the number of bytes of the received string to another variable. Each string will end with the same value: 255. Once the variables values are evaluated by other code, I want to return to the Rx loop, flush the Rx buffer and repeat the process.

It doesn't seem like it should be that difficult, but I am having a mental block, and would appreciate any suggestions. Thanks!

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-05-17 18:16
    There are string methods in some of the serial objects that let you receive a full string at a time. Usually the string ends with a carriage return (13). Do you need 255 to be your end of message marker? I'm not sure, but there might be a problem with some serial drivers receiving 8-bits since ASCII characters are only 7-bits. (Edit: As I think about this a bit more, I think most serial drivers do receive 8-bits.)

    Look at StringIn in PST. I think PST also has a DecIn which I think is what you are after.

    If you don't use the PST methods I mentioned, you'd want to use a loop instead of the way your doing it. Something like this:
    index := 0
      repeat
        newCharacter := serial.rx
        ReceivedByte[index++] := newCharacter
      while newCharacter <> 255 and index < 16
    
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-05-18 13:32
    You are on the right track with rxCheck. Most useful. It goes in a compact loop, something like this...
    [SIZE=1][FONT=courier new]pub rxData | idx, char
      idx~
      fds.rxFlush
      repeat
        if (char := serial.rxCheck) > -1
          receivedByte[idx++] := char
      until char == 255[/FONT][/SIZE]
    

    The loop exits with the string including the terminating 255.
  • coryco2coryco2 Posts: 107
    edited 2012-05-18 16:43
    Oh...of course! An incremental operator for the byte number and a conditional loop until the terminator seems so obvious now that I can see the code. Thank you both very much for the help.
  • coryco2coryco2 Posts: 107
    edited 2013-07-25 17:17
    I recently came back to this project, and found that for some reason, if I call this this method, it gets stuck in the repeat and doesn't return if there's nothing in the Rx buffer. Why is this? I thought serial.rxCheck in FullDuplexSerial didn't wait for bytes.

    I've tried every way I could think of to make this work (e.g. adding another "if" statement to detect when the value of serial.rxCheck is -1, etc), but everything seems to screw up the timing to receive bytes when they are in the buffer.

    Any suggestions?


    You are on the right track with rxCheck. Most useful. It goes in a compact loop, something like this...
    [SIZE=1][FONT=courier new]pub rxData | idx, char
      idx~
      fds.rxFlush
      repeat
        if (char := serial.rxCheck) > -1
          receivedByte[idx++] := char
      until char == 255[/FONT][/SIZE]
    

    The loop exits with the string including the terminating 255.
  • kuronekokuroneko Posts: 3,623
    edited 2013-07-25 17:26
    Your repeat loop only exits when char is 255. rxCheck returns -1 which - when stored in a long - is still -1 (0xFFFFFFFF) but never 255. You could change the exit condition to something like until ~char == -1. The sign extension op will elevate 255 to -1 and keep -1 intact (until char.byte{0} == 255 will do as well). It really all depends on when you want to exit.
  • coryco2coryco2 Posts: 107
    edited 2013-07-25 18:13
    Thanks, kuroneko. I tried both and they do return, but also corrupt the data when there are bytes to be received. I don't understand this. Does adding one more instruction throw off the timing for the serial rx, or is there something else going on?
  • kuronekokuroneko Posts: 3,623
    edited 2013-07-25 18:22
    coryco2 wrote: »
    ... but also corrupt the data when there are bytes to be received.
    What's the nature of the corruption? Note that if you're receiving bytes while processing the previous string (FDS works in the background) calling this method again will effectively discard everything received so far by calling rxFlush. I assume that your buffer is big enough.

    And last but not least, do you have a simple test case?
  • coryco2coryco2 Posts: 107
    edited 2013-07-30 09:37
    The nature of the "corruption" turned out to indeed be that rxFlush was prematurely zeroing out the received bytes before they were processed. Thanks for the helpful direction!
Sign In or Register to comment.