C# 获取图表上达到目标(上图)和退出目标(下图)之间的时间

C# 获取图表上达到目标(上图)和退出目标(下图)之间的时间,c#,winforms,plc,C#,Winforms,Plc,下表使用winforms计时器每秒更新其值。红线表示恒定的目标测试压力,蓝线表示从PLC对象读取的实际压力 要求显示蓝线达到恒定所需测试压力(红线)和低于 所需的恒定试验压力 设置恒定所需测试压力的块: ... chart1.ChartAreas[0].CursorY.Position = d; chart1.ChartAreas[0].CursorY.LineWidth = 1; chart1.ChartAreas[0].CursorY.Lin

下表使用winforms计时器每秒更新其值。红线表示恒定的目标测试压力,蓝线表示从PLC对象读取的实际压力

要求显示蓝线达到恒定所需测试压力(红线)和低于
所需的恒定试验压力

设置恒定所需测试压力的块:

...
        chart1.ChartAreas[0].CursorY.Position = d;
        chart1.ChartAreas[0].CursorY.LineWidth = 1;
        chart1.ChartAreas[0].CursorY.LineColor = System.Drawing.Color.Red;
我被卡住的部分(此块位于每秒更新图表的方法中):

double-plcTestpressure=((uint)plc.Read(“MD220”)).ConvertToDouble();
double reqTestPressure=Convert.ToDouble(txtTestingPressure.Text);
如果(plcTestpressure>reqTestPressure&&!Q)
{
DateTime OVERREQ=新的DateTime();
UpperReq=DateTime.Now;
Isabaq=真;
//这用于检查plc读数压力
字符串currentpressure=((uint)plc.Read(“MD220”).ConvertToDouble().ToString();
}
//检查当前压力是否低于要求,以及一秒钟前压力是否高于要求。。。
if(plcTestpressure
我已经尝试并逐步通过了这个模块,但它在tickCounter中给了我一个误导性的答案(33秒,当您可以在图表上看到5秒已经过去),并且在第一次分配tickCounter之后,上面的Req日期时间戳不想更改


有没有更好的方法来实现这个目标?我做错了吗?我应该提供更多细节吗?

我必须假设您有多个名为“overreq”的变量,因为在“if”块中声明的变量是该块的局部变量。这意味着,当您访问第二个“if”块中的“overreq”变量时,您访问的不是同一个变量

还执行
字符串currentpressure=((uint)plc.Read(“MD220”)).ConvertToDouble().ToString()确实需要在if块内(仅在高于目标时跟踪当前压力)

-----------------------------编辑---------------------------------------

我做错了吗

如果将压力监控逻辑移到一个单独的类中,从而保持单一责任原则,则会认为它更干净

您可以通过实现一个压力监控类来实现这一点,该类将在超过阈值时引发事件-大致如下-

        public class PressureObserver
        {
            public event EventHandler<double> OnRaisedAboveThreshhold;
            public event EventHandler<double> OnFellBelowThreshhold;

            public double ThresholdPressure{ get; }

            private double _lastMeasured = 0; //Initial Pressure

            public PressureObserver(double thresholdPressure)
            {
                ThresholdPressure = thresholdPressure;
            }

            public void Observe(double plcTestpressure)
            {
                double pressureDelta = plcTestpressure - _lastMeasured;

                if (pressureDelta > 0) //Pressure climbed
                {
                    if(_lastMeasured < ThresholdPressure &&  //Last measurement was below threshold
                        plcTestpressure > ThresholdPressure) //This one is above, cross made
                    {
                        OnRaisedAboveThreshhold?.Invoke(this, plcTestpressure);
                    }
                }
                else if(pressureDelta < 0) //Pressure declined
                {
                    if (_lastMeasured > ThresholdPressure &&  //Last measurement was above threshold
                        plcTestpressure < ThresholdPressure) //This one is below, cross made
                    {
                        OnFellBelowThreshhold?.Invoke(this, plcTestpressure);
                    }
                }

                _lastMeasured = plcTestpressure;
            }
        }
您将定义两种方法来响应阈值更改

        private void Obs_OnRaisedAboveTreshhold(object sender, double e)
        {
            //Code to do on raised above
            _raisedAboveTime = DateTime.Now;
        }

        private void Obs_OnFellBelowTreshhold(object sender, double e)
        {
            //Code to do on fell below
            _fellBelowTime = DateTime.Now;
            _overpressureDuration = _fellBelowTime.Subtract(_raisedAboveTime).TotalSeconds;
        }
在构造函数中,您将订阅observer类

       _pressureObserver = new PressureObserver(60); //replace 60 with threshold

       _pressureObserver.OnRaisedAboveThreshhold += Obs_OnRaisedAboveTreshhold;
       _pressureObserver.OnFellBelowThreshhold += Obs_OnFellBelowTreshhold;
在你的滴答计时器中,你只需添加

_pressureObserver.Observe(plcTestpressure);
“if”块中声明的变量是该块的局部变量”,太好了,真不敢相信我错过了。这消除了我在这方面的困惑。
        private void Obs_OnRaisedAboveTreshhold(object sender, double e)
        {
            //Code to do on raised above
            _raisedAboveTime = DateTime.Now;
        }

        private void Obs_OnFellBelowTreshhold(object sender, double e)
        {
            //Code to do on fell below
            _fellBelowTime = DateTime.Now;
            _overpressureDuration = _fellBelowTime.Subtract(_raisedAboveTime).TotalSeconds;
        }
       _pressureObserver = new PressureObserver(60); //replace 60 with threshold

       _pressureObserver.OnRaisedAboveThreshhold += Obs_OnRaisedAboveTreshhold;
       _pressureObserver.OnFellBelowThreshhold += Obs_OnFellBelowTreshhold;
_pressureObserver.Observe(plcTestpressure);