Main Site Documentation

Reading serial data on Panda


#1

Is there anything like Serial.IsAvailable similar to arduino? I find I have to use a read timeout to prevent it from blocking for a long time so in situations where I’m reading data I end up doing a lot of unnecessary waiting. If I try to make the read timeout smaller after the port is open it throws an exception.


#2

Like BytesToRead? Check out the SerialPort documentation.


#3

also, you have to set the port timeout AFTER you create the instance but BEFORE you open the port; that way it sets the timeout and then opens the port with that timeout active.


#4

BytesToRead will return 0 or fewer bytes than if Read is called with a longer timeout (maybe because data is still being written to the wire). I think maybe the only way to get it to behave like the arduino isavailable is with a small timeout and reading one character at a time. But in this case I found a way to reduce the number of read calls and make it less of an issue so I’m good.


#5

@ PaulB. Hi. BytesToRead should really only be used a “hint” or a signal that something was sent. It is only point in time. As you said, the wire is most likely sending a lot more data even before BytesToRead call returns. So don’t use it as a way to size a read buffer or anthing like that. There are really only 3 ways to read serial correctly (and are various on a theme):

  1. ReadLine(). This internally allocates buffer and returns a string after eol. Good for quick and dirty, but not the best. Having an unbounded buffer like this can be problematic.

  2. Read fixed size buffers and keep reading until buffer is full. Your protocol, by convention, will dictate the buffer size and pad unused space out.

  3. Prepend the data length as an int (or byte, or uint). This “header” could contain other header info. But the header is always fixed size. If just an int, it will always be 4 bytes. Then allocate a buffer of header.Size and keep reading into that buffer (using readLeftToRead counter) until full. Repeat as needed. This, imho, is the best way for a couple reasons. 1 - you can have variable len data section, and 2 - you always know what is left to read and can hash out issues on both ends easier. Many of your internet protocols (i.e. DNS, etc.) use this method for good reason.


#6

Are you using a standard UART or a USB virtual Serial port? If you’re using USB Host on Domino then you can’t do this :wink:

There’s a data recieved event that you can use to know you need to act on data, and then you read the correct number of bytes based on BytesToRead. That way you actually don’t need to worry too much about blocking.

You can see an example on the GPS Extension on Fezzer http://www.fezzer.com/project/47/gps-extension/


#7

The datareceived event does work well for me, but in thise case there was a conversation that had to occur, i.e. send these 5 bytes and then you will get these 3 bytes back with a response. So using an asynchronous method wasn’t very natural. The problem I was having was that the device would sometimes send more info than I was expecting so I wanted to get all that off the wire before doing the next command batch. As it turned out I was passing an incorrect option to it so it was actually sending me exactly what I asking for… Once I fixed that I didn’t need to clear the wire anymore so the issue went away. Thanks for all the help.


#8

true, when you know how the conversation goes, datarecieved isn’t the logical choice.

glad to hear you’re sorted though! Onward and upward!