Как Сбросить millis()
- Войдите на сайт для отправки комментариев
Вс, 29/06/2014 - 04:59
возникла необходимость самостоятельно сбрасывать таймер millis()
это возможно???
возникла необходимость самостоятельно сбрасывать таймер millis()
это возможно???
почему нет? кнопка ресет сломалась?
1. Безопастно и гарантированно не имея побочных эффектов - никак.
2. На форуме, вверхну справа, есть поиск - тема обсуждалась. Например: millis(); Как при нажатии на кнопку, его обнулить?! | Аппаратная платформа Arduino . Думаю еще не одну найти можно...
3. Объективных причин для подобной "необходимости" - не существует. Если "нужно" - значит код выстроен не верно. Привязка к абсолютным значением millis() допустима только если сама задача стоит "через xxx миллисекунд после подачи питания или ресета, нужно..." (но тогда опять-таки обнулять millis() не нужно, ответ Puhlyaviy-го очевиден). Во всех остальных случах использование абсолютных значений - архитектурная ошибка.
По аналогии:
У вас есть часы или время в телефоне.
Как часто вы сбрасываете время в часах или в телефоне и с какой целью. Расскажите мне за чем это время вам нужно?
Поддерживаю. Если Вам нужно что-то сделать через 1 час, Вы ж не сбрасываете часы на ноль, и в 1:00:00 делаете это?
Объявие две глобальные четырёхбайтные переменные. Одну инициализируйте текущим значением millis(); вторую в нужное вам время. Их разность и будет иметь величину от нуля.
мои часы отстают в сутки на 47 секунд..... Как в Гринвиче каждые сутки притормозить всемирное координированное время на туже величину ?
мои часы отстают в сутки на 47 секунд..... Как в Гринвиче каждые сутки притормозить всемирное координированное время на туже величину ?
Это же очень просто - прибавлять к каждой минуте/часу константу.
Раньше были такие часы наручные советские электронные. У них была подстройка хода, благодаря которой их можно было настроить очень точною.
Но лучше всего часы постоянно корректировать от GPS/NTP
а, зачем это если в "букваре" написано - " Это количество сбрасывается на ноль, в следствие переполнения значения, приблизительно через 50 дней "
Молодца. Теперь с 50% вероятностью ждем "помогите, дуина пишет not in sync resp=... и скетчи не заливаются".
мои часы отстают в сутки на 47 секунд..... Как в Гринвиче каждые сутки притормозить всемирное координированное время на туже величину ?
Это же очень просто - прибавлять к каждой минуте/часу константу.
Раньше были такие часы наручные советские электронные. У них была подстройка хода, благодаря которой их можно было настроить очень точною.
Но лучше всего часы постоянно корректировать от GPS/NTP
:) :) :) ...часы механические, старенькие, не хочется их лишний раз переводить - пусть уж Гринвич переводят ! ( millis() ) :)
Но лучше всего часы постоянно корректировать от GPS/NTP
Шаговиком?
А, ну да. Яж привык что делаю всё на отдельной плате в меге с квадратным корпусом, и туда программа отправляется по ICSP. А при таком способе бажного загрузчика (который впадает в ступор от срабатывания watchdog) нету.
Ну тогда аффтар, разочарую. Никак.
Или меняем загрузчик на optiboot.
Ну тогда аффтар, разочарую. Никак.
Или меняем загрузчик на optiboot.
Вопрос на засыпку: а все остальные переменные, направление и состояние входов/выходов тоже сохраниться? А если скажем какой-то шилд установлен. Которому после подачи питания нужно init() сделать ОДИН РАЗ?
Так что не "меняем загрузчик", а "это нафиг не нужно".
как тема разрослась-то.... без автора, правда... A ХОТЕЛОСЬ БЫ УЗНАТЬ - ЗАЧЕМ точку отсчёта по времени назначать новую = "обнулять когда Я хочу" ?
Точно не нужно? Прям точно точно? Я просто в этом месте не очень понимаю. Объясните, если не затруднит.
Рассмотрим поведение программы за X-n мс до переполнения millis(), если нужно отмерить интервал в X мс. Предположим, X=5000, n=300, тогда началом интервала будет FFFFFFFF-(5000-300)=4294967295-4700=4294962595. Сохраним метку времени T: millis()=4294962595. Через 4701 мс millis() будет равно 0, т. е. наступит переполнение. Остаётся 299 мс, через которые условие должно сработать. Условие у нас записано как if(millis()-T>=X), где T - метка. Имеем X-T=5000-4294967295=-4294962295. Внимание вопрос: будет ли 4294962595 равно 299? Если да - то да, можно этот костыль с перезагрузкой не делать.
А вот от этого уже хромает надёжность. То есть у нас получается - какой-то форс-мажор, повисло где, ну с кем не бывает. Watchdog сработал. И тут шилд залип, потому что видите ли дважды инициализировался. Да гнать такие шилды из системы ссаными тряпками. Или отводить один из выводов под спец сброс всей периферии кроме дуины, в setup() делать на нём ноль, потом 1, пару секунд ждать - и только затем инициализировать.
как if(millis()-T>=X), где T - метка. Имеем X-T=5000-4294967295=-4294962295. Внимание вопрос: будет ли 4294962595 равно 299? Если да - то да, можно этот костыль с перезагрузкой не делать.
Да. Будет. Костыль можно не делать.
>То есть у нас получается - какой-то форс-мажор, повисло где, ну с кем не бывает. Watchdog сработал.
Если у нас предусмотрен вачдог именно как вачдог. Защита от форс-мажоро, то логично, что после перезагрузки будет предсумотрена и процедура воставновления. Проверка того, а был ли уже инит (да, да, при желании можно выяснить это подача питания или перезагрузка по вачдогу), будет возможность в железе передернуть питание шилду.... и т.д. и т.п. Это когда это НУЖНО.
Но городить все это из-за того что было лень потратить время на чтение примера "мигаем без delay()", и банального нежелание включить здравый смысл и поррасуждать (вот как вы выше сделали с переполнениями), - нет уж, увольте.
А сказать "гнать сцаными тряпками" - это конечно можно. Сказать. Да вот только когда в даташите написанно что "вот так нужно инициализировать".... и альтернативной микрухи нема. Что будете делать? Шилд выгнали, а работать кто будет?
Или, скажем у вас уже сделанно 90% работы. И тут вы захотели, вдруг, миллис сбросить. Из-за этого все переделывать на другую микруху? Разбираться заново и т.д. и т.п.
Или когда вам захотелось рестенуть, вы данные принимали по блютусу... заново коннектится? Пейрить девайсы?
Да в конце концов. Вы что хотите сказать что это нормально, когда какому-то кусочку логики, что-то потребовалось и он, по этому поводу, взял да и "рубанул все". Где же принцип несвязности кода?
Мне вот инетерестно, что-бы вы сказали, если бы у вас на PC какая-нибудь программа/напоминалка, выдавала напоминание, а потом ребутала машину (причем жестко). Что-бы вы сказали об авторе подобного чуда?
Гы... подумалось.
Кстати, скажем если этот таймер нужно запускать "по кнопке". То как тогда избежать что-бы он не срабатывал от просто включения питания, а действительно ЖДАЛ первого нажатия? EEPROM? Внешняя обвязка? А если нужно два таймера?
Эмм, а как выяснить, перезагрузилось ли само по сторожевому таймеру, либо загрузилось при включении? i2c RAM память?
std,
в даташите ищите MCUSR
>> Bit 0 – PORF: Power-on Reset Flag
This bit is set if a Power-on Reset occurs.
Но говорят, что достать информацию не просто.
Объективных причин для подобной "необходимости" - не существует. Если "нужно" - значит код выстроен не верно. Привязка к абсолютным значением millis() допустима только если сама задача стоит "через xxx миллисекунд после подачи питания или ресета, нужно..." (но тогда опять-таки обнулять millis() не нужно, ответ Puhlyaviy-го очевиден). Во всех остальных случах использование абсолютных значений - архитектурная ошибка.
Я бы на этом остановился. И при переполнении значений millis() не нужно изобретать ЛИСАПЕТ.А где автор?
есть система отсчёта дат... была "проблема" 2000-го года.... Щас опять про тоже ? ...в более мелком масштабе ?
Эмм, а как выяснить, перезагрузилось ли само по сторожевому таймеру, либо загрузилось при включении? i2c RAM память?
Я таки удивлен... а мысль что бы вачдог прежде того что бы дернуть ресет оставил записку во флеше? Не?
Эмм, а как выяснить, перезагрузилось ли само по сторожевому таймеру, либо загрузилось при включении? i2c RAM память?
Ну что вы. Куда уж нам до такого додуматься. Слово EEPROM выше было написанно случайно. В виде очепятки.
Так все таки есть какой то вариант чтоб milis запускалось только по нажатии определенной кнопки? у меня задача сделать устройство что при нажатии(или разжатии кнопки) ардуина отсчитывала заданное время и включало определенный механизм, может таймер какой то применять подскажите варианты?
49
// что-то сделать один раз по условию и по истечении времени интервала - генератор в одновибратор.
50
if
(условие) {nD_01.start();}
51
if
(nD_01.push_tick) {nD_01.stop(); код чего-то;}
класс титановый велосипед для delay без delay().
класс титановый велосипед для тактовой кнопки.
нада переварить прочитаное а то уже целый день с разными алгоритмами задолбался
нада переварить прочитаное а то уже целый день с разными алгоритмами задолбался
ну, смотри класс титановый велосипед для delay без delay(). обрабатывает нажатие/отпускание кнопки и отслеживание неактивности после - может быть достаточно для твоей задачи.
если что-то более расширенное, то цепляешь + класс титановый велосипед для delay без delay(). и делаешь одно событие через заданный интервал.
Так все таки есть какой то вариант чтоб milis запускалось только по нажатии определенной кнопки? у меня задача сделать устройство что при нажатии(или разжатии кнопки) ардуина отсчитывала заданное время и включало определенный механизм, может таймер какой то применять подскажите варианты?
Я устал повторять - для того чтобы получить ПРАВИЛЬНЫЙ ответ - нужно задать ПРАВИЛЬНЫЙ вопрос!
1.Тебе надо ИМЕННО миллис?
2. Тебе надо таймаут более 50 часов?
Без контекста - купи платку точного времени типа такой
http://ru.aliexpress.com/item/2pcs-lot-DS3231-AT24C32-IIC-Module-Precision-Clock-Module-for-Arduino-Free-Shipping/1509551405.html
DS3231 AT24C32 IIC Module Precision Clock Module, 50-60 руб цена вопроса.
поставь туда батарейку и читай себе точное время и соответственно разницу по времени.
Мне например нужно для реквизита таймаут до 16 часов - что совершенно меньше 50 часов миллса....
Так все таки есть какой то вариант чтоб milis запускалось только по нажатии определенной кнопки?
Кончечно, причём аппаратный. Нужно кнопкой подать минус на RESET pin :)
Так все таки есть какой то вариант чтоб milis запускалось только по нажатии определенной кнопки?
Кончечно, причём аппаратный. Нужно кнопкой подать минус на RESET pin :)
Благодарю :) я какраз путем проб и ошибок пришел к этому
Доброго времени суток! А как, например измерить время между подачей питания на одну ногу и подачей питания на другую? И не сбрасывать при этом миллис?
Столкнулся с необходимостью обнулять счетчик количества срабатываний датчика через указанное время, к примеру 30 сек. использую для этого:
делаю это для избежания ложных срабатываний. Но, как я понимаю при достижении millis предельного значения и сбросе его в ноль, условие не выполнится и счетчик не обнулится.
Сработает ли условие в таком виде:
А меньше нуля видиме не получится, значение беззнаковое.
У Вас интервал 30 сек, это 30 000 микросек. Просто укажите условие если millis() меньше 30 000...., а дальше приравнивайте millis();
Ничего страшного не случится если раз в месяц прочитаются данные не через 30 а через 50 секунд
30 сек это 30 000 000 микросек или 30 000 милисек.
Можете объяснить почему?
как я понимаю:
if (millis() - previousMillis < 0 ) результат вычетания. и перед переполнением, previousMillis будет равнятся скажем, 4 294 967 290, а millis после переполнения = 1000 в этом случае millis() - previousMillis как раз будет меньше нуля.
А меньше нуля видиме не получится, значение беззнаковое.
нет возможности сейчас в ардуино скетч залить, вечером попробую, но почему-то мне кажется, что результат вычетания millis() - previousMillis в операторе if без присвоения его переменной может быть отрицательным. или я ошибаюсь?
Потому что у unsigned long нет ни единого битика для хранения знака числа. То бишь "по определению". :)
Да, ответ на вопрос в названии темы (почему-то так никто его и не дал):
Сбросить millis() можно занулив счетчик переполнений таймера, фракционную порцию милисекунд и сам таймер при закрытых прерываниях (атомарно). Не помню как эти глобалы зовутся у wiring, но никаких проблем эта операция вызывать не должна.
залейте этот скетч и вопросы отпадут
а вот более наглядно
немного не такой скетч нужно залить =)
все дело в том, что previousMillis никогда не станет отрицательным числом.
отрицательным будет результат вычитания millis() - previousMillis в случае, когда previousMillis будет больше, чем millis().
мне кажется нужно проверить так:
если монитор порта первые 10 секунд будет писать "it Works" знач все получится =) вечером проверю.
Результат вычитания двух беззнаковых целых есть беззнаковое число и тоже целое.
я не просто так сделал отрицательным, так делать нельзя, но когда вы зальте то увидите чему равно previousMillis, просто не надо ждать 50 дней а 1 секунду
отрицательное беззнаковое число
Вы так компилять пробовали? Вас компилятор просто обязан в таком виде тормознуть и послать в дальнее эротическое путешествие по несоответствию типа переменной и заливаемой в неё константы, явно несовпадающего типа.
не послал
и попробуйте в этом скетче задать положительное значение previousMillis , пусть будет 10000 , что получите?
Kisoft и Arhat109-2, я думаю вам надо залить этот скетч и попробовать задать значение переменной previousMillis = 10000, я думаю после этого вы полезете в wirring искать, почему при при вычитании из функции millis() не задается переменная previousMillis
Зря не послал. Кривой компилятор или слишком добрый. :)
То, что он вам запихнул знаковое в беззнаковое - весьма пичалька. И это ни коим разом не отменяет кривости примеру. Почему вычитание двух беззнаковых чиселок работает верно - тут было объяснение и не единожды, лично мне - лень повторятся, но суть в том, что когда вы вычитаете из меньшего большее, то происходит "заем" (переполнение наоборот) из старших разрядов, в т.ч. и "за" разрядной сеткой. Раз нет знака - стало быть получить отрицательное число нельзя "в принципе", поэтому факт заема - игнорируется в сравнении.
это понятно, я не об этом, а о том почему не присваивается значение переменной в связке с millis()?
Условие не выполняется, вот и не изменяется .. у вас же выводится результат вычитания, что там непонятно?