gpt4 book ai didi

c# - SerialPort 类问题

转载 作者:太空狗 更新时间:2023-10-29 18:31:45 28 4
gpt4 key购买 nike

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

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 之类的消息时,它通常会顺利通过,而在接收端,监视器显示它正在通过;但是,当它打印到控制台时,它会在第一条消息后被截断。我附上了在端口监视器和控制台输出上通过的消息的屏幕截图(显示的笑脸和心形是正在转换的前缀字节 - 为什么它是心形和笑脸我不知道)

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

在串口监视器上,正在传输的消息如下(我发送了三次,每次发送之间有几秒的“滞后时间”):
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♥

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

最佳答案

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

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

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

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

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() 方法来处理您收到的数据。

关于c# - SerialPort 类问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21142647/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com