Цикличный отсчет времени
- Войдите на сайт для отправки комментариев
Чт, 15/06/2017 - 14:12
Здравствуйте, уважаемыепрограммисты. Я не силен в программировании поэтому обращаюсь к вам.
Задача следующая.
Необходимо написать код который циклично отсчитывал бы время назад. Например, я задал 10сек. нажал кнопку старт и процесс обратного отсчета пошел 10, 9, 8, ... 0. Как только дошел до 0 снова встал на 10 сек и отсчитывает 10, 9, 8... до 0. Накидал код, но почему-то он с каждым новым циклом прибавляет или отнимает разные значения. Не могу понять закономерность. Помогите его подправить.
unsigned long TimeLightOffOn = 10000;
void setup()
{
Serial.begin(9600);
}
void loop()
{
byte Seconds = ((TimeLightOffOn-millis())/1000UL)%60;
byte Minutes = (((TimeLightOffOn-millis())/1000UL)/60UL)%60;
byte Hours = (((TimeLightOffOn-millis())/1000UL)/3600UL)%24;
Serial.print(Hours);
Serial.print(':');
Serial.print(Minutes);
Serial.print(':');
Serial.println(Seconds);
if (Seconds == 0 && Minutes == 0 && Hours == 0) //(millis() - timer > 3000) {
TimeLightOffOn = millis() + TimeLightOffOn;
delay(1000);
}
Вот коротко какой результат получаю^
0:0:10
0:0:9
0:0:8
0:0:6
0:0:5
0:0:4
0:0:3
0:0:2
0:0:1
0:0:0
0:0:9
0:0:8
0:0:6
0:0:5
0:0:4
0:0:3
0:0:2
0:0:1
0:0:0
0:0:18
0:0:17
0:0:16
Пожалуйста вставляйте код правильно. Вот как его сейчас обсуждать, если номеров строк нет?
Накидал код
Впредь попробуйте писать, будет лучше получаться. Накидывают навоз на грядку.
Не могу понять закономерность
Всё Вы можете, просто посмотрите внимательнее на код.
В строке №ХЗ Вы пишете "TimeLightOffOn = millis() + TimeLightOffOn;", т.е. Вы затираете старое значение TimeLightOffOn новым. Т.е. Вы портите величину интервала. Вот он у Вас и растёт постоянно. Сейчас скакнуло с 9 до 18, потом ещё вдвое скакнёт. Вы уж значение интервала сохраняйте всегда неизменным - зачем его портить-то то?
Это мое первое сообщение на форуме. Поэтому по строкам вышло так... Исправлюсь. Спасибо за подсказку. Т.е. Нужно ввести беременную которая будет хранить дельту?
Semka_2005 Вот мой скетч, где я применил похожее. Если разберетесь пригодится
ПС: класс Cl_back_timer и его представитель Back_timer
Semka_2005, я не ЕвгенийП и не заметил опечатки, тем не менее, реакция на Ваш вопрос у меня была примерно такая же.
В самом деле:
- можно ввести указанную Вами переменную и решить проблему,
- можно решить проблему бе введения указанной переменной,
- можно ввести переменную и НЕ решить проблему.
И как в таком случае на Ваш вопрос следует отвечать?
Я не могу понять как решить мою задачу.
Как я это вижу я. Скажем прошло 5сек (000 - опустим для простоты) с момента первого отсчета и значение millis() = 5
TimeLightOffOn = 5 (оно задано изначально)
тогда TimeLightOffOn-millis() или 5 - 5 = 0 Первый цикл прошел и мы пришли в ноль.
Теперь чтобы мне вернуться на заданые 5 сек и произвести отсчет обратно требуется
TimeLightOffOn = (millis ()= 5) + (TimeLightOffOn = 5) = 10
Получил значение TimeLightOffOn = 10 от которого я снова могу отнимать millis ()
TimeLightOffOn-millis() или 10 - 6 = 4
TimeLightOffOn-millis() или 10 - 7 = 3
TimeLightOffOn-millis() или 10 - 8 = 2
TimeLightOffOn-millis() или 10 - 9 = 1
TimeLightOffOn-millis() или 10 - 10 = 0
Почему не работает?
Первый раз работает, судя по Вашим ранешним печатям. А вот второй раз ... продолжите вот такое же расписывание для второго раза и увидите. что интервал увеличится вдвое. Сделайте.
Я не считаю это помощью. Это решит Вашу проблему сию секунду, но "срок годности" такой помощи - до следующего раза, когда Вам потребуется тоже самое. Как только потребуется, проблема возникнет снова, т.к. Вы от такой помощи ничему не научитесь.
Вся необходимая Вам техника есть вот в этом примере - там и задача очень похоже, тоже надо постоянно отсчитывать равные интервалы.
Вставьте код правильно и вежливо попросите, не забудьте "пожалуйста". ;) Я поправлю Ваш код. + одна строка и + одно исправление. луччше два исправления, но это уж как вам захоццо. ;)
wdrakula, да ладно Вам. Пусть возьмёт "блинк без делэй" и сам разберётся.
Женя! У Вас педагогическая железа сверхпродуктивна! Может опухолью закончится... берегите себя!
Достаточно сказать ТСу два слова: интервал и начало интервала - это разные понтия! Интервал - всегда 10 и его не надо менять, начало нужно переставлять. Так, возможно(?) , он сам догадается.
Это так? wdrakula, Пожалуйста, не сочтите за труд, поправьте код чтоб он заработал как надо!
Я вас понимаю, но я не программист и решив эту задачу сейчас, я к ней больше не вернусь в своей жизни. По крайней мере не собираюсь. У меня есть простенькая задачка которую я решу один раз в жизни и больше не вернусь к этому. Другое дело если бы я был студент и в дальнейшем мой заработок был связан с профессией программирования. А так... Решил задачу и забыл...
но я не программист
Но я то - программист. И отношусь к этому занятию очень серьёзно.
но я не программист
Но я то - программист. И отношусь к этому занятию очень серьёзно.
Дак я и не имею против вашей профессии ничего против. И именнопо этому обращаюсь к вам за квалифицированной помощью.
Это так? wdrakula, Пожалуйста, не сочтите за труд, поправьте код чтоб он заработал как надо!
дракула уволен за антисимитизм и русофобию.
подсказываю // TimeLightOffOn = millis() + TimeLightOffOn;
Это так? wdrakula, Пожалуйста, не сочтите за труд, поправьте код чтоб он заработал как надо!
код кривой, но я сохраню этот незабываемый стиль.
Разницу видите? интервал - это интервал, а ваша переменная с непроизносимым именем - это начало отсчета.
Я вас понимаю, но я не программист и решив эту задачу сейчас, я к ней больше не вернусь в своей жизни. По крайней мере не собираюсь. У меня есть простенькая задачка которую я решу один раз в жизни и больше не вернусь к этому. Другое дело если бы я был студент и в дальнейшем мой заработок был связан с профессией программирования. А так... Решил задачу и забыл...
Вот за такие высказывания и гоняют тут тряпками! Если программирование микроконтроллеров - не ваше хобби или профессия, то Вы обязаны платить за услугу. Вас не стригут бесплатно в парикмахерской?
Быть долбое.ом - не стыдно, я тоже чего-то не знаю, стыдно быть наглым долбое.ом и выклянчивать услугу бесплатно.
Я вас понимаю, но я не программист и решив эту задачу сейчас, я к ней больше не вернусь в своей жизни. По крайней мере не собираюсь. У меня есть простенькая задачка которую я решу один раз в жизни и больше не вернусь к этому. Другое дело если бы я был студент и в дальнейшем мой заработок был связан с профессией программирования. А так... Решил задачу и забыл...
Вот за такие высказывания и гоняют тут тряпками! Если программирование микроконтроллеров - не ваше хобби или профессия, то Вы обязаны платить за услугу. Вас не стригут бесплатно в парикмахерской?
Быть долбое.ом - не стыдно, я тоже чего-то не знаю, стыдно быть наглым долбое.ом и выклянчивать услугу бесплатно.
Это не хобби и не профессия. Я на этом не заработаю. Это очередная жизненая задачка.
Работает! Спасибо, wdrakula!
+ поставил к вашей карме )
Работает! Спасибо, wdrakula!
+ поставил к вашей карме )
даже маленькая кружка, лучше большого спасибо.
Я вас понимаю, но я не программист и решив эту задачу сейчас, я к ней больше не вернусь в своей жизни. По крайней мере не собираюсь. У меня есть простенькая задачка которую я решу один раз в жизни и больше не вернусь к этому. Другое дело если бы я был студент и в дальнейшем мой заработок был связан с профессией программирования. А так... Решил задачу и забыл...
Правила предельно просты:
Если Вы хотите научиться на примере конкретной задачи, Вам помогут бесплатно.
Если Вы не хотите учиться, но Вам нужно решить конкретную задачу, для Вас сделают это за деньги.
Все остальное - mauvais ton.
Правила предельно просты:
Если Вы хотите научиться на примере конкретной задачи, Вам помогут бесплатно.
Если Вы не хотите учиться, но Вам нужно решить конкретную задачу, для Вас сделают это за деньги.
Все остальное - mauvais ton.
Вот с этим согласем полностью. Никого не волнует - зарабатываете вы на этом или нет.
Делай сам или плати.
Это главный принцип светлого капиталистического будущего, что мы с Путиным тут строим. ;) Вы против?
Qui ne travaille pas, ne mange pas. Ну раз уж пошли proverbes francais.
Это не хобби и не профессия. Я на этом не заработаю. Это очередная жизненая задачка.
До Вас никак не может дойти простая вещь. Я уже пытался Вам сказать, что для меня-то это профессия!
Вот, смотрите, я сегодя подвёз голосовавшую на дороге бабушку. Бесплатно. На попытку сунуть мне какую-то мелочь ответил, что типа не надо, я зарабатываю другим способом. А вот если бы на моём месте был таксист и начал бы бесплатно бабушек подвозить, это было было дико и странно, т.к. он-то как раз зарабатывает именно этим способом.
Точно также здесь. Я готов помочь начинающему коллеге чему-то научиться. И довольно часто это делаю здесь и в других местах безвозмездно. Но писать программы для решения чьих-то жизненных задач - ради бога, пожалуйста - но это моя профессиональная деятельность и бесплатно я этого не делаю также как таксист бесплатно не подвозит бабушек.
Вас я понял. "Злые" вы какие-то. ))
Работает! Спасибо, wdrakula!
+ поставил к вашей карме )
даже маленькая кружка, лучше большого спасибо.
кинуть вам денег на телефон за услугу? Сколько стоит ваш труд?
кинуть вам денег на телефон за услугу? Сколько стоит ваш труд?
такая работа стоит пива. Можешь на стоимость бутылки пива поставить свечку в храме.
О здравии р.б. Владислава.
Уважаемые!
Дерзну задать еще один вопрос в продолжение первого. Надеюсь от камней которые полетят в мою сторону я не погибну...
Код работает замечательно при зарание обозначеном времени в переменной TimeLightOffOn за пределами setup и loop. Как же мне сделать это значение не зарание фиксированным? Ведь в жизни часто все гараздо сложнее и это значение меняться в соответствии с тем какое время обратного отсчета задал пользователь. Один ставит 10сек и МК отсчитывает циклично в обратном направлении, а другой пользователь может поставит 1мин и тоже МК остчитывает.
Как же мне сделать это значение не зарание фиксированным?
А как же, кто-то говорил: "я решу один раз в жизни и больше не вернусь к этому"? Оказывается, как тут кто-то сказал:"в жизни часто все гараздо сложнее".
Теперь ответ:
Она же у Вас переменная, а не константа. Так что в любой момент Вы можете задать ей новое значение при помощи операции присваивания.
Если я правильно понимаю то переменную не в пределал Луп пользователь изминить не может.
ПИШУ код в согласии с вашей подсказкой:
Результат:
Вставил воть сюда, заработало:
Это правильно с точки зрения граммотного программиста?
Это правильно с точки зрения граммотного программиста?
Конечно, нет.
1. Переменная TimeLightOffOn используется в строке 14 до того, как она получит осмысленное значение.
2. Техника, используемая в строке 25 приводит к сбою при переполнении millis. Я Вам советовал изучить пример "блинк без делэй", видимо совет проигнорирован. Там работают через вычитание, а не через сложением и это правильно.
Я уж не буду придираться к мелочам, типа того, что
1. определяемые в строка 14-16 переменные получают значение, которое потом нигде не изменяется, значит их грамотнее объявить как const.
2. переменные TimeLightOffOn и Interval используются только в одной функции loop и нигде более, так каого рожна они объявлены глобальными?
3. Те же переменные всегда получают одни и те же значения. Зачем? Но, допускаю, что это "на вырост".
Ну, а строка 26 - это, наверное, для лулзов.
Это так, с первого взгляда, внимательно не смотрел.
Если я правильно понимаю то переменную не в пределал Луп пользователь изминить не может.
Вы под "пользователем" кого имеете в виду? Кто скетч пишет или кто кнопку нажимает? Если первое - Вы можете вставить переменную куда угодно, что вы ниже и продемонстрировали. Если того, кто будет пользоваться вашей прогой - он ни ни в одном из ваших скетчей ничего не сможет изменить, пока вы не добавите в программу средства связи с пользователем (например, кнопки для изменения интервала)
Это правильно с точки зрения граммотного программиста?
Конечно, нет.
1. Переменная TimeLightOffOn используется в строке 14 до того, как она получит осмысленное значение.
2. Техника, используемая в строке 25 приводит к сбою при переполнении millis. Я Вам советовал изучить пример "блинк без делэй", видимо совет проигнорирован. Там работают через вычитание, а не через сложением и это правильно.
Я уж не буду придираться к мелочам, типа того, что
1. определяемые в строка 14-16 переменные получают значение, которое потом нигде не изменяется, значит их грамотнее объявить как const.
2. переменные TimeLightOffOn и Interval используются только в одной функции loop и нигде более, так каого рожна они объявлены глобальными?
3. Те же переменные всегда получают одни и те же значения. Зачем? Но, допускаю, что это "на вырост".
Ну, а строка 26 - это, наверное, для лулзов.
Это так, с первого взгляда, внимательно не смотрел.
мигание без делэй? вот это? http://arduino.ru/tutorials/BlinkWithoutDelay
а техника вычитания это?
if
(currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
Если я правильно понимаю то переменную не в пределал Луп пользователь изминить не может.
Вы под "пользователем" кого имеете в виду? Кто скетч пишет или кто кнопку нажимает? Если первое - Вы можете вставить переменную куда угодно, что вы ниже и продемонстрировали. Если того, кто будет пользоваться вашей прогой - он ни ни в одном из ваших скетчей ничего не сможет изменить, пока вы не добавите в программу средства связи с пользователем (например, кнопки для изменения интервала)
Пользователь кто кнопки жмет. Я просто опустил этот момент. Управление пользователь энкодером будет осуществлять.
мигание без делэй? вот это? http://arduino.ru/tutorials/BlinkWithoutDelay
а техника вычитания это?
Ну, да, а Вы зачем-то используете сложение и наступаете на грабли.
Если я правильно понимаю то переменную не в пределал Луп пользователь изминить не может.
Вы под "пользователем" кого имеете в виду?
Пользователь кто кнопки жмет. Я просто опустил этот момент. Управление пользователь энкодером будет осуществлять.
Тогда да, обычно в loop(). Только чтобы енкодер работал, вам надо будет от delay() в коде loop() избавится совсем.
Женя! Я не исправлял его логичческие ошибки. Там не только сложение было, но я же говорил, что у меня скилл коррекционной педагогики не прокачен.
Сегодня я томный и похмельный, снова матерью Терезой побуду.
Вот вам таймер, нормальный. В мониторе порта стандартного ИДЕ нужно выбрать в правом нижнем углу, рядом со скоростью, "возврат каретки" или "новую строку", только не обе вместе ;).
вводим число секунд таймера в мониторе. Если ничего не вврдим, то нажатие Ентер - просто старт/стоп таймера. После "стопа" счет продолжится с того же места.
Все понятно?
Женя! Я не исправлял его логичческие ошибки. Там не только сложение было, но я же говорил, что у меня скилл коррекционной педагогики не прокачен.
Сегодня я томный и похмельный, снова матерью Терезой побуду.
Вот вам таймер, нормальный. В мониторе порта стандартного ИДЕ нужно выбрать в правом нижнем углу, рядом со скоростью, "возврат каретки" или "новую строку", только не обе вместе ;).
вводим число секунд таймера в мониторе. Если ничего не вврдим, то нажатие Ентер - просто старт/стоп таймера. После "стопа" счет продолжится с того же места.
Все понятно?
Интересно... я всегда считал, что чем меньше строчек тем проще код. Почему Вы считаете что у меня сложнее я покане понимаю. Просто потому что я использую метод сложения, а не вычитания?
Попробовал вогнать Ваш код в ИДЭ и получил токую ошибку:
Жесть. 1 - то что вы пишите в скетче это не программа, а исходник. А вот исходник компилируется в программу. А значит что зависимости от объема текста в скетче и объема программы нет никакой. Если строитель откроет проект строительства высотного дома найдет детский рисунок , то ему станет понятно как строить этот дом.
2 - что такое сложность программы. Сложность для компилятора или для программиста. А если у программиста вообще нет знаний, то он вообще больше 2 двух строк коментария не поймет ничего.
3- я не пытаюсь вас тролить. Программирование это не умение затролить друг друга на форуме. Программирование это умение писать программы, которые компилируются компилятором и дальше нормально работают.
4 - не в сложении и вычитании дело, а в провереном опыте. Вас не удивляет факт, что с понедельника до пятницы пять дней, а с пятницы до понедельника всего два дня. Скорее это не потому что понедельник день тяжелый. А потому что это проверенный жизнью факт.
Попробовал вогнать Ваш код в ИДЭ и получил токую ошибку:
Есть такое на старых ИДЕ.
нужно buf описать, как char [], а не как byte [].
Строка № 16
Нужно так:
================
Да. И смысл не проще/сложнее, а в том, что показанный код без делеев, то есть неблокирующий.
Для своего проекта Вы просто заменяете блок чтения ввода на свой энкодер, а блок вывода - на свой экранчик.
Для своего проекта Вы просто заменяете блок чтения ввода на свой энкодер, а блок вывода - на свой экранчик.
Разбираю ваш код на косточки. где экранчик поменять я понимаю, а вот где заменить код чтения ввода я не понимаю. Наверно потому, что у меня работает только энтр. т.е. старт/стоп причем отсчет начинается с значения переменной Interval в строчке 10. Сколько я там сек ставлю от такого числа и отсчитывает. А на цифры введенные в ком порте не реагирует. Какие бы не вводил считать начинает или продолжает с переменной Interval. И не могу еще понять как сбросить. Мне не нужно чтобы он продолжал отсчет после паузы. Нужно чтоб сбрасывался после стоп и при старте начинал опять.
руки кривые? Я специально 1.6.5 поставил (не на Виндоус, а на Линух - но это не должно иметь значение) - все там нормально, кроме дебильного слова "вргужаем". Курсор в строку ввода поставьте и "возврат каретки" выберите.
Код чтения с ком-порта даже коментарием выделен. Что именно вам не ясно?
Но, я повторю, я не спец в коррекционной педагогике. Может кто другой возмется?