|
|
  |
MEGA+энкодер |
|
|
|
Jun 18 2008, 09:41
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(676038 @ Jun 17 2008, 19:48)  Просто надо проанализировать логику работы и решить для себя, какое событие считать информационным, а какое дребезгом.
Из моего опыта - все что срабатывает в то время, пока идет обработка обработчика - это дребезг. Вот его и сбрасываем заканчивая обработчик. +100 первому высказыванию. О втором: странный критерий. Сколько времени длится прерывание, устанавливающее флаг? Будем задержки совать в прерывание? Если перейти к пункту 1  то станет понятно, что для энкодера информационное событие - это фронт одного сигнала, регистрирующий новое состояние другого. Всё. Хоть 100 прерываний на один дребезг (если конечно дребезги не пересекаются во времени - но это уже негодный энкодер). Любителям задержек для подавления дребезга. Подключите "резиновую" кнопку к осциллографу, понажимайте, посмотрите. Затянутые фронты, дребезг чуть ли не в секунду длиной - как здрасьте.
|
|
|
|
|
Jun 18 2008, 11:36
|

Участник

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

|
Цитата(Maik-vs @ Jun 18 2008, 12:41)  О втором: странный критерий. Сколько времени длится прерывание, устанавливающее флаг? Будем задержки совать в прерывание? Если перейти к пункту 1  то станет понятно, что для энкодера информационное событие - это фронт одного сигнала, регистрирующий новое состояние другого. Всё. Хоть 100 прерываний на один дребезг (если конечно дребезги не пересекаются во времени - но это уже негодный энкодер). какое новое состояние другого если вращение идет в одну сторону? если прерьівание по изменению первого то второй свое значение не меняет, иначе - никакого нового состояния, кроме как вращения в противоположную сторону. или анализировать по двум прерьіваниям...? тогда без ввода задержек может и рполучится... НО внешних прерьіваний всего 2 а мне еще хочется пульт прикошачить, ему тоже кстати надо внешнее прерьівание
Сообщение отредактировал wired - Jun 18 2008, 11:50
|
|
|
|
|
Jun 18 2008, 12:47
|

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

|
Цитата(676038 @ Jun 17 2008, 18:48)  Просто надо проанализировать логику работы и решить для себя, какое событие считать информационным, а какое дребезгом. Итак, как можно построить обработчик энкодера? 1. Можно повесить один из выходов энкодера на прерывание (например, по фронту); второй выход - для определения направления. Каждое прерывание - приращение (или декримент, в зависимости от направления) значения. Недостаток: тяжело бороться с дребезгом (причем, при этом методе нужно бороться с дребезгом того выхода энкодера, который заведен на прерывание). Сброс флага прерывания в конце процедуры обработки прерывания может и не помочь (зависит от длительности дребезга и от времени работы процедуры обработки прерывания). Достоинства: простота обработчика. 2. Можно вспомнить, что за один щелчок энкодера (шаг) состояние его выходов меняется четыре раза (00, 01, 11, 10 и т.д. - "микрошаги"). Второй вариант обработчика энкодера. Некая процедура запускается периодически: в бесконецном цикле main (если не жалко и цикл не загружен иными задачами), или по таймеру и проверяет состояние выходов энкодера. Максимальный период следует выбирать из максимальной скорости вращения энкодера. По состоянию выходов энкодера на предыдущем шаге и текущему состоянию выходов определяется микрошаг поворота энкодера (с учетом направления). "Микрошаги" суммируются и при значении числа "микрошагов" =4 инкрементируется значение регулируемой величины, при числе "микрошагов" =-4 - величина уменьшается на единицу; и сумма "микрошагов" сбрасывается в ноль. Недостатки: 1) некая грамозкоскть обработчика, 2) возможно, жалко отдать под обработчик таймер. Достоинства: нет нужды принимать специальные меры по борьбе с дребезгом, посколько дребезг приводит к колебанию числа "микрошагов" на единицу и повлиять на значение регулируемой величины не может. P.S. Кто-то предложит ещё (может, не один) метод?
|
|
|
|
|
Jun 18 2008, 14:25
|

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

|
Посмотрел DS. В нём есть рисунок "Quadrature Output Table", в котором фиксированное положение ротора прихотится на серидину "микрошага". Конечно, этот рисунок производителя ни к чему не обязывает, но, ИМХО, при производстве энкодеров стараются выдержать нечто близкое... Фиксация положения - вроде, давольно чёткая. Недавно выпускали серию приборов с энкодерами. ОТК их придирчиво все проверяли, особенно как работает энкодер, потому, что в пилотном экземпляре были выявлены глюки с энкодером (его обработка производилась по фронту одного из выходов и очень часто бывало изменение регулируемой величины на 2 за шаг). Нареканий не было. Может быть, потому, что - энкодеры новые, ещё не обтёрлись...
|
|
|
|
|
Jun 18 2008, 14:33
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(wired @ Jun 18 2008, 15:36)  какое новое состояние другого если вращение идет в одну сторону? если прерьівание по изменению первого то второй свое значение не меняет, иначе - никакого нового состояния, кроме как вращения в противоположную сторону.
или анализировать по двум прерьіваниям...? тогда без ввода задержек может и рполучится... НО внешних прерьіваний всего 2 а мне еще хочется пульт прикошачить, ему тоже кстати надо внешнее прерьівание Да, получается, что нужно 2 прерывания. Лучше периодически опрашивать сигналы, причём можно не через равные интервалы, лишь бы достаточно часто. При вращении в одну сторону получается последовательность 0-2-3-1-0-2-3-1... в другую - 0-1-3-2-0-1-3-2... Принятые сигналы сдвигаем в регистр. Получается, что в регистре хранится 4 последних состояния энкодера. Отбрасывая старые 2 бита и сравнивая его с константой, получаем ответ - был ли шаг и в какую сторону. Это, в общем, реализация способа 2 Палыча. PS А, я уже писал об этом. (#3 и #4) Анализировать надо таки 3 последних состояния, особенно если опрос. Потому что частота дребезга непредсказуема, пропустить переход в последовательности 2-3-2-3-2-3 вполне вероятно, и вот оно - двойное срабатывание на один "зуб".
Сообщение отредактировал Maik-vs - Jun 18 2008, 14:45
|
|
|
|
|
Jun 18 2008, 15:01
|

Участник

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

|
Цитата(Maik-vs @ Jun 18 2008, 17:33)  Да, получается, что нужно 2 прерывания. Лучше периодически опрашивать сигналы, причём можно не через равные интервалы, лишь бы достаточно часто. При вращении в одну сторону получается последовательность 0-2-3-1-0-2-3-1... в другую - 0-1-3-2-0-1-3-2... Принятые сигналы сдвигаем в регистр. Получается, что в регистре хранится 4 последних состояния энкодера. Отбрасывая старые 2 бита и сравнивая его с константой, получаем ответ - был ли шаг и в какую сторону. Это, в общем, реализация способа 2 Палыча. PS А, я уже писал об этом. (#3 и #4) Анализировать надо таки 3 последних состояния, особенно если опрос. Потому что частота дребезга непредсказуема, пропустить переход в последовательности 2-3-2-3-2-3 вполне вероятно, и вот оно - двойное срабатывание на один "зуб". ОК.. я пока новичок. и прерьівания обрабатьівать както нагляднее, пройдусь по єтим граблям  потом буду разбираться с регистром... может примерчик ? а....
|
|
|
|
|
Jun 18 2008, 15:14
|
Гуру
     
Группа: Свой
Сообщений: 2 318
Регистрация: 13-02-05
Из: Липецкая область
Пользователь №: 2 613

|
Цитата(Палыч @ Jun 18 2008, 18:25)  Посмотрел DS. В нём есть рисунок "Quadrature Output Table", в котором фиксированное положение ротора прихотится на серидину "микрошага". Конечно, этот рисунок производителя ни к чему не обязывает, но, ИМХО, при производстве энкодеров стараются выдержать нечто близкое... Фиксация положения - вроде, давольно чёткая. Недавно Да, в фиксированном положении оба контакта должны быть разомкнутыми. Фиксация положения обеспечивается пружинным кольцом с выступом. Кольцо хлипкое. В общем, мне больше нравятся на 12 положений.
|
|
|
|
|
Jun 20 2008, 20:37
|

Частый гость
 
Группа: Участник
Сообщений: 88
Регистрация: 14-03-06
Из: Житомир (UA)
Пользователь №: 15 228

|
Цитата(wired @ Jun 18 2008, 14:36)  ...
или анализировать по двум прерьіваниям...? тогда без ввода задержек может и рполучится... НО внешних прерьіваний всего 2 а мне еще хочется пульт прикошачить, ему тоже кстати надо внешнее прерьівание Лично я когда то сделал так (потому как второе прерывание тоже надо было для других целей): Внешнее прерывание по фазе A выставил на срабатывание по любому событию, фазу B на любой вход. И сам обработчик: Код // External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { if ( FASE_A ^ FASE_B)
{ if (FASE_A){ if (FASE_B) current_counter++; else current_counter--; } } else { if (!FASE_A){ if (!FASE_B) current_counter++; else current_counter--; } } } Работает замечательно до сих пор.
|
|
|
|
|
Jun 23 2008, 06:39
|

Участник

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

|
Цитата(Maik-vs @ Jun 18 2008, 17:33)  Да, получается, что нужно 2 прерывания. Лучше периодически опрашивать сигналы, причём можно не через равные интервалы, лишь бы достаточно часто. При вращении в одну сторону получается последовательность 0-2-3-1-0-2-3-1... в другую - 0-1-3-2-0-1-3-2... Принятые сигналы сдвигаем в регистр. Получается, что в регистре хранится 4 последних состояния энкодера. Отбрасывая старые 2 бита и сравнивая его с константой, получаем ответ - был ли шаг и в какую сторону. Это, в общем, реализация способа 2 Палыча. PS А, я уже писал об этом. (#3 и #4) Анализировать надо таки 3 последних состояния, особенно если опрос. Потому что частота дребезга непредсказуема, пропустить переход в последовательности 2-3-2-3-2-3 вполне вероятно, и вот оно - двойное срабатывание на один "зуб". я правильно понял: по каждому изменению заполняем некую переменную, состояниями входов, while... { reg = (reg<<1)+A reg = (reg<<1)+B } соответственно заполняется влево 013 00000111 132 00011110 320 00111000 201 00100001 вправо 023 00001011 231 00101101 310 00110100 102 00010010 отбросив старшие 5 бит reg = (reg & 0x07); далее сравниваю влево reg = 1 001 reg = 7 111 reg = 6 110 reg = 0 000 вправо reg = 2 010 reg = 3 011 reg = 5 101 reg = 4 100
|
|
|
|
|
Jun 24 2008, 18:08
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 17-06-08
Из: Томск
Пользователь №: 38 346

|
Читать всю тему влом, поэтому просто приведу свой код обработки энкодера. Работает с энкодером PEC16, частоту сканирования менял в пределах 100uS....1mS, все работает очень четко. Внешний обработчик события поворот в вправо или влево просто проверяет содержимое байта в ОЗУ-Encoder_Status, вообщем из кода вроде должно быть все ясно. Код ;=============================================================================== ============================================== ; Подпрограмма обработки энкодера ;=============================================================================== ============================================== Encoder: lds temp,(Encoder_Status) ; Прочитать из памяти состояние кольцевого буфера энкодера cpi temp,0b00110100 ; Если кольцевой буфер содержит код состояния энкодера "против часовой" breq Encoder_End ; то перейти на выход cpi temp,0b00011100 ; Если кольцевой буфер содержит код состояния энкодера "по часовой" breq Encoder_End ; то перейти на выход clr temp ; Обнулить все разряды РОН out DDRB,temp ; Сделать все выводы порта В входами и записать конфигурацю nop ; подождать пока установиться напряжение на выводах порта В nop ; подождать пока установиться напряжение на выводах порта В nop ; подождать пока установиться напряжение на выводах порта В nop ; подождать пока установиться напряжение на выводах порта В nop ; подождать пока установиться напряжение на выводах порта В lds temp3,(Encoder_rep_state); Прочитать из памяти число повторов состояние контактов энкодера in temp,PINB ; Сканировать состояние энкодера com temp ; Получить обратный код замкнутых контактов andi temp,0b00010100 ; Выделить разряды к которым подключен энкодер через маску контактов энкодера lsr temp lsr temp inc temp ; Сдвинуть первый бит влево если он равен "1" lsr temp ; Сдвинуть байт влево, приведя код состояния энкодера к нормальному виду lds temp2,(Encoder_prev) ; Прочитать из памяти состояние кольцевого буфера энкодера cpse temp,temp2 ; Сравнить состояние контактов энкодера с предыдущим, если они неравны, clr temp3 ; то очистить счетчик повторов sts (Encoder_prev),temp ; Сохранить текущее состояние контактов энкодера в "предыдущем"
cpi temp3,2 ; Сравнить счетчик числа повторов с контстантой (=3 для частоты сканирования 1кГц и 15 для 10кГц)
breq Encoder_1 ; Перейти если равно, в обновлению состояния кольцевого буфера brsh Encoder_End ; Перейти если больше, на выход inc temp3 ; Увеличить счетчие числа повторов sts (Encoder_rep_state),temp3; Сохранить в памяти число повторов состояние контактов энкодера clr temp ; вывести на все выводы порта В нули out PORTB,temp ; запись нули в РВВ порта В com temp ; Установить все разряды РОН в единицу, out DDRB,temp ; Сделать все выводы порта В выходами и записать конфигурацию ret ; Выйти из подпрограммы обработки энкодера Encoder_1: lds temp,(Encoder_Status) ; Прочитать из памяти состояние кольцевого буфера энкодера lsl temp ; Сдвинуть кольцевой буфер состояния энкодера на шаг в лево lsl temp ; Сдвинуть кольцевой буфер состояния энкодера на шаг в лево add temp,temp2 ; Добавить новое состояние контактов энкодера в кольцевой буфер inc temp3 ; Увеличить счетчие числа повторов sts (Encoder_Status),temp ; Сохранить в памяти состояние кольцевого буфера энкодера Encoder_End: sts (Encoder_rep_state),temp3; Сохранить в памяти число повторов состояние контактов энкодера clr temp ; вывести на все выводы порта В нули out PORTB,temp ; запись нули в РВВ порта В com temp ; Установить все разряды РОН в единицу, out DDRB,temp ; Сделать все выводы порта В выходами и записать конфигурацию ret Цитата(haker_fox @ Jun 24 2008, 06:33)  P.S. Есть ли в природе дешевые энкодеры с небольшим количеством импульсов на оборот, но не дорогие? PEC16-4020F-S0012 - имеют 12 отсчетов на 1 оборот
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|