Problems with SerialPort Class

I have a lot of problems trying to get the serial port to get the correct message. He continues to trim messages. Here is my code, and I will try to clarify it after the code.

public SerialComms(SerialPort sp) { this.sp = sp; this.sp.Open(); this.sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); do { Console.WriteLine("port open waiting message"); Console.ReadKey(); } while(!_terminate); this.sp.Close(); } void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) { string dataReceived; StringComparer strComp = StringComparer.OrdinalIgnoreCase; SerialPort sp = (SerialPort)sender; int i = sp.BytesToRead; byte[] _byte = new byte[i]; char[] _char = new char[i]; sp.read(_byte, 0, i); dataReceived = Encoding.UTF8.GetString(_byte); //dataReceived = new string(_char); //dataReceived = sp.ReadExisting(); if (strComp.Equals("00000000000000"), dataReceived)) _terminate = true; Console.WriteLine(dataReceived); } 

Now I have a test project that we use to test our serial computers in production with legacy software - I know that this is normal. I connected a serial monitor to the port, and the message coming through the transmission does not cause any problems. When I send a message, such as 012345678901234, the first time it usually passes through it is a fine, and on the receiving side, the monitor shows that it passes; however, when it prints to the console, it is clipped after the first message. I attach screenshots of the message passing through the port monitor and the output to the console (the emoticon and heart that appear are converted to prefix bytes - why is it a heart and emoticon that I don’t know about)

Okay, so I can’t post the image because I don’t have enough reputation to do this. I will write what the output to the console looks like below (in this case, for some reason, it also cut the first message :()

On the serial port monitor, the transmitted message is as follows (I sent it three times in a few seconds, the “delay time” between each sending of the message):
02 31 32 33 34 35 36 37 38 39 30 31 32 33 34 03.12345678901234.
02 31 32 33 34 35 36 37 38 39 30 31 32 33 34 03.12345678901234.
02 31 32 33 34 35 36 37 38 39 30 31 32 33 34 03.12345678901234.

On the console, I received the following (the characters ☺ and ♥ are 02 and 03, this is a STX and ETX message, standard for our programs):
☺123456
78901234 ♥

123
456
7890
123
4 ♥

123
456
7890
123
4 ♥

This problem is driving me crazy !!! Please help! The legacy uses the obsolete MSCommLib, and we move on to .Net 4

+7
c # serial-port
source share
2 answers

This is completely normal and common in any communication protocol. TCP over the network has this property. Bytes are transmitted as a stream, not a data packet. Therefore, when the DataReceived event handler fires, you only know that you have several bytes available. You must collect the received bytes in a complete response before processing it.

This requires a protocol, a way to recognize that you have received a complete answer. You have one, these STX and ETX bytes will tell you. ETX, in particular, STX, is a way to filter out the noise bytes that you can get when connecting a device.

A very simple way to get this is to set the NewLine property to (char)3 and just call ReadLine ().

The best way to do this is also to filter out noise, which STX will help you eliminate, and also avoid the deadlock scenario:

 private const int MaxResponse = 42; private const int STX = 2; private const int ETX = 3; private byte[MaxResponse] response; private int responseLength; void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) { var sp = (SerialPort)sender; int cnt = sp.BytesToReceive; for (int ix = 0; ix < cnt; ++ix) { byte b = (byte)sp.ReadByte(); if (responseLength == 0 && b != STX) continue; if (b != ETX) response[responseLength++] = b; else { var str = Encoding.ASCII.GetString(response, 0, responseLength); HandleResponse(str); responseLength = 0; } } } 

And write the HandleResponse () method to process the received data.

+5
source share

There is a possible combination of two problems.

Firstly, a common mistake when working with streams is that just because you ask for i bytes from Read does not mean that Read really reads that many bytes are hardly your problem, but you should be aware this, see the answer to this question for the correct template .

The second problem is that threads are threads, not messages. He doesn’t know that you sent ☺12345678901234♥ , he just knows that he received ☺123456 between the last moment when he was installed, and now he must report this information to the user.

You need to change your read code to keep the data buffered until it receives the next , and then it takes the entire buffer array of bytes and sends it to the user. This is the reason for sending and over a wired connection, which allows the receiver to detect when it got to the beginning or end of the message.

+3
source share

All Articles