需要.NET串口帮助,主要是在多个“数据包”中收到的数据

时间:2009-05-21 05:17:03

标签: c# .net serial-port

我通过.net在串口上发送数据非常新,我注意到在实现了一个TCP对应物之后我就不会那么容易用串口了!

所以从顶部开始,我几乎与我的串行双向通信实现,我只是陷入了一些事情: -

  1. 我的读取被分割为多个消息,或者作为通过COM端口的碎片响应接收,我不知道我可能需要什么设置,或者我应该如何编写代码来解决这个问题。什么可能导致这个?我正在SerialPort_DataReceived.
  2. 的断点检查消息

    基本上,数据应按以下方式发送:

    01: LS|DA090521|TI111043|q
    02: PS|RN102|PTC|TA1040000|P#0|DA090521|TI111429|j
    

    但它正在分裂(在每个请求的阅读中随机位置)

    01: LS|DA090521|TI111
    02: 043|q
    03: PS|RN102|PTC|TA1
    04: 0000|P#0|DA090521|TI111429|j
    

    - 问题1已经回答了,感谢Chris W.和其他人!我现在有消息,我期望逐步从片段构建(寻找STX,{msg body},ETX),然后在消息完全构建时执行一个动作,并使用线程安全的队列,非常高兴

    。我收到了“|”通过我几乎每个循环读取的符号,这是由于我以某种方式错误地设置的命令,串行通信的工件,或设备发送给我的东西? (我不这么认为,因为超级终端连接显示这个角色没有连续发送。)

    。 3.您能否确认我正在各自的方法中正确地阅读和写入数据。

    谢谢你们看看我的另外两个问题。

    相关代码如下:

    ...
        //                          COM3,    9600,     None,   8,        One
        SerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBits);
        if (SerialPort.IsOpen) SerialPort.Close();
        // SerialPort.RtsEnable = true; // Request-to-send
        // SerialPort.DtrEnable = true; // Data-terminal-ready
        SerialPort.ReadTimeout = 150; // tried this, but didn't help
        SerialPort.WriteTimeout = 150; // tried this, but didn't help
        SerialPort.Open();
    
        SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
    }
    
    void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // Process received data
        SerialPort sp = (SerialPort)sender;
        byte[] buffer = new byte[sp.BytesToRead];
        int bytesRead = sp.Read(buffer, 0, buffer.Length);
    
        // message has successfully been received
        message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
    }
    
    public bool SendMessage(string text)
    {
        // Only send message if a client is connected
        if (SerialPort != null && SerialPort.IsOpen)
        {
            byte[] buffer = Encoding.ASCII.GetBytes(text);
            SerialPort.Write(buffer, 0, buffer.Length);
        }
    }
    

3 个答案:

答案 0 :(得分:4)

  

我的阅读被分成多条消息

这是正常的,预期的,不可避免的行为。它也可以通过TCP上的数据发生。对于串行接口,它只是一个无穷无尽的字节流。您的应用程序有责任将这些字节重新打包为数据包。

如果数据包边界的位置很重要,并且如果您无法通过查看接收的数据来判断数据包边界应该在哪里,那么您可能需要重新考虑数据的格式以便可以告诉数据包边界在哪里。

  

我收到了“|”通过我几乎每个周期阅读的符号

该角色的十六进制值是多少?看看将Handshake属性设置为XOnXOffRequestToSendXOnXOff是否会改善这种情况。

答案 1 :(得分:3)

在较低级别,串行端口可以决定何时触发数据接收事件。它可能决定在“完整”数据包到达之前这样做。但是,看起来您的预期数据集中有一个终结符。如果是这样,您可以执行以下操作(请注意,我已更改您的SerialPort分配以避免语法混淆:

        p = new SerialPort(PortName, BaudRate, Prty, DataBits, SBits);
        p.NewLine = Terminator;

其中Terminator是一个包含终止字符的字符串。然后你可以使用SerialPort.ReadLine()(和SerialPort.WriteLine(),如果适用)。这至少可以帮助您解决第一个问题。

答案 2 :(得分:3)

我已经完成了很多Win32串口编程,但是只需要一点点.NET,所以请大家多听一下。

  

我的读取被分割为多个消息,或者作为通过COM端口的碎片响应接收,我不知道我可能需要什么设置,或者我应该如何以不同方式编写代码以解决此问题。

正如其他人所说,这是完全正常的。根据DCE方面的设备类型,您可能需要自己重新包装。我不确定你连接的是什么类型的设备,所以我真的不能说更多。

如果您想获得更多数据,可以尝试以下方法:

  • 调整System.Int32 ReceivedBytesThreshold属性
  • 使用同步I / O并指定要读取的固定字节数而不是基于事件的接收
  

我收到了“|”通过我的阅读几乎每个周期的符号,是   这是由于我设定的命令   不知怎的,错误的串行神器   沟通,或设备的东西   送我? (我不这么认为   但是,作为超级终端连接   揭示这个角色不存在   连续发送。)

如果您对线路上的内容感到好奇,请查看PortMon from SysInternals,这是一个免费的应用程序,可以在您通过线路传输数据时窥探您的COM端口。这似乎是技术性的,但实际上您只需要查看IRP_MJ_WRITE和IRP_MJ_READ命令,在线上您将看到以字节为单位的长度以及通过线路发送的数据。有了这个,您应该能够判断问题是.NET SerialPort对象还是设备实际发送“|”在线。

  

你能证实我在读书吗?   正确地写入数据   各自的方法。

基于事件的接收数据的方法看起来很合适。