Борьба с дребезгом кнопок.

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Здравствуйте!
Меня зовут Андрей!
Я преподаватель, мы с ребятами пытаемся сделать проект на конкурс кансат.
И у нас возник вопрос о аппаратной борьбе с дребезгом, т.к. проект сложный и лишний раз не хочется усложнять код.
Во вторых есть опасение, что нам не хватит памяти. По условию соревнований мы используем плату ардуино микро.
Что мы пробовали:
1. У Александра есть пример в уроке про кнопку. https://alexgyver.ru/lessons/arduino-buttons/
2. Дребезг контактов и как с ним бороться - https://radioprog.ru/post/251
И еще несколько похожих статей, но везде в общем одно и тоже, только номиналы чуть отличаются.
Схема подключения такая:
https://alexgyver.ru/wp-content/uploads/2020/08/debounce-sch.jpg

Мои номианалы:
R = 10kOm
C = 100nF

Использовался вот такой код.
C++:
bool flag1 = 0;
bool flag2 = 0;

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
 }

void loop()
{
  //digitalWrite(12,1);
 
 bool btnState1 = !digitalRead(8);
  bool btnState2 = !digitalRead(9);
 
  if (btnState1 )
  {
    flag1 = !flag1;
  }
 
  if (btnState2 )
  {
    flag2 = !flag2;
  }
 
  if(flag1)
    { 
      digitalWrite(13,1 );
    }
    else if(!flag1)
    {
      digitalWrite(13,0 );
    }
 
    if(flag2)
    { 
      digitalWrite(12,1 );
    }
    else if(!flag2)
    {
      digitalWrite(12,0 );
    }
}
Результат на макетке с Ардуиной Уно оказался забавным - светодиоды при нажатии загораются, при отпускании тухнут.
Но! Если нажать на одну кнопку то по нажатию на другую срабатывает...
Если убрать конденсатор, то работает как и должно без защит от дребезга.
Я к сожалению еще не разобрался как работает эта схема и не могу понять что нужно менять - номинал резистора или конденсатора, или код ...
Буду благодарен за любую подсказку!
 

bort707

★★★★★★✩
21 Сен 2020
3,066
914
делайте программно, всего-то. что нужно - подождать 10-20мс после нажатия перед считыванием. Если оформить в виде библиотеки - памяти на это уйдет минимум
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
делайте программно, всего-то. что нужно - подождать 10-20мс после нажатия перед считыванием. Если оформить в виде библиотеки - памяти на это уйдет минимум
К стати о программном варианте...
почему-то нормально срабатывает только при 200 мс. Везде говорят о 20-50мс.
Может я и тут не правильно делаю?
C++:
unsigned long Timer1;
unsigned long Timer2;
bool ledState = 0;
bool flag1 = 0;
bool flag2 = 0;

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(8,INPUT_PULLUP);
  pinMode(9,INPUT_PULLUP);
 
}

void loop()
{
  //digitalWrite(12,1);
 
 bool btnState1 = !digitalRead(8);
  bool btnState2 = !digitalRead(9);
 
  if (btnState1 && millis() - Timer1 > 200)
  {
    flag1 = !flag1;
    Timer1 = millis();
    //Serial.println("press");
  }
 
  if (btnState2 && millis() - Timer2 > 200)
  {
    flag2 = !flag2;
    Timer2 = millis();
    //Serial.println("press");
  }
 
  if(flag1)
    { 
      digitalWrite(13,1 );
    }
    else if(!flag1)
    {
      digitalWrite(13,0 );
    }
 
    if(flag2)
    { 
      digitalWrite(12,1 );
    }
    else if(!flag2)
    {
      digitalWrite(12,0 );
    }
    
}
Но вообще, очень хочется разобраться. Как оно аппаратно работает...
Тема то нужная...
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
Но! Если нажать на одну кнопку то по нажатию на другую срабатывает...
Поясните, что Вы имеете в виду?
А вообще... В коде ошибка! Вы, извините, новичок что ли? Как преподаватель может этого не видеть?
 

bort707

★★★★★★✩
21 Сен 2020
3,066
914
Может я и тут не правильно делаю?
конечно неправильно. Условий на каждую кнопку должно быть минимум два - первое просто на нажатие. В нем запоминаем время.
Второе условие - спустя 20мс. Если прошло 20мс с первого нажатия и кнопка все еще нажата - значит считаем нажатие настоящим, а не дребезгом.
А вы там накрутили каких-то флагов, диодов. две кнопки... а сам код неверный, вы в первом же условии пытаетесь считывать и кнопку и таймер

вы начните с простого - одна кнопка и все.
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Поясните, что Вы имеете в виду?
А вообще... В коде ошибка! Вы, извините, новичок что ли? Как преподаватель может этого не видеть?
Если нажать на одну кнопку и удерживать, то по нажатию на вторую светодиод загорается.
Да, к сожалению не вижу ошибку, укажите пожалуйста где конкретно...
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@bort707, да там вообще логика страдает. Похоже, это ученик, а не преподаватель.

@prohor-nastya, а надо? На этом сайте есть несколько уроков по кнопкам. Если совсем лень - посмотрите любую библиотеку, обрабатывающую кнопки. Любую! Там все "методы" описаны 100500 раз!

А по поводу ошибки...
Вот нажали Вы, допустим, первую кнопку, btnState1 стал true, flag1 стал true, на 13-ом пине появилось 5В. Дальше loop стал выполняться заново. btnState1 остался true (кнопку-то Вы не отпустили за микросекунду), flag1 стал false, 13 пин выключился...
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,066
914
возьмите за пример любую библиотеку кнопок и разберитесь, как она работает.
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
С программным вариантом вообще нет проблем. Уже разобрался...
Вопрос только с аппаратным...
 

bort707

★★★★★★✩
21 Сен 2020
3,066
914
С программным вариантом вообще нет проблем. Уже разобрался...
Вопрос только с аппаратным...
аппаратный без верного кода тоже работать не будет. А у вас какая-то ерунда накручена.
Если разобрались с программным - выкладывайте правильный код для аппаратного, будем разбираться.
 
Изменено:

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Да, проблема была в коде. С номиналами С - 100nF & R - 10KOm все прекрасно работает. В тестах дребезг устраняет на 100%.
Но собственно вопрос то остался... как работает эта RC цепочка и какова зависимость ее работы от номиналов...
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
Но собственно вопрос то остался... как работает эта RC цепочка и какова зависимость ее работы от номиналов...
Смотрите здесь. Для понимания работы нужно разобраться (Вам, я-то знаю), для чего применена команда, например,
pinMode(8,INPUT_PULLUP);
Количество элементов в рассмотрении несколько возрастает, но смысл может быть понятен и из общего объяснения RC-цепи. Чем больше R и C, тем больше "время ожидания", своего рода задержка переключения состояния входа. Примерное время реакции на ступеньку "нажатие" можно посчитать перемножив R и C, для выбранных значений оно будет равно 10^4 * 10^(-7) = 1мс. Так как у нас периодический процесс, то время срабатывания при изменении состояния кнопки нужно умножить на 2. При отпускании в процесс добавляется резистор pull-up и расчёт совсем немного усложняется, предлагаю найти его Вам самому, результат будет примерно 8мс.
 
  • Лойс +1
Реакции: prohor-nastya

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Добрый день!
Получается принцип работы такой - при замыкании контакта кнопки конденсатор разряжаясь (в течении очень короткого времени) подпирает напряжение на кнопке и оно возрастает по кривой что позволяет контроллеру определить высокий сигнал когда кривая перейдет значение 3В. При отпускании кнопки происходит тоже, но в обратном направлении, И время заряда уже определяется номиналом конденсатора и резистора PULLUP. Номиналы по сути определяются техническими характеристиками самой кнопки. У разных типов кнопок разное устройство и разные материалы, что определяет время дребезга. Соответственно сначала нужно исследовать кнопку какой у нее дребезг, по времени, а потом рассчитывать номиналы RC цепи чтобы разряд - заряд конденсатора был дольше дребезжания контакта. Поправьте пожалуйста, если чего не так.
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@prohor-nastya, всё так, только напряжение "подпирается" на выводе Ардуино, уменьшаясь из-за разряда конденсатора через внешний резистор по закону, напоминающему перевёрнутую экспоненту при нажатии на кнопку и увеличиваясь при зарядке через резистор pull up.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,267
1,303
Москва
Я чего то не понимаю... ведь время заряда конденсатора можно оценить..
t=RC
при =10000*0.0001=1 , что очень много для кнопки. А вот если взять 1 мкф, то получиться уже 0.01 (10мс) сек, что вполне себе приятно.
 

poty

★★★★★★✩
19 Фев 2020
3,237
942
@Старик Похабыч, конденсатор у автора взят 100нФ (100 на 10 в минус девятой степени). А в Ваших расчетах поставлен 100мкФ (100 на 10 в минус шестой степени).
 

ТехнарьКто

★★★★★✩✩
13 Янв 2020
270
438
И у нас возник вопрос о аппаратной борьбе с дребезгом, т.к. проект сложный и лишний раз не хочется усложнять код.
Схема круглого модуля.
enc_scheme.jpg
Поскольку в скетче использован PULLUP, R3 не нужен.
Итого, схема с этого сайта.
Qu.jpg