Аналоговые кнопки на прерывании

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

День добрый!

Так называемые тактовые кнопки всё не дают покоя )

Целью было гарантированное обслуживае кнопок, которое может обеспечить прерывание, но их определнно мало, по сравнению с желаемым кол-вом кнопок.

Изначальная идея запостена в теме кнопок, но та схема, в том виде, не рабочая. Поигрался с разными вариантами, в итоге появилась следующая схема

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, не соответвует кнопкам, при этом нажатие кнопки теряется.

Пока не понял, что с этим сделать, возможно кто сможет подсказать? )

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

в чём сакральная суть необходимости прерывания?

T.Rook
Offline
Зарегистрирован: 05.03.2016

1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.

2. INT - 1023  - и есть "левая" сработка от "дребезга" при ненажатых кнопках.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

T.Rook пишет:

1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.

неправильно понял и мне не интересно, что ты думаешь о моей стратегии.

зачем ты используешь прерывание?

T.Rook
Offline
Зарегистрирован: 05.03.2016

Клапауций 112 пишет:

T.Rook пишет:

1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.

неправильно понял и мне не интересно, что ты думаешь о моей стратегии.

зачем ты используешь прерывание?

1. Обращение было к ТС.

2. Прерывание использует ТС.

так шо ты вопросил не того.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

T.Rook пишет:

1. Обращение было к ТС.

2. Прерывание использует ТС.

так шо ты вопросил не того.

блин. солнце в глаз светит - извини, промахнулся.

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

Клапауций 112 пишет:

в чём сакральная суть необходимости прерывания?

"Многие меня поносят
и теперь, пожалуй, спросят:
глупо так зачем шучу?
Что за дело им? Хочу."
© А.С. Пушкин

 

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

T.Rook пишет:

1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.

2. INT - 1023  - и есть "левая" сработка от "дребезга" при ненажатых кнопках.

Идея в том, что при срабатывании прерывания, которое срабатывает только при смене HIGH на LOW, оно себя же отключает, подавая на PIN HIGH, вследствии чего на D2 LOW быть не может(до отработки цикла, в котором D2 получает LOW), вне зависимости от сочетания кнопок.

INT - 1023 получается 2м срабатыванием прерывания, которого, в теории, быть не должно.

T.Rook
Offline
Зарегистрирован: 05.03.2016

BoBo4kA пишет:

T.Rook пишет:

1. Если я Вас правильно понял, то Ваша стратегия "исключения дребезга" - сработка по первому фронту и игнорирование всего остального. Что , по меньшей мере, спорно.

2. INT - 1023  - и есть "левая" сработка от "дребезга" при ненажатых кнопках.

Идея в том, что при срабатывании прерывания, которое срабатывает только при смене HIGH на LOW, оно себя же отключает, подавая на PIN HIGH, вследствии чего на D2 LOW быть не может(до отработки цикла, в котором D2 получает LOW), вне зависимости от сочетания кнопок.

INT - 1023 получается 2м срабатыванием прерывания, которого, в теории, быть не должно.

Идея понятна и , безусловно, она  нестандартна. Но установка в HIGH на PIN и отстутствие смены  HIGH на LOW на А0 - совершенно разные физические процессы. В чем Вы и убедились. Про запрет прерываний почитайте interrups nointerrupsю Возможно этого будет Вам и достаточно.

Но продумайте еще раз сам алгоритм. деДребезг - это убедится что кнопка сменила состояние, а не выждать и принять решение по первой смене состояния как у Вас. 

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

T.Rook пишет:

Идея понятна и , безусловно, она  нестандартна. Но установка в HIGH на PIN и отстутствие смены  HIGH на LOW на А0 - совершенно разные физические процессы. В чем Вы и убедились. Про запрет прерываний почитайте interrups nointerrupsю Возможно этого будет Вам и достаточно.

Но продумайте еще раз сам алгоритм. деДребезг - это убедится что кнопка сменила состояние, а не выждать и принять решение по первой смене состояния как у Вас. 

Вопрос не столько в значении А0, сколько в желании понять причину двойного срабатывания прерывания. Отключение прерывания я пробовал, артифакты всплывают заменто чаще при схожей схеме подключения. Сейчас появились мысли, касательно особенности стороения аналоговой части МК, в частности соединение портов D2 A0. Отнесительно дедребезга, мне подходит вариант срабатывая при первой смене состояния с HIGH на  LOW на D2

T.Rook
Offline
Зарегистрирован: 05.03.2016

BoBo4kA пишет:

 Отнесительно дедребезга, мне подходит вариант срабатывая при первой смене состояния с HIGH на  LOW на D2

Тогда зачем так сложно - второй пин, изменение его... Если можно просто поймать изменение и программно игнорить весь дребезг?

А двойное срабатываение прерывания - Вам бы присмотреться что происходит на А0.

Про артефакты при отключении прерываний - видимо Вы не там отключали. Отключение , обычно,  первая команда в обработке. Даже теоретически не может появится вторая сработка.

А вот при Вашей схеме, несмотря на "двойную" подтяжку к +5В, на А0 может появится все что угодно. Да и в переходные процессы Вы вглядывались?

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

T.Rook пишет:

Вы вглядывались?

Вглядываться, к сожалению, нечем ((

Про 2й пин, не понял.

Тут же смысл не только обработать прерывание, но и определить какая именно кнопка его вызвала.

T.Rook
Offline
Зарегистрирован: 05.03.2016

BoBo4kA пишет:

Про 2й пин, не понял.

Тут же смысл не только обработать прерывание, но и определить какая именно кнопка его вызвала.

Определение кнопки- одна команда analorRead( A0). Запретил прерывания, посмотрел какая кнопка. Через 250 - разрешил прерывание и готов смотреть дальше. Таков Ваш алгоритм.

Зачем PIN от земли отрывать в HIGH переводить? Я понимаю что это "эквивалент" запрета прерывания, типа жми-не жми на А0 почти +5. Ну.. впрочем причину вроде выяснили. а дисскусия не уверен что нужна :)

Повесьте кондер на А0 - и делов то всех :)

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

Просто конденсатор проблему не решил, вот такой вариант работает без артефактов. Доп резисторы по 1к, конденсатор 1мкФ (что под рукой было)

значения кнопок поменялись, но это не критично.

 

UPD: с D2 резистор можно убрать, артефактов не выявлено.

T.Rook
Offline
Зарегистрирован: 05.03.2016

BoBo4kA пишет:

Просто конденсатор проблему не решил, вот такой вариант работает без артефактов. Доп резисторы по 1к, конденсатор 1мкФ (что под рукой было)

значения кнопок поменялись, но это не критично.

 

UPD: с D2 резистор можно убрать, артефактов не выявлено.

В итоге имеем на 4 кнопки = 3 занятых пина, занятое прерывание + внешняя обвеска. Дорого, как по мне :)

 

BoBo4kA
Offline
Зарегистрирован: 15.01.2016

T.Rook пишет:

В итоге имеем на 4 кнопки = 3 занятых пина, занятое прерывание + внешняя обвеска. Дорого, как по мне :)

Вкл/выкл прерывания я проверю позже, как будет время, возможно с конденсатором и в этой реализации проблем не будет. Сразу могу сказать, что при зажатой кнопке прерывание, предполагаю, может не срабатывать(при его вкл, если оно будет FALLING), если PIN пойдет на землю. Касательно стоимости и задействованых пинов, при определенных номиналах резисторов данную схему можно смаштабировать до большего кол-ва кнопок, при тех же пинах.

Logik
Offline
Зарегистрирован: 05.08.2014

T.Rook пишет:

А двойное срабатываение прерывания - Вам бы присмотреться что происходит на А0.

Про артефакты при отключении прерываний - видимо Вы не там отключали. Отключение , обычно,  первая команда в обработке. Даже теоретически не может появится вторая сработка.

Может. И теоретически, и практически. Механизм прерываний построен на том, что при возникновении события прерывания этот факт фиксируется в соответствующем флаге. Далее если возможна обработка, происходит вызов обработчика и сброс флага. Если в течениии выполнения обработчика сново возникнет прерывание, оно взведет флаг и вызовет повторную обработку. Очевидно при дребезге как раз это и происходит. Поставив конденсатор Вы задавили дребезг аппаратно.

ПС. BoBo4kA, у Вас слишком много дурных идей собралось в одном месте )) Т.е. на кнопках. Толку не будет. Если хочется пооригинальничать - сделайте лучше наколку. 

T.Rook
Offline
Зарегистрирован: 05.03.2016

Logik пишет:

Может. И теоретически, и практически.

Вы, без сомнения, все очень правильно написали о прерываниях, но в алгоритме ТС разрешение прерывания только после обработки клавиши, так что не было бы "артефактного" срабатывания.  Потому что вторично  попадали бы в обработчик прерывания  уже приняв решение по нажатию :)

Но это скорее поозорничать написал, по механизму прерываний, повторюсь - да, обстоит так, как Вы написали :)

Logik
Offline
Зарегистрирован: 05.08.2014

T.Rook пишет:

 но в алгоритме ТС разрешение прерывания только после обработки клавиши, так что не было бы "артефактного" срабатывания. 

А вот тут "мужики могут и не знать". Многие либы раеализуют такую логику, перед критическим действием запрещают прерывание, а затем разрешают его. И им плевать что оно сразу было запрещено. Так оно разрешается мимо воли разработчика. Тут надо внимательно код анализировать.