Официальный сайт компании Arduino по адресу arduino.cc
millis(); Как при нажатии на кнопку, его обнулить?!
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Ср, 23/04/2014 - 15:04
Всем доброго времени суток!
Подскажите пожалуйста как кнопкой обнулить функцию millis(); ?
т.е. есть программа, при нажатии на кнопки вызываются определенные действия и должен начать работу таймер, вот только у меня таймер начинает работать срзу при включении ардуино и когда нажимаю на кнопки через пару минут, то сразу включается все, хотя должно было включаться поочереди по таймеру..
Вот небольшой набросок, подскажите где ошибка, никак не пойму:
JuriySOFT, вам нужно идти от простого к сложному. Вы вставляете строки из примеров не понимая как они работают. Естественно вы тут не добъётесь результата, пока не поймёте бессмысленность строк 9,10, абсурдность строк 18,21,23. В предыдущей вашей теме я вам простое задание дал, на развитие логики. Там как раз создаётся отсчёт времени после нажатия на кнопку. Шаг за шагом, и придёте к решению такой задачи как ваша первоначальная.
>Подскажите пожалуйста как кнопкой обнулить функцию millis(); ?
Никак.
Представте себе что у вас есть часы. Обыкновенные. Без таймера. И вам нужно сварять "яйцо-в-смятку". В рецепте вы вычитали, что "нужно закипятить воду, бросить яйцо, вынуть через три минуты".
Как вы обеспечите "варить яйцо три минуты", если переводить стрелки часов на 12:00 ночи вам религия не позволяет (ну или у часов отломанна головка и перевести их невозможно)? (это то что вы пытаетесь проделать спрашивая "как обнулить millis()?")
Каковы ваши "действия/рассуждения"?
Никак.
Что значит "никак"? Я вот на кнопку "ресет" нажимаю - у меня millis() исправно обнуляется. :) Это какая-то неправильная кнопка?
Никак.
Что значит "никак"? Я вот на кнопку "ресет" нажимаю - у меня millis() исправно обнуляется. :) Это какая-то неправильная кнопка?
Да. Неправильная. Почитайте условия задачи. "ничается отсчет при включении" - не подходит.
И главное - решение через "ресет" никоем образом не помогает топик-стартеру в понимании "а как же вообще делать таймеры".
В "яично-варочной аналогии" вы предложили решение "возми машину времени, благо она есть, и вернись в полночь и вари яйцо пона на часах не будет три минуты первого".
Ну или я чего-то не понимаю. И скажем вы знаете как, при помощи ресет, скажем включить светик через три минуты после нажатия кнопки, потом подождать 4-ре минут, а потом выключить. И все это без delay().
И скажем вы знаете как, при помощи ресет, скажем включить светик через три минуты после нажатия кнопки, потом подождать 4-ре минут, а потом выключить. И все это без delay().
Ну-у, я даже не знаю... :) Записать в eeprom, нажать на ресет из скетча, прочитать из eeprom - что делать после ресета. Без delay(), как и просили...
Понятно, что автор пытается решать задачу не тем способом, но и говорить о том, что "millis() кнопкой не обнуляется" - тоже не совсем корректно.
Понятно, что автор пытается решать задачу не тем способом, но и говорить о том, что "millis() кнопкой не обнуляется" - тоже не совсем корректно.
Корректно. Reset-том, вы дуину перегружаете. А не делается действие "обнуление millis())". Мы же не в анекдоте где головную боль лечат отрубанием головы. Так что не нужно высказываний вида "заявлять что топор не является средством от головной боли - не совсем корректно". Я считаю, что, все-таки, не является :) Лучше цитрамон или что-то подобное.
а откуда эта функция беред значения? может можно обнулить соответсвующий регистр?
Ну если очень любопытно, то можете посмотреть в файлик hardware\arduino\cores\arduino\wiring.c
Но лично я, с наскока, без очень веской причины, вряд ли смог обнулить там так "что-бы ничего не поломать". Тупо "присвоить ноль" - может иметь нежелательные побочные эффекты. Я думаю, что тот кто сможет "обнулить абсолютно корректно", совершенно не будет испытывать проблем со стартовой задачей и без обнуления.
И главное "зачем?" Прости, но это, в любом случае "удаление гланд, через Ж.., автогеном".
Если вы считате что "так проще". То тогда вопрос про "яйцо и часы" - можете отнести к себе тоже. Вы будете стрелки часов переводить? Или все-таки попроще сможете отсчитать 3 минуты без попыток вскрыть ломом бабушкины ходики?
то что это полное извращение это понятно)
leshak, Geronimo, в принципе можно и обнулять millis, я лично особого извращения тут не вижу... Только не саму миллис(), а её первопричинную переменную. Вызываем в нужном месте скетча timer0_millis=0 , и дело в шляпе. Только нужно сделать #include <wiring.c> что -б был доступ к закрытым переменным.
> Вызываем в нужном месте скетча timer0_millis=0
Может вы и правы. Вот только я не уверен. Что дело "будет в шляпе". Вернее "может и заработает", но вот когда и в каком месте вылезут "неприятные эффекты" - я не уверен. Ну как минимум, а если в этот момент сработает timer0? Поняно что сейчас вы вспомните про "запрет прерываний", но... ведь сразу не вспомнили. И еще могут быть "нюансы". А сколько еще библиотек, могут расчитывать на то что millis() растет линейно, и ее "резкое падение" означаент "было переполнение"? И еще могут быть... вообщем "нафиг, нафиг...". В лоб, может выйти больно. Причем не сразу, а "когда пару дней лбом об стол в дебаге побъешься".
А еще есть micros(), про который вы забыли... и они с millis() получаются "разойдутся". А еще, там, в зависимости от того под какой камень компилим... чуть чуть отличается логика и какие переменные используются. Вот здрово будет потом разбиратся почему "на этой плате работает, а на этой - не работает"....
Вообщем если бы у меня, кто-то в комманде, попытался такой код на продакшн запустить - точно по шляпе бы получил.
Я думаю вы поняли, что лично меня убедить в целесообразности/безопасности обнуления millis().
Ну или с другого конца. timer0_millis объявленна где-то в .h файлах? Нет. То есть это какая-то ПРИВАТНАЯ переменная. Внутреняя реализация. Которая может поменять в любой момент. Как угодно. Исчезнуть при любом обновлении ArduinoIDE или, что еще хуже, начать использоваться, внутри, как-то совсем по другому. Нарушение инкапсуляции - один из смертных грехов :)
Кстати, компилятор, уверен на 99% скажет вам тоже самое. И на попытку не то что поменять, а даже "прочитать" timer0_millis - пошлет вас нафиг. Не, при желании, через указатели мы до нее можем добратся. Но это уже будет 100% порнография.
Или начинать резть руками в Arduino.h. Что уже по определнию является "грязнохаком".
Вы по прежнему не видите в этом извращения? ;)
а еще веселее будет, если и micros() не сбойнет, и привязки к камню не будет, но в одном длинном-длинном скетче, который пишется очень долго, разные функции будут независимо друг от друга обнулять millis(), каждая для своих целей, а программист об этом забудет. или одна обнулять, а другая считать, что он постоянно возрастает.
не, должно быть в нашей жизни хоть что-то незыблемое, и пусть этой основой и будет millis :)
Ой! Как много "страшных" сообщений было написано за это время!....
Быть может можно сделать как-то попроще?
Я просто не знаю как это написать, но алгоритм в голове пока крутится такой:
если(millis()-currentMillis()+10000>=10000) { то .......}
где currentMillis = millis()
но чувствую что тут нужна какая-то дополнительная переменная, но не знаю какая.
Я ж только начал изучать АРдуину....
П.С. Может есть где учебники именно где можно подробно прочитать про millis() и все что с этим связано?
Я много искал, но везде одно и тоже, один и тот же пример про светодиод, а углубленного изучения нигде нет.
Я тут немного поэксперементировал и вот что получилось:
Но не могу понять почему, когда при нажатии кнопки сразу после запуска программы работает реле, а если нажать через 2 сек, то загорится еще светодиод, но если включить программу и подождать пару сек. то при нажатии кнопки включаются сразу и реле и светодиод...? В чем ошибка, подскажите? Я уже голову сломал.
У ткбя переменная change всегда равна 0
А как же тогда объяснить то, что отсчет 2х секунд все равно есть, но работает не так как мне надо?
А как же тогда объяснить то, что отсчет 2х секунд все равно есть, но работает не так как мне надо?
однозначно - чюдо.
leshak, чессгря я не отношусь к внутренним функциям ардуины как к чему-то священному, что нельзя трогать. Трогаю, и трогал раньше, ибо интересно :) Ну да, при какой-нибудь ситуации теоритически могут быть проблемы, но с другой стороны я и не предлагаю эту фишку использоваться всем подряд. Это из разряда, "как нет кнопки обнуления, а ресет?" :-))) Как в таких случаях говорят "используете на свой страх и риск"
JuriySOFT, вы заблуждаетесь, думая что у вас только с millis проблема. У вас проблема во всём, вы берёте что-то из примеров, и непонимая как это работает вставляете в свой скетч. Изучите справочник языка ардуино http://arduino.ru/Reference
JuriySOFT, вы заблуждаетесь, думая что у вас только с millis проблема. У вас проблема во всём, вы берёте что-то из примеров, и непонимая как это работает вставляете в свой скетч. Изучите справочник языка ардуино http://arduino.ru/Reference
Я уже читал его неоднократно... там очнь мало, впрочем как и на других сайтах, все одно и тоже, просто скопировано и переведено с оригинала.
JuriySOFT, да, там не всегда понятно, не спорю. Но тем не менее у вас не должно быть в скетче ни одной строчки, смысл которой вам не ясен как дважды два. Если вы присвоили переменной CHANGE тип bool значит вы не понимате что такое bool. Тут написано более чем понятно http://arduino.ru/Reference/BooleanVariables
Разве bool определен не как тайпдеф к чару? Синтаксически верно, но, но семантически ерунда написана.
Geronimo, долго думал над вашей фразой, но ничего не понял :) Что общего между bool и char ? В теории bool может достигать 255, но на практике всё что не 0 -то 1.
Это я к тому, что булеан, это исскуственный тип, созданный для удобства структуирования кода.
я опять опоздал на своевременное обсуждение топика.
По условию задачи, должен "запускаться таймер", а не секундомер(миллисекундомер), то есть парень сам не знает, что хочет и оттого цель недостижима. Если бы по условию требовалось активировать реле на заданный промежуток времени в момент нажатия кнопки, то предлагаю такой код:
Kolaha, то что вы код написали сами замечательно. Код кривоватенький и не учета дребезга, хотя код рабочий.
Kolaha, то что вы код написали сами замечательно. Код кривоватенький и не учета дребезга, хотя код рабочий.
Ну, то есть, топикстартер упоминал активацию реле на время. Я не думаю, что это означает интервалы в 0.1 секунды, сопоставимые с серьезным дребезгом контакта.
Ну да. Обычно на дребезг забивают. Но иногда нужно учитывать и его. Вот код , хотя немного не по теме.
а если так?
Kolaha. Вы наверно знаете, что такое грабли(или швабра). И главное чем черевато на них попадание. Так если вы захотите повязать на "черный пояс по программированию в системе Ардуино" , то не разбрасывайте их у себя в коде.
1
Большое спасибо. Мне очень приятно, что в моем коде это было единственное, к чему можно придараться. А, за разъяснение и примеры, я очень признателен.
Большое спасибо. Мне очень приятно, что в моем коде это было единственное, к чему можно придараться. А, за разъяснение и примеры, я очень признателен.
К сожелению, там много всего к чему я бы придрался. Но если вы выполните все мои придирки, то начнете писать как я. Ведь такие же требования я предьявляю и к своему коду.
Разумеется таймер millis() остановить нельзя, но можно запомнить начало в переменной и указать в константе интервал времени от этого начала. Но так как надо сделать это один раз, то нужен флаг. Что у вас написано. Но опять же , в такой конструкции можно ошибиться. Так что бы ошибок было поменьше и нужен стиль. Вот от сюда источник придирок к написанию кода.
Разумеется таймер millis() остановить нельзя,
Если сильно хочется, то можно и останавливать и обнулять:-) обнулить совсем просто -в шапке подцепить #include "wiring.c" и потом обнулить timer0_millis=0;
я так понимаю что миллис не тормозит программу и умеет значение да 50 дней, значит эта функция в постоянном цикле без загружения цикла(т. е. не тормозит программу) работает?
в моем пректе два дня без тормозов сработает?
я так понимаю что миллис не тормозит программу и умеет значение да 50 дней, значит эта функция в постоянном цикле без загружения цикла(т. е. не тормозит программу) работает?
в моем пректе два дня без тормозов сработает?
у меня уже нервов не хватает, да я сегодня под шафэ. перепишу .
я так понимаю что миллис не тормозит программу и меняет значение до 50 дней. значит миллис не будет меня тормозить двое суток(программа у меня на двое суток будет написана)
у меня планов собралось, а вопросов больше, а в програмировании ноль, но хотелка решается уже
форум должен быть создан для того чтобы поделиться мнением, а не угарать. вы как комент выглядите на ютубе, поугарать
форум должен быть создан для того чтобы поделиться мнением, а не угарать. вы как комент выглядите на ютубе, поугарать
http://arduino.ru/Reference
форум должен быть создан для того чтобы поделиться мнением, а не угарать. вы как комент выглядите на ютубе, поугарать
http://arduino.ru/Reference
я изучил
millis() - это системная переменная, не имеющаяя отношения к Вашей программе и её исполнению. Следовательно, она Вам ничего не "тормозит".
огромное спасибо, кое как вчера пытался осмыслиться. ответ меня порадовал. будем изучать дальше.
А такой вариант- если нажата кнопка то
И будут писаться значения нажатия кнопки за ноль
А такой вариант- если нажата кнопка то
И будут писаться значения нажатия кнопки за ноль
i чему равно?
В оглавлении я создал масив ONfaer[50]- Это 50 ячеек
А тепер пишу
ONfaer[i] = millis()-tochkaOtcheta; i++;
что означает что каждая запись будет в новой ячейке
если же нужна определенная то i=5 например
И сделано это для того чтобы после нажатия в этой переменной таймер будет отсчитываться с нуля так как например прошло с включения ардуины 5 минут 5-5 =о а вот следующая минута 6-5=1))) это мненадо для создания трека действий после нажатия кнопки
ок.
http://arduino.ru/Reference/Array
Это масив количество ячеек памяти тоесть 50 переменных я могу записать под этим названием изменяя тока цифру
Чтобы не писать каждый раз новую переменную
Можно пойти дальше и сделать под каждую переменную отдельную ардуино, со своим отдельным рейд массивом дисков на ССД.
Можно пойти дальше и сделать под каждую переменную отдельную ардуино, со своим отдельным рейд массивом дисков на ССД.
один рейд - одна переменная
и, писать летопись вселенной втуда