GyverTimer, обсуждение библиотеки

bort707

★★★★★★✩
21 Сен 2020
2,859
850
Спасибо за ответ, попробую.
P.S.: Я же могу оставить тело цикла while пустым?
вы не поняли. Алекс пошутил.
Код
while (!timer.isReady());
вообще ничем не отличается от delay() - он точно также блокирует программу.
Применять его не нужно
 
  • Лойс +1
Реакции: mezko

Askar

✩✩✩✩✩✩✩
17 Фев 2021
3
0
Всем привет, подскажите пожалуйста что я делаю не так. Суть делаю таймер в обычном режиме не что не происходит, при долгом нажатие на кнопку таймер переключается в состояние отсчёта времени. После того как первый лимит времени вышел, таймер спрашивает у пользователя продолжить, если пользователь нажимает на кнопку, то запускается 2й таймер. По окончании 2го лимита времени таймер снова спрашивает продолжить, если пользователь нажимает на кнопку то запускается 1й таймер и так по кругу. Но если пользователь не нажмёт на кнопку во время подтверждения или нажмёт во время любого таймера на длительное время, то программа выходит из режима таймер.
C++:
#define BTN     2       // Пин кнопки
#define BUZZER_PIN  5       // Пин для баззера (если нужен)
#define BUZZER_TONE 2500    // Частота баззера в герцах
#define BUZZER_DUR  300     // Длинна сигнала баззера в мс

#include <GyverButton.h>
GButton btn(BTN, HIGH_PULL);

#include "GyverTimer.h"
GTimer_ms Timer_1((long)3 * 60 * 1000);         // 3 минут
GTimer_ms Timer_2((long)5 * 60 * 1000);         // 5 минуты

bool checkFlag = false;
uint32_t checkTimer;

void setup()
{
  Serial.begin(9600);
  pinMode(BUZZER_PIN, OUTPUT);  // Пин баззера как выход
  btn.setTimeout(1500);  
}

void loop()
{
  btn.tick();     // опрос кнопки

  if (btn.isClick()) {    // короткое нажатие
      checkFlag = !checkFlag;   // инверт флага
      Serial.print("checkFlag ");
      Serial.println(checkFlag);
  }

  if (btn.isHolded()) { // длинное нажатие
    Serial.println("Tick");
    tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR); // подаем сигнал
    Tick();        // переход в рабочий цикл
  }




}

void Tick()
{
  if (Timer_1.isReady()) { // Запуск 1го таймера на 3 минуты
    checkFlag = true;
    checkTimer = millis();
    tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR); // подаем сигнал
    Serial.println(3);
  }

  if (checkFlag && millis() - checkTimer >= 1500) { // после конца 1го таймера дается 1.5 сек. на нажатие кнопки. Если нажата, запуск 2го таймера, иначе вывод ошибки
    //checkTimer = millis();
    checkFlag = false;
    Serial.println("Click");

  } //else { Serial.println("NOOOOOOOOOOOOOOOOOOOOO Click");}
  if (!checkFlag) {
    Timer_2.start();

  }

  if (Timer_2.isReady()) {  // Запуск 2го таймера на 5 минут
    tone(BUZZER_PIN, BUZZER_TONE, BUZZER_DUR); // подаем сигнал
    Serial.println(5);
  }

  //else { Serial.println("EROR"); }
}
 

Вложения

poty

★★★★★★✩
19 Фев 2020
2,956
886
@Askar, есть несколько неучтённых моментов:
1. Таймеры запускаются сразу после объявления и не останавливаются (использовать функцию reset() для сброса таймера на начало и флаги для обхода незадействованного в данный момент таймера или использование setTimeout для однократного запуска таймера).
2. Если Вы начали использовать таймеры Гайвера, то логично их использовать для всех отсчётов времени. (не обязательно)
3. Вход в функцию Tick() осуществляется лишь один раз по длинному нажатию на кнопку. Всё остальное время Вы ничего, кроме кнопок, не проверяете.
 

poty

★★★★★★✩
19 Фев 2020
2,956
886
1. Таймеры.
2. см. п.1, вместо использования:
C++:
millis() - checkTimer >= 1500
3. Поищите недавно здесь была тема по поводу последовательной отработки нажатий кнопок, там ровно та же проблема была и были представлены пути её решения.
 
Изменено:

Liyfifi

✩✩✩✩✩✩✩
15 Авг 2022
5
0
Не могу реализовать простейшую задачу с помощью библиотеки Gyver_Timer переключение реле день/ночь. Просто не улавливаю логику некоторых функций. То работает только в одном режиме и не переключается по триггеру на другой, либо срабатывает один цикл. Понимаю, что должно быть просто и библиотека этому способствует, но… Уже 2 дня маюсь, памагите! Причем в проге еще с десяток таймеров - и все нормально, но с этим таймером меня заклинило конкретно.
C++:
#include <GyverTimer.h>

GTimer dayPeriod_relay_myTimer(MS);
GTimer nightPeriod_relay_myTimer(MS);
GTimer relay_OnWork_myTimer(MS);

void setup()
{
  Serial.begin(9600);
    pinMode(2, OUTPUT);
    digitalWrite(2, 0);

   dayPeriod_relay_myTimer.setInterval(5000);
   nightPeriod_relay_myTimer.setInterval(10000);
   relay_OnWork_myTimer.setTimeout(3000); 
}
void loop() { 

  if (analogRead(2) > 400) {
    
    if (dayPeriod_relay_myTimer.isEnabled())nightPeriod_relay_myTimer.stop();
    
    if (dayPeriod_relay_myTimer.isReady()){
    digitalWrite(2,HIGH);
    relay_OnWork_myTimer.start();
    }
  if (relay_OnWork_myTimer.isReady()) digitalWrite(2,LOW);
  }


  if (analogRead(2) < 400) {
    
    if (nightPeriod_relay_myTimer.isEnabled())dayPeriod_relay_myTimer.stop();
    
    if (nightPeriod_relay_myTimer.isReady()){
    digitalWrite(2,HIGH);
    relay_OnWork_myTimer.start();
    }
  if (relay_OnWork_myTimer.isReady()) digitalWrite(2,LOW);
  }
}
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
312
100
Я не разбирался с GyverTimer, но по "общечеловеческой" логике, если вы дали команду stop то дальше таймер работать не должен.
 

Liyfifi

✩✩✩✩✩✩✩
15 Авг 2022
5
0
@Bruzzer, Справедливо.Было у меня по разному, и так было и по другому, не фурычит
C++:
#include <GyverTimer.h>

GTimer dayPeriod_relay_myTimer(MS);
GTimer nightPeriod_relay_myTimer(MS);
GTimer relay_OnWork_myTimer(MS);

void setup()
{
  Serial.begin(9600);
    pinMode(2, OUTPUT);
    digitalWrite(2, 0);

   dayPeriod_relay_myTimer.setInterval(5000);
   nightPeriod_relay_myTimer.setInterval(10000);
   relay_OnWork_myTimer.setTimeout(3000); 
}
void loop() { 

  if (analogRead(2) > 400) {
    
    if (dayPeriod_relay_myTimer.isEnabled())nightPeriod_relay_myTimer.stop();
    dayPeriod_relay_myTimer.start();
    if (dayPeriod_relay_myTimer.isReady()){
    digitalWrite(2,HIGH);
    relay_OnWork_myTimer.start();
    }
  if (relay_OnWork_myTimer.isReady()) digitalWrite(2,LOW);
  }


  if (analogRead(2) < 400) {
    
    if (nightPeriod_relay_myTimer.isEnabled())dayPeriod_relay_myTimer.stop();
    nightPeriod_relay_myTimer.start();
    if (nightPeriod_relay_myTimer.isReady()){
    digitalWrite(2,HIGH);
    relay_OnWork_myTimer.start();
    }
  if (relay_OnWork_myTimer.isReady()) digitalWrite(2,LOW);
  }
}
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
312
100
@Liyfifi,
У вас что то не работает. Но как должно работать не написано. А в программе нет ни одного комментария. Библиотека гайвера вам не понятна, но что именно не понятно вы тоже не пишите. Это плохо.
Скорее всего команды в строках 22 и 34 должны быть в случае else
 

Liyfifi

✩✩✩✩✩✩✩
15 Авг 2022
5
0
@Bruzzer, Работа реле в двух режимах: днем (фотосенсор) реле включается каждые 5 сек (в данном случае, это для отладки, чтобы долго не ждать), работает 3 сек, потом выключается, и снова.Ночью реле включается каждые 10 сек, работает также 3 сек и выключается. Триггер - это фотосенсор.