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

Коллеги, продолжаю возиться с энкодерами, возникла проблема. Ардуино Mega2560. Собрана схема на SN74HC14N. Все проверено: КЗ, неконтакты, “сопли“ на плате отсутствуют. Схема тут: https://cloud.mail.ru/public/Ti7G/G3SM3AdSt Все резисторы - 10 ком, конденсаторы - 0,1 мкф. Все свободные пины микросхем соединены с минусом. Я не радиоинженер, но надеюсь, нарисовал понятно. Проблемы:

  1. При вращении энкодеров показатели перескакивают не всегда в виде “переменная++;“, иной раз - на несколько единиц (слава Богу, хоть в нужную сторону).
  2. При вращении энкодеров часто меняется значение их кнопок.

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

Скетч:

//ЭНКОДЕР НАСТРОЙКИ
//Пины
#define pin_but_setup 2 //кнопка
#define pin_enc_setup_A 3 //вывод А на прерывание
#define pin_enc_setup_B 4 //вывод В
//Переменные
volatile int but_setup_val=0;  // Значение кнопки
volatile int enc_setup_val=0;  // Значение энкодера 

//ЭНКОДЕР ТЕМПЕРАТУРЫ
//Пины
#define pin_but_temp 19 //кнопка
#define pin_enc_temp_A 18 //вывод А на прерывание
#define pin_enc_temp_B 16 //вывод В
//Переменные
volatile int but_temp_val=0;  // Значение кнопки
volatile int enc_temp_val=0;  // Значение энкодера 

//ЭНКОДЕР КЛАПАНА И НАСОСА
//Пины
#define pin_but_valve 21 //кнопка
#define pin_enc_valve_A 20 //вывод А на прерывание
#define pin_enc_valve_B 17 //вывод В
//Переменные
volatile int but_valve_val=0;  // Значение кнопки
volatile int enc_valve_val=0;  // Значение энкодера 


void setup() 
{               
  Serial.begin(115200);// Объявляем скорость порта
  //Пины чтения энкодера настройки на вход
  pinMode(pin_but_setup, INPUT);  //пин чтения кнопки
  pinMode(pin_enc_setup_A, INPUT); //пин чтения вывода энкодера А 
  pinMode(pin_enc_setup_B, INPUT); //пин чтения вывода энкодера В
 
  //Пины чтения энкодера температуры на вход
  pinMode(pin_but_temp, INPUT);  //пин чтения кнопки
  pinMode(pin_enc_temp_A, INPUT); //пин чтения вывода энкодера А 
  pinMode(pin_enc_temp_B, INPUT); //пин чтения вывода энкодера В

  //Пины чтения энкодера клапана и насоса на вход
  pinMode(pin_but_valve, INPUT);  //пин чтения кнопки
  pinMode(pin_enc_valve_A, INPUT); //пин чтения вывода энкодера А 
  pinMode(pin_enc_valve_B, INPUT); //пин чтения вывода энкодера В

  //Назначение прерываний
  attachInterrupt(2, BUTTON_VALVE, RISING);   //пин прерывания кнопки клапана и насоса
  attachInterrupt(3, ENCODER_VALVE, RISING);  //пин прерывания энкодера клапана и насоса
  attachInterrupt(4, BUTTON_TEMP, RISING);   //пин прерывания кнопки температуры
  attachInterrupt(5, ENCODER_TEMP, RISING);  //пин прерывания энкодера температуры
  attachInterrupt(0, BUTTON_SETUP, RISING);   //пин прерывания кнопки настройки 
  attachInterrupt(1, ENCODER_SETUP, RISING);  //пин прерывания энкодера настройки 

}

void loop() 
{
    Serial.print (but_setup_val);	
    Serial.print (" ");  
    Serial.print (enc_setup_val);  
    Serial.print (" ");  
    Serial.print (but_temp_val);  
    Serial.print (" ");  
    Serial.print (enc_temp_val); 
    Serial.print (" ");  
    Serial.print (but_valve_val);  
    Serial.print (" ");  
    Serial.println (enc_valve_val); 
}

void BUTTON_SETUP()  //Читаем кнопку настройки
{
    but_setup_val++;
}

void ENCODER_SETUP()  //Читаем энкодер настройки
{ 
  if (digitalRead (pin_enc_setup_B)) {enc_temp_val++;}
  else {enc_setup_val--;}  
}

void BUTTON_TEMP()  //Читаем кнопку температуры
{
    but_temp_val++;
}

void ENCODER_TEMP()  //Читаем энкодер температуры
{ 
    if (digitalRead (pin_enc_temp_B)) {enc_temp_val++;}
    else {enc_temp_val--;}
}

void BUTTON_VALVE()  //Читаем кнопку клапана и насоса
{
    but_valve_val++;
}

void ENCODER_VALVE()  //Читаем энкодер клапана и насоса
{ 
    if (digitalRead (pin_enc_valve_B)) {enc_valve_val--;}
    else {enc_valve_val++;}
}

Пока не понял, как и где искать трабл? Энкодеры не юзанные. Копиллятор на скетч не ругается.

Ткните носом неуча, пожалуйста!

Ты используешь прерывания для обработки энкодера. Чему удивляться? У тебя обработка прерываний происходит быстрее обработки в общем цикле.

Если можно, чуть подробнее разжевать? И как бороться?

А хто, звиняюсь спросить?

Да лекарь я…

Т.е со стороны никогда не прислушиваетесь? :slightly_smiling_face:

А что тут разжёвывать? Ты крутнул на пять (например) прерываний, счетчик на них и поменялся, а в основном цикле только последнее значение пришло.

И по поводу схемы - я уже писал, вроде бы, - не хотите часто менять энкодер - последовательно с конденсаторами ставьте резисторы ом на 30-50.

Так не пять! Один щелчок - а изменения то на 1, то на 5, то на 3, то на 4…. И при этом кнопка реагирует (правда, не каждый раз).

Ого! Надо будет попробовать. Что это даст?

Меняй энкодер.

В смысле? Прислушиваюсь.

Избавит от подобных проблем, что в этой теме.

То есть, подозрение на брак?

А каков механизм исправления с помощью резистора?

Вам несколько раз писали, что в прерывании надо ставить флаги/приращения, а не целые функции. И, главное, выкинуть триггер если уж

1 лайк

У меня подобное было с Хреновым энкодером и именно в прерывании. На удивление, в общем цикле, были «косяки», но значительно реже (видимо скорость чтения ардуиновых функций вносили задержку, что в прерывании не возможно).

Справедливости ради - ничего «супер критичного» у него там в прерывании нет.

Спасибо, друзья. Буду пробовать, читать, извращаться. О результате сообщу.

Любой конденсатор, даже 0.1мкФ при кз создаёт искровой разряд, резистор служит ограничением тока. Не уверен, что это может сильно на дребезг влиять (но вполне возможно), но срок службы контактов механического энкодера продлевает значительно.)