计时器无法与 wiringPiISR(QtQuick 应用程序)一起使用

timer couldn't work with wiringPiISR (QtQuick application)

我创建了一个 class Capteur_Input 并且构造函数中的一个选项使用 wiringPiISR

创建了一个中断

wiringPiISR(m_pin, INT_EDGE_RISING, isrInput);

我的 class 也有一个属性 m_impulsion,每次发生中断时我都会增加这个值。

这是我的中断处理程序的样子

void Capteur_Input::isrCallback()
{
    if(m_pin== Pin_vitesse)
{
    increment_impulsion();
        emit digital_inputChanged(m_impulsion);
}
    else
        emit digital_inputChanged(m_value);
}

在我的 main.cpp 中我创建了这个 class

的一个实例
static void isrInput_vitesse();

static Capteur_Input vitesse(Pin_vitesse,PUD_OFF,INT_EDGE_RISING,isrInput_vitesse);

static void isrInput_vitesse()
{
    vitesse.isrCallback();
}

一切正常,qml 和 C++ 部分。

现在我想计算每秒检测到的脉冲数。但我做不到。

我的classCapteur_Input也有定时器,我在构造函数里配置了

m_timer =new QTimer (this);
    m_timer->setTimerType(Qt::PreciseTimer);
    connect (m_timer,SIGNAL(timeout()),this,SLOT(onTimeout()));
    m_timer->start(500);

并且我尝试在 SLOT onTimeout() 中进行测试,但是这个 qDebug()<<"VITESSEEEEEEEE"<<m_pin <<readPin()<<vitesse; 从未出现过。我不知道为什么可能是因为 wiringPiISR 是一个线程并且比定时器具有更高的优先级? 有人可以向我解释一下,如何制作一个计算准确时间并同时使中断工作的计时器吗? 计时器正在为这个 class 的其他实例工作,这些实例只是输入没有中断

void Capteur_Input::onTimeout()
{
    qDebug()<<"time is up"<<m_pin;

    if(m_pin== Pin_vitesse)
    {
        qDebug()<<"m_pin== Pin_vitesse";
    int vitesse;

    vitesse= int (calcul_vitesse/4*2.166);//*0.001/3600;
    qDebug()<<"VITESSEEEEEEEE"<<m_pin <<readPin()<<vitesse;

    emit vitesse_Changed(vitesse);
    qDebug()<<"VITESSEEEEEEEE"<<m_pin <<readPin()<<vitesse;


    }
    else{

        emit digital_inputChanged(readPin());
        qDebug()<<"signal DIGITAL emitted m_pin"<<m_pin <<"value"<<readPin();
    }
}

实际上插槽 onTimeout 正在为这 2 个实例工作

#define Pin_vitesse 3
#define PinFrein 0
#define PinClignotnat_G 2

Capteur_Input frein(PinFrein,PUD_UP,NO_INTERRUPT);
Capteur_Input clignotant_G(PinClignotnat_G,PUD_DOWN,NO_INTERRUPT);

并且不适用于这个中断 static Capteur_Input vitesse(Pin_vitesse,PUD_OFF,INT_EDGE_RISING,isrInput_vitesse);

这就是我得到的输出

time is up 0
signal DIGITAL emitted 0 1
time is up 2
signal DIGITAL emitted 2 0

time is up 0
signal DIGITAL emitted 0 1

计时器对其他实例有效,但对中断实例无效

您的 timeout 信号可能受到干扰或延迟。

您可以尝试指定一个 Qt::Connectiontype 以强制 Qt 在您的 timeout 信号发出后立即处理它。

QObject::connect(m_timer, &QTimer::timeout, this, &Capteur_Input::onTimeOut, Qt::DirectConnection);

这将在 timeout 信号发出后立即将其传送到 ontimeOut 插槽。

Qt 不支持静态 QObject 实例,如下所述(QObject 可重入 section):

In general, creating QObjects before the QApplication is not supported and can lead to weird crashes on exit, depending on the platform. This means static instances of QObject are also not supported. A properly structured single or multi-threaded application should make the QApplication be the first created, and last destroyed QObject.

如果在 isr 中断出现时需要回调,静态指针应该可以工作:

static void isrInput_vitesse();

static Capteur_Input *vitesse = nullptr;

static void isrInput_vitesse()
{
    if(!vitesse) //not initialized yet
         return; 
    
    QMetaObject::invokeMethod( vitesse, "isrCallback", Qt::QueuedConnection ); //or blockingQueue if you need to handle it directly in Qt way.
}

vitesse 指针应在 QApplication 实例初始化后在 main() 中初始化。

 int main(int argc, char *argv[])
 {
       QApplication a(argc, argv);

       //.....  your main application body  

       vitesse = new  Capteur_Input(Pin_vitesse,PUD_OFF,INT_EDGE_RISING,isrInput_vitesse);

       //...
 }