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

dekort

✩✩✩✩✩✩✩
18 Дек 2018
9
0
Привет,
в данной библиотеки реализована проверка сброса millis() в 0 ? (происходит примерно через 50 дней)
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
357
564
Проверка - нет, но благодаря переполнению переменной таймера переход через 50 дней отрабатывается полностью корректно, таймер считается без сбивания периода
 

dekort

✩✩✩✩✩✩✩
18 Дек 2018
9
0
допустим у меня проработал контроллер 50 дней до переполнения осталось 30 минут, я засекаю очередной таймер на 2 часа. при обнуление millis () таймер не сработает давай вот такой код сделаем
C++:
boolean GTimer_ms::isReady() {
    if (!_state) return false;
    if ((long)millis() < _timer) {_timer = millis();}
    if ((long)millis() - _timer >= _interval) {
        if (_mode) _timer = millis();
        return true;
    } else {
        return false;
    }
}
тоесть добавить эту строку if ((long)millis() < _timer) {_timer = millis();}
описано тут
http://arduino.ru/forum/programmiro...a-nol-priblizitelno-cherez-50-dnei-kak-oboiti

можно кстати проверить на micros он переполниться через 70 минут , если таймер установить в 60 минут он по идеи сработает один раз только
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Доброго дня!

Появилась необходимость вывода времени таймера, если появилось событие раньше назначенного периода. (Запустили таймер на 5 секунд, а если нажали кнопку раньше, то надо определить это время. (Функция секундомера параллельно выполняемая в функцией интервала)
В самой библиотеке нет такой функции, всю просмотрел, сначала подумал что в переменной _timer оно лежит, но похоже не то..

Предполагаемое решение- добавить в библиотеку переменную+функцию расчёта этого времени. Запомнили - uint32_t время старта = millis(); затем по наступлению события делаем millis()- время старта ...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Ну замечательно.. пост - мысли в слух, а вопрос нет.
Ну я бы предложил тебе такое решение
Добавляешь библиотеку гайвербатон, определяешь там событие нажатия на кнопку на определенный пин.
Заводишь глобальную переменную для запоминания времени как и хотел выше.
Далее так.
Перед инициацией таймера запоминаешь время millis в переменную
При нажатии кнопки выводишь время millis-запомненое время.
Если тебе надо время относительно последнего срабатывания таймера, то в ка;дом вызове процедуры таймера запоминаешь в переменную время millis
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Мгм , требующие подтверждения!, дабы лишнего неправильного не городить ;)
У меня не кнопка, а щелевой датчик на аналоговый вход, но не суть важно.

А почему бы не сделать переменную для запоминания членом класса? в public например, чтоб при создании объекта GTimer у него была своя переменная, т.к. на данном этапе уже 2 таймера объявлено..

Попробую этот метод, после финала битвы VSCode VS IDE.. мозг уже набекрень
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
А почему бы не сделать переменную для запоминания членом класса? в public например, чтоб при создании объекта GTimer у него была своя переменная, т.к. на данном этапе уже 2 таймера объявлено..
Потому что само нажатие кнопки к таймеру никакого логического отношения не имеет. Но если надо несколько таких таймеров, каждый который будет следить за отдельной щелью (кнопкой), то имеет смысл написать наследный класс от таймера, тут да. Все упирается в "стоит ли городить класс для удобства, если это надо разово"
А кнопка, прерыватель не суть. суть в изменении сигнала на пине , так что гайвербатон должен щель обработать :D Но можно и прерываение повесить на этот пин, тут тебе виднее как городить . Каждый заблуждается в меру своих возможностей )
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
А делать наследный класс чтоб добавить одну функцию - маленько не понятно для чего так загоняться ;). Ради уважения к автору , ака " не будем ничего добавлять к исходнику, дабы не оскорбить автора".
В данном случае это больше выглядит как доработка имеющейся библиотеки, ввиду отсутствия нужной функции, и выпуска новой версии библиотеки на радость всем нам :) Если Mr. Alex сочтёт необходимым.

@Старик Похабыч, В итоге , немного пораскинув мозгами, сделал как ты советовал, не стал мудрить с библиотекой, сделал пару глобальных переменных для своих нужд, и через millis() всё организовал.
Проще простого :)

Осталось только вникнуть как прикрутить переполнение миллис(), но это дело техники.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
А зачем прикрутить переполнение ?
Смотри, пусть таймер будет байт и твоя переменная байт. т.е. максимум 255, после 255 сразу опять 0 и по кругу. время идет милис-запомнутое.
если запомнил 200, а время перепыгнуло и стало 5, то 5-200 будет -195, а т.к. минус быть не может, то будет 60, а это и есть разница во времени. ничего делать не надо , все и так работает
Главное что бы все было беззнаковое и одинакового типа
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
@Старик Похабыч, Понял тебя, Старче :) как раз сейчас подошел к этому моменту, обмозговал всё, вспомнил что ты сказал и согласился с этим. Сразу тему подсказал (y)
 

z2z

✩✩✩✩✩✩✩
10 Фев 2020
17
0
как изменить время срабатывания таймера?
C-like:
#include "GyverTimer.h"
GTimer_ms myTimer;               // создать таймер

void setup() {
  Serial.begin(9600);
 // myTimer.setInterval(500);   // настроить интервал
 Serial.println("start Timer!");
}

void loop() {
  myTimer.setInterval(500);
  //myTimer.reset();
  //myTimer.start();
  if (myTimer.isReady()) Serial.println("Timer!");

//   
}
вот такая конструкция не работает
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
myTimer.setInterval(500); перезапускает таймер каждый раз. А т.к. ты ставишь в цикле, то это ра 25000 в секунду происходит
 
  • Лойс +1
Реакции: z2z

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Правильно Старче говорит.
Так а че ты в setup() прописал , и закомментил )))
и резет и старт не нужен, (в данном коде)
 
  • Лойс +1
Реакции: z2z

z2z

✩✩✩✩✩✩✩
10 Фев 2020
17
0
Спасибо! Заработало)
надо время срабатывания изменять по АЦП
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Надо читать мануал.
Но идея смены времени таймера "на ходу" не очень хорошая. Т.е. если было изменение на АЦП, то по хорошему надо остановить таймер, изменить время, запустить таймер. Но АЦП будет дребезжать постоянно, тогда таймер совсем не сработает
 

z2z

✩✩✩✩✩✩✩
10 Фев 2020
17
0
@Старик Похабыч, посмотреть на мониторе как сильно скачут данные ацп и изменять таймер если данные изменились на большее или меньшую величину. Это решаемо)
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Да все решаемо в жизни, вопрос сколько надо с этим заниматься любовью и стоит ли результат выеденного гроша или ломаного яйца...
 

z2z

✩✩✩✩✩✩✩
10 Фев 2020
17
0
ну, я не знаю как иначе решить вопрос подстройки прибора в полевых условиях
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
А, т.е. это не постоянно мониторить, а подстраивать. Ну тогда проще. Можно хоть потенциометр, хоть энкодер прикрутить. Энкодером можно менять на ходу, удобнее. Нажал, сдвинул, посчитал щелчки, понял на сколько .
С потенциометра можно считывать значение в setup и уже использовать его все время. Надо новое - крутанул, ресет по питанию и в бой
Вот у меня таки мысли первоначально возникли
 

z2z

✩✩✩✩✩✩✩
10 Фев 2020
17
0
да ну, прерывание на него тратить, ногу лишнюю использовать)
за советы и внимание- спасибо!!
 

z2z

✩✩✩✩✩✩✩
10 Фев 2020
17
0
должен быть идеальный мир, должен! в котором события происходят в тот момент, когда программа готова их обработать) в нашем же, обычном мире, программа может, например, сидеть в долгом цикле и пользователь может хоть обкрутиться энкодером, но без всякого результата.
то есть хочу сказать, что не представляю как без использования внешнего прерывания правильно обработать вращение энкодера
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
должен быть идеальный мир, должен! в котором события происходят в тот момент, когда программа готова их обработать) в нашем же, обычном мире, программа может, например, сидеть в долгом цикле и пользователь может хоть обкрутиться энкодером, но без всякого результата.
то есть хочу сказать, что не представляю как без использования внешнего прерывания правильно обработать вращение энкодера
смотря как ты программу организуешь.. тут я у тебя не вижу мега цикла на тыщу строк :))))
А интервал может меняться в течении лупа хоть 100 раз в 100 разных местах и ничего тупить не будет. Я сейчас пишу прогу где у меня 2 таймера и по срабатыванию АналогРиид меняется интервал без проблем.
Так что не надо усложнять там, где это не требуется.
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Столкнулся с проблемой (хотя может я чего то недопонял).
Суть в том, что как будто Таймаутный таймер, нифига не таймаутный, а циклический, и не останавливается после отсчёта нужного времени.
C++:
#include <GyverTimer.h>
#include <GyverTM1637.h>
#define CLK 6
#define DIO 7

GyverTM1637 Disp(CLK, DIO);
GyverTimer PageTimer(MS);

void setup{ 
  PageTimer.setTimeout(2000);   //устанавливаем
}

void loop{
    if(PageTimer.isEnabled()){               //пока таймер работает(возвращает "true"), показываем надпись StEP
        Disp.displayByte(_S, _t, _E, _P);
    }else{                                       //теперь когда отсчитали время, статус таймера должен вернуть "false"
        Disp.displayInt((int)stepper2.currentPosition());         // теперь показываем на каком шаге стоит шаговик ( 28BYJ-48)
    }
}

Ну и получается что горит только надпись "СТЕП" , и не переключается на вывод текущей позиции.
 
Изменено:

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
boolean isEnabled(); // вернуть состояние таймера (остановлен/запущен)

Здесь более уместно
boolean isReady(); // возвращает true, когда пришло время