改进串行端口连接

发布于 2024-09-15 15:06:17 字数 1315 浏览 8 评论 0原文

这次的问题很简单。我有一个应用程序与另一台计算机上的应用程序的另一个副本进行通信。一个应用程序发送相当稳定的数据流,另一个应用程序接收它。

发送数据的代码如下所示(其中 serialPort 是 C# .Net 2.0 中 System.IO.Ports.SerialPorts 类的实例):

private void bgDataWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e){
    try{
        string tempStr = Convert.ToString(String.Format("{0:0.000000}", data));
        serialPort.Write(tempStr); // Write "data" out to 6 decimal places  
    }
    catch (TimeoutException){ }
    catch (InvalidOperationException err){ // Port is obstructed or closed
        this.Invoke((MethodInvoker)delegate{
            MessageBox.Show(this, "Couldn't send wireless data:\n\n" + 
                            err.ToString(), "NanoMETER - Wireless Error (Data)", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
            Global.remoteEna = false;
            serialPort.Close();
            usingBT = false;  
        }); 
    }
}

它在计时器上调用。接收代码甚至更加简单:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    string buffer = serialPort.ReadExisting();
    HandleInput(buffer);
}

数据被发送和处理,一切都很好,但是有一些不必要的不​​稳定,它要么不能以恒定的速率可靠地发送数据,要么不能接收所有内容。我不确定这是否可以在我的代码中修复,或者这是否只是拥有一些缓慢的机器和可能不稳定的蓝牙连接的本质。有什么建议吗?

Pretty simple question this time around. I have an application that communicates with another copy of the application on another machines. One application sends a pretty constant stream of data, the other receives it.

The code to send data looks like this (where serialPort is an instance of the System.IO.Ports.SerialPorts class in C# .Net 2.0):

private void bgDataWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e){
    try{
        string tempStr = Convert.ToString(String.Format("{0:0.000000}", data));
        serialPort.Write(tempStr); // Write "data" out to 6 decimal places  
    }
    catch (TimeoutException){ }
    catch (InvalidOperationException err){ // Port is obstructed or closed
        this.Invoke((MethodInvoker)delegate{
            MessageBox.Show(this, "Couldn't send wireless data:\n\n" + 
                            err.ToString(), "NanoMETER - Wireless Error (Data)", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
            Global.remoteEna = false;
            serialPort.Close();
            usingBT = false;  
        }); 
    }
}

It's called on a timer. The receive code is even more straightforward:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    string buffer = serialPort.ReadExisting();
    HandleInput(buffer);
}

Data gets sent and handled and it's all fine and dandy, but there's some unwanted choppiness where it's either not reliably sending data at a constant rate, or it's not picking up everything. I'm not sure if this can be fixed in my code, or if it's just the nature of having a few slow machines and a possibly shakey bluetooth connection. Any suggestions?

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

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

发布评论

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

评论(1

顾北清歌寒 2024-09-22 15:06:17

实习生被分配将旧代码转换到新平台的情况并不罕见。

您可以进行一些改进。

1) 当通过端口发送的字节要以块(例如命令)进行解释时,以下策略是很好的。你们有某种协议吗?决定您发送的消息的格式的东西。例如,用于指示即将到来的命令的开始和长度的特定分隔符。这使您可以快速确定命令是否只发送了一半,或者是否丢失了字节。更好的是在末尾添加 CRC。

2)不要读取计时器,而是基于串行端口对象标记的事件。这是我使用的示例:

    //OnReceive event will only fire when at least 9 bytes are in the buffer.
    serialPort.ReceivedBytesThreshold = 9; 
    //register the event handlers
    serialPort.DataReceived += new SerialDataReceivedEventHandler(OnReceive);
    serialPort.PinChanged += new SerialPinChangedEventHandler(OnPinChanged);

在上面的代码中,我设置了阈值 9,您应该将其更改为适合您的上下文的值。此外,Pinchanged 事件值得监控,它可以让您快速识别电缆是否已断开。关于 CTSChanged 还有更多内容,但如果您感兴趣,可以查找。

最后,如果这不能帮助您进一步了解,请显示所发生问题的示例,以便这里的人员可以为您提供更多帮助。

It's not uncommon for interns to be assigned to converting old code to a newer platform.

There are a few improvements you can make.

1) The following strategy is good when the bytes sent through the port is meant to be interpreted in blocks, such as commands. Do you have some sort of protocol? Something that dictates the format of the message you are sending. For instance, a specific delimiter to indicate the beginning and the length of the upcoming command. This allows you to quickly determine if the command was only half sent, or if there were missing bytes. Even better is to add a CRC at the end.

2) Instead of reading on a timer, base yourself on the events flagged by your serialport object. Here's an example of what i use:

    //OnReceive event will only fire when at least 9 bytes are in the buffer.
    serialPort.ReceivedBytesThreshold = 9; 
    //register the event handlers
    serialPort.DataReceived += new SerialDataReceivedEventHandler(OnReceive);
    serialPort.PinChanged += new SerialPinChangedEventHandler(OnPinChanged);

In the code above, i set a threshhold of 9, you should change that to whatever fits your context. Also, the Pinchanged event is something good to monitor, it will allow you to quickly identify if the cable has been disconnected. There is more on this, regarding CTSChanged but you can look it up if you are interested.

Lastly, if this doesn't help you get a little further, show an example of the problem that occured so the peolpe here can give you more help.

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