Используем Энкодер

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

Логик слово малоценным закавычил не напрасно )))

чуток добавил к коду DIMAX

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

ua6em пишет:

Логик слово малоценным закавычил не напрасно )))

чуток добавил к коду DIMAX

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

надо использовать правильные энкодеры, без дребезга, видимо

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

Logik пишет:

ua6em пишет:

Логик слово малоценным закавычил не напрасно )))

чуток добавил к коду DIMAX

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

надо использовать правильные энкодеры, без дребезга, видимо

Отличный совет по борьбе с дребезгом )))

Чувствуется рука Мастера!

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Иногда без прерываний никак не обойтись, если в loop что-то тяжёлое крутится.  Ну mc14490 для глушения дребезга можно ставить. На Али на них цена не поднялась, так и остались 150р/5шт в dip-версии.

Vlad1m1r
Vlad1m1r аватар
Offline
Зарегистрирован: 08.06.2019

Dimax, в mc14490 по даташиту уже имеется подтяжка к Vcc. Я правильно понимаю, что в программе инициализировать вход с подтяжкой уже не нужно?

DIVGENY
Offline
Зарегистрирован: 23.08.2016

Vlad1m1r пишет:
Dimax, в mc14490 по даташиту уже имеется подтяжка к Vcc. Я правильно понимаю, что в программе инициализировать вход с подтяжкой уже не нужно?

да, там есть "подтяжка" на входе микросхемы 14490, на выходе присутствует логический уровень. он равен 1 или 0. И если ты подтянешь ноги микроконтроллера к + или не подтянешь, критического ничего не случиться. так что решать тебе.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

dimax пишет:

Для энкодеров, которые за один щелчок совершают полный импульс (типа ec-11, подробно об этом в #247) есть более совершенный вариант обработчика. Алгоритм взял тут у Леонид Иваныча, и воткнул в прерывания. С этим методом дребезгоподавляющие конденсаторы не нужны. По аналогии можно переделать на другие пины

//Энкодер на пинах А0, А1. Используется внутренняя подтяжка.
volatile int enc;
void setup(){                
Serial.begin(9600);
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание 
}

ISR(PCINT1_vect){
static char EncPrev=0;      //предыдущее состояние энкодера
static char EncPrevPrev=0;  //пред-предыдущее состояние энкодера
  char EncCur = 0;
  if(!(PINC & (1 << PC0))){EncCur  = 1;} //опрос фазы 1 энкодера
  if(!(PINC & (1 << PC1))){ EncCur |= 2;} //опрос фазы 2 энкодера
  if(EncCur != EncPrev)             //если состояние изменилось,
  {
    if(EncPrev == 3 &&        //если предыдущее состояние 3
       EncCur != EncPrevPrev )      //и текущее и пред-предыдущее не равны,
    {
      if(EncCur == 2)          //если текущее состояние 2,
        enc++;            //шаг вверх
      else                          //иначе
        enc--;            //шаг вниз
    }
    EncPrevPrev = EncPrev;          //сохранение пред-предыдущего состояния
    EncPrev = EncCur;               //сохранение предыдущего состояния
  }


  }



void loop() {
Serial.println(enc); 
}

 

Глаз зацепился.
При таком расположении пинов
Строки 15 и 16 можно заменить на:

EncCur=PINC&3;

А если использовать другие соседствующие пины, то можно что то типа этого делать:

EncCur=((PINC>>4)&3); //для А4,А5

Gomez
Offline
Зарегистрирован: 09.09.2017

Код прекрасно работает! Нет, не так: Код прекрааасно рабооотает (с эстонским акцентом). ;)
Так вообще обвязка больше не нужна? Никаких резисторов? Просто вроде и так шикарно отрабатывает.