C# 串行通信中的拆分消息

C# 串行通信中的拆分消息,c#,serial-port,packets,C#,Serial Port,Packets,我不熟悉串行通信。我已经阅读了不少教程,我尝试做的大部分工作都是工作,但是我有一个关于与C#的串行通信的问题。我有一个微控制器,它不断地通过串行线路发送数据。数据列表的格式如下: Bxxxxix.xx,xx.xx* 其中x代表不同的数字,+或-符号。 在某些时候,我想从电脑上的C#程序中读取这些信息。我遇到的问题是,即使我使用 读到(“*”); 我想这会把所有的东西都读到*字符。 如何确保收到的信息完整 谢谢你的帮助 public string receiveCommandHC()

我不熟悉串行通信。我已经阅读了不少教程,我尝试做的大部分工作都是工作,但是我有一个关于与C#的串行通信的问题。我有一个微控制器,它不断地通过串行线路发送数据。数据列表的格式如下: Bxxxxix.xx,xx.xx* 其中x代表不同的数字,+或-符号。 在某些时候,我想从电脑上的C#程序中读取这些信息。我遇到的问题是,即使我使用 读到(“*”); 我想这会把所有的东西都读到*字符。 如何确保收到的信息完整

谢谢你的帮助

    public string receiveCommandHC()
    {

        string messageHC = "";
        if (serialHC.IsOpen)
        {
            serialHC.DiscardInBuffer();
            messageHC = serialHC.ReadTo("*");

        }
        return messageHC;
    }

我不知道你为什么要这样做,但是你在读取之前丢弃了缓冲区中串行端口中的所有内容,所以如果计算机在那一点上已经接收到“bxxx”,那么你扔掉它,你只会读取“xixx.xx,xx.xx”。

我猜你实际上得到了命令的结尾,也就是说,您得到的不是
b01234.56.78.9
(省略最后的
*
),而是
.56.78.9
。这是因为您丢弃了输入缓冲区。不要那样做。您无法知道该点的状态(就在读取之前),因此丢弃缓冲区完全是错误的。删除
serialHC.DiscardInBuffer()行。

您几乎总能在串行通信中发现数据消息(除非非常小)被拆分。这主要取决于通信速度和从端口检索数据的时间点

通常,您会将代码设置为在单独的线程中运行(以帮助防止影响代码其余部分的性能),该线程在收到完整消息时引发事件,并接收完整消息以进行传输。读写功能由工作线程处理(串行通信流量缓慢)

您需要一个读写缓冲区。这些数据应该足够大,可以保存数个周期的数据

将从输入读取的数据追加到读取缓冲区的末尾。让读取缓冲区从缓冲区开始循环读取完整消息

根据所使用的协议,通常有一个数据开始,可能有一个数据结束指示器,还有一个消息大小(这可能是固定的,同样取决于您的协议)。我从您的协议中收集到消息开始字符是
'b'
,消息结束字符是
'*'
。丢弃邮件开始字符('b')之前的所有数据,因为这是来自不完整的邮件

当找到完整的消息时,将其从缓冲区前端剥离,并引发一个事件以指示其到达

发送数据也会运行类似的过程,只是您可能需要拆分消息,因此要发送的数据会附加到缓冲区的末尾,并且要发送的数据会从开头读取

我希望这能帮助您理解如何处理串行通信

正如Marc指出的,您当前正在以一种会导致问题的方式清除缓冲区

编辑


正如我在评论中所说,我不认识serialHC,但是如果处理原始数据,请查看使用
SerialPort
类。关于如何使用它的更多信息和一个示例(大致使用了我上面描述的过程)可以找到。

当你说它在奇数位置被拆分时,你能更具体一点吗?它被拆分为随机消息,这意味着有时messageHC将是bxxxi,然后下次它返回类似于xx或其他的内容。删除DiscardInBuffer()调用,它只会导致无法诊断的数据丢失。@HansPassant感谢您的评论,我已经删除了它,但是它确实有帮助,正如我在下面的一些评论中所描述的,我仍然没有得到完整的消息返回。我想我需要把我得到的所有信息重新组合成一条完整的消息,然后从我的函数中返回,但是我不知道怎么做。哇,这很简单,我想这就成功了。只是想知道,我的缓冲区会不会溢出???@user1173059呃,不会。
丢弃…
调用会丢弃已经到达但您尚未使用的数据。您好,谢谢您的回复。b应该是消息的一部分,我认为从我的理解来看,我应该发送一个明确的“消息开始”命令和一个“消息结束”命令,然后找到它们之间发送的内容。一旦我得到了完整的信息,我就可以从我的函数中返回它。有一种简单的方法可以做到这一点吗?@ChrisBD如果使用原始读取,这肯定是正确的,但是我相信
ReadTo
使用read-loop.Marc在内部进行缓冲,您建议我使用原始读取吗?我仍然不太明白如何将我收到的数据拼凑成一条完整的信息。如果有帮助,我可以更改微控制器发送的数据,以包括特定的消息开始和消息结束命令。很抱歉问这么简单的问题,作为一名机械工程师,这是一个非常新的问题。@Marc-是的,我在处理原始数据输入。我承认我没有识别serialHC。@user1173059在我回答这个问题之前,删除
放弃…
会修复它吗?