Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

c# - Reading from serial port affecting values

I'm having a little headache trying to read properly from the SerialPort class.

If I use the blocking method ReadLine or ReadExisting the aplication works like charm, but some of my values get affected because of the string conversion. I.e: the 0xFC byte shows as 0x3F ("?"). My guess is that any value outside of the ASCII scope will get lost too.

I tried using the Read(byte[] buffer,int offset,int count) method using the SerialPort.ReadBufferSize to see how many bytes I was supposed to read, but it is always returning almost 5000 , even when I'm trying to read only like 8 bytes from the UART. I had to create a function to trim this array to smaller one and the use it. I could use this method even though it's not efficient, but I sometimes get array out of bounds execution error using it. After debugging I found out this happens when I read a full array of zeroes.

My last try was using this code:

private void DataRec(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    byte[] myarray = new byte[200];
    int pos = 0;
    bool eol = false;
    while (!eol)
    {
        myarray[pos++] = (byte) sp.ReadByte();
        if (myarray[pos] == 0x7E) eol = true;
    }

    byte[] newarray = Recorta(myarray);
    this.Dispatcher.Invoke(new AtualizaCallBack(this.atualiza), new object[] { newarray });
    sp.DataReceived -= DataRec;
}

When debugging this I never get to the byte[] newarray = Recorta(myarray); breakpoint, no errors though. A weird thing is that whenever the event is fired again (I tell the UART to send me a packet) the pos variable does not start a zero.

Any ideas of what could be happening?

Some thing worth mentioning:

  • 0x7E "~" is my end of line character
  • 200 is the maximum amount of bytes I'll ever receive at one time
  • The UART code is sending data one byte at a time, but only after receiving a proper request
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are just using the wrong members of the SerialPort class. ReadLine() and ReadExisting() return strings, but your data cannot be stored in a string. There is no ASCII character code for 0xFC so it just gives up and produces the "cannot convert that byte" value. Which is 0x3F, a question mark.

Similarly, ReadBufferSize is a fixed number, unless you reassign the value. It sets the size of the buffer that the serial port driver uses to store received bytes before your program reads it. At best you'd be interested in the BytesToRead property. Which tells you how many bytes are available for reading inside that buffer.

Just use the SerialPort.Read() method. And be sure to pay attention to its return value, it tells you how many bytes were read. Which is almost always a small number, typically one or two bytes. Serial ports are slow. You'll need to keep reading until you got the device's full response. In your case when you got that 0x7E.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...