Перейти к содержанию
    

Есть MEGA64 и инкрементальный энкодер PEC12-4220F , кто работал с энкодером посоветуйте , как правильно обстучать его? :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Один из сигналов (А или В ) я заводил на внешнее прерывание, второй на любую ногу порта, сконфигурированую как вход. Прерывание - по любому логическому изменению сигнала. В обработчике, исходя из предыдущего и текущего значения сигналов А и В (предыдущее значение - значение А и В, при предыдущем вызове обработчика внешнего прерывания ) принимал решение в какую сторону происходит вращение и соотв. увеличивал или уменьшал значение требуемой переменной. Вот краткий алгоритм работы.. если нужно более подробное описание - обращайтесь...

Изменено пользователем XsanyaX

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обработка энкодера по прерываниям неудобна, так как требуется давить дребезг. Более того, чтобы корректно реализовать квадратурный декодер 1х (или 2х, 4х), прерывания должны происходить не по фронту или спаду одного из сигналов, а по любому изменению состояния энкодера. Отсюда следует порочность декодера типа "программный D-триггер, один сигнал энкодера на вход D, второй - на C". При такой реализации INC/DEC всегда происходит по фронту одного из сигналов энкодера, что есть неправильно. Если вал энкдера просто пошевелить на месте, может насчитаться куча импульсов. INC/DEC нужно делать по изменению состояния двух сигналов, чтобы и INC, и DEC происходили в одной и той же точке, но при её проходе с разными направлениями вращения. Информацию о построении правильных квадратурных декодеров можно почерпнуть из описания спец. микросхем, например, HCTL-2000.

Я обрабатываю энкодер и его кнопку в основном цикле программы. Если программа чем-то занята, то она всё равно не сможет отреагировать на вращение энкодера, а буферизовать проделанный поворот и откладывать его обрботку - это уже слишком. Практика показала, что для комфорного использования энкодера задержки на подавление дребезга не должны превышать 500 мкс, иначе становится заметным пропуск шагов при резком повороте ручки. Я использую 300 мкс. Столь малые времена, к сожалению, не могут быть сформированы системным таймером как большинство других временных интервалов в программе. Поэтому приходится применять "тупую" задержку в виде цикла. Для таких малых интервалов это вполне допустимо, потери производительности процессора будут минимальными. Тем более, что обработка энкодера - это общение с пользователем, который всегда является самым медленным звеном системы :) Более того, если какая-то задача в основном цикле захочет временно забрать все ресурсы процессора (за вычетом потерь на прерывания), она сможет это сделать. В это время энкодер обслуживаться не будет. Для кнопки время подавления дребезга должно быть существенно большим, я использую 50 мс. Уж очень разные механические характеристики контактных групп кнопки и энкодера.

 

Сюда выложил пример обработки энкодера на асме для AVR:

http://upload.caxapa.ru/Enc.txt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть MEGA64 и инкрементальный энкодер PEC12-4220F , кто работал с энкодером посоветуйте , как правильно обстучать его? :help:

здесь кусок обслуживающий кодер, кнопку сам допишешь. :biggrin:

Полностью согласен с Леонидом Ивановичем, поэтому функцию вызываю из основной

программы примерно раз в 20мСек, избавляюсь от дребезга и слишком быстрого вращения

define PIN_Coder PIND//PD0,PD1

 

 

char status,encoder = 0;

 

//-----------------------------------------------------------------------------------

signed char ReadEncoder(void)

{

register signed char temp = 0;

encoder = (~PIN_Coder & 0x03);//ïðîâåðÿåì PD0,PD1

if(status != encoder)

{

switch(encoder)

{

case 0:

if(status == 1) temp = 1;

else if(status == 2) temp = -1;

break;

case 1:

if(status == 3) temp = 1;

else if(status == 0) temp = -1;

break;

case 2:

if(status == 0) temp = 1;

else if(status == 3) temp = -1;

break;

case 3:

if(status == 2)temp = 1;

else if(status == 1) temp = -1;

break;

}

status = encoder;

}

return temp;

}

//-----------------------------------------------------------------------------------

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не невозможно сделат на 2 перервания.

Вот я делал. Прилагаю изходник. Ето работает стабилно.

encoder_if.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обработка энкодера по прерываниям неудобна, так как требуется давить дребезг. Я обрабатываю энкодер и его кнопку в основном цикле программы.

А я наоборот отказался от полинга работы с энкодером

когда имеем достаточный загруз контроллера - иногда очень не аккуратно получалось ;-)

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

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

проблем уже как 3 года не наблюдаю причем даже с нонейм энкодерами, и энкодерами имеющие достаточный мех износ....

плюс ко всему под прерывание все прекрасно ложиться - и ресурсов кушает очень мало...

так что вот ещё автору, тема для обмозгования..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какой физический смысл несет переменная "чувствительность энкодера"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

проблем уже как 3 года не наблюдаю причем даже с нонейм энкодерами, и энкодерами имеющие достаточный мех износ.... плюс ко всему под прерывание все прекрасно ложиться - и ресурсов кушает очень мало...

 

Если не жалко - можно пример кода на Си ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Выходы енкодера обрабатывались по 100 мкс прерываниям фильтром на вертикальных счетчиках. Результат: PIn - отфильтрованные входы, PInChg - изменения по входам.

Извините, прога на ассемблере под PIC'и. C-шный код достаточно раскомментировать.

PIn и PInChg можно дальше обработать в основном цикле, или, если напряг по времени, не отходя от кассы. PInChg должен быть обработан до следующего прерывания.

Применительно к энкодеру в предположении, что обрабатываются только два входа:

uchar EncPos = 0;
// IA и IB , естесно, равны номерам битов входов, на которые бегут выходы енкодера
// bit-fields располагаются соответственно
#define IA   0
#define IB   1
union
{
   uchar i;
   struct
   {
      uchar A: 1;
      uchar B: 1;
   } b;
} PIn, PInChg;
...
   if(PInChg.i == ((1<<IA)|(1<<IB)))
   {
      switch (PIn.i)
      {
         не вдаваясь в подробности
         case 0: ...
         case (1<<IA): ...
         case (1<<IB): ...
         case ((1<<IA)|(1<<IB)): ...
      }
      EncPos = PIn.i;
   }

Ограничения: битовые позиции входов по портам (если обрабатываются входы с нескольких портов) не должны пересекаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще есть такое решение:

По тику таймерного прерывания заполняется кольцевой буфер. С каждым тиком в буфер засылается значение состояния энкодера. Анализируются элементы массива буфера: при равенстве элементов в массиве, возвращаем код состояния энкодера. Следующее заполнение кольцевого буфера только после обнаружения перекрытия фаз сигналов. Кольцевой буфер на 4-е элемента, частота опроса - 20 Гц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если частота опроса 20 Гц, то получится страшно тормозной энкодер. При быстром вращении он будет пропускать шаги - это некомфортно. Нужна частота опроса в 100 раз выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какой физический смысл несет переменная "чувствительность энкодера"?

фактически это счетчик инкрементов или декриментов

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

 

Если не жалко - можно пример кода на Си ?

увы на си для 8 бит не пишу...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наверно загадочность заключается в том что :

- при первом же прерывании устанавливается флаг состояния порта и первого прерывания(переменная) и наверно (если нужна перепроверка состояния порта через определенное время) запускается таймер. При этом для предотврашения многочисленных прерываний от порта вследствии дребезга - прерывание порта деактивизируется.

- при прерывании таймера прочитывается порт и сверяется с предыдушим, полученным при прерывании от порта

если совпадает - то рапортуем в коунтер, если нет то в обратное состояни . И также прерывание таймера

деактивизируется и прерывание порта опять активизируется .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...