Не получается устранить дребезг с помощью триггера Шмитта

Уберите HC, подключите только энкодер с подтяжкой, проверьте на готовой библиотеке(да хоть Гайверовской GitHub - GyverLibs/EncButton: Лёгкая и очень функциональная библиотека для энкодера с кнопкой, энкодера или кнопки с Arduino). Хоть поймёте где у вас беда.

1 лайк

Насколько я понял схему, пины энкодера и кнопок у вас подтянуты к +5в.
Однако, из скетча следует, что активный уровень HIGH.
Так и не будет нормально работать.
Объявите прерывания FALLING, активную кнопку(пин энкодера) читайте
так(активный уровень LOW)

  if (!digitalRead (pin_enc_setup_B)) {enc_temp_val++;}

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

1 лайк

Согласен с @andriano (предыдущая реплика), но чисто в плане борьбы с дребезгом, вот изучите. Там и программные и аппаратные средства рассматриваются. Очень хорошая статья.

Евгений, спасибо! Обязательно ознакомлюсь. Глянул “по диагонали” - похоже, то, что надо в полном объеме.

Согласно рекомендациям, попробовал применить библиотеку от Гайвера. Скетч “demo“ заработал сразу и без каких-либо затыков. С одним энкодером все четко отрабатывается (и кнопка и повороты). Наверное, возьму на вооружение. Но есть вопрос (не нашел, как сделать): мне надо подключить три энкодера. Где в скетче надо изменить, чтобы библиотека работала с тремя “крутилками“? Или направьте в нужную ссылку. Заранее спасибо!

// Демо.
#include <Arduino.h>
// #define EB_NO_FOR           // отключить поддержку pressFor/holdFor/stepFor и счётчик степов (экономит 2 байта оперативки)
// #define EB_NO_CALLBACK      // отключить обработчик событий attach (экономит 2 байта оперативки)
// #define EB_NO_COUNTER       // отключить счётчик энкодера (экономит 4 байта оперативки)
// #define EB_NO_BUFFER        // отключить буферизацию энкодера (экономит 1 байт оперативки)

// #define EB_DEB_TIME 50      // таймаут гашения дребезга кнопки (кнопка)
// #define EB_CLICK_TIME 500   // таймаут ожидания кликов (кнопка)
// #define EB_HOLD_TIME 600    // таймаут удержания (кнопка)
// #define EB_STEP_TIME 200    // таймаут импульсного удержания (кнопка)
// #define EB_FAST_TIME 30     // таймаут быстрого поворота (энкодер)
// #define EB_TOUT_TIME 1000   // таймаут действия (кнопка и энкодер)
#include <GyverIO.h>
#include <EncButton.h>
//EncButton eb(2, 3, 4);
// EncButton eb(2, 3, 4, INPUT); // + режим пинов энкодера
EncButton eb(2, 3, 4, INPUT_PULLUP); // + режим пинов кнопки

void setup() {
    Serial.begin(115200);

    // показаны значения по умолчанию
    eb.setBtnLevel(LOW);
    eb.setClickTimeout(500);
    eb.setDebTimeout(50);
    eb.setHoldTimeout(600);
    eb.setStepTimeout(200);
    eb.setTimeout(1000);

    eb.setEncReverse(0);
    eb.setEncType(EB_STEP4_LOW);
    eb.setFastTimeout(30);

    // сбросить счётчик энкодера
    eb.counter = 0;
}

void loop() {
    eb.tick();

    // обработка поворота общая
    if (eb.turn()) {
        Serial.print("turn: dir ");
        Serial.print(eb.dir());
        Serial.print(", fast ");
        Serial.print(eb.fast());
        Serial.print(", hold ");
        Serial.print(eb.pressing());
        Serial.print(", counter ");
        Serial.print(eb.counter);
        Serial.print(", clicks ");
        Serial.println(eb.getClicks());
    }

    // обработка поворота раздельная
    if (eb.left()) Serial.println("left");
    if (eb.right()) Serial.println("right");
    if (eb.leftH()) Serial.println("leftH");
    if (eb.rightH()) Serial.println("rightH");

    // кнопка
    if (eb.press()) Serial.println("press");
    if (eb.click()) Serial.println("click");

    if (eb.release()) {
      Serial.println("release");

      Serial.print("clicks: ");
      Serial.print(eb.getClicks());
      Serial.print(", steps: ");
      Serial.print(eb.getSteps());
      Serial.print(", press for: ");
      Serial.print(eb.pressFor());
      Serial.print(", hold for: ");
      Serial.print(eb.holdFor());
      Serial.print(", step for: ");
      Serial.println(eb.stepFor());
    }

    // состояния
    // Serial.println(eb.pressing());
    // Serial.println(eb.holding());
    // Serial.println(eb.busy());
    // Serial.println(eb.waiting());

    // таймаут
    if (eb.timeout()) Serial.println("timeout!");

    // удержание
    if (eb.hold()) Serial.println("hold");
    if (eb.hold(3)) Serial.println("hold 3");

    // импульсное удержание
    if (eb.step()) Serial.println("step");
    if (eb.step(3)) Serial.println("step 3");

    // отпущена после импульсного удержания
    if (eb.releaseStep()) Serial.println("release step");
    if (eb.releaseStep(3)) Serial.println("release step 3");

    // отпущена после удержания
    if (eb.releaseHold()) Serial.println("release hold");
    if (eb.releaseHold(2)) Serial.println("release hold 2");

    // проверка на количество кликов
    if (eb.hasClicks(3)) Serial.println("has 3 clicks");

    // вывести количество кликов
    if (eb.hasClicks()) {
        Serial.print("has clicks: ");
        Serial.println(eb.getClicks());
    }
}

Код пока (!) тупо скопирован, чтобы проверить брак-не брак в энкодерах. Брака нет.

“Нтелектуально” - так GitHub - GyverLibs/EncButton: Лёгкая и очень функциональная библиотека для энкодера с кнопкой, энкодера или кнопки с Arduino
А обычно тупо номер добавляют :slightly_smiling_face:

Я правильно понял, что надо прописать, например так?

18 | //EncButton eb(2, 3, 4, INPUT_PULLUP);
19 | EncButton eb1(2, 3, 4, INPUT_PULLUP);
20 | EncButton eb2(5, 6, 7, INPUT_PULLUP);
21 | EncButton eb3(8, 9, 10, INPUT_PULLUP);

А потом в коде указывать в нужном месте eb1, eb2, eb3…..

1 лайк

спалил специализацию наш доктор ;-)))

1 лайк

Да, зачем это надо, со своим кодом и схемой разбираться))

Так у ТС это уже третья тема с этой схемой и таким способом обработки энкодера - пора уже смирится :slightly_smiling_face:

Ладно, я смирился

Переменные перепутаны. В первом коде

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

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

1 лайк

… Что то я очкую Славик …

2 лайка

Триггер Шмитта инвертирующий. Поэтому в этом ошибки нет.

1 лайк

думаешь у Гайвера нет рабочих библиотек?

Да, ошибся, не внимательно, бегло пробежал. Приношу извинения @Sonologist, и др.
Но мне больше не понравился сам факт быстрого отказа от своего кода, без
попытки разобраться, хотя, может я и здесь не прав, это лишь моё ИМХО.

Да, к слову, по схеме не видно, ни что это триггер, ни что инвертирующий.