Таймер обратного отчета
- Войдите на сайт для отправки комментариев
Сб, 18/12/2021 - 20:00
Доброго времени суток, уважаемые форумчане.
Есть желание сделать таймер обратного отчета(секунды, минуты, часы) максимально точный, управляется кнопками (энкодер в дальнейшем), вывод на LCD 1602, закину на ардуино нано
НО, чего то совсем не могу разобраться до конца. Прошу помощи и рекомендаций по оптимизации. Огромное спасибо заранее!
#include <LiquidCrystal.h> const int rs = 11, en = 12, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); byte tim_H, tim_M, tim_S; unsigned int period = 20; const int ledPin = 6; const int buttonPin = 7; const int buttonPinH = 10; const int buttonPinM = 9; const int buttonPinS = 8; ///////////////////////////////////////////// void setup(){ lcd.begin(16, 2); Serial.begin(9600); pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); pinMode(buttonPinH, INPUT_PULLUP); pinMode(buttonPinM, INPUT_PULLUP); pinMode(buttonPinS, INPUT_PULLUP); lcd.setCursor(0, 0); lcd.print("T1-"); lcd.setCursor(3, 0); lcd.print("00:00:00"); lcd.setCursor(13, 0); lcd.print("GO"); } ///////////////////////////////////////// unsigned long btnTimer1 = 0; bool flag = false; bool flag1=0; unsigned long btnTimer = 0; bool flagH = false; unsigned long btnTimerH = 0; bool flagM = false; unsigned long btnTimerM = 0; bool flagS = false; unsigned long btnTimerS = 0; /////////////////////////////////////////////////// void loop(){ ////////////////ЧАСЫ///////////////////////////// bool btnStateH = !digitalRead(buttonPinH); if (btnStateH && !flagH && (millis() - btnTimerH) > 20) { flagH = true; btnTimerH = millis(); tim_H=(tim_H+1); lcd.setCursor(3, 0); if(tim_H<10){lcd.print("0");} lcd.print(tim_H); } if (!btnStateH && flagH && (millis() - btnTimerH) > 20) { flagH = false; btnTimerH = millis(); } ////////////////МИНУТЫ///////////////////////////////// bool btnStateM = !digitalRead(buttonPinM); if (btnStateM && !flagM && (millis() - btnTimerM) > 20) { flagM = true; btnTimerM = millis(); tim_M=(tim_M+1)% 60; lcd.setCursor(6, 0); if(tim_M<10){lcd.print("0");} lcd.print(tim_M); } if (!btnStateM && flagM && (millis() - btnTimerM) > 20) { flagM = false; btnTimerM = millis(); } ////////////////СЕКУНДЫ/////////////////////////////// bool btnStateS = !digitalRead(buttonPinS); if (btnStateS && !flagS && (millis() - btnTimerS) > 20) { flagS = true; btnTimerS = millis(); tim_S=(tim_S+1)% 60; lcd.setCursor(9, 0); if(tim_S<10){lcd.print("0");} lcd.print(tim_S); } if (!btnStateS && flagS && (millis() - btnTimerS) > 20) { flagS = false; btnTimerS = millis(); } ////////////////НАЖАЛ КНОПКУ/////////////////////////////////////////// bool btnState = !digitalRead(buttonPin); if (btnState && !flag && (millis() - btnTimer) > 20) { flag = true; btnTimer = millis(); if(btnState){ if (tim_S == 0) {tim_S = 60; tim_M = tim_M - 1;} if (tim_M < 0 ) {tim_M = 0;} flag1 = 1;} digitalWrite(ledPin, HIGH); Serial.println("press"); } if (!btnState && flag && (millis() - btnTimer) > 20) { flag = false; btnTimer = millis(); } /////////////ИДЕТ РАСЧЕТ И ВЫЧЕТ/////////////////////////////////////////// //tim_S=constrain(tim_S, 0, 59); // tim_M=constrain(tim_M, 0, 59); tim_H=constrain(tim_H, 0, 11); while (flag1 == 1) { if (millis() - btnTimer1 > period) { btnTimer1 = millis(); tim_S=tim_S-1; //////////////////////////////////////// if (tim_S == 0 && tim_M == 0 && tim_H == 0) { lcd.setCursor(3, 0); if(tim_H<10){lcd.print("0");} lcd.print(tim_H); lcd.setCursor(6, 0); if(tim_M<10){lcd.print("0");} lcd.print(tim_M); lcd.setCursor(9, 0); if(tim_S<10){lcd.print("0");} lcd.print(tim_S); flag1 = 0; digitalWrite(ledPin, LOW); } ///////////////////////////////////////// if (tim_S == 0 && flag1 ==1) { tim_S = 59; // if(tim_M==0&&tim_H!=0) {tim_M = 59;} tim_M = tim_M - 1; // if(tim_H!=0) {tim_H = tim_H - 1;} if (tim_M < 0 ) {tim_M = 0;} } /* if (SEC == 0 && w==1) { SEC = 59; MIN = MIN - 1; if (MIN < 0 ) { MIN = 0; } */ /////////////////////////////////////////////// /* if (tim_S == 0 && tim_M == 0 && flag1 ==1) { tim_M = 59; tim_H = tim_H - 1; if(tim_H!=0) {tim_H = tim_H - 1;} if (tim_H < 0) { tim_H = 0; } } */ //------------------------------------ Serial.println("pressH"); Serial.println(tim_H); Serial.println("pressM"); Serial.println(tim_M); Serial.println("pressS"); Serial.println(tim_S); //------------------------------------ if (flag1 == 1) { lcd.setCursor(3, 0); if(tim_H<10){lcd.print("0");} lcd.print(tim_H); lcd.setCursor(6, 0); if(tim_M<10){lcd.print("0");} lcd.print(tim_M); lcd.setCursor(9, 0); if(tim_S<10){lcd.print("0");} lcd.print(tim_S); } } } }
Останется перерезать красный мммм или может чёрный провод :)))
Может у кого есть похожая реализация?
У меня есть в планах точный таймер, и для его реализации я заказал модуль DS1302 (он дешевый и мне подходит), так как нужный мне таймер на 2 часа максимум всего. Вам же нужно что-то вроде DS3231 (например: https://aliexpress.ru/item/1005003514093522.html ). На миллис точность будет так себе - плюс / минус пару кирпичей.
Сам код не смотрел, мелко пробежал глазами. Я бы (на вашем месте) купил вышеописанный модуль реального времени и сначала просто «поиграл» бы с ним (вывод, установка времени и т.п.), потом уже можно и таймер «соорудить».
ЗЫ: А так же схему подключения нужно прикладывать и более детально описывать ЧТО ХОЧЕТСЯ и ЧТО ПОЛУЧАЕТСЯ.
Ок, заказал таймер, будет примерно через месяц.
А что касается кода, есть какие варианты?
Если миллис низкая точность, какая реализация будет точнее?
Спасибо.
Дык с использованием модуля реального времени и будет все точнее. И тогда, с использованием модуля, код будет совершенно другой))
ЗЫ: И правильно пишется - отСчета. Так как он считает, а не отчитывает кого-то )))
Ок, заказал таймер, будет примерно через месяц.
А что касается кода, есть какие варианты?
Если миллис низкая точность, какая реализация будет точнее?
Спасибо.
Так вроде бы в заголовке темы точность сформулирована до секунд. Чего придираться за зря? А миллис сильно далеки от этого. Особенно на китайских ардуино с керамическими резонаторами.
На миллис точность будет так себе - плюс / минус пару кирпичей.
Время отслеживать не через жопу , а в формате unix time , предлагали уже ?
Это в момент запуска таймера запоминать метку timestamp, добавлять к ней нужное значение и следить за разницей заданное-текущее.
Так вроде бы в заголовке темы точность сформулирована до секунд. Чего придираться за зря? А миллис сильно далеки от этого. Особенно на китайских ардуино с керамическими резонаторами.
Для серьёзного обсуждения нужно знать допустимую погрешность - абсолютную или относительную, и условия работы устройства.
На миллис точность будет так себе - плюс / минус пару кирпичей.
За несколько часов millis может уйти на пару минут. Вряд ли ТС согласится с тем, что такой точности "вполне достаточно".
Миллис + NTP спасет таймер ТС
А если нужен таймер обратного отчета(выставляешь время и он отчитывает обратно до 0) тоже нужны часы точного времени?
На миллис точность будет так себе - плюс / минус пару кирпичей.
Буду кнопками выбирать секунды, минуты и часы и отчитывать в обратном порядке
а есть пример или может проект реализован похожий?
Пример сложения 32-битных чисел и их сравнения?
Так вроде бы в заголовке темы точность сформулирована до секунд. Чего придираться за зря? А миллис сильно далеки от этого. Особенно на китайских ардуино с керамическими резонаторами.
Для серьёзного обсуждения нужно знать допустимую погрешность - абсолютную или относительную, и условия работы устройства.
Точность максимальная, ну максимум погрешность 1с в сутки. Если такое возможно?
На миллис точность будет так себе - плюс / минус пару кирпичей.
За несколько часов millis может уйти на пару минут. Вряд ли ТС согласится с тем, что такой точности "вполне достаточно".
За несколько часов 2-3 минуты - это много. А как можно повысить точность? если такое вообще возможно?
а еще есть способы поднять точность?
Пример сложения 32-битных чисел и их сравнения?
А есть пример? Или реализация похожего проекта? Можно по подробнее?
А самостоятельно почитать про unix time слабо ?
Там даже понимать практически ничего не надо.
Пример есть. От предполагаемой даты/времени отображаем разность с текущей. Сколько осталось: ГГ, ММ, ДД, ЧЧ, мм, СС.
Как бы вы это решили? Просто словами.
Некоторые даже хотели в миллисекундах. Говорят, очень стимулирует.)
unix time , предлагали уже ? т.е. я так понимаю нужно подключить библиотеку #include <UnixTime.h>
// https://www.unixtimestamp.com/index.php
А можете объяснить зачем так сложно для таймера обратного отчета? И зачем в таймере год и месяц...
Пример есть. От предполагаемой даты/времени отображаем разность с текущей. Сколько осталось: ГГ, ММ, ДД, ЧЧ, мм, СС.
Как бы вы это решили? Просто словами.
Некоторые даже хотели в миллисекундах. Говорят, очень стимулирует.)
Мне нужно сделать таймер, т.е. ввожу минуты и секунды 00:11:11, нажимаю кнопку(включается реле), на LCD минуты и секунды идут в обратном отчете и считают время до 00:00:00 (выключается реле)
Что произойдет 19 января 2038 года?
В этот день штамп времени Unix перестанет работать из-за 32-битного переполнения. До этого момента миллионы приложений должны будут либо принять новое соглашение для меток времени, либо перейти на 64-битные системы, что позволит «выиграть» для метки времени «немного» больше времени.
Den09, ну что ты мельтишишь? Садись и пиши код, за тебя его писать никто не будет.
Я написал, но он не работает, т.е. работает, но не корректно работает, когда вводишь часы, происходит фигня, и тут у меня ступр, я не знаю где копать...(
Значить, ничего не получится
У вас уже спрашивали - опишите четко, что вы пытались сделать в коде, что в итоге получилось и чем одно отличается от другого.
Есть желание сделать таймер обратного отчета(секунды, минуты, часы) максимально точный, управляется кнопками (энкодер в дальнейшем), вывод на LCD 1602, закину на ардуино нано
Нужен таймер обратного отчета. Вводишь часы, минуты, секунды (01:10:11), нажимаешь кнопку, идет обратный отчет до 00:00:00. Так вот у меня работает с минутам и секундами, а вот с часами нет, вот и прошу помощи посмотреть и кто сможет помочь. Заранее спасибо.
2500р
Ничего копать не нужно, так же как и не нужно «срать сообщениями». Ты же сказал, что уже заказал модуль реального времени - это так? Ну так пока едет модуль - почитай как ИМЕННО С НИМ работать, как получить время, как установить время и как отсчитать время. Это все три параметра работы, нужные тебе. ЧИТАЙ, ИЗУЧАЙ и вот если что будет не понятно - пиши. НИЧТО КРОМЕ МОДУЛЯ ЧАСОВ РЕАЛЬНОГО ВРЕМЕНИ не даст тебе заявленной точности. И забей на тролей местных о том что «в цифрах не указал точность», они мыслят деньгами (временем на разработку), а не человеческими понятиями.
Ничего копать не нужно, так же как и не нужно «срать сообщениями». Ты же сказал, что уже заказал модуль реального времени - это так? Ну так пока едет модуль - почитай как ИМЕННО С НИМ работать, как получить время, как установить время и как отсчитать время. Это все три параметра работы, нужные тебе. ЧИТАЙ, ИЗУЧАЙ и вот если что будет не понятно - пиши. НИЧТО КРОМЕ МОДУЛЯ ЧАСОВ РЕАЛЬНОГО ВРЕМЕНИ не даст тебе заявленной точности. И забей на тролей местных о том что «в цифрах не указал точность», они мыслят деньгами (временем на разработку), а не человеческими понятиями.
Да. Спасибо, буду изучать. Напишу, будут вопросы.
Мне нужно сделать таймер, т.е. ввожу минуты и секунды 00:11:11, нажимаю кнопку(включается реле), на LCD минуты и секунды идут в обратном отчете и считают время до 00:00:00 (выключается реле)
Ну это совсем просто. Нужна только защита от дурака.
Мне нужно сделать таймер, т.е. ввожу минуты и секунды 00:11:11, нажимаю кнопку(включается реле), на LCD минуты и секунды идут в обратном отчете и считают время до 00:00:00 (выключается реле)
Ну это совсем просто. Нужна только защита от дурака.
Нужна только защита от дурака.- это что значит?
у меня работает с минутам и секундами, а вот с часами нет, вот и прошу помощи посмотреть и кто сможет помочь. Заранее спасибо.
блин, ну ты совсем "непонятливый"? третий раз спрашиваю - ЧТО ИМЕННО НЕ ПОЛУЧАЕТСЯ???
Четко ответить можешь?
Примеры - "ввожу 1 час, а на экране 22"
" секунды и минуты идут, часы нет"
" часы. минуты и секунды доходят до нуля и уходят в минус..."
Выберите один из вариантов или напишите свой. Только подробно и четко, а не мычите как пьяный "оно не работает.... ИК!"
Что бы нельзя было ввести более 24:00:00.
Что бы нельзя было ввести более 24:00:00.
у него там нельзя больше 11 часов ввести
у меня работает с минутам и секундами, а вот с часами нет, вот и прошу помощи посмотреть и кто сможет помочь. Заранее спасибо.
блин, ну ты совсем "непонятливый"? третий раз спрашиваю - ЧТО ИМЕННО НЕ ПОЛУЧАЕТСЯ???
Четко ответить можешь?
Примеры - "ввожу 1 час, а на экране 22"
" секунды и минуты идут, часы нет"
" часы. минуты и секунды доходят до нуля и уходят в минус..."
Выберите один из вариантов или напишите свой. Только подробно и четко, а не мычите как пьяный "оно не работает.... ИК!"
у меня минуты и секунды нормально уменьшаются, но часы, в какой то момент перекидываются на 255 и все на lcd сбивается(
часы. минуты и секунды доходят до нуля и уходят в минус..."- с часами видимо это происходит.
Спасибо)
Точность максимальная, ну максимум погрешность 1с в сутки. Если такое возможно?
Думаю, без RTC это нереально. Собственный резонатор платы Ардуино (от которого работает millis) может дать погрешность несколько сотен секунд в сутки.
у меня минуты и секунды нормально уменьшаются, но часы, в какой то момент перекидываются на 255 и все на lcd сбивается(
Если тип переменной - byte, то она не может принимать отрицательное значение. При вычитании единицы из нулевого значения таковой переменной результатом будет 255 и условие (H < 0) никогда не сработает.
Выбирайте правильный тип переменной - со знаком. Например int, int8_t.
Вряд ли. Там такой геморрой... Вот лично мне не удалось придумать, как получать время NTP в момент максимально близкий к наступлению очередной секунды. Ну и как результат: мне не удалось добиться погрешности с верхней оценкой менее 2 с.
Мне кажется, наиболее простой способ реализации поставленной задачи - использовать RTC.
В кампутерном NTP вроде как дрифт вычисляется и потом с его учётом установка идет.
...я так понимаю нужно подключить библиотеку #include <UnixTime.h>
Неправильно понимаете.
Сердце Вашего проекта - достаточно точный источник времени. Встроенная millis в принципе не способна обеспечить необходимую точность. Другими словами, Вам надо не надеяться на программное решение, а сразу выбирать способ аппаратного решения задачи. Были предложены RTC и NTP. На мой взгляд, первое гораздо проще и, главное, в принципе способно обеспечить точность не хуже 1 с (на мой взгляд, решение с NTP не может обеспечить погрешность менее 2 с).
как результат: мне не удалось добиться погрешности с верхней оценкой менее 2 с.
погрешность менее 2х секунд получить трудно, согласен. Зато довольно просто ограничить уход часов величиной НЕ БОЛЕЕ нескольких сек в любой сколь угодно долгий период времени. Например год. 3 сек в год - это неплохой результат
у меня минуты и секунды нормально уменьшаются, но часы, в какой то момент перекидываются на 255 и все на lcd сбивается(
Если тип переменной - byte, то она не может принимать отрицательное значение. При вычитании единицы из нулевого значения таковой переменной результатом будет 255 и условие (H < 0) никогда не сработает.
Выбирайте правильный тип переменной - со знаком. Например int, int8_t.
Так мне и не нужно принимать отрицательное значение.
255 и условие (H < 0) никогда не сработает- как нужно сделать?
255 и условие (H < 0) никогда не сработает- как нужно сделать?
ты все-таки очень... непонятливый. Вот же ответ на твой вопрос - в предыдущем сообщении
...я так понимаю нужно подключить библиотеку #include <UnixTime.h>
Неправильно понимаете.
Сердце Вашего проекта - достаточно точный источник времени. Встроенная millis в принципе не способна обеспечить необходимую точность. Другими словами, Вам надо не надеяться на программное решение, а сразу выбирать способ аппаратного решения задачи. Были предложены RTC и NTP. На мой взгляд, первое гораздо проще и, главное, в принципе способно обеспечить точность не хуже 1 с (на мой взгляд, решение с NTP не может обеспечить погрешность менее 2 с).
RTC DS3231 подойдет? а есть пример использования для обратного таймера?
Так мне и не нужно принимать отрицательное значение.
255 и условие (H < 0) никогда не сработает- как нужно сделать?
Я же написал - выбрать сообразный решаемой задаче тип переменной.
RTC DS3231 подойдет? а есть пример использования для обратного таймера?
ну какой еще пример-то? для того чтобы посчитать по часам, когда истекут 9 часов 23 мин 44 сек - тебе пример нужен? В библиотеке к RTC есть примеры на этот счет.
Кстати. а зачем тебе таймер? Судя по вопросам - ты явно не самодельщик и не домашний мастер... что взрывать собрался?