首页 > 解决方案 > 功能延迟时计时器停止

问题描述

我使用带有多个计时器的 NodeMCU。此代码运行正常。有 3 个计时器函数,其计数取决于来自 firebase 的输入,每个函数都有延迟。但是当延迟到来时,另一个计时器会停止一段时间,直到延迟完成。代码如下所示:

//timerrak1
void t2Callback() {
        if (start[0] == milis[0]) {
          Serial.println("TIMER1");
          digitalWrite(selenoid[0], LOW);
          digitalWrite(pompa, LOW);
          delay(durasi[0]);
          digitalWrite(pompa, HIGH);
          digitalWrite(selenoid[0], HIGH);
          t2.disable();
          start[0] = 0;

     }


     start[0] = start[0] + 1000;
}

//timerrak2
void t4Callback() {
  if (start[1] == milis[1]) {
          Serial.println("TIMER2");
          digitalWrite(selenoid[1], LOW);
          digitalWrite(pompa, LOW);
          delay(durasi[1]);
          digitalWrite(pompa, HIGH);
          digitalWrite(selenoid[1], HIGH);
          t4.disable();
          start[1] = 0; 

     }
     start[1] = start[1] + 1000;
}
//timerrak3
void t5Callback() {
        if (start[2] == milis[2]) {
          Serial.println("TIMER3");
          digitalWrite(selenoid[2], LOW);
          digitalWrite(pompa, LOW);
          delay(durasi[2]);
          digitalWrite(pompa, HIGH);
          digitalWrite(selenoid[2], HIGH);
          t5.disable();
          start[2] = 0;

     }


     start[2] = start[2] + 1000;
}

我的问题是如何让每个定时器的延迟不影响另一个定时器的功能。

标签: c++timernodemcu

解决方案


听起来好像(好吧,我不知道nodeMCU,所以笼统地回答......)回调只是在主循环中一个接一个地调用。

如果是这样,自然每个回调延迟都会阻止其他回调。delay您可以重新启动计时器并退出该函数,而不是通过忙等待(函数)进行延迟,这将解除对其他回调的阻塞。

它可能类似于以下模式:

#define INTERVAL 1000
#define INTERMEDIATE_DELAY 100

void callback()
{
    static bool isDelay = false;

    if(!isDelay)
    {
        restartTimer(INTERMEDIATE_DELAY);

        // part of code BEFORE delay
    }
    else
    {
        restartTimer(INTERVAL - INTERMEDIATE_DELAY);

        // part of code AFTER delay
    }
    isDelay = !isDelay;
}

在执行代码之前重新启动计时器不会将执行时间添加到间隔中,因此您可以获得更高的精度......

旁注:如评论中所述,避免代码重复:

void callbackHandler(unsigned int index)
{
    Serial.print("rak ");
    Serial.print(index + 1);
    Serial.println(millis[index];
    {
        //logselenoid[2 * index] = logselenoid[2 * index] + 1;
        // simpler:
        ++logselenoid[2 * index];
    }
}

// just a shortened sample, add further parameters as needed

void t2Callback()
{
    callbackHandler(0, t2); // tx as additional parameter?
}

使用此中间函数,要执行的代码仅存在一次(除非您将其设为内联),并通过额外的函数调用购买。模板函数不是内联中间函数,而是一种更优雅的方法:

template <unsigned int Index, WhatEver& Tx>
//                            ^^^^^^^^^ can be done since one of the
//                                      recent standards, C++14 or 17(?)
void callbackHandler()
{
    // just as the handler above
}

推荐阅读