-3

Im using a NodeMCU with multiple timer. This code is running properly. There are 3 timer functions that counting depends on input from firebase with delay on each. But when the delay comes, the other timer is stopped for a while until the delay is done. The code is showed below:

//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;
}

My question is how to make every timer's delay not affect another timer's function.

  • 1
    Those functions are all identical except for the array offset. You could either make that a template parameter or a function argument. – Henri Menke Aug 03 '18 at 07:06

1 Answers1

0

Sounds as if (well, I don't know nodeMCU, so answering in general terms...) callbacks are just called one after the other from within the main loop.

If so, naturally each callback delay blocks the other callbacks. Instead of delaying by busy-wait (delay function), you might restart the timer and exit the function, that would unblock the other callbacks.

It might look similar to the following pattern:

#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;
}

Restarting the timer before the code executed will not add execution time to the intervals, so you get slightly higher precision...

Side note: As denoted in the comments already, avoid code duplication:

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?
}

With this intermediate function the code to execute exists only once (unless you make it inline), bought with an additional function call. Instead of inlining the intermediate function, a template function is a more elegant approach:

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
}
Aconcagua
  • 24,880
  • 4
  • 34
  • 59