Хочу знать когда сработает таймер!
- Войдите на сайт для отправки комментариев
Всем не равнодушным привет!
Решил реанимировать старый вопрос. Задача такова, нужно что бы отображался остаток времени до включения таймера, в формате чч:мм:cc Не спрашивайте зачем. Пока что выдаю в сериал монитор, там дальше будет видно. Графически себе представляю это примерно так.

Наваял такой не замысловатый код.
uint32_t previousMillis = 0; // время, когда таймер последний раз сработал.
const long interval = 1; // цикличность обратного отсчета времени 1 сек.
bool triggerActive = false; //переменные для отслеживания, были ли активированы триггеры или нет.
uint32_t timer; // Переменные хранения времени
uint8_t t1 = 13 // 13 период включения 13 сек.
uint8_t t3 = 5 // длительность 5 сек.
void loop()
{
// ############# Вывод остатка времени до включения таймера ##############
uint32_t currentMillis = millis() / 1000; // объявляем переменную currentMillis в секундах
if (currentMillis - previousMillis >= interval)
{
uint32_t remains = t1 * 3600 - currentMillis; // переменная остатка в секундах
uint8_t H = remains / 3600; // остаток часов
uint8_t M = (remains % 3600) / 60; // остаток минут
uint8_t S = (remains % 3600) % 60; //остаток секунд
if (ledState == "1") // если таймер сработал то выполняем код ниже...
{
char buffer1[9];
sprintf(buffer1, "%02d:%02d:%02d", H, M, S);
Serial.println(buffer1); // отобразим обратный отсчет времени
} else {
Serial.println("ON");
}
previousMillis = currentMillis;
}
// ################# Собственно сам таймер ####################
if (currentMillis - timer >= (ledState ? t3 : t1) && !triggerActive)
{
timer = currentMillis;
ledState = !ledState;
Serial.println("timer ON");
}
}
Как видим, таймер построен на millis, работает нормально. Но обратный отсчет работает криво. Включаю контроллер пошел обратный отсчет времени. Через заданное время таймер срабатывает и отсчет прекращается, в сериал монитор как и положено выдало статус "ON". По достижению времени отключения таймер отключается и тут снова должен начаться обратный отсчет с нуля, до
следующего включения таймера. Вместо этого начинает казать какое-то левое время. Мне кажется в строке 15 что то криво у меня посчитано. Поможите выйти из штопора затупления?
ну да, очень быстро стала бы отрицательной )))
20if(ledState =="1")а это сколько ?
разберитесь с единицами времени, миллис у вас в миллисекунлах, интервалы зачем-то в секундах. а остаток времени считаете в часах. Вот потому и путаетесь.
например в строке 15 какая-то бредятина написана
b707, там много бредятины. Чтобы ее избежать (как b707 выше писал) - нужно использовать измерения одного типа. И если используется миллис - проще всего в миллисекундах. Если сложно считать - используй макросы по полной. Например:
onehours 1000UL * 60 * 60
Да да, упустил этот момент. Спасибо.
Бр...р - а где ledState объявлена? Может у меня косоглазие?
Давайте, Вы начнёте с начала и нормально сами для себя уясните задачу. Сейчас Вы задачу не понимаете, а просто делаете пассы руками, внутренн убеждая себя, что всё понятно. У Вас каша в голове и Вы пытатесь из этой каши что-то вылепить
Вот прямо первое, Ваш рисунок
Не бывает на одной оси две разные точки t1! Видимо, вторая t1 равно t2 + некая константа? Так вот, если бы Вы так и написали - это помогло бы Вам делать программу. А так, как у Вас - только запутывает и сбивает с толку.
Начните с начала. И для начала, сделайте внятный рисунок и внятное описание задачи.
ну да, очень быстро стала бы отрицательной )))
Так и есть. Первый период отрабатывает нормально. Второй и последующий периоды кажет левое время.
b707, там много бредятины. Чтобы ее избежать (как b707 выше писал) - нужно использовать измерения одного типа. И если используется миллис - проще всего в миллисекундах. Если сложно считать - используй макросы по полной. Например:
Дык там и так всё лишь в секундах. В 12 строке обявлена переменну currentMillis, дальше работаем только с ней . Переменная remains опирается на currentMillis, которая так-же в секундах. В упор не вижу миллисекунд. Дефайны не использовал, потому что это просто автоподмена. Если просто значение в дефайнах, то да. А тут везде где встретится в коде onesec (onehours), будет считать. Лучше уж один раз посчитать, чем постоянно контроллер грузить расчетами.
Ладно, это всё косметика. Суть в другом. Мне кажется если бы после t2 обнулить millis() , то последущие вычеслиния уже шли бы с учетом этого обнудения. Нет?
там и так всё лишь в секундах.
а вот это в чем? В секундах? А 3600 что такое?
как только начинаются предложения "обнулить миллис" - я закрываю ветку. Не хочу слушать бред.
Если вы уверены, что у вас все в программе сделано правильно - то пользуйтесь ей, зачем вы в конфу то пришли?
Adolf_Balalaykin - и еще вам подсказка.
Подумайте, что вы пытаетесь вычислить? - Время, оставшееся от ТЕКУЩЕГО МОМЕНТА до следующего включения таймера, так?
ТЕКУЩИЙ МОМЕНТ - это currentmillis. Покажите мне это время на вашей схеме:
Его тут нет! Схема неверная, remains - это вовсе не та разница между t1 и t2. как у вас на рисунке.
Может именно поэтому вы и не можете его верно подсчитать?
Адольф, меньше ерепенься, больше слушай (читай) что говорят (пишут). Ты же сюда за помощью пришёл или просто показать «какой крутой»? Если первое, то вникай. Если второе - то так и скажи, поржем вместе и разойдёмся.
b707 часто резковат, но в основном пишет по делу.
Может именно поэтому вы и не можете его верно подсчитать?
Да, похоже бестолку. Мой пост о том же самом (#8) проигнорирован. ТС, похоже, надо не думать, а трясти.
Remains - это интервал между включениями. Вот в нём то и должен идти обратный отсчет времени. Далее просто следует повторение цикла и так до бесконечности.
Машину времени изобретаешь? Как можно узнать сколько осталось, если не знаешь сколько было изначально? Задай значение этого Remains и уменьшай его на единицу каждую секунду. Дошел до 0 - счет остановил, включил таймер. Таймер выключился - опять присвоил то же значение Remains и считаешь дальше.
Спасибо всем большое за потраченное время. Таки победил эту заразу. Постарался учесть все рекомендации.
#define ledPin 25 // Светодиод повесим на 25 пин. bool ledState = false; // по дефолту в 0. uint32_t previousMillis = 0; // запоминаем время, последнего срабатывания таймера. const long interval = 1; // цикличность обратного отсчета времени 1 сек. bool triggerActive = false; // переменная для отслеживания, был ли активирован триггер или нет. uint32_t timer; // Переменная хранения времени uint32_t t1 = 7200; // период включения в секундах (2 часа) uint32_t t3 = 3600; // длительность в секундах (1 час) void setup() { Serial.begin(9600); delay(1000); pinMode(ledPin, OUTPUT); } void loop() { uint32_t currentMillis = millis() / 1000; // аптайм в секундах. // ####################### Таймер ####################### if (currentMillis - timer >= (ledState ? t3 : t1) && !triggerActive) // Условие включения таймера { timer = currentMillis; ledState = !ledState; digitalWrite(ledPin, ledState); Serial.println("ON"); } // ############# Вывод остатка времени до включения таймера ############## if (currentMillis - previousMillis >= interval) { if (!ledState) { uint32_t countdown = t1 - (currentMillis - timer); uint8_t H = countdown / 3600; // остаток часов uint8_t M = countdown / 60 % 60; // остаток минут uint8_t S = countdown % 60; // остаток секунд char buffer[9]; // кол-во знаков sprintf(buffer, "%02d:%02d:%02d", H, M, S); // в буфер формат чч:мм:cc Serial.println(buffer); // в сериал порт } previousMillis = currentMillis; } }На эмуляторе всё работает. https://wokwi.com/projects/333892206403256916
Форум великая сила! :)