C#While循环具有不同的运行时

时间:2015-02-08 16:08:51

标签: c# while-loop dllimport

我在C#项目中使用C ++ dll来控制科学项目的线性轴。我必须在短时间内绘制轴的位置和电机电流。轴通过LAN连接到我的PC。 这是向轴发送命令的函数的DllImport。

        [DllImport("Axis3.dll", EntryPoint = "sendCommand", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        protected static extern int m_pSendCommand(StringBuilder pcStr, StringBuilder pcRet, bool bReadLine, int iTimeOut, int iConnectionNumber);

在移动轴的过程中,我使用while循环读取位置和motorcurrent,并将它们写入图表列表。

private void CollectCurrentAndPositionContinous()
        {
            bool boolAxisIsMoving;
            if (AxisIsMoving(out boolAxisIsMoving, numberofController) == 0)
            {
                while (boolAxisIsMoving == true)
                {
                    if (AxisIsMoving(out boolAxisIsMoving, numberofController) != 0)
                    {
                        break;
                    }
                    CollectCurrentAndPosition();
                }
            }
        }

        private void CollectCurrentAndPosition()
        {
            string returnText;
            int errorNumber = GetPositionandCurrent(out returnText);
            if (errorNumber == 0)
            {
                if (zedDiagram.GraphPane.CurveList.Count <= 0) //make sure that the curvelist has at least one curve
                    return;

                LineItem curveCurrent = zedDiagram.GraphPane.CurveList[0] as LineItem; //Get the first CurveItem in the graph
                if (curveCurrent == null)
                { return; }


                IPointListEdit list = curveCurrent.Points as IPointListEdit; // Get the PointPairList

                if (list == null)// If this is null, it means the reference at curve.Points does not support IPointListEdit, so we won't be able to modify it
                { return; }

                string[] returnTextSplit = returnText.Split(new Char[] { ' ' }); //splits the returntext at space char
                double position = ConvertStringToDouble(returnTextSplit[0]);
                double currentA = ConvertStringToDouble(returnTextSplit[1]);
                double currentB = ConvertStringToDouble(returnTextSplit[2]);
                list.Add(position, currentA);
            }
            else
            {DisplayText(ErrorText(errorNumber));}
        }

        private int GetPositionandCurrent(out string o_returnText)
        {
            double position = 0.0;
            Venus3Wrapper.GetPosition(1, ref position, numberofController);
            int errorNumber = SendCommand("1 gc" + System.Environment.NewLine, out o_returnText, true, 50, numberofController);
            o_returnText = position.ToString(en.NumberFormat) + " " + o_returnText;
            return errorNumber;
        }

我的问题是,保存的数据之间存在很大的时间差异。在5ms内保存两个点,然后在接下来的两个点之间有100ms的间隙。我甚至在它自己的线程中启动这个函数,并且每秒只重绘我的图表,但差距仍然存在。有人可以给我一个提示,告诉我如何获得更经常的解决方案吗?

2 个答案:

答案 0 :(得分:1)

我的建议是重新考虑设备和PC之间的协议。虽然我无法在OP中的代码中找到时间方面,但在我看来,如下所述的协议可以解决问题。

PC-&gt;设备:开始跟踪电机/轴(无论如何)数据 设备 - > PC:累积测量的数据包,每个都看起来像...... {TimeStamp,Values []}。

这里有2个用例。 1.保存数据以供以后分析。 2.绘制数据。如果您有高频数据,如果您为每个数据包发送一个值(无效),或者您收集了一堆数据点并以合理大小的数据包发送它们,则没有人会注意到差异。

你的图形的x轴不会有通信和垃圾收集以及一般的PC非实时抖动,你可以稍后用分析步骤中的数据做更多工作,因为从设备发送的时间戳是比PC端产生的时间戳更可靠。

如果您使用TCP / IP进行通信并且在设备端编写单个值,那么您的数据中的“间隙”也可能来自nagle算法。如果我没记错的话,nagle会超时100ms ...在发送之前收集下一个数据包的数据一段时间。这也可以解释你所看到的内容。

答案 1 :(得分:0)

m_pSendCommand()似乎返回错误代码,您获取此错误代码并经历从GetPositionandCurrent()实际返回它的麻烦,然后您继续完全忽略它,只执行正文如果错误代码为0,则为您的主if语句,否则忽略它。

这是灾难的秘诀。如果您的代码与设备之间的通信失败,m_pSendCommand()可能会试图告诉您,但您没有注意它。这可以解释差距。