Serial Port BytesToRead and readbuffer

本文关键字:readbuffer and BytesToRead Port Serial | 更新日期: 2023-09-27 17:53:30

我正试图以非常快的速度连续从串行端口获取数据。波特率为"230400"。当我将数据,时间戳和BytesToRead打印到文件中时,我注意到每当BytesToRead下降到个位数并且readLine()没有在200ms中读取任何内容时,都会发生200ms的延迟。延迟之后,BytesToRead回到3000左右,这个过程一次又一次地发生。从本质上讲,我没有连续地获取数据。

我想也许我的阅读速度比缓冲区中积累的速度数据快,所以我尝试改变readBuffer大小,并将此线程休眠1ms,以便让缓冲区保持我正在阅读的速度。没有一个成功。还有一些延误。

欢迎有任何想法。

 private void dostuff()//The thread I created after the port is opened
    {
        var startTime = DateTime.Now;
        var stopwatch = Stopwatch.StartNew();
        while (serialPortEncoder.IsOpen)
        {
            if (serialPortEncoder.BytesToRead > 210)
            {
                try
                {
                    var line = serialPortEncoder.ReadLine();
                    var timestamp = (startTime + stopwatch.Elapsed);
                    var lineString = string.Format("{0}  ----{1}",
                                    line,
                                    timestamp.ToString("HH:mm:ss:fff") + " "+serialPortEncoder.BytesToRead+"'r'n");
                    richTextBoxEncoderData.BeginInvoke(new MethodInvoker(delegate()
                    {
                        richTextBoxEncoderData.Text = line;//update UI                           
                    }));                                     
                }
                catch (Exception ex) { MessageBox.Show(ex.ToString()); }

            }}

Serial Port BytesToRead and readbuffer

除非每210字节换行一次,否则您的ReadLine()函数可能超时并且不返回任何内容。ReadLine()将读取输入缓冲区,直到遇到换行值,然后返回它之前的数据。http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readline.aspx

什么样的信息正在通过端口?如果您想读取特定大小的缓冲区,只需使用Read方法。如果你需要一直读到换行,使用ReadLine()并经常检查它是否返回一个字符串。

你的代码从根本上是有缺陷的,它遭受了"热等待循环"的错误。当串行端口没有足够的数据时,您的循环正在燃烧100%核心。这将使Windows在你烧毁量子后把你的线程关在狗屋里一段时间,给其他线程一个运行的机会。在狗窝里呆200毫秒是有点长,但肯定不是不寻常的。

你应该做不同的,你应该给Windows一个机会,当有实际的数据可用从串行端口唤醒你。当它寻找下一个要调度的线程时,它倾向于已经完成I/O的线程。这很容易做到,只需删除BytesToRead测试。ReadLine()调用是一个阻塞调用,在接收到换行符之前不会返回。你的线程现在将消耗接近0%的cpu周期。

当机器负载过重或垃圾收集器运行时,您仍然会损失任意数量的时间。不,这还不足以可靠地读取编码器并关闭反馈回路。要做到这一点,需要一个具有可预测实时行为的微控制器。可从工业电子产品供应商处获得。

在网上进行了无休止的研究之后,我找到了延迟的原因。设备管理器->端口---->advance---->将延迟更改为1ms将解决问题。现在,每次当缓冲区下降到零时,它只需要最多2ms就能恢复正常。我现在使用一个单独的线程轮询数据。它工作得很好。

但就像汉斯·帕桑特说的,我正在努力找出一个更好的设计方法。