Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: Обработка нажатия кнопки в AVR...

Пт янв 11, 2019 11:21:24

BOB51 писал(а):Как под Си...
так же, как и у пчёлок :)))

Re: Обработка нажатия кнопки в AVR...

Пт янв 11, 2019 15:19:39

Необходим алгоритм для определения последней устойчивой КОМБИНАЦИИ нажатых/активных кнопок, а не "поштучное" оценивание каждой кнопы в отдельности.
8)
Без схемотехники кноп затруднительно подсказать...
:dont_know:

Кнопки нажимаются на землю, подтянуты внутренними резисторами МК к питанию. Вот по поводу алгоритма как раз и тупняк. На асме когда писал, все получалось, на Сях туго идет.
Вот имеется прерывание, ну не совсем так конечно, итог работы этого прерывания - флаг разрешения опроса опроса кнопок, который выставляется через каждые 50мс. Получается мне надо считать все кнопки в одну переменную и куда-то положить это, а уже в следующем прерывании считать снова и сравнить с предыдущем результатом и выплюнуть статус кнопок в виде возвращаемого значения функции? Но уберет ли это дребезг? Антидребезг это ведь не просто опрос через определенный интервал, тут логика нужна. Я перед тем как написать поизучал и попробовал несколько алгоритмов. Специально для проверки написал конечный автомат - переключалку светодиода, по его работе очень хорошо видно что бывает, когда алгоритм кривой.

ARV писал(а):по-моему, надо просто убрать все флаги и тупо выполнять в switch-е нужное действие по коду нажатой кнопки. в этом случае надо учитывать и комбинации нажатых кнопок. при необходимости после switch-а дожидаться отпускания кнопок.

Здравствуйте, Роман! Я так пробовал, убираешь флаги светодиоды начинают переключаться и не очень четко (см. про переключалку выше) с каждым новом заходом в опрос кнопок. Ведь у меня алгоритм такой, что я при первом нажатии что-то делаю, а потом выставляю флаг, что дело сделано и если что-то на линии - это дребезг, а интервала от первого "круга" до второго 50мс как раз хватает понять, дребезг или нет. В общем по вашему совету в дефолте свитча сейчас добавил условие: если переменная с кнопками равна нулю, то сбрасываем все флаги, иначе выставляем все флаги принудительно. Выглядит так, работает четко. Но я чувствую, что алгоритм кривой...
Код:
void buttons (void)
{
   btns=~PIND; //читаем PIND в переменную и инвертируем прочитанное
   btns=btns&((1<<BTN1)|(1<<BTN2)|(1<<BTN3)); //отсекаем лишние разряды, оставляем только кнопки

   switch(btns)
   {
      case (1<<BTN1): //если нажата кнопка 1
        if(~flags&(1<<BTN1)) //если флаг первой кнопки не установлен, то
           {
              flags|=(1<<BTN1); //устанавливаем флаг
            toggle(RED); //что-то делаем
         }   
          break; //и на выход

      case (1<<BTN2): //если нажата кнопка 2
        if(~flags&(1<<BTN2)) //если флаг второй кнопки не установлен, то
          {
               flags|=(1<<BTN2); //устанавливаем флаг
            toggle(YELLOW); //что-то делаем
          }
         break; //и на выход

      case (1<<BTN3): //если нажата кнопка 3
        if (~flags&(1<<BTN3)) //если флаг третьей кнопки не установлен, то
               {
            flags|=(1<<BTN3); //устанавливаем флаг
            toggle(GREEN); //что-то делаем
          }
       break; //и на выход

      default: //если не нажата ни одна кнопка или любая другая комбинация
        if (btns==0)
         {
          flags=0; //сбрасываем все флаги
              }
        else
         {
         flags=(1<<BTN1)|(1<<BTN2)|(1<<BTN3); //выставляем все флаги
         }
       break; //и на выход
   }
   keys=0; //сбрасываем флаг разрешения опроса кнопок
}

Господа, большое спасибо за помощь! А то я в дефолте уже пытался еще один свитч нагородить... В общем получились четкие однократные "бабушкины" кнопки, что и хотел!

Re: Опрос кнопок микроконтроллером

Пт янв 11, 2019 18:19:15

Вариант кнопы на адурине (вобщем тот же Си) - учебно-тренировочный проект.
max72t3.rar
(54.83 KiB) Скачиваний: 518

Антидребезг плюс смена функционала (секундомер - пуск-стоп-сброс)
То же на switch и флагах но в режиме поллинга, а не по прерыванию.
:dont_know:

Re: Опрос кнопок микроконтроллером

Пт янв 11, 2019 18:41:28

Вариант кнопы на адурине (вобщем тот же Си) - учебно-тренировочный проект.

Спасибо, сохранил себе в коллекцию примеров.
Возможно кому-нибудь пригодится, раз зашел разговор про Ардуино, вот тут неплохой материал, в итоге автор создает класс на плюсах для работы с кнопкой.

Re: Опрос кнопок микроконтроллером

Пт янв 11, 2019 23:47:23

Да нормально убирает дребезг опрос с интервалом. Верней, работа кнопки перестаёт зависеть от дребезга. Если мозгами пораскинуть - когда опрос приходится на отсутствующий дребезг т.е. или точно нажата или точно отпущена у нас проблем нет никаких, а вот когда опрашиваем в момент дребезга - появляется неопределённость кнопка может считаться нажатой или отпущеной - одно из двух, и эта неопределённость не страшна сама по себе, ведь мы знаем если движение толкателя кнопки начато то к следующему опросу оно точно закончится и дребезг гарантированно пройдет. Страшно становится когда мы после первого чтения сразу же читаем второй раз, и попадаем скорей всего на тот же дребезг и ту же неопределённость, и вот тут начинается веселье - в первое чтение мы видим что кнопка нажата, второе - отпущена, регистрируем клик... потом ещё один, пятый десятый... и всё это менее чем за 1мс. Но если между чтением кнопки мы выдерживаем интервал НЕ МЕНЕЕ чем длится дребезг кнопки, то мы можем быть уверены что второе чтение точно не попадёт на дребезг, несмотря на момент первого чтения - приходился он на начало дребезга или конец... в худшем случае, если считываем в момент дребезга и выпадает состояние "отпущена" мы зарегистрируем кнопку следующим опросом, когда точно дребезга уже не будет.

Re: Опрос кнопок микроконтроллером

Пн фев 18, 2019 08:45:05

Дабы не плодить новой темы про энкодер, задам вопрос сюда, ибо энкодер, это те же кнопки :)

Подскажите, нужен ли триггер шмитта для подключения энкодера к МК? Я поставил RC фильтры для устранения дребезга, но фронты сигналов от этого стали не вертикальными.
Собственно нужен ли для восстановления фронта триггер шмитта или это "масло маслянное" и в МК уже все на входе есть?

P.S. МК AVR.

Re: Опрос кнопок микроконтроллером

Пн фев 18, 2019 10:17:55

Триггер Шмитта не нужен, а вот резистор подтяжки примерно 1...2к здорово помогает от дребезга.
Так работает энкодер со встроенными подтяжками

Так работает тот же энкодер с внешними подтяжками
Вложения
Валкодер3.PNG
(122.38 KiB) Скачиваний: 974
valcoder 001_1.jpg
(46.79 KiB) Скачиваний: 931

Re: Опрос кнопок микроконтроллером

Пн фев 18, 2019 11:28:30

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

Re: Опрос кнопок микроконтроллером

Чт мар 14, 2019 16:32:35

Появилась надобность в алгоритме опроса кнопок, чтобы он умел отслеживать короткие и длинные нажатия. При этом не использовать тупых задержек, а опрос кнопок вести по прерыванию от таймера с частотой 100 Гц. У меня с наскока победить не удалось. То короткие нажатия хорошо ловит, но не ловит длинные, то наоборот. Начал уже на бумаге алгоритмы накидывать, но все получается какое-то корявое.
Сегодня случайно нашел нарисованный алгоритм, реализовал его в коде, но и он не пашет.
Оригинал.
Изображение
Стал внимательно изучать, и что-то мне кажется, с ним не все гладко и есть ошибки. Помогите довести алгоритм до ума!
Изображение

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

Re: Опрос кнопок микроконтроллером

Чт мар 14, 2019 18:11:37

вы сформулируйте, что такое длинные и короткие нажатия.
я вот понимаю короткое нажатие это просто нажатие, а долгое - это автоповтор нажатой кнопки. однако, бывают случаи, когда код нажатой на 0,1 сек кнопуи и код нажатой на 1,5 сек кнопки должны отличаться. соответственно, и алгоритмы разные...

Re: Опрос кнопок микроконтроллером

Чт мар 14, 2019 19:11:27

Короткое - это клик кнопкой. С учетом подавления дребезга, как на картинке, пусть будет 100мс. Длинное нажатие - 2 секунды.
Судя по картинке с алгоритмом, короткое нажатие там выставляется b1 минимум через 200 мс. Вначале считаем 100 мс при нажатой кнопке и выставляется бит b0. А затем после отпускания кнопки, на количество тиков в первом счетчике. А там их может быть вплоть до времени длительного нажатия. Это снижает реакцию системы на следующее нажатие. Это второй ошибочный, на мой взгляд, момент в этом алгоритме. Надо по-другому: проверять при отпускании кнопки бит b0 и счетчик1. Если оба имеют не нулевые значения, то считать коротким нажатием.

Re: Опрос кнопок микроконтроллером

Чт мар 14, 2019 20:50:58

Там защита от дребезга уже не нужна. Сам опрос каждые 10мс и есть защита от дребезга для кнопок с дребезгом меньше 10мс. В чем смысл алгоритма? Считайте прерывания, отслеживайте отпускание кнопки - если оно произошло до того как счетчик досчитает до 250 - значит это короткое, если счетчик досчитает 250 - регистрировать как длинное и ждать отпускание кнопки. После отпускания сбросить счетчик времени нажатия.

Re: Опрос кнопок микроконтроллером

Чт мар 14, 2019 21:00:36

соответственно, и алгоритмы разные...

На мой дилетантский взгляд, с точки зрения опроса кнопок, алгоритм ничем не отличается. В данном конкретном случае надо отслеживать два типа событий: длинное нажатие на кнопку и короткое.
А каким образом эти события будут дальше в программе обрабатываться, на суть алгоритма не влияет.
Alexeyslav писал(а):Сам опрос каждые 10мс и есть защита от дребезга

Не уверен в этом. По крайней мере надо будет отслеживать в данном случае отличается ли код кнопки через 10 мс от предыдущего. Дребезги всякие бывают.
Ранее, когда делал защиту от дребезга на задержках, наиболее стабильно отслеживался клик после паузы в 100 мс с несколькими промежуточными проверками кнопки. При 50 мс я ловил ложные срабатывания.

Re: Опрос кнопок микроконтроллером

Чт мар 14, 2019 22:04:25

Кнопка которая брынчит на 50мс - надо выкидывать. Может конечно это и не дребезг у ней вовсе, а особенность конструкции когда происходит разрыв контакта при сильном нажатии. В любом случае таким низкокачественным конопкам место в мусорном ведре. Но если хочется такие кнопки всё же использовать, ставь скорость 10 опросов в секунду всеравно надежно различить нажатие такой кнопки будет трудно с большей скорсотью, но это уже добавит дискомфорт в пользование устройством и будет ужаснейшим решением с точки зрения пользовательского опыта. Проще кнопки поменять.
Отслеживать состояние кнопок проще простого - заводишь их всех в регистр, сравниваешь функцией XOR с предыдущим состоянием и там где остаётся "1" - значит в тех кнопках произошли изменения а какие это изменения узнаёшь с текущего состояния - "1" значит произошло нажатие "0" - отпускание.
Досихпор эта логика не давала сбоев при исправных кнопках.

Re: Опрос кнопок микроконтроллером

Пт мар 15, 2019 08:53:22

заводишь их всех в регистр, сравниваешь функцией XOR с предыдущим состоянием

Интересный метод. С точки зрения логики красивый, можно отслеживать одновременное нажатие кнопок. Но практически я такой реализации нигде не встречал, и сам не делал, естественно. Надо обмозговать.

Добавлено after 31 minute 53 seconds:
Переделал алгоритм в соответствии с моими размышлениями здесь https://radiokot.ru/forum/viewtopic.php ... 8#p3591468
и все заработало. dec Сч1 - это зло

Re: Опрос кнопок микроконтроллером

Пт мар 15, 2019 09:00:38

я опрашиваю матричную клавиатуру по таймеру каждые 50 мс (для борьбы с дребезгом) и вызываю вот такую функцию:
Код:
static void key_repeater(char kk){
   MAKE_TIMER(TR, 0, 0);
   static char old_kk;

   if(kk == 0){
      timer_stop(&TR);
   } else {
      if(old_kk != kk){
         timer_start(&TR, 1000, 0);
         put_message(QUEUE, MSG_KEY, kk, 0);
      } else {
         if(timeout(&TR)){
            timer_start(&TR, 300, 0);
            put_message(QUEUE, MSG_KEY, kk, 0);
         }
      }
   }
   old_kk = kk;
}
тут я применяю программный таймер TR и очередь сообщений, через которую моя программа узнает о том, что кнопка нажата (т.е. как бы опроса нет, есть обработка события "кнопка нажата").

алгоритм должен легко просмариваться по коду.
если символ kk равен 0 - это значит, не нажата ни одна кнопка, в этом случае таймер TR останавливается и все.
если же символ не нулевой, то происходит сравнение его с тем значением, что было при предыдущем вызове функции.
если они разные, значит, обнаружено первичное нажаие кнопки (клик). в этом случае запускается таймера на период 1 сек и посылается сообщение в очередь с кодом кнопки.
если предыдущее и текущее значение символа одинаковы, то сообщение посылается только посл истечения таймера, причем в этом случае он заново переустанавливается на интервал 300 мс.

в итоге имеем:
1. реакцию на однократное нажатие - клик
2. реакция на долгое удержание: после 1 сек удержания начинается автоповтор кода 3 раза в секунду.

Re: Опрос кнопок микроконтроллером

Сб мар 30, 2019 07:34:15

А я борюсь с дребезгом контактов посредством интегратора с последующим триггером Шмитта. Точнее, их упрощенной программной моделью. Как правильно аппаратно обрабатывать плохой контакт (дребезжащую кнопку, скользящий контакт энкодера) ? Ставим интегратор, за ним триггер Шмитта. По нажатию кнопки интегратор начинает заряжаться. Размыкание кнопки запускает обратный процесс - разряд интегратора. Если это происходит в процессе дребезга, то на кривой напряжения на интеграторе появляется зубец, но (при нажатой кнопке) общая тенденция - все-таки нарастание сигнала. Когда это напряжение дойдет до порога срабатывания ТШ, пойдет сигнал "кнопка нажата" Порог отпускания ТШ должен быть существенно ниже размаха зубцов от дребезга. Когда кнопу отпустят, начинается разряд интегратора, если и там присутствует дребезг, опять же будут зубцы, но порог ниже, обратное переключение произойдет только когда интегратор разрядится до порога отпускания ТШ. Скорости заряда и разряда можно выбрать разные, зависит от поведения конкретных контактов.

Использую прерывания по таймеру, довольно частые - 1-10 кГц (100-1000 мкс). Для каждой кнопки использую одну байтовую целочисленную переменную (элемент массива). Получив очередное таймерное прерывание, смотрю замкнут ли какой контакт. Если да, прибавляю к его переменной константу нарастания, если нет - вычитаю из нее константу убывания. Потом сравниваю полученный результат с порогами срабатывания и отпускания, по ним перехожу в состояния "кнопка нажата" или "кнопка отпущена". Да, надо не забыть про насыщение интегратора, т.е., когда число в переменной для кнопки превысит "потолок интегратора", туда надо переслать этот потолок. Ну, и про насыщение снизу не забыть, если число в этой переменной станет отрицательным, переслать туда ноль.

Таким образом, на каждый контакт (группу одинаковых контактов) нужны три константы: "потолок" интегратора, порог срабатывания ТШ и порог отпускания ТШ. Ну, и четвертый - частота прерываний по таймеру. В общем-то, разглядывая осциллограммы замыкания-размыкания контактов, можно рассчитать подходящие значения этих констант, но я их, обычно, просто подбираю.

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

Re: Опрос кнопок микроконтроллером

Сб мар 30, 2019 08:55:11

Возможно, для каких-то особо ужасных кнопок это и имеет смысл, но выглядит как-то уж слишком ресурсоемко. И кто принуждает применять убитые энкодеры?!

Re: Опрос кнопок микроконтроллером

Сб мар 30, 2019 19:27:52

ARV писал(а):Возможно, для каких-то особо ужасных кнопок это и имеет смысл,
Вообще-то этот алгоритм я сочинил для обработки номеронабирателей дисковых телефонов, где-то в начале 90-х. Реализовано это было на ДВК (наша микро-ЭВМ по мотивам PDP-11). Там это была необходимость, а для энкодеров на АВР я его применил, как говорит молодежь, по приколу: увидел осциллограммы того убитого энкодера и вспомнил, что нечто подобное я видел на тех телефонах. Ну, и принял вызов. :)

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

ARV писал(а):И кто принуждает применять убитые энкодеры?!
Вообще-то эти китайские контактные энкодеры при более-менее интенсивной эксплуатации выходят из строя довольно быстро. И, если использовать этот алгоритм, менять их придется намного реже. :)

Re: Опрос кнопок микроконтроллером

Ср апр 10, 2019 21:56:18

Сегодня случайно нашел нарисованный алгоритм, реализовал его в коде, но и он не пашет.
Привет
Разобрался с алгоритмом?
Это мой алгоритм, я его рисовал еще во времена ассемблера, поэтому там все так мутно)
Если что могу скинуть реализацию на си как раз основанную на этом алгоритме...
Ответить