И снова битва с энкодером!

И энкодер и его кнопка на прерываниях. Оба прерывания отрабатываются. С кнопкой проблем нет, работает штатно. При вращении же энкодера В ЛЮБУЮ СТОРОНУ показатель, от него зависящий, только увеличивается, “обратного хода” нет. Где копать?
Заранее спасибо!

//UNO
//Переменные настройки
int pin_but=2; //Пин прерывания кнопки
int pin_clk=3; //Пин прерывания энкодера
int pin_data=4; //Пин Data энкодера
volatile int full_ten; //Паспортная мощность ТЭНа
volatile int button=0; //Значение кнопки
volatile int clk;  //Состояние пина clk энкодера
volatile int data;  //Состояние пина data энкодера

//Подключение библиотеки max7219
#include <LedControl.h>
//создаём объект класса LedControl (din,clk,cs,X) X - количество модулей (Провода: clk-оранжевый, cs-зеленый, din-желтый)
LedControl lc_wat = LedControl(8, 9, 10, 1);
// Массив с закодированными символами для надписей.
byte bukvy[6] =
{
  B01001110,    //C-0
  B00011100,    //u-1
  B00000101,    //r-2
  B01001111,    //E-3
  B01000111,    //F-4
  B00001100,    //l-5
};

void setup()
{
  ////Инициализация пинов энкодера
  pinMode(pin_but, INPUT);   //Пин кнопки на вход
  pinMode(pin_clk, INPUT);   //Пин clk на вход
  pinMode(pin_data, INPUT);   //Пин data на вход

  //Назначение прерываний энкодера
  attachInterrupt(0, BUTTON, FALLING);   //пин прерывания кнопки
  attachInterrupt(1, ENCODER, FALLING);  //пин прерывания clk

  //Назначение пинов max7219 на выход
  for (int ind = 8; ind <= 10; ind++)
  {
    pinMode(ind, OUTPUT);
  }

  //Инициализация max7219
  lc_wat.shutdown(0, false); //Выводим из спящего режима
  lc_wat.setIntensity(0, 4); //Яркость дисплея на 4. Всего возможных режимов яркости от 0 до 15
  lc_wat.clearDisplay(0);    //Очистить дисплей

  // Объявляем скорость порта
  Serial.begin(115200);
}

void loop()
{
  if (button==0) //Индикация текущей мощности
  {
    //Пишем "Curr"
    lc_wat.setRow(0, 7, bukvy[0]);//Индикация C"
    lc_wat.setRow(0, 6, bukvy[1]);//Индикация "u"
    lc_wat.setRow(0, 5, bukvy[2]);//Индикация "r"
    lc_wat.setRow(0, 4, bukvy[2]);//Индикация "r"
    
 }
  else //Настройка
  {
    lc_wat.setRow(0, 7, bukvy[4]);//Индикация F"
    lc_wat.setRow(0, 6, bukvy[1]);//Индикация "u"
    lc_wat.setRow(0, 5, bukvy[5]);//Индикация "l"
    lc_wat.setRow(0, 4, bukvy[5]);//Индикация "i"
  }
  Serial.println(full_ten);
  delay(500);
}

void BUTTON () //Переключение от настройки к индикации
{
  if (button==0) {button=1;}
  else {button=0;}
}
void ENCODER ()
{
  clk = digitalRead(pin_clk);
  data = digitalRead(pin_data);
  
  if (clk < data) 
    {
      full_ten++;
    }
  else 
    {
      full_ten--;
    }
}

Я думаю, что у тебя ошибка тут:

Зачем в условии ставить clk < data, если от clk на самом деле ничего не зависит?

Проблема в том, что я просто скопировал это с РАБОТАЮЩЕГО скетча. А тут… Или подскажете правильный подход?

Снова неисправный экнодер?

Вот интересно, как называется топик об этой же самой эпичной битве на форуме, где тусуется энкодеры?

Неужели вот так?

https://rutube.ru/video/3115d2a1ac0e5567bd67fe3be9f681eb/

Да не должен бы… Он уже работал в другом проекте. Думаю, что я в скетче накосячил…

Берется библиотека энкодера, открывается пример, прошивается…

Вот еще библу присобачивать! Можно же без нее. Я ж говорю: прерывание отрабатывается, а вот результат странный.

У меня скетч работает, изменяет в обе стороны. Только как-то неустойчиво

Дык, энкодер же проверить

Хотя, чего я, собственно, хотел - дребезг жи ))

Что сделаешь… Будем проверять.

Очень рекомендую обработчик от dimax. Даже с раздолбанным энкодером четко отрабатывает.

Не, друзья мои! Не могут ТРИ разных энкодера врать одинаково. Попробовал три штуки - результат одинаковый: вращение в обе стороны дает только увлечение показателя. Дело в скетче, я так думаю. Помогайте!

Дело явно не в скетче

А можно на фрагмент скетча посмотреть?

Скетч ваш из первого сообщения

Нашлась “дыра”. Правда, методом тыка. Поменял местами пины clk и data, и все заработало. Причину буду искать (пока не понял в чем дело…).

Я тоже.

Очень может быть. Никуда не притянутый пин - антенна, сами знаете.

@Sonologist, в строках №№30-31 замените INPUT на INPUT_PULLUP. В строке № 29 сами смотрите, может тоже надо.

Но, не стабильно :slight_smile:

Притягивайте пины :slight_smile:

Хм, возможно. У меня модуль с подтяжкой