код для КНОПОК - помогите разобраться

Тема в разделе "Микроконтроллеры AVR", создана пользователем Alexandro77, 26 сен 2019.

Метки:
  1. Alexandro77

    Alexandro77 Нуб

    Часто так бывает , кнопки плохо "контачит". В итоге дребезг , шум , итд.
    Хотелось бы написать код для кнопок, простой : без выкрутасов, куча флагов, итд. Но хорошо бы : чтобы без delay() повторного опроса ; чтобы программа не останавливалась на все эти кнопки. А кнопок там много )) - клавиатура .
    кто как делает ? ?

    {
    unsigned long realTime = millis(); ??? Он нужен вообще
     
    Последнее редактирование: 26 сен 2019
  2. parovoZZ

    parovoZZ Гуру

    Всё делается на системном вызове от таймера. Например, кнопки достаточно опрашивать 50 раз в секунду. Никакой антидребезг при этом не нужен. Если кнопок очень много, то тут тоже выкладывались коды обработок. Обсуждалось 100500 раз.
     
  3. Alexandro77

    Alexandro77 Нуб

    Как бы это правильно написать ? для 1 кнопки , пример пожалуйста

    В соседних ветках, нашел только либо ставить кондеры, либо делай , либо milis
     
  4. Daniil

    Daniil Гуру

    к сожалению код пишется под задачу. Нужно надежно/быстро/не нагружая мк/итп тогда надо писать код используя делеи/миллис, куча проверок/итп.
    Одного решения нет.
     
    Alexandro77 нравится это.
  5. b707

    b707 Гуру

    Александр, у вас вчера в первом сообщении был пример кода работы с кнопками. А теперь вы его стерли, почему?
     
  6. b707

    b707 Гуру

    использую код как раз таки с кучей флагов, с миллисом. с повторным опросом (и даже не одним).
    Если у вас получится написать борьбу с дребезгом без всего этого - с интересом посмотрел бы код.
     
    Последнее редактирование: 27 сен 2019
  7. a1000

    a1000 Гуру

    Я использую библиотеку OneButton. В ней предусмотрена обработка трёх видов нажатий: короткое, длинное и длинное с авто повтором. У меня нормально работало с 4 кнопками, больше не пробовал. На форуме есть люди которым эта библиотека не нравится, не знаю - меня устраивает.
     
  8. b707

    b707 Гуру

    если это гиверовская. то, насколько помню, она берет 16 байт оперативки на каждую кнопку. Пока у вас их 4 - это, конечно, незаметно. но у же на 30 кнопок терять только на кнопки четверть всей оперативки ардуино как-то неприлично.
     
  9. a1000

    a1000 Гуру

    Alexandro77 нравится это.
  10. Unixon

    Unixon Оракул Модератор

    Есть простой способ фильтрации дребезга, но при этом нужно разделять собственно опрос кнопок и фильтрацию и запрос состояния кнопок. Опрос ведется постоянно из главного цикла либо по таймеру, внутри процедуры опроса выполняется считывание кнопок с портов МК, считывания метки времени из millis() и фильтрация состояния клавиатуры по заданным задержкам, последнее стабильное состояние запоминается в отдельной переменной. Запрос состояния производится в том месте программы, где требуется знать состояние кнопки и по сути состоит только в считывании этой переменной удобным способом. Фильтрации дребезга выполняется одним из вариантов:
    1) фиксируется первое переключение, после которого вводится задержка, в течение которой повторные переключения игнорируются;
    2) после первого переключения опрос продолжается, но кнопка считается нажатой только если в течение некоторого времени переключений больше не было, т.е. ее "точно нажали", а не "случайно задели";
    Для клавиатуры выполняется оптимизация по памяти: http://forum.amperka.ru/threads/Дребезг-кнопки.6607/#post-101850
     
    SergeiL нравится это.
  11. SergeiL

    SergeiL Оракул Модератор

    А сколько кнопок нужно?
    Про самый быстрый и оптимальный антидребезг было тут.
     
    Alexandro77 нравится это.
  12. Alexandro77

    Alexandro77 Нуб

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

    внизу упростил код , для одной кнопки
    Код (C++):
    START_PIN_flag = false;

    void setup()
    {
    pinMode(START_PIN, INPUT); digitalWrite(START_PIN, LOW);   // кнопка тактовая старт игры , подтянута резистором 10к на землю

    }

    void loop()
    {
      unsigned long realTime = millis();


    if (digitalRead(START_PIN) == HIGH && START_PIN_flag == false)
        {
          START_PIN_flag = true;
          START_PIN_time = realTime;
        }

        if (digitalRead(START_PIN) == LOW && START_PIN_flag && realTime - START_PIN_time > 100 ) // 100 мс на шум от кнопки (  не воспринимать значения)
        {
    // какое либо действие
          digitalWrite(LED, LOW);
    //
          }

    } }
     
    Последнее редактирование: 27 сен 2019
  13. b707

    b707 Гуру

    Александр, переменная START_PIN_time не описана, поправте код, без этого не понятно, как он работает
     
  14. Alexandro77

    Alexandro77 Нуб

    [​IMG]
    Вот как бы , такой алгоритм сделать ( не воспринимать значение шума)? это картинка из библиотеки Bounce . Мой кусок кода , такое не умет , там почему чуток будет игла на входе и хиракс - воспринимает как нажатие (((
     
  15. parovoZZ

    parovoZZ Гуру

    И в чем, собственно, проблема? По первому фронту засекаем таймер на 50 мс. По окончанию отсчета опять считываем значение пина.
     
  16. b707

    b707 Гуру

    собственно, так большинство антидребезгов и работают
     
  17. b707

    b707 Гуру

    Alexandro77 - я вас просил описать переменную STАRT_PIN_time. а вы зачем-то мне картинку выложили
     
  18. ostrov

    ostrov Гуру

    Вот это вставляете, например в loop и оно фигачит каждые 50 мс, в случае события "нажато" возвращает 1.
    Код (C++):
    byte readBut(byte pinBut) {       // вписывается в цикл, возвращает 1 при нажатии
      static byte but[2];
      static uint32_t timerBut = 0;
      if (timerBut > millis()) return;
      but[0] = but[1];
      but[1] = digitalRead(pinBut);
      if (but[0] && !but[1]) {        // нажато!
        return 1;
      }
      timerBut = millis() + 50;
      return 0;
    }
    Перфекционисты могут переделать под решения проблемы 2000 переполнения таймера, ускорить считыванием из порта напрямую и уменьшить группировкой в один байт всех данных
     
    Alexandro77 и issaom нравится это.
  19. parovoZZ

    parovoZZ Гуру

    Много кода. Все решается на прерывании в пару строк. И по факту быстрее работать будет.
     
  20. issaom

    issaom Гуру

    Скинь образец кода что-ли....
     
    SergeiL нравится это.