C#串口数据,格式化接收数据

时间:2016-04-12 16:33:27

标签: c# serial-port

所以我从串口读取数据,到目前为止一直很好,但来自串口的数据是分块的,我的协议规定每条消息都以SOH(\ u0001字节)开头并结束使用EOT(\ u0004),我尝试按SOH字节拆分消息,但仍然存在问题。 有一种更优雅,更安全的方法吗?

private  void RecebendoDados(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        var id_prova = Form1._Form1.IDPROVA;
        var serie = Form1._Form1.SERIE;
        var fase = Form1._Form1.FASE;

        var http = new ComunicacaoWeb();
        var sp = (SerialPort)sender;
        var indata = sp.ReadExisting();
        Console.WriteLine(indata+"\n\r");

        if (!sp.IsOpen) {
            sp.Open();
        }

        var pacotes = indata.Split(new[] { "\u0004" }, StringSplitOptions.None);

1 个答案:

答案 0 :(得分:0)

<强> 1

  

这是一种更强大,更优雅,更安全的方法吗?

如果您的消息以EOT控制代码结束,则SerialPort允许您准确读取此char的第一个匹配项。

SerialPort sp = (SerialPort)sender;
// this lines converts the hex-code of EOT to a char and read the incoming
// message only up to this point
string indata = sp.ReadTo(Convert.ToChar(0x04));

现在你只需要摆脱SOT:

indata = indata.TrimStart(Convert.ToChar(0x01));

此时你应该有干净的信息。

属性BytesToRead将告诉您缓冲区中是否还有数据:

int stillToBeRead = sp.BytesToRead;

如有必要,您可以检查并重复阅读程序。

<强> 2

  

这是一种更加优雅和安全的方式吗?

如果您尝试从已关闭的端口读取,则它将失败并显示System.InvalidOperationException。通过这种逻辑,永远不会输入代码中的if条件来重新打开端口。

var sp = (SerialPort)sender;
var indata = sp.ReadExisting();

if (!sp.IsOpen) {
    // this will never be executed
    sp.Open();
}

你应该检查端口是否打开,并且在尝试读取之前有数据要读取。我猜RecebendoDadosDataReceived事件,所以关闭端口和没有数据读取的概率很低,但仍然是:魔鬼睡在细节中;)