获取事件之间的时间跨度 [英] Get timespan between events

查看:101
本文介绍了获取事件之间的时间跨度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到来自串口的消息,每隔几秒就会传递给一个变量一次。该消息由微处理器生成,它基本上是一个包含1 / r的简单字符串,表示电机的一整圈(每次按下微动开关,微型打印1 / r)在串行端口上。为了在文本框中显示这种电机的每分钟转数,根据变量更新之间的时间间隔,我想实现一个时间跨度方法。因此,我应该获得从开始到结束之间经过的时间。转弯并将结果返回到原始方法的进一步操作。

这是我到目前为止所做的但不起作用:



I receive a message from serial port that is passed to a variable once every few seconds. The message is generated by a microprocessor and it is basically a simple string containing "1/r" which represent one complete turn of a motor (every time a microswitch is pressed, the micro prints "1/r) on the serial port). In order to show in a text box the revolution per minute of such motor, based on the time interval between the update of the variable, I would like to implement a timespan method. I should therefore obtain the time elapsed between the start and the end of a turn and return the result for further actions to the original method.
This is what I have done so far but does not work:

public void CalcolaRPM (string giriRicevuti, out double RPM)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            {
                if (giriRicevuti == "1/r")
                {
                    stopWatch.Stop();
                }
            }
            double elapsedT = stopWatch.ElapsedMilliseconds;
            stopWatch.Restart();
            RPM = elapsedT;
            giriRicevuti = "";
        }
    
    }





我得到的结果是0.0,我怎么能得到时间更新变量giriRicevuti之间的毫秒数?



The result I get is 0.0, how can I get the time in milliseconds between updates of the variable "giriRicevuti"?

推荐答案

要做的第一件事就是要意识到代码永远不会起作用。

giriRicevuti是你的方法的字符串参数,所以一旦调用方法,外面的世界就不能以任何方式改变值(字符串是不可变的,所以即使改变外部世界字符串也只会产生一个新的引用,方法中的字符串将不受影响。



因此,您的测试只会计算该行的性能:

The first thing to do is to realize that that code is never going to work.
giriRicevuti is a string parameter to your method, so the world outside cannot in any way change the value once the method is called (strings are immutable, so even a change to the outside world string will just produce a new reference and the string in the method will be unaffected).

So your test will only ever time the performance of the line:
if (giriRicevuti == "1/r")

这与从uProcessor接收数据的速度毫无关系。



有很多亲这里有你需要看的瑕疵。一些最主要的是:

1)数据接收不一定与uProcessor传输的数据同步:Windows不是实时系统,您的任务可能无法在任何给定时间执行:如果它错过一个插槽,它可能会运行几秒钟甚至几分钟。

2)系统收到的所有数据都是缓存的,无论是硬件还是软件,这样数据就不会丢失 - 这对于普通应用程序来说非常好,但是会让你的计时错误,因为你永远不会知道什么时候收到字节 - 各种缓冲区和Windows消息可能需要很长时间才能被你的应用程序处理。





我这样做是这样的:

有一个定时器事件,它以预期的转速倍数触发。因此,如果你在100Hz附近旋转或旋转,那么我会将时间设置为10HX,或者可能更少 - 5Hz甚至1Hz,具体取决于你想要的准确度。

创建两个类级变量:和整数计数,以及一个DateTime

处理串口DataRecieved事件,每次收到''1'后跟''\ r''(并记住这些可能来是单独的事件,所以你不能只检查这次出现的数据)将计数增加一。

在计时器事件中,读取计数,并将其归零。获取当前时间,计算自上一次以来的时间跨度,然后保存下次的当前值 - 不要使用DateTime.Now不止一次,否则会引入一个小的(但很重要的)错误。

您现在可以使用时间跨度和计数来计算定时器事件之间的平均转速。

Which has nothing at all to do with the speed at which data is received from your uProcessor.

There are a large number of problems here which you need to look at. Some of the most major are:
1) Data receive is not necessarily synchronous with the data transmitted by the uProcessor: Windows is not a real time system, and your task may not execute at any given time: if it "misses" a slot, it could conceivably not run for several seconds or even minutes.
2) All data received by the system is buffered, both in hardware and software so that data is not lost - this is great for normal applications, but will bugger your timing right up as you will never know when a bytes was received - the various buffers and windows messages may take significant time to be processed by your application.


The way I would do it is this:
Have a timer event which fires at an expected multiple of the rotation speed. So if you moter or rotating at around 100Hz, then I would set the time to 10HX, or possible less - 5Hz or even 1Hz, depending on how accurate you want to be.
Create two class level variables: and integer count, and a DateTime
Handle the serial port DataRecieved Event, and each time you receive a ''1'' followed by a ''\r'' (and remember that these may come is separate events, so you can''t just check the data present this time) increment the count by one.
In the timer event, read the count, and zero it. Get the current time, calculate the timespan since the previous one, then save the current value for next time - DO NOT USE DateTime.Now more than once, or you will introduce a small (but significant) error.
You can now use the timespan and the count to work out the average rotation speed between timer events.


感谢您的建议,特别是对OriginallGriff,我最终得到了这个解决方案。满足我的应用程序的要求。我还使用return语句和一些浮点变量简化了方法,以便在结果中获得更高的准确性。



Thanks to your advices and especially to OriginallGriff, I ended up with this solution that is satisfying the requirement of my app. I also simplified the method using a return statement and some float variables to get more accuracy in the result.

class Turns
    {
        static DateTime prevTimeInstance = DateTime.Now;
        static float RPM = 0;

        public float Counts(int getTurn)
        {
            TimeSpan currentTimeSpan = TimeSpan.Zero;
            if (getTurn.Equals(1))
            {
                currentTimeSpan = DateTime.Now.Subtract(prevTimeInstance);
                prevTimeInstance = DateTime.Now;
                if (currentTimeSpan.TotalSeconds != 0)
                    RPM = 60.0f / (float)currentTimeSpan.TotalSeconds;
            }
            return RPM;
        }
    }


这篇关于获取事件之间的时间跨度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆