Only one byte is read when reading just now opened SerialPort

后端 未结 3 643
傲寒
傲寒 2021-01-22 10:30

Strange issue.

When I read from com-port with SerialPort.Read(), then if data arrive, only one byte is read on the first call, disregards of count

相关标签:
3条回答
  • 2021-01-22 11:09

    There are several ways to handle this problem. If you are expecting a reply from a command you send you should sleep for at least 250 msec after calling the serialPort.Write() Before calling serilPort.Read(). Or if you know how many bytes your device is sending back to you can use the serialPort.BytesToRead property to delay reading until the number of bytes you expect are available. If you are using the DataReceived Event you can set the serialPort.ReceivedBytesThreshold (default is 1) to prevent the event from being raised until the expected number of bytes are available. Keep in mind that the serialPort.Read method is not guaranteed to return the number of bytes requested. That is why the serialPort.Read method returns an integer which is the actual number of bytes read.

    0 讨论(0)
  • 2021-01-22 11:32

    I've found my solution I hpe this helps:

    ireadCount = serialPort.Read(readBuffer, 0, serialPort.ReadBufferSize);
    Thread.Sleep(1);//This can be removed, just use it in case need time to complete the reception.
    ireadCount = serialPort.Read(readBuffer, 1, serialPort.ReadBufferSize-1);
    ireadCount +=1;
    

    This way I can have the whole response from the external device without losing the first byte.

    Regards.-

    0 讨论(0)
  • 2021-01-22 11:33

    Because at the moment of reading, the other bytes didn't arrive, it will read only one byte because only one is there in the queue. So if at least one byte is there it won't wait for the required number of bytes since timeout has happened but it won't throw and exception. If none is there it will throw timeout exception. Therefore you should try reading until you read as many bytes as you need (10 in your case). You can try with something like this:

    int count = 0;
    var read = new byte[10];
    while ((count += port.Read(read, count, read.Length - count)) != read.Length) ;
    

    but what if timeout happens, maybe this can strengthen the code:

    int count = 0;
    var read = new byte[10];
    while (count < read.Length)
    {
        try
        {
            count += port.Read(read, count, read.Length - count);
        }
        catch (TimeoutException te)
        {
            //maybe increase ReadTimeout or something, use exponential backoff, your call
        }
    }
    
    0 讨论(0)
提交回复
热议问题