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

Так вам он нужен в качестве элемента управления? Я-то думал - как промышленый датчик... Тогда зачем энкодер? Поставьте многопозиционный переключатель и будет вам щасття

 

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

:) К счастью, у нас есть конструкорский отдел и механический цех, который умеет точить любые детали, а уж диск с зубьями 1.6 мм - плевое дело.

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

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

Конечно. Для себя, "для души". Но если что-то такое, что уже "есть в природе" - то стимулом может быть разве что неподходящая цена или качество. Чаще - отсутствие каких-то требуемых функций. Однако времена, когда радиолюбители с энтузиазмом химичили с самодельными детектирующими кристаллами, высунув язык, искали активные точки, делали конденсаторы из стекла и фольги, а резисторы из угольных стержней и стеклянных трубок - давно прошли. Серийный компонент "на коленке" не сделать лучше, чем Bourns, ALPS или кто еще. Так что неубедительно даже применительно к любительской конструкции. В серийное же продаваемое изделие мне такое решение поставить - даже в кошмарном сне не привидится. Это кошмарные ужасы совка, надеюсь, что в далеком прошлом, и возврата к ним не будет...

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

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


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

Но если что-то такое, что уже "есть в природе" - то стимулом может быть разве что неподходящая цена или качество.

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

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


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

Пробовал тут рулёз от Parallax...Может то же попробуете.

 

А смысл? С обработкой энкодера нормально справляется AVR. Сейчас использую такой код:

 

char Enc_Scan(void)
{
  char n = 0;
  if(Pin_ENC_F1) n |= EF1;       //проверка линии F1
  if(Pin_ENC_F2) n |= EF2;       //проверка линии F2
  return(n);
}

//вызывается в основном цикле:
void Encoder_Exe(void)
{
  char EncTmp = Enc_Scan();      //сканируем энкодер и запоминаем результат
  char EncChg = EncTmp ^ EncPre; //разница текущего и предыдущего значений
  if(!EncChg) return;            //ели нет изменений, выход

  Delay_us(ENCDEB);              //антидребезговая задержка для энкодера

  char EncNew = Enc_Scan();      //сканируем энкодер еще раз
  if(EncNew != EncTmp) return;   //дребезг не закончился, выход
  EncTmp = EncPre;               //запоминаем предыдущее значение
  EncPre = EncNew;               //обновляем предыдущее значение

  if(!(EncTmp & EF1) && (EncNew & EF1) && !(EncNew & EF2))
    { Msg = ENC_DN; return; } //вращение против часовой стрелки
  if((EncTmp & EF1) && !(EncNew & EF1) && !(EncNew & EF2))
    { Msg = ENC_UP; return; } //вращение по часовой стрелке
}
//Msg - сообщение энкодера, которое сбрасывается при обработке.

 

Иногда делаю еще измерение скорости вращения энкодера и при быстром вращении формирую другие сообщения (например, для изменения редактируемого параметра в 10 раз быстрее).

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


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

Ты предлагаешь не делать "комплектующие", а покупать. Но ведь

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

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


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

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

 

Исходные даные - один выход энкодера заводим на вход INT0 (PIND_Bit2), второй выход на другую ногу (в данном случае PIND_Bit3). Настраиваем прерывание INT0 по любому фронту.

Есть глобальная переменная "Volume", которая изменяет свое значение при вращении энкодера.

 

...

 

 

взял за основу, прерьівание по спаду

volume - вьівожу на дисплейчик

сделал так:

 

interrupt [EXT_INT0] void ext_int0_isr(void)
{
GICR = 0x00;   
delay_ms(3);  
if (!PIND.2)    
{  
if ((PIND.1==0) && (volume <255))  volume++;
if ((PIND.1==1) && (volume > 0)) volume--;                         
}   
GICR = 0x40; 
}

 

получил интересную картину, на один щелчок енкодера проходит 2 значения

т.е. на дисплейчике видньі только четньіе или нечетньіе числа

что я не так делаю?

или советуете обрабатьівать в основном цикле как у Леонид Иванович

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


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

взял за основу, прерьівание по спаду

volume - вьівожу на дисплейчик

сделал так:

 

interrupt [EXT_INT0] void ext_int0_isr(void)
{
GICR = 0x00;   
delay_ms(3);  
if (!PIND.2)    
{  
if ((PIND.1==0) && (volume <255))  volume++;
if ((PIND.1==1) && (volume > 0)) volume--;                         
}   
GICR = 0x40; 
}

 

получил интересную картину, на один щелчок енкодера проходит 2 значения

т.е. на дисплейчике видньі только четньіе или нечетньіе числа

что я не так делаю?

или советуете обрабатьівать в основном цикле как у Леонид Иванович

 

Я считаю, что обрабатывать энкодер в основном цикле - пустая трата ресурсов процессора, ведь обычно энкодер - это устройство ввода команд пользователя, и прибор обычно находится в ожидании таких команд. (Услилитель играет музыку 2 часа в день, а громкость мы выставляем за 5 секунд...)

 

Обычно есть проблема с недостаточной чувствительностью (пропуски щелчков), а здесь же наоборот - и это хорошо. Значит надо просто посмотреть, как настроено прерывание - по переднему фронту, по заднему или изменению состояния. Если стоит измение состояния - то задать по фронту. Ну а если же настроено по фронту, то "real_volume = volume >> 1;" должно помочь.

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


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

Я считаю, что обрабатывать энкодер в основном цикле - пустая трата ресурсов процессора, ведь обычно энкодер - это устройство ввода команд пользователя, и прибор обычно находится в ожидании таких команд. (Услилитель играет музыку 2 часа в день, а громкость мы выставляем за 5 секунд...)

 

Обычно есть проблема с недостаточной чувствительностью (пропуски щелчков), а здесь же наоборот - и это хорошо. Значит надо просто посмотреть, как настроено прерывание - по переднему фронту, по заднему или изменению состояния. Если стоит измение состояния - то задать по фронту. Ну а если же настроено по фронту, то "real_volume = volume >> 1;" должно помочь.

сейчас прерьівание по спаду импульса.

думаю разницьі не будет спад или фронт... похоже гдето у меня в логике косяк...

 

обработка результата работьі енкодера у меня в основном цикле

если изменился volume то...

отключаем прерьівания глобально

пишем в индикатор,

пишем в регулятор громкости

пишем в память EEPROM

включаем прерьівания....

едем дельше по основному циклу

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

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


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

взял за основу, прерьівание по спаду

volume - вьівожу на дисплейчик

.......

получил интересную картину, на один щелчок енкодера проходит 2 значения

т.е. на дисплейчике видньі только четньіе или нечетньіе числа

что я не так делаю?

или советуете обрабатьівать в основном цикле как у Леонид Иванович

Достался мне как-то "в наследство" проект, в котором обработывался энкодер... "Дядя" его обработку сделал - как и Вы: прерывание по одному выходу энкодера; направление вращения - анализ состояния другого выхода. Получалось - примерно тоже, что и у Вас: то изменение значения на 1 за щелчок, то на 2... Пришёл к следующему заключению: выход энкодера, заведённый на прерывание - он тоже, конечно, "дребезжит", поэтому после изменения этого выхода -> взводится соответствующий флаг -> происходит прерывание -> флаг сбрасывается, но "дребезг" приводит к повторной установке флага во время обрабоки прерывания -> после выхода из прерывания имеем ещё одно прерывание на тот же щелчок энкодера. Иногда повторного прерывания не происходит, тогда - приращение на 1. В результате - переделал обработку энкодера - получил, что-то аналогичное обработке от Леонида Ивановича. Рекомендую и Вам сделать что-то такое же.

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


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

Достался мне как-то "в наследство" проект, в котором обработывался энкодер... "Дядя" его обработку сделал - как и Вы: прерывание по одному выходу энкодера; направление вращения - анализ состояния другого выхода. Получалось - примерно тоже, что и у Вас: то изменение значения на 1 за щелчок, то на 2... Пришёл к следующему заключению: выход энкодера, заведённый на прерывание - он тоже, конечно, "дребезжит", поэтому после изменения этого выхода -> взводится соответствующий флаг -> происходит прерывание -> флаг сбрасывается, но "дребезг" приводит к повторной установке флага во время обрабоки прерывания -> после выхода из прерывания имеем ещё одно прерывание на тот же щелчок энкодера. Иногда повторного прерывания не происходит, тогда - приращение на 1. В результате - переделал обработку энкодера - получил, что-то аналогичное обработке от Леонида Ивановича. Рекомендую и Вам сделать что-то такое же.

но на время обработки я прерьівание то запрещаю... жду... странно.

собсно ничего не мешает устроить обработчик в основном цикле

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


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

но на время обработки я прерьівание то запрещаю... жду... странно.

собсно ничего не мешает устроить обработчик в основном цикле

 

Добавь в конце обработчика прерывания строчку типа:

PCIFR|=(1<<PCIF1); //сбрасываем флаг прерывания, если оно произошло во время обработки. Это такая защита от дребезга.

 

А в обработчике прерывания запрещать прерывания не надо, они и так запрещены, и разрешаются после выхода из прерывания автоматически (компилятором), хотя про Codevision я не уверен.

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


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

но на время обработки я прерьівание то запрещаю... жду...
Чего их (прерывания) запрещать? Они при входе в процедуру прерывания и так - запрещены. Дело в том, что при прерывании сбрасывается флаг, который это прерывание порадил, но поскольку уровень сигнала некоторое время скачет ("дребезг"), то за время выполнения процедуры прерывания флаг взводится повторно! После того как будет произведен выход из прерывания - оно (прерывание) повторится. Как вариант - очистка флага перед выходом из прерывания.

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


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

Добавь в конце обработчика прерывания строчку типа:

PCIFR|=(1<<PCIF1); //сбрасываем флаг прерывания, если оно произошло во время обработки. Это такая защита от дребезга.

 

А в обработчике прерывания запрещать прерывания не надо, они и так запрещены, и разрешаются после выхода из прерывания автоматически (компилятором), хотя про Codevision я не уверен.

 

Может стоит добавить, сейчас обрабатываю энкодер так:

//PCINT8-14 interrupt implementation
#pragma vector=PCINT1_vect
__interrupt void handler_pcint1(void)
{
static unsigned char flag=0xFF; //переменная для хранения предыдущего значения порта

unsigned char tmp; //переменная для хранения текущего значения порта

tmp = PINC & 0x0F; //запоминаем состояние порта

switch (tmp ^ flag) //сравниваем с предыдущим и выполняем действие если изменился соответствующий бит
  {
  case 0x01:
      if (((tmp >> 1) & 0x01) == (tmp & 0x01))  Execute(0x11); //если поворот первого энкодера вправо
          else Execute(0x10); //иначе это поворот первого энкодера влево
      break;//выход
  case 0x02:
      if (((tmp << 1) & 0x02) == (tmp & 0x02))  Execute(0x10); //если поворот первого энкодера влево
          else Execute(0x11); //иначе поворот первого энкодера вправо
      break;//выход
  case 0x04:
      if (((tmp >> 1) & 0x04) == (tmp & 0x04))  Execute(0x21); //если поворот второго энкодера вправо
          else Execute(0x20); //иначе поворот второго энкодера вправо
      break;//выход
//  case 0x08: !!! второй энкодер обрбатываем при изменении только одной линии, уменьшая чувствительность вдвое...
  }

flag = tmp; //сохраняем значение для следующего опроса

PCIFR|=(1<<PCIF1); //сбрасываем флаг прерывания если оно произошло во время обработки. Это такая защита от дребезга.

}

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


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

Может стоит добавить, сейчас обрабатываю энкодер так:
Прерывание на что настроено: изменение, или фронт/спад? Второй сигнал - он тоже дребезжит... В предыдущем варианте, вроде, было ожидание окончания дребезга (delay_ms(3); ). Кстати, Вы уверены, что дребезг закончится за 3 мс?

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


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

В своем последнем варианте - по изменению состояния, используется PIN-Change Interrupt на все четыре пина, куда подключены два энкодера.

 

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

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


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

Чего их (прерывания) запрещать? Они при входе в процедуру прерывания и так - запрещены. Дело в том, что при прерывании сбрасывается флаг, который это прерывание порадил, но поскольку уровень сигнала некоторое время скачет ("дребезг"), то за время выполнения процедуры прерывания флаг взводится повторно! После того как будет произведен выход из прерывания - оно (прерывание) повторится. Как вариант - очистка флага перед выходом из прерывания.

УПС... :) вот про єто я не знал, что прерьівания во время входа в обработчик запрещеньі.

а про флаг спасибо, буду сбрасьівать.

 

 

 

Может стоит добавить, сейчас обрабатываю энкодер так:

      if (((tmp >> 1) & 0x01) == (tmp & 0x01))  Execute(0x11); //если поворот первого энкодера

 

я правильно понял? в Execute(0x11) тьі вьізьіваешь внешний обработчик?

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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