Я использую NodeMCU с несколькими таймерами.
Этот код работает правильно. Существует 3 функции таймера, отсчет которых зависит от входных данных от базы с задержкой на каждой. Но когда приходит задержка, другой таймер останавливается на некоторое время, пока задержка не будет сделана. Код показан ниже:
//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;
}
Мой вопрос заключается в том, как сделать так, чтобы задержка каждого таймера не влияла на функцию другого таймера.
Звучит так, как будто (ну, я не знаю, 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
}
Других решений пока нет …