реклама на сайте
подробности

 
 
6 страниц V  « < 2 3 4 5 6 >  
Reply to this topicStart new topic
> MEGA+энкодер
rx3apf
сообщение May 19 2008, 18:51
Сообщение #46


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(777777 @ May 19 2008, 13:09) *
Так вам он нужен в качестве элемента управления? Я-то думал - как промышленый датчик... Тогда зачем энкодер? Поставьте многопозиционный переключатель и будет вам щасття


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

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

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

Сообщение отредактировал rx3apf - May 19 2008, 18:52
Go to the top of the page
 
+Quote Post
777777
сообщение May 20 2008, 07:27
Сообщение #47


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(rx3apf @ May 19 2008, 22:51) *
Но если что-то такое, что уже "есть в природе" - то стимулом может быть разве что неподходящая цена или качество.

Ты наверное не понял. Ты предлагаешь не делать "комплектующие", а покупать. Но ведь то изделие, которое ты разрабатываешь - оно тоже является "комплектующим" для более крупного изделия. И если рассуждать как ты - то делать вообще ничего не надо, ведь наверняка кто-то уже это делает. Но тогда ты не получишь зарплату, а твой шеф - прибыль. Так что, стимулом для изготовления чего угодно является не цена или качество имеющегося, и уж тем более не его отсутствие, а банальное желание получить прибыль и подвинуть конкурентов.
Go to the top of the page
 
+Quote Post
Леонид Иванович
сообщение May 20 2008, 09:03
Сообщение #48


Местный
***

Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986



Цитата(sitafern @ May 18 2008, 14:23) *
Пробовал тут рулёз от 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 раз быстрее).


--------------------
Go to the top of the page
 
+Quote Post
gte
сообщение May 20 2008, 09:06
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 2 318
Регистрация: 13-02-05
Из: Липецкая область
Пользователь №: 2 613



Цитата(777777 @ May 20 2008, 11:27) *
Ты предлагаешь не делать "комплектующие", а покупать. Но ведь

Если Вы можете сделать энкодер для себя с меньшими затратами при требуемых технических характеристиках и количествах, то это причина, что бы делать. При каких тиражах должны окупаться энкодеры я не знаю, но при сотнях штук точно не окупятся.
Go to the top of the page
 
+Quote Post
wired
сообщение Jun 17 2008, 11:06
Сообщение #50


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 13-06-08
Из: KYIV
Пользователь №: 38 269



Цитата(676038 @ Dec 6 2006, 16:28) *
Перечитал эту ветку и хочу предложить свой алгоритм подавления дребезга. Обкатал его на макете с двумя разными энкодерами (оптический из старой мышки) и механический 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 значения
т.е. на дисплейчике видньі только четньіе или нечетньіе числа
что я не так делаю?
или советуете обрабатьівать в основном цикле как у Леонид Иванович
Go to the top of the page
 
+Quote Post
676038
сообщение Jun 17 2008, 13:45
Сообщение #51


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 25-07-06
Пользователь №: 19 070



Цитата(wired @ Jun 17 2008, 17:06) *
взял за основу, прерьівание по спаду
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;" должно помочь.
Go to the top of the page
 
+Quote Post
wired
сообщение Jun 17 2008, 14:11
Сообщение #52


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 13-06-08
Из: KYIV
Пользователь №: 38 269



Цитата(676038 @ Jun 17 2008, 16:45) *
Я считаю, что обрабатывать энкодер в основном цикле - пустая трата ресурсов процессора, ведь обычно энкодер - это устройство ввода команд пользователя, и прибор обычно находится в ожидании таких команд. (Услилитель играет музыку 2 часа в день, а громкость мы выставляем за 5 секунд...)

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

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

обработка результата работьі енкодера у меня в основном цикле
если изменился volume то...
отключаем прерьівания глобально
пишем в индикатор,
пишем в регулятор громкости
пишем в память EEPROM
включаем прерьівания....
едем дельше по основному циклу

Сообщение отредактировал wired - Jun 17 2008, 14:14
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 17 2008, 14:51
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(wired @ Jun 17 2008, 14:06) *
взял за основу, прерьівание по спаду
volume - вьівожу на дисплейчик
.......
получил интересную картину, на один щелчок енкодера проходит 2 значения
т.е. на дисплейчике видньі только четньіе или нечетньіе числа
что я не так делаю?
или советуете обрабатьівать в основном цикле как у Леонид Иванович
Достался мне как-то "в наследство" проект, в котором обработывался энкодер... "Дядя" его обработку сделал - как и Вы: прерывание по одному выходу энкодера; направление вращения - анализ состояния другого выхода. Получалось - примерно тоже, что и у Вас: то изменение значения на 1 за щелчок, то на 2... Пришёл к следующему заключению: выход энкодера, заведённый на прерывание - он тоже, конечно, "дребезжит", поэтому после изменения этого выхода -> взводится соответствующий флаг -> происходит прерывание -> флаг сбрасывается, но "дребезг" приводит к повторной установке флага во время обрабоки прерывания -> после выхода из прерывания имеем ещё одно прерывание на тот же щелчок энкодера. Иногда повторного прерывания не происходит, тогда - приращение на 1. В результате - переделал обработку энкодера - получил, что-то аналогичное обработке от Леонида Ивановича. Рекомендую и Вам сделать что-то такое же.
Go to the top of the page
 
+Quote Post
wired
сообщение Jun 17 2008, 15:01
Сообщение #54


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 13-06-08
Из: KYIV
Пользователь №: 38 269



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

но на время обработки я прерьівание то запрещаю... жду... странно.
собсно ничего не мешает устроить обработчик в основном цикле
Go to the top of the page
 
+Quote Post
676038
сообщение Jun 17 2008, 15:09
Сообщение #55


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 25-07-06
Пользователь №: 19 070



Цитата(wired @ Jun 17 2008, 21:01) *
но на время обработки я прерьівание то запрещаю... жду... странно.
собсно ничего не мешает устроить обработчик в основном цикле


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


А в обработчике прерывания запрещать прерывания не надо, они и так запрещены, и разрешаются после выхода из прерывания автоматически (компилятором), хотя про Codevision я не уверен.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 17 2008, 15:09
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(wired @ Jun 17 2008, 18:01) *
но на время обработки я прерьівание то запрещаю... жду...
Чего их (прерывания) запрещать? Они при входе в процедуру прерывания и так - запрещены. Дело в том, что при прерывании сбрасывается флаг, который это прерывание порадил, но поскольку уровень сигнала некоторое время скачет ("дребезг"), то за время выполнения процедуры прерывания флаг взводится повторно! После того как будет произведен выход из прерывания - оно (прерывание) повторится. Как вариант - очистка флага перед выходом из прерывания.
Go to the top of the page
 
+Quote Post
676038
сообщение Jun 17 2008, 15:12
Сообщение #57


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 25-07-06
Пользователь №: 19 070



Цитата(676038 @ Jun 17 2008, 21:09) *
Добавь в конце обработчика прерывания строчку типа:
Код
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); //сбрасываем флаг прерывания если оно произошло во время обработки. Это такая защита от дребезга.

}
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 17 2008, 15:32
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(676038 @ Jun 17 2008, 18:12) *
Может стоит добавить, сейчас обрабатываю энкодер так:
Прерывание на что настроено: изменение, или фронт/спад? Второй сигнал - он тоже дребезжит... В предыдущем варианте, вроде, было ожидание окончания дребезга (delay_ms(3); ). Кстати, Вы уверены, что дребезг закончится за 3 мс?
Go to the top of the page
 
+Quote Post
676038
сообщение Jun 17 2008, 15:48
Сообщение #59


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 25-07-06
Пользователь №: 19 070



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

Просто надо проанализировать логику работы и решить для себя, какое событие считать информационным, а какое дребезгом. Из моего опыта - все что срабатывает в то время, пока идет обработка обработчика - это дребезг. Вот его и сбрасываем заканчивая обработчик. Конечно, в этом варианте есть завязка на время нахождения в обработчике прерывания (время подавления дребезга), но у меня это оказалось не критичным.
Go to the top of the page
 
+Quote Post
wired
сообщение Jun 18 2008, 07:54
Сообщение #60


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 13-06-08
Из: KYIV
Пользователь №: 38 269



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

УПС... smile.gif вот про єто я не знал, что прерьівания во время входа в обработчик запрещеньі.
а про флаг спасибо, буду сбрасьівать.



Цитата(676038 @ Jun 17 2008, 18:12) *
Может стоит добавить, сейчас обрабатываю энкодер так:
Код
      if (((tmp >> 1) & 0x01) == (tmp & 0x01))  Execute(0x11); //если поворот первого энкодера


я правильно понял? в Execute(0x11) тьі вьізьіваешь внешний обработчик?
Go to the top of the page
 
+Quote Post

6 страниц V  « < 2 3 4 5 6 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 10:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01506 секунд с 7
ELECTRONIX ©2004-2016