Помогите с кнопками и светом разобраться
- Войдите на сайт для отправки комментариев
Вс, 06/01/2013 - 14:34
В общем проблема банальная не работает управление светодиодом от кнопки
в целом хочется следующего
если жать на кнопку менее 1 сек то светодиод или гаснет или зажигается (смотря что он делел до нажатия)
если нажать дольше 1 сек то плавно гаснет или зажигается
пытаюсь сначала сделать первую часть
int pin = Button; // кнопка int led = GREEN_LED; // светодиод unsigned long dur; // длина нажатия void setup(){ pinMode(pin, INPUT); pinMode(led, OUTPUT); } void loop(){ if (pin==HIGH){ dur = millis(); // тут вроде должно храниться время нажатия } if (dur<1000){ // если жмем кнопку менее 1 сек то... digitalWrite(led,!digitalRead(led)); // зажигаем или гасим диод } }
Проблема в том что диод горит постоянно если (dur<1000)
и негорит постоянно (dur>1000)
Помогите разобраться
1. Вставка программного кода в тему/комментарий
2. Что такое Button и GREEN_LED, вы в каком-то эмуляторе пишите?
3. Начните изучение стандартных примеров работы с кнопками: Exemples -> 2.Digital -> ...
Пробема в том что фараза слово "время нажатия" в русском языке является не однозначным. Это может быть как
"точное время когда нажали кнопку" так и "сколько времени держим нажатым". То есть "момент" и "период".
В коде переменную dur вы вначале используете в одном смысле, а потом в другом. Сохраняете "когда нажали", а сравниваете как "сколько времени держим нажатую". Логично что если мы нажали кнопку, предполложим в 13 часов, сорок минут, то это время всегдя больше, скажем "одной минуты".
Вообщем разберитесь где у вас "момент времени", а где "временной интервал". Подсказка: millis() возращает "момент времени", а интервал уже вычислять самому.
К тому же, когда будете засекать "момент нажатия", обратите внимание что вам нужно засечь именно переход от LOW в HIGH, то есть "начало давления". Если смотреть просто на HIGH, То у вас по жизни будет "вот только что нажали кнопку".
Вообщем примерно так:
В вашем случае, можно обнулять eventTime (или dur) когда кнопку отпустили, а не внутри обработчика события. Что-бы небыло сработок типа "нажали кратко, отпустили, а оно потом через время сработало".
1. Вставка программного кода в тему/комментарий
Увидел тему после того как написал сообщение, хотел исправить но кнопки "редактировать" чтото на форуме нет (или я её незамечаю)
2. Что такое Button и GREEN_LED, вы в каком-то эмуляторе пишите?
Ну это я написал для того чтобы не путаться у каждого вместо этих значений могут быть свои номера вводов выводов (но я пишу в эмуляторе Energia для MSP430 поэтому кнопку на плате pin 5 заменил на Button, а pin 14 на Green_led)
3. Начните изучение стандартных примеров работы с кнопками: Exemples -> 2.Digital -> ...
Ну сначала я вцепился в функцию pulseIn
она как мне казалось точнее соответствует понятию "сколько времени держим нажатую"
и код был такой
Но в итоге этот код вообще странный т.к. диод горит всегда и гаснет после удержания кнопки нажатой в течении 2-х сек, а при отпускании снова горит и на duration < или > ему вообще пофиг
Спасибо!
Но не варит оно, может я чегото конечно не догоняю но
диод горит всегда
К тому же, когда будете засекать "момент нажатия", обратите внимание что вам нужно засечь именно переход от LOW в HIGH, то есть "начало давления". Если смотреть просто на HIGH, То у вас по жизни будет "вот только что нажали кнопку".
Все понял кроме одного какой оператор осуществляет засекание перехода LOW в High??
Я, со своей стороны, посоветую вам разобраться в отличиях между понятиями "событие" и "состояние". Тогда советы Leshak'а пойдут вам в прок.
А пока что вы проверяете состояние кнопки 100500 раз в секунду и обнаружив на соответствующем пине состояние HIGH (кнопка нажата) радостно регистрирует время наступления события. Пардон, какого? Может быть кнопка у вас вот в сей момент перешла из состояния "отжато" в "нажадо" и тогда телодвижения с регистрацией точного времени имеют под собой основание. А может быть, на нее уже с утра давят не отпуская... Зачем в таком случае засекать время? Ведь события не произошло (=состояние не изменилось).
UPD. Пока я читал-писал, вы уже успели выразить недоумение советом Leshak'а. В таком случае - вперед на изучение упомянутых в первом предложении различий!!!
UPD2. Оператор, засекающий переход LOW->HIGH - вы сами, точнее, написанная вами программа.
Спасибо!
Но не варит оно, может я чегото конечно не догоняю но
диод горит всегда
Вы думаете, я просто так вас направил сначала изучать стандартные примеры? Покажите в каком месте вашего кода происходит чтение состояния вывода?
я всегда считал что в 13 строке идет чтение состояния
Если вам так сложно посмотреть стандартные примеры, сделаю это за вас:
И еще раз напоминаю - вам необходимо не просто считывать состояние, а отслеживать события. В данном конкретном случае - изменение состояния вывода с LOW на HIGH (ну или с HIGH на LOW). Именно от этих событий (моментов их наступления) вы и будете отсчитывать интервалы времени, в зависимости от которых и будете тем или иным способом включать/выключать свои светодиоды.
Но сначала - изучать основы...
Мне не сложно вот как раз сидел вкуривал
Вроде работает
Но диод рвется гореть
т.е. все работает так
Диод горит
жмем кнопку более 1 сек - гаснет
потом сам зажигается
Как не зажигать диод самопроизвольно?
Забудьте пока про время, разберитесь сначала с "событием", там же смотрим пример StateChangeDetection, и пытаемся понять что до вас пытается донести step962.
Ну незнаю/непонимаю я, что пытаются мне донести
я в упор не понимаю примера StateChangeDetection
В итоге этот код не работает
любая попытка внести что либо в код с измерением времени выводит код из строя
http://arduino.ru/forum/programmirovanie/pomogite-s-kodom-korotkogo-myrg...
http://arduino.ru/forum/programmirovanie/zapusk-servo-knopkoimikrosvitch...
для дальнейшего написания вам лучше этот пример рассматреть в таком виде
Спасибо
буду ссылки читать
Смотрите что значит "событие перехода из LOW в HIGH"? Это значт что кнопка БЫЛА не нажата, а СТАЛА нажата.
В самом описании событие у нас присусвует и LOW и HIGH значит и в условии должны оба присутсвовать, логично? Два элемента в if проверять нужно "прошлое состояние кнопки" и "текущие состояние кнопки".
Под "прошлое" подразумевается "что мы прочитали при предыдущем опросе кнопки". Если мы опрашиваем кнопку один раз за проход loop, значит "то что мы прочитали при прошлом проходе loop". А значит нужно куда-то сохранять его. Завести еще одну переменную.
Ну и, надеюсь, вы не забыли про подтягивающий резистор для кнопки. Иначе, при не нажатой кнопке, вы будете с нее читать случайные числа.
Вот этот код работает хороше
а код с
Работает хуже
Я вот не понимаю как переход состояния L-H привязать и замерить длину нажатия
Вообще-то
и
одно и тоже.
Я это понимаю поэтому и удивлен
Пока вы не поймете как работает ваш код (#21) вы так и не сможете понять что такое "переход"/"событие" или наоборот. ) Покажите какие строки кода, собственно, и находятся в этом "переходе"/"событии" ?
Во первых "замерить длину" - у вас уже есть пример. Вам нужно разобратся как L-H детектить.
Насколько я понимаю событие -это манипуляции с flag
Не ищите какой-то особый "програмерский смысл" в этих словах. Он бывает, но в данном случае слова "событие" и "состояние" используется в своем прямом назначении. Просто в словаре посмотреть что значат эти слова. И различать их.
Вот фраза "лампочка горит" - это событие или состояние? "включение лампочки" - это событие или состояние?
Без четкого улавливание разницы этих двух вещей - трудно писать/понимать код.
"лампочка горит" - состояние
"включение лампочки" - это событие
но как я считаю - для меня важно состояние кнопка нажата и длительность этого состояния
Я вот набросал нерабочий код как заготовку чего хочу добиться (пока на {} и ; не обращайте внимания)
Либо вы возвращаетесь к сообщению #8 и начиная с него перечитываете и изучаете, как же все таки отловить только самый первый момент изменения сигнала так называемый фронт сигнала, событие, переход и т.д. Или можете дальше считать что вам важно и придумывать те действия коду, которые на самом деле он не делает, вместо того что бы разобираться в его работе. Вы лучше спросите что вам не понятно...
вообще тут уже всем кажется ясно что я не понимаю
что за фронт сигнала такой и бьюсь об это как в закрытую дверь
кнопка либо true или false, что за непонятное состояние полунажатия????
вы же не со знанием этой потаенной истины родились!? Где хоть это обьясняется?? Где почитать о этом?
то что мне написал step962
" пока что вы проверяете состояние кнопки 100500 раз в секунду и обнаружив на соответствующем пине состояние HIGH (кнопка нажата) радостно регистрирует время наступления события. Пардон, какого? Может быть кнопка у вас вот в сей момент перешла из состояния "отжато" в "нажадо" и тогда телодвижения с регистрацией точного времени имеют под собой основание. А может быть, на нее уже с утра давят не отпуская... Зачем в таком случае засекать время? Ведь события не произошло (=состояние не изменилось)."
кажется мне вполне логичным
да я проверяю состояние кнопки если кнопку нажали регистрирую время нажатия -логично
но и второе тоже логично наблюдатель начинает измерять время как только замечает состояние нажатой кнопки, пусть её и нажали с утра или вчера или год назад но заметили мы это сейчас и засекаем время с момента как заметили
вообще тут уже всем кажется ясно что я не понимаю
что за фронт сигнала такой и бьюсь об это как в закрытую дверь
Первая же ссылка в Яндексе по магическому поисковому запросу "фронт сигнала" - тыц.
кнопка либо true или false, что за непонятное состояние полунажатия????
Наверное, все же не состояние полунажатия, а переход из одного состояния в другое, т.е. пресловутый "фронт сигнала"?
вы же не со знанием этой потаенной истины родились!? Где хоть это обьясняется?? Где почитать о этом?
Ровно так же поступаем и с другими непонятными словосочетаниями.
Дам совет, но вряд ли вы сможете его послушатся (я бы не послушался): отложите все на день два. Пойдите прогуляйте на лыжах (или другая физ. нагрузка), а потом вернетесь к задаче. Без сарказма говорю. Серьезно. Состояние "ушел в тупняки" бывает у каждого и регулярно. А когда одновременно 5-ть человек пытаются что-то объяснить - это вообще не удивительно. Нужно просто отвлечься отдохнуть.
Когда вернетесь: не нужно искать "тайные знания". Банальная логика и здравый смысл. Представте себе что вы контроллер которому нужно выполнять скетч. Попробуйте в голове выполнить. Представить что происходит когда кнопка нажата, какие значения имеет каждая переменная при первом проходе loop, при втором. Нажали кнопку, еще парочку раз в голове "прокрутили".
Что-бы был хоть какой-то шанс это сделать: упростите задачу. Давайте для забудем все флаги, "время когда отпустили кнопку", "плавную яркость и т.п.".
Делаем File/New. И пытаемся решить задачу "если кнопку держат нажатой больше одной секунды - зажигаем диод, если отпустили - сразу гаснет". Давайте вначале это. Потом досконально понять "как это работает", а потом уже постепенно "усложнять/добавлять" плюшки в него будем.
Что-бы решить эту задача вам нужно "слепить вместе" два кода (практически без добавлений каких-то переменных и т.п.) из сообщения #25 - в нем есть как ловить момент нажатия и отжатия кнопки и сообщения #3 - там пример "как следить за интервалом". В этих премерах отсутсвует только setup(). Нужно дописать инициализацию светика на выход и подтяжку кнопки вверх.
Попробуйте их "слепить". Постарайтесь воздержатся от введения дополнительных переменных, преобразования типов и т.п. и т.п.
Итак: держим кнопку нажатой более 1 сек - светик загорелся, отпустили - сразу погас.
Раз уж зацепили "фронт сигнала" - тут опять все проще чем кажется. Просто представте напряжение на каком-то контакте как "уровень воды". Когда он меняется от нуля до 5v и обратно "поднялся/опустился" - это похоже на "прошла волна". Передний край этой "волны" назовут "фронтом", а задний - спадом. Вот и все. Просто предствте обычную волну на мелководье. Вы сидите в какой-то точке и меряете глубину (напряжение) и поверх вас прокатываетяс цунами. "Вот все пипец" (резкое наростание грубины) - это фронт, "фух. вроде попускает" - спад ;)
По ссылке на википедию которую дал step962 все замечательно видно на картинке.
Единсвенное что они не добавили для полного понимания - это оси координат. Что-бы было понятно что это горафик функции напряжение от времени V(t). Мысленно дорисуйте их сами. По вертикали - это напряжения на пине, а по горизонтали - время .
Update: смотрите на код из #25. Строка 11 ловит точки (3), а строка 15 ловит точки (4).
Код из сообщения #3 замеряет текущую длину "плато" (2)
Вам нужно всего лишь понять смысл протого механизма называемого тригером (их много разновидностей, не будем уточнять) после чего вы сможете и время засекать в нужный момент и светодиод включать. Это именно простой механизм.
У меня такой вопрос - вы понимаете что функция loop, в которой находится ваша программа повторяется несколько сотен тысяч, а иногда и несколько миллионов раз в секунду?
Вам нужно всего лишь понять смысл протого механизма называемого тригером
Да шо же вы делаете? :) У человека и так информационный перегруз. А вы все новые слова подкидываете. Ему же кажется что это "еще что-то" с чем нужно разобратся, а не что это все время одну и ту же вещь называют разными именами пытаясь объяснить.
Максим, представте что вы нормальный человек. А нормального человека слово "триггер" - пугает :) Да еще и "разных видов бывают" (ну ваще!!!!)
Offtop: меня вот убивает использование слово "транзакция" в инструкциях к банкоматам. Я не могу себе вообразить как какая-то бабушка с пенсией на карточке сможет это когда-нибудь понять. Я сомневаюсь что хотя-бы 10% самих банковских работников точно и правильно понимают значение этого слова (обычно путают с "проводкой"). Даже не каждый програмер, в зависимости от области деятельности, точно понимает (если не работает с базами, ORM и т.п.). А тут его используют "для работяг получающих зарплату".
Да' я понимаю что loop крутится как колесо с высокой частотой и что помимо состояния low и high будет несколько сотен циклов непонятно чего (пока кнопка нажимается)
меня путают стандартные примеры где рассмотрено нажатие кнопки и светодиод
там все просто if(pin, high){digitalwrite(led,high)
else (led,low)
Все! В примерах никто не заморачивается фронтами , а потом появляется пример StateChangeDetection с каимито счетчиками
в итоге я смотрю на это И вижу
2х2=4 пример 1
g(x) = f '(x)/f(x) пример 2
Те пример один предельно прост а пример два предельно сложен и прочитать про середину просто негде
Как говорится "назвался груздем ... ", если не плюнет на все это дело, то разберется, а когда разберется то все будет норм.
Называть это все "хренью", "той фигней" или "штукой" тоже как-то не правильно, пусть привыкает.
Все! В примерах никто не заморачивается фронтами , а потом появляется пример StateChangeDetection с каимито счетчиками
Ну да. Там же не делают "разрыва во времени". Как нажали - так и засветили. Важно только "текущие состояние кнопки". Поэтому никаких "время событие", попыток различать вид события (нажали или отпустили), никаких "а что у нас было перед этим" и т.п.
Мы хотим "чуть позже". Нажатие кнопки - в один момент, а действия по этому поводу - в другой. Поэтому и приходится "покупать часы" (millis()), запоминать время и т.п.
в итоге я смотрю на это И вижу
2х2=4 пример 1
g(x) = f '(x)/f(x) пример 2
Те пример один предельно прост а пример два предельно сложен и прочитать про середину просто негде
Это скорее вы пытаетесь "перепрыгнуть" :) Посмотрите в предыдущих постах я предложил вам упрощенную задачу. А "серединные" примеры, обычно сам человек разбирается. Путем комбинирования нескольких простых. Только вот их суть - нужно понять, а не "сразу бежать в сложное". Сделатте парочку 2x2, 3x3, 3x2 . Вы только "посмотрели" 2x2, а сами 3x3, 3x2 не сделали :) Сразу за f'(x) взялись :)
В вашем случае нет никакой середины, есть самый первый проход "колеса" когда кнопка только нажалась/отпустилась, тоесть в примере if(pin, high){digitalwrite(led,high) пока вы держите кнопку на led так и будет каждый раз посылаться сигнал high, хотя это нужно сделать только один раз.
Подтвердите мою догадку
о том что контроллер понимает, что событие произошло, когда сравнивает предыдущее и текущее состояние кнопки
и если эти состояния отличаются то это и есть "событие"
Все верно, только это не "контроллер понимает", а вы так пишите код, вы создаете механизм, который работает по вашему алгоритму.
Спасибо
Наконецто до меня дошло
Ну а теперь при собитии "кнопка нажалась" присваиваете некой переменной текущее значение функции millis(), а при событии "кнопка отпустилась" вычисляете время удерживания - вычитаете из текущеего значения функции millis() эту переменную и по результату делаете нужные действия, практически все есть в вашем коде выше.