Новичковый вопрос про защиту от дребезга
- Войдите на сайт для отправки комментариев
Всем привет!
Не судите строго, не пинайте ногами - я действительно только начинаю осваивать ардуину :-)
Тема, начатаю Нестандартом (http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-no...) прочитал, помогло.
Лешего в мире ардуино (http://alxarduino.blogspot.co.uk/2013/08/delay.html) тоже прочитал, тоже большое спасибо.
Но вот по дребезгу (вернее по защите от него) вопрос остался открытым.
У меня есть простенькая программка и простенькое устройство - всего две кнопки.
Отпервой кнопки ловим только длинное нажатие (более двух секунд) - поэотму на дребезг не обращаем внимания. От второй - любое, но только только тогда, когда идет процесс (когда поднят флаг процесса). Соответственно на дребезг тоже можно не обращать внимания.
А теперь я задумал добавить в систему менюшку, т.е. появилась необходимость от первой кнопки отслеживать помимо долгих нажатий еще и короткие нажатия, дабл-клики. И тут встала проблема дребезга.
Классы и библиотеки подключать не хочу до тех пор, пока как минимум не смогу написать их сам, пока не разберусь как они работают.
Теперь собственно вопросы.
Я опрашиваю первую кнопку каждый цикл лупа. Сравниваю результат опроса с предыдущим состояним. Соответственно получаю 4 случая:
1. Кнопка давно отпущена, ничего не происходит.
2. Кнопка нажата, прошел фронт. Запускаем таймер кнопки.
3. Кнопка удерживается нажатой. Ждем и смотрим таймер.
4. Кнопка отпущена. прошел фронт отпускания. Останавливаем таймер кнопки. Далее логика программы.
Поскольку в моей системе есть плюс (мне надо совершать действие по факту нажатия кнопки!), то собственно вопрос: А почему бы просто не поднимать флаг при прохождении фронта? Т.е. в состояниях 2 и 4 поднимаем флаг, засекаем время. И на некий заданный период просто запрещаем опрашивать кнопку. Период прошел - флаг опускаем.
Т.е. опрашиваем кнопку не просто каждый цикл лупа, а каждый цикл если флаг опущен! Сответственно прошел фронт - совершили действие (запустили таймер кнопки), но при этом подняли флаг и держим паузу в опросе кнопки, тем самым выполняя антидребезг. Т.е. все действия будут осуществляться только по первому фронту из дребезга, затем просто все фронты будут игнорироваться в 30 мсек (например).
Все правильно понимаю?
Все правильно понимаю?
кого понимаешь? О_О
Вопрос "Все ли правильно понимаю?" относился к моему пониманию идеи программной реализации антидребезга путем запрета опроса кнопки (игнорирования кнопки) после первого прохождения фронта на период антидребезга (30 мсек).
Такая схема вообще имеет право на жизнь или в ней скрыт какой-то глобальный косяк/проблема?
Вас понимаю не всегда :-) Собственно поэтому и спрашиваю :-)
Вопрос "Все ли правильно понимаю?" относился к моему пониманию идеи программной реализации антидребезга путем запрета опроса кнопки (игнорирования кнопки) после первого прохождения фронта на период антидребезга (30 мсек).
это самый простой алгоритм - но, есть вероятность, что ты за время работы таймера антидребезга успеешь ещё раз нажать/отпустить кнопку или так сойдутся звёзды, что на линии кнопки будут присутствовать два пика неизвестного происхождения.
в чём вопрос?
в википедии сто раз всё апсосано https://ru.wikipedia.org/wiki/Дребезг_контактовhttps://ru.wikipedia.org/wiki/Дребезг_контактов
если желается странного, то здесь ещё есть всякого
https://hackaday.com/2015/12/09/embed-with-elliot-debounce-your-noisy-bu...
https://hackaday.com/2015/12/10/embed-with-elliot-debounce-your-noisy-bu...
совсем странное - здесь(если желаешь срабатывания при повреждениях сигнала на линии кнопка-контроллер менее 50%, типо на случай ядрёной атаки)
http://www.kennethkuhn.com/electronics/debounce.c
Очень хорошое и полное руководство по дребезгу. Рассматриваются и программные решения, и аппаратные, и смешанные.
И еще раз спасибо!
ОК, я попробую переформулировать вопрос. Меня в описании алгоритма смущает вот что:
Это зачем? Для исключения помех на линии?
Ведь если ты все время сравниваешь состояние кнопки с предыдущим - то ты четко видишь, что прошел фронт включения. Было выключено, стало замкнуто. И если программа совершает действия по факту нажатия кнопки - то зачем добавиться "устойчиво замкнутого состояния"?
Прошел фронт - подняли флаг и игнорируем дребезг. Зачем проверять "спустя антидребезговое время"? А если за это время ты реально по кнопке топнул и отпустил ее? Ведь тогда такой клик будет проигнорирован как случайное нажатие!
Т.е. в википедии и во всех примерах описана схема: Появился сигнал - ставим задержку - читаем сигнал еще раз - если совпало - значит конпка нажата.
Я думаю над схемой: Появился сигнал - ставим статус "кнопка нажата" - ставим задержку и игнорируем изменения состояния кнопки на период задержки.
Есть ли у меня логическая ошибка? Почему? Я вот серьезно не понимаю, зачем проверять после задержки еще раз.
Я вот серьезно не понимаю, зачем проверять после задержки еще раз.
ок. а, если бы тебе отсекали по одной фаланге палца за сутки непонимания - ты бы понял?
отож. О_О
Гм. Понятнее не стало.
Есдли мне надо реагировать на сигнал на линии (который дает кнопка) - то лигично реагировать на первый пришедший сигнал (фронт), не? А дребезг - это последующие фронты на спад и включение, вот их то и будем отсекать задержкой.
Зачем сравнивать с тем, что повится после задержки, если мы ловим короткие клики? Чем плоха схема?
Извинитеза ошбки, пальцы толстые :-) Впредь буду внимательнее.
Зачем сравнивать с тем, что повится после задержки, если мы ловим короткие клики? Чем плоха схема?
не знаю, о какой схеме ты говоришь.
первый раз ты взводишь таймер фильтра дребезга - подозревается, что это было нажатие/отжатие на кнопку.
после окончания работы фильтра дребезга проверяем состояние кнопки, если совпадает с первым, то это было нажатие/отжатие, иначе делаем вид, что ничего не произошло - сидим в засаде и ловим изменения. О_О
Ведь если ты все время сравниваешь состояние кнопки с предыдущим - то ты четко видишь, что прошел фронт включения. Было выключено, стало замкнуто. И если программа совершает действия по факту нажатия кнопки - то зачем добавиться "устойчиво замкнутого состояния"?
Я вот серьезно не понимаю, зачем проверять после задержки еще раз.
Факт прихода фронта вовсе не означает, что кнопка была нажата. Например,
- где-то в схеме включилась нагрузка (и при включении на очень короткое время приятнула землю к своему питанию)
- где-то в схеме выключилась индукивность и по линии питания пошёл очень короткий всплеск.
- рядом с Вашим прибором включили мощную нагрузку (утюг). Особенно хорошо, когда в ту же розетку, в которую Ваш прибор включён.
Есть ещё 100500 причин по которым может прилететь кратковременный "сигнал". Например, подключите "вполне приличный из недорогих" блок питания в розетку, подключите в его выходу осциллограф и посмотрите что происходит в моменты включения/выключения вытяжной вентилляции в туалете.
А вооще, наберите в гугле "наносекундные помехи" прямо в кавычках, чтобы поменьше лишнего наловить. Узнаете много интересного.
P.S. Кстати. если сейчас "набигут" и будут говорить, что это всё бред и от таких вещеё можно защититься аппаратно, не верьте, вернее, верьте, но с оговоркой. Защититься, наверное, можно, но путём трёх- или более кратного удорожания устройства. А при защите "в пределах разумного", кратковременные импульсы проскакивать всё равно будут и никуда от этого не денешься.
Клапауций, Евгений - СПАСИБО!
В принципе все ясно - "сидеть в засаде" и считывать значение кнопки ПОСЛЕ антидребезгового времени требуется отлько для отсечения случайных помех на линии. Чтобы случайную помеху не принять за факт нажатия кнопки.
В моем случае секундомера (ардуина и две кнопки, питание от батарейки, линии по пять метров витой пары) - случайных помех можно не опасаться. Если только по воздуху прилетят.
Но впредь учту и буду делать академически правильно, с поднятием флага, считыванием состояния после антидребезгового времени и сравнения с первым считыванием.
Еще раз спасибо.