使用c#从串口部分接收消息

发布于 2024-08-28 05:00:36 字数 396 浏览 5 评论 0原文

我正在使用下面的代码使用 c# 接收来自串行端口的消息。

    void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (comPort.IsOpen == true)
        {
            string msg = comPort.ReadExisting();
            MessageBox.Show(msg.Trim());
        }
    }

问题是,我正在部分地获取消息。就像,如果你发送“你好,你好吗” 我逐字逐句地收到它。我希望一次性完成。我该怎么办?

另外,是否可以检索应用程序发送和接收消息的端口名称?

I am using the below code to receive the messages from serial port using c#

    void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (comPort.IsOpen == true)
        {
            string msg = comPort.ReadExisting();
            MessageBox.Show(msg.Trim());
        }
    }

The problem is, i am getting the messages part by part. Like, if u send "Hello, How are you"
I am receiving it word by word. I want that in a single stretch. How can i do ??

Also, is it possible to retrieve the port name from which the application is sending and receiving messages ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时间你老了 2024-09-04 05:00:36

到目前为止,通过串行端口一次性传输固定量数据的最简单方法是在数据前面添加长度标头。使用固定数量的字节作为长度(2-4 就足够了),然后使用 Read 方法同步读取 length 字节的数据。当然,您也可以异步执行此操作,只需将长度保存在某个成员字段中,并在达到长度后立即执行后处理。

次佳方法是附加停止字符或单词。如果它恰好是换行符,那么您可以使用同步 SerialPort.ReadLine 方法。否则,将接收到的数据收集在 StringBuilder 中,继续附加到 StringBuilder 直到遇到停止字符,然后返回该 StringBuilder 的内容直到(但不包括)停止字符。

如果您无法控制源数据,需要读取固定数量的数据,并且事先不知道该大小是多少,那么您的工作将会变得更加困难。我认为真正处理这种情况的唯一方法是等待预定的超时,此时如果您没有收到任何新数据,则假设传输已结束。它不是特别可靠,这就是为什么大多数通信协议都使用上述设计之一的原因。

如果您考虑串行端口(或任何端口)的工作方式,只需通过电线推送位,那么很明显,如果无法预测未来,就无法知道传输是否已完成。如果您连接到远程主机(即通过调制解调器),并且该主机在传输完成后断开连接,那么您可能可以使用载波检测,但听起来并非如此。

希望这不是您当前所处的情况,并且您有一定的能力来控制源数据,或者您要连接的设备已经使用长度标头和/或停止模式。如果是的话,一定要使用它。否则,您可能会因使用超时而陷入困境。

By far the easiest way to transmit a fixed amount of data over a serial port in one shot is to prepend the data with a length header. Use a fixed number of bytes for the length (2-4 should suffice) and then read length bytes of data synchronously using the Read method. You can do this asynchronously too, of course, you just need to save the length in a member field somewhere and perform your post-processing as soon as the length is hit.

The next-best way is to append a stop character or word. If it happens to be a newline, then you can use the synchronous SerialPort.ReadLine method. Otherwise, collect the received data in a StringBuilder, keep appending to the StringBuilder until you hit the stop character, then return the contents of that StringBuilder up to (but excluding) the stop character.

If you do not have control over the source data, need to read a fixed amount of data, and don't know what that size is in advance, then your job is going to be considerably more difficult. I think the only way of really dealing with this situation is to wait for a predetermined timeout, at which point you assume that the transmission is over if you haven't received any new data. It's not particularly reliable, which is why most communication protocols use one of the aforementioned designs.

If you think about the way a serial port (or any port) works, by simply pushing bits over a wire, then it should be clear that there's no way to know whether or not a transmission has completed without being able to predict the future. If you're connected to a remote host, i.e. over a modem, and that host disconnects you when the transmission is finished, then you might be able to use the Carrier Detect, but that doesn't sound like the case here.

Hopefully this is not the scenario you're currently in, and either you have some ability to control the source data or the device you're connecting to already uses a length header and/or stop pattern. If it does, definitely use that. Otherwise, you'll probably be stuck using timeouts.

累赘 2024-09-04 05:00:36
   private void MonitorSP_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                System.IO.Ports.SerialPort SP = (System.IO.Ports.SerialPort)sender;

                //Get the ports available in system
                string[] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames();
                string strAvlPortNames = "";
                foreach (string s in theSerialPortNames)
                {
                    strAvlPortNames += s.ToString() + ", ";
                }

                //Read an contruct the message
                Thread.Sleep(1000);
                string msg = SP.ReadExisting();
                string ConstructedMsg = "Port's Found : " + strAvlPortNames + "\n" + "Port Used : " + SP.PortName + "\n" + "Message Received : " + msg;

                if (InvokeRequired)
                {
                    richTextBox1.Invoke(new MethodInvoker(delegate { richTextBox1.Text = ConstructedMsg; }));
                    //Send acknowlegement to sender port
                    SP.Write(SP.PortName);
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace.ToString());
            }
        }  
   private void MonitorSP_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                System.IO.Ports.SerialPort SP = (System.IO.Ports.SerialPort)sender;

                //Get the ports available in system
                string[] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames();
                string strAvlPortNames = "";
                foreach (string s in theSerialPortNames)
                {
                    strAvlPortNames += s.ToString() + ", ";
                }

                //Read an contruct the message
                Thread.Sleep(1000);
                string msg = SP.ReadExisting();
                string ConstructedMsg = "Port's Found : " + strAvlPortNames + "\n" + "Port Used : " + SP.PortName + "\n" + "Message Received : " + msg;

                if (InvokeRequired)
                {
                    richTextBox1.Invoke(new MethodInvoker(delegate { richTextBox1.Text = ConstructedMsg; }));
                    //Send acknowlegement to sender port
                    SP.Write(SP.PortName);
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace.ToString());
            }
        }  
千寻… 2024-09-04 05:00:36

尝试阅读,直到您按下 CRLF

Try reading until you hit a CRLF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文