如何在Qt中进行“deadman switch”?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Qt中进行“deadman switch”?相关的知识,希望对你有一定的参考价值。

我想监视一个周期性的动作,以便我可以在它停止时做一些事情。例如,切换到本地计时器以保持该操作,并在它再次启动时切换回主源。

我能想出的最好的理论范例是:

#define FRAME_INTERVAL_MSEC     33  // ~30Hz
bool periodFromUSB;
QTimer* myTimer;

void Processing::localTimeout()
{
    //connected to myTimer->timeout();
    if (periodFromUSB)
    {
        periodFromUSB = false;
        myTimer->stop();
        myTimer->setSingleShot(false);
        myTimer->setInterval(FRAME_INTERVAL_MSEC);
        myTimer->start();
    }

    processDMX();
}

void Processing::newFrame()
{
    //called periodically from my USB driver
    myTimer->stop();
    if(!periodFromUSB)
    {
        periodFromUSB = true;
        myTimer->setSingleShot(true);
        myTimer->setInterval(FRAME_INTERVAL_MSEC * 2);
    }
    myTimer->start();

    processDMX();
}

但无论我如何安排它,我都会在USB驱动程序运行时继续调用这两个函数。 (立即点击上面代码中的任何地方的断点)

有没有更好的方法来做死人?

答案

如果调用start(),则计时器将重置为0并重新启动当前间隔。也就是说,只要在达到超时之前调用newFrame()槽,就永远不会调用localTimeout()。

您的代码将如下所示:

#define FRAME_INTERVAL_MSEC     33  // ~30Hz
bool periodFromUSB;
QTimer* myTimer;

void Processing::localTimeout()
{
    //connected to myTimer->timeout();
    if (periodFromUSB)
    {
        periodFromUSB = false;
    }

    processDMX();
}

void Processing::newFrame()
{
    //called periodically from my USB driver
    if(!periodFromUSB)
    {
        periodFromUSB = true;
    }
    myTimer->start(); // restarts current timer interval

    processDMX();

    // for debugging: display actual interval length in milliseconds:
    static qint64 start = QDateTime::currentMSecsSinceEpoch();
    static qint64 count = 0;
    ++count;
    qint64 curr = QDateTime::currentMSecsSinceEpoch();
    float msecsPerInterval = float(curr - start) / float(count);
    qDebug() << "msecs per interval: " << msecsPerInterval;
}

void Processing::init()
{
    myTimer = new QTimer();
    connect(myTimer, &QTimer::timeout, this, &Processing::newFrame);
    myTimer->setInterval(FRAME_INTERVAL_MSEC);
    myTimer->start();
}

如果仍调用localTimeout()槽,则FRAME_INTERVAL_MSEC太低。

您可以使用我添加到newFrame()的调试代码来检查这一点。

这可能是因为:

  • 你的USB驱动程序很少或很少接收数据
  • processDMX()中的处理时间太长(如果processDMX()的持续时间比FRAME_INTERVAL_MSEC长,则下一个时隙不会及时调用)

以上是关于如何在Qt中进行“deadman switch”?的主要内容,如果未能解决你的问题,请参考以下文章

如何在qt vs中利用qt进行界面设计

如何使用Qt插件在Qt中进行ROS开发

在 Qt 中如何对 QModelIndex 的直接子索引进行排序

如何在 Xcode 中进行 Qt 开发(可使用使用 Homebrew 来安装qt)

如何在我的 Qt 应用程序中对小部件进行分组?

如何在 Qt 中进行 UDP 打孔?