Аналоговые кнопки на прерывании
- Войдите на сайт для отправки комментариев
Так называемые тактовые кнопки всё не дают покоя )
Целью было гарантированное обслуживае кнопок, которое может обеспечить прерывание, но их определнно мало, по сравнению с желаемым кол-вом кнопок.
Изначальная идея запостена в теме кнопок, но та схема, в том виде, не рабочая. Поигрался с разными вариантами, в итоге появилась следующая схема
R1-5: 1к; 1,5к; 2к; 2,7к; 18,2к соотв.
и код к ней
#define PIN 6 //номер пина, куда подключили PIN схемы unsigned long lm = 0; //предыдущее срабатывание unsigned long cm; //текущее значение volatile int a = 0; void setup() { analogReference(DEFAULT); Serial.begin(115200); //для мониторинга pinMode(2, INPUT); pinMode(A0, INPUT); pinMode(PIN, OUTPUT); digitalWrite(PIN, LOW); attachInterrupt(0, button, FALLING); } void loop() { lm = millis(); while (a > 0) { cm = millis(); if (cm > lm + 250) //пауза срабатывая кнопок, сюда же добавляем действие в зависимости от значения переменной "а" { Serial.print(cm); Serial.print(" - "); Serial.println(a); a = 0; lm = cm; digitalWrite(PIN, LOW); //"вкл" прерывание } } } void button() { a = analogRead(A0); digitalWrite(PIN, HIGH); //"выкл" прерывание Serial.print("INT - "); Serial.println(a); }
Текущая схема обрабатывает нажатие кнопки, исключает дребезг*, и обрабатывает зажатые кнопки. Обработка одновременно нажатых кнопок в цель не входила, но при определенных значениях резисторов это возможно получить.
Возвращаемые значения переменной "а" в зависимости от кнопки: 51-53; 77-79; 99-101; 129-131. Значения зависят от реального сопротивления резисторов.
*Касательно дребезга, очень редко, и не на всех кнопках, наблюдается странный артефакт, прерывание срабатывает дважды, не заходя в цикл while. Предполагаю, дребезг кнопки происходит быстрее, чем меняется состояние с LOW на HIGH на PIN, в мониторе выглядит как:
INT - 78 - сработало прерывание, значение переменной а, соотв кнопке
INT - 1023 - сработало прерывание, значение переменной а, что не соответствует ни одной нажатой кнопке
599131 - 1023 - значение millis и значение переменной а, попадаемое в while, не соответвует кнопкам, при этом нажатие кнопки теряется.
Пока не понял, что с этим сделать, возможно кто сможет подсказать? )
в чём сакральная суть необходимости прерывания?
1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.
2. INT - 1023 - и есть "левая" сработка от "дребезга" при ненажатых кнопках.
1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.
неправильно понял и мне не интересно, что ты думаешь о моей стратегии.
зачем ты используешь прерывание?
1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.
неправильно понял и мне не интересно, что ты думаешь о моей стратегии.
зачем ты используешь прерывание?
1. Обращение было к ТС.
2. Прерывание использует ТС.
так шо ты вопросил не того.
1. Обращение было к ТС.
2. Прерывание использует ТС.
так шо ты вопросил не того.
блин. солнце в глаз светит - извини, промахнулся.
в чём сакральная суть необходимости прерывания?
"Многие меня поносят
и теперь, пожалуй, спросят:
глупо так зачем шучу?
Что за дело им? Хочу."
© А.С. Пушкин
1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.
2. INT - 1023 - и есть "левая" сработка от "дребезга" при ненажатых кнопках.
Идея в том, что при срабатывании прерывания, которое срабатывает только при смене HIGH на LOW, оно себя же отключает, подавая на PIN HIGH, вследствии чего на D2 LOW быть не может(до отработки цикла, в котором D2 получает LOW), вне зависимости от сочетания кнопок.
INT - 1023 получается 2м срабатыванием прерывания, которого, в теории, быть не должно.
1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.
2. INT - 1023 - и есть "левая" сработка от "дребезга" при ненажатых кнопках.
Идея в том, что при срабатывании прерывания, которое срабатывает только при смене HIGH на LOW, оно себя же отключает, подавая на PIN HIGH, вследствии чего на D2 LOW быть не может(до отработки цикла, в котором D2 получает LOW), вне зависимости от сочетания кнопок.
INT - 1023 получается 2м срабатыванием прерывания, которого, в теории, быть не должно.
Идея понятна и , безусловно, она нестандартна. Но установка в HIGH на PIN и отстутствие смены HIGH на LOW на А0 - совершенно разные физические процессы. В чем Вы и убедились. Про запрет прерываний почитайте interrups nointerrupsю Возможно этого будет Вам и достаточно.
Но продумайте еще раз сам алгоритм. деДребезг - это убедится что кнопка сменила состояние, а не выждать и принять решение по первой смене состояния как у Вас.
Идея понятна и , безусловно, она нестандартна. Но установка в HIGH на PIN и отстутствие смены HIGH на LOW на А0 - совершенно разные физические процессы. В чем Вы и убедились. Про запрет прерываний почитайте interrups nointerrupsю Возможно этого будет Вам и достаточно.
Но продумайте еще раз сам алгоритм. деДребезг - это убедится что кнопка сменила состояние, а не выждать и принять решение по первой смене состояния как у Вас.
Вопрос не столько в значении А0, сколько в желании понять причину двойного срабатывания прерывания. Отключение прерывания я пробовал, артифакты всплывают заменто чаще при схожей схеме подключения. Сейчас появились мысли, касательно особенности стороения аналоговой части МК, в частности соединение портов D2 A0. Отнесительно дедребезга, мне подходит вариант срабатывая при первой смене состояния с HIGH на LOW на D2
Отнесительно дедребезга, мне подходит вариант срабатывая при первой смене состояния с HIGH на LOW на D2
Тогда зачем так сложно - второй пин, изменение его... Если можно просто поймать изменение и программно игнорить весь дребезг?
А двойное срабатываение прерывания - Вам бы присмотреться что происходит на А0.
Про артефакты при отключении прерываний - видимо Вы не там отключали. Отключение , обычно, первая команда в обработке. Даже теоретически не может появится вторая сработка.
А вот при Вашей схеме, несмотря на "двойную" подтяжку к +5В, на А0 может появится все что угодно. Да и в переходные процессы Вы вглядывались?
Вы вглядывались?
Вглядываться, к сожалению, нечем ((
Про 2й пин, не понял.
Тут же смысл не только обработать прерывание, но и определить какая именно кнопка его вызвала.
Про 2й пин, не понял.
Тут же смысл не только обработать прерывание, но и определить какая именно кнопка его вызвала.
Определение кнопки- одна команда analorRead( A0). Запретил прерывания, посмотрел какая кнопка. Через 250 - разрешил прерывание и готов смотреть дальше. Таков Ваш алгоритм.
Зачем PIN от земли отрывать в HIGH переводить? Я понимаю что это "эквивалент" запрета прерывания, типа жми-не жми на А0 почти +5. Ну.. впрочем причину вроде выяснили. а дисскусия не уверен что нужна :)
Повесьте кондер на А0 - и делов то всех :)
значения кнопок поменялись, но это не критично.
UPD: с D2 резистор можно убрать, артефактов не выявлено.
значения кнопок поменялись, но это не критично.
UPD: с D2 резистор можно убрать, артефактов не выявлено.
В итоге имеем на 4 кнопки = 3 занятых пина, занятое прерывание + внешняя обвеска. Дорого, как по мне :)
В итоге имеем на 4 кнопки = 3 занятых пина, занятое прерывание + внешняя обвеска. Дорого, как по мне :)
Вкл/выкл прерывания я проверю позже, как будет время, возможно с конденсатором и в этой реализации проблем не будет. Сразу могу сказать, что при зажатой кнопке прерывание, предполагаю, может не срабатывать(при его вкл, если оно будет FALLING), если PIN пойдет на землю. Касательно стоимости и задействованых пинов, при определенных номиналах резисторов данную схему можно смаштабировать до большего кол-ва кнопок, при тех же пинах.
А двойное срабатываение прерывания - Вам бы присмотреться что происходит на А0.
Про артефакты при отключении прерываний - видимо Вы не там отключали. Отключение , обычно, первая команда в обработке. Даже теоретически не может появится вторая сработка.
Может. И теоретически, и практически. Механизм прерываний построен на том, что при возникновении события прерывания этот факт фиксируется в соответствующем флаге. Далее если возможна обработка, происходит вызов обработчика и сброс флага. Если в течениии выполнения обработчика сново возникнет прерывание, оно взведет флаг и вызовет повторную обработку. Очевидно при дребезге как раз это и происходит. Поставив конденсатор Вы задавили дребезг аппаратно.
ПС. BoBo4kA, у Вас слишком много дурных идей собралось в одном месте )) Т.е. на кнопках. Толку не будет. Если хочется пооригинальничать - сделайте лучше наколку.
Может. И теоретически, и практически.
Вы, без сомнения, все очень правильно написали о прерываниях, но в алгоритме ТС разрешение прерывания только после обработки клавиши, так что не было бы "артефактного" срабатывания. Потому что вторично попадали бы в обработчик прерывания уже приняв решение по нажатию :)
Но это скорее поозорничать написал, по механизму прерываний, повторюсь - да, обстоит так, как Вы написали :)
но в алгоритме ТС разрешение прерывания только после обработки клавиши, так что не было бы "артефактного" срабатывания.
А вот тут "мужики могут и не знать". Многие либы раеализуют такую логику, перед критическим действием запрещают прерывание, а затем разрешают его. И им плевать что оно сразу было запрещено. Так оно разрешается мимо воли разработчика. Тут надо внимательно код анализировать.