SerialPort 类问题

SerialPort Class issues(SerialPort 类问题)
本文介绍了SerialPort 类问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试让串行端口接收正确消息时遇到很多问题.它不断截断消息.这是我的代码,我会在代码之后详细说明.

I am having a lot of issues trying to get a serial port to receive the correct message. It keeps truncating the messages. Here is my code and I will try to elaborate 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);
}

现在我有一个测试项目,我们用它来测试我们在生产中使用旧版软件的串行通信 - 我知道它运行良好.我已将串行监视器连接到端口,并且通过传输的消息没有任何问题.当我第一次发送诸如012345678901234之类的消息时,通常可以正常通过,而在接收端,监视器显示它已通过;但是,当它打印到控制台时,它会在第一条消息后被截断.我附上了在端口监视器和控制台输出上通过的消息的屏幕截图(出现的笑脸和心是被转换的前缀字节 - 为什么它是心和笑脸,我不知道)

Now I have a test project that we use for testing our serial coms in production with legacy software- I know this runs fine. I have attached a serial monitor to the port and the message coming through transmits without any issues. When I send a message such as 012345678901234 the first time through it usually goes through just fine, and on the receiving end, the monitor shows it coming through; however, when it prints to the console it gets truncated after the first message. I am attaching screenshots of the message going through on the port monitor and the console output (the smiley face and heart that show up are the prefix bytes being converted- why it is a heart and a smiley face I have no idea)

好的,所以我不能发布图片,因为我没有足够的声誉来这样做.我将在下面的控制台中写入输出的样子(在这种情况下,由于某种原因,它也截断了第一条消息:()

Ok so I can't post the image because of the fact that I do not have enough reputation to do so. I will write what the output looks like to the console below (in this case for some reason it truncated the first message as well :( )

在串口监视器上,正在传输的消息如下(我发送了三次,每次发送消息之间有几秒钟的延迟时间"):
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 serial port monitor the message being transmitted is as follows (I sent it three times with a few seconds 'lag time' between each message send):
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.

在控制台上我收到以下信息(☺ 和 ♥ 字符是 02 和 03,它们是我们传输的标准 STX 和 ETX 消息):
☺123456
78901234♥

123
第456章
7890
123
4♥

123
第456章
7890
123
4♥

On the console I received the following (The ☺ and ♥ characters are 02 and 03, they are an STX and ETX message that is standard for our transmissions):
☺123456
78901234♥

123
456
7890
123
4♥

123
456
7890
123
4♥

这个问题快把我逼疯了!!!请帮忙!遗留问题是使用过时的 MSCommLib,我们正在迁移到 .Net 4

This issue is driving me mad!!! Please help! The legacy is using the outdated MSCommLib and we are moving to .Net 4

推荐答案

这在任何通信协议中都是完全正常和常见的.网络上的 TCP 也具有此属性.字节作为 传输,而不是数据包.因此,当您的 DataReceived 事件处理程序触发时,您只知道您有 一些 字节可用.您可以在处理之前将接收字节组装成完整的响应.

This is entirely normal and common in any communication protocol. TCP over a network has this property as well. Bytes are transferred as a stream, not a packet of data. So when your DataReceived event handler fires, you only know that you have some bytes available. It is up to you to assemble the receive bytes into a complete response before you process it.

这需要一个协议,这是一种识别您得到完整响应的方法.你有一个,那些 STX 和 ETX 字节告诉你.特别是 ETX,STX 是一种过滤掉连接设备时可能收到的噪声字节的方法.

This requires a protocol, a way to recognize that you got a full response. You have one, those STX and ETX bytes tell you. ETX in particular, the STX is a way to filter out noise bytes that you might get when you connect the device.

一个非常简单的方法是将 NewLine 属性设置为 (char)3 并调用 ReadLine().

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

更好的方法是同时过滤 STX 帮助您消除的噪音,同时避免死锁情况:

A better way to do this is to also filter the noise that STX helps you to eliminate, also avoids a 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;
       }
   }
}

并编写 HandleResponse() 方法来处理收到的数据.

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

这篇关于SerialPort 类问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)