0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
|
|
1 | |
Энкодер через прерывания / зараза дребезг16.04.2015, 22:09. Показов 24864. Ответов 24
Метки нет (Все метки)
Всем привет!
Делаю обработчик сигнала с инкрементального двухфазного энкодера . Алгоритм следующий: <ul>1) на одну фазу сажаю прерывание, что позволяет вести счет тактов 2) т.к. одна фаза отстает/обгоняет другую на полшага, то в обработчике прерывания смотрю вторую фазу для определения направления вращения, если вторая фаза 0 - значит обратный ход, если 1 - значит вперед</ul>Вроде бы все прсто и красиво, но вот проблема - дребезг! Имеется дребез который создает ложные прерывания. Как от него можно избавиться? Знаю что у STM32 есть аппаратный обработчик энкодера(пользовался и умею настраивать), но в данном случае его использовать не могу. К триггеру Шмитта и другм аппаратным решениям прибегать не хочеться. Можно ли как-то решить эту проблему програмно? Спасибо!
0
|
16.04.2015, 22:09 | |
Ответы с готовыми решениями:
24
Задержки на SysTick внутри обработчика прерывания, дребезг Энкодер влияет на прерывания, хотя напрямую не подключен. Графика через прерывания на Borland С++ 3.1 Прерывания звука через Bluetooth устройства Рисование линий через прерывания в видеорежиме |
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
16.04.2015, 22:29 | 2 |
Япона мать! У STM32 есть таймеры. И у таймеров есть режим "энкодер". И аппаратная защита от дребезга!!!
Ну почему нельзя почитать даташит??? // для решения программно нужно будет реализовать алгоритм антидребезга таймера. Это — костыли и тормоза.
0
|
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
|
|
16.04.2015, 22:39 | 3 |
Сообщение от Iddy_Im
Поэтому мне и нужно сваять костыли для оставшихся 2.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
16.04.2015, 22:41 | 4 |
Ну, по мне прочитать страницу даташита и сделать устойчивую обработку энкодера - сопоставимые по сложности вещи. Благо, энкодеру даже антидребезг не нужен: если в обработчике читать оба пина и сравнивать их состояние с предыдущим, то самое страшное, что грозит - неточность на один отсчёт. А если работать по таймеру - то даже она не грозит.
0
|
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
|
|
16.04.2015, 22:48 | 5 |
Сообщение от oomomstir
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
16.04.2015, 22:54 | 6 |
Повесьте на таймер.
Вкратце: у вас два бита x и y, и предыдущие значения x1 и y1. Таблица: x1 x y1 y: ymsrement 0000, 0011, 1100, 1111: - без изменений 0001, 0111, 1110, 1000: +1 1101, 0100, 0010, 1011: -1 Остальные - ошибка.
0
|
0 / 0 / 0
Регистрация: 12.07.2011
Сообщений: 2
|
|
16.04.2015, 22:54 | 7 |
А так не годится - http://iosyitistromyss.ru/obrabotka-mno ... menno.html?
0
|
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
16.04.2015, 22:57 | 8 |
ОК, подсказываю простой вариант: в обработчике прерывания от энкодера вы запрещаете этот EXTI, а уже по прошествию, скажем, 30мс, разрешаете обратно (в основном цикле КА).
Я так на STM8 делал.
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
16.04.2015, 23:01 | 9 |
0
|
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
|
|
16.04.2015, 23:21 | 10 |
Сообщение от PRS
0
|
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
16.04.2015, 23:40 | 11 |
Думаю, тут проблема с говнистым энкодером. Вверх оно бежало тупо потому, что энкодер удалось установить в запрещенное состояние, а программно почему-то это состояние не обрабатывалось.
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
16.04.2015, 23:56 | 12 |
Повесить на таймер - да, по переполнению таймера. Скажем, если предельная скорость вращения 10 оборотов в секунду и у энкодера 24 отсчёта - надо не чаще 240 раз в секунду читать порты.
Ещё один вариант - перечитывать все энкодеры по прерыванию от любой ноги, если у вас есть что-нибудь типа avr-ного PCINT (одно прерывание на все ноги, всё равно в обработчике будете смотреть, кто изменился)
0
|
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
|
|
17.04.2015, 03:07 | 13 |
MoxymS - наверное уже сам догадался, что необходимо два прерывания...
То прерывание что сработало - запрещаем, второе разрешаем. Энкодер должен тонуть в воде, если плавает - то только замена.
0
|
0 / 0 / 0
Регистрация: 15.06.2014
Сообщений: 118
|
|
17.04.2015, 04:11 | 14 |
Энкодеры дребезжат дай боже. Когда их много (или матрица кнопок, энкодеров и тп), и ресурсов в достатке, можно чтение порта с этим зоопарком на DMA вешать. Потом брать "среднее арифметическое" для устранения дребезга. Не самый изящный метод, но время выполнения - константа.
0
|
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
|
|
17.04.2015, 10:43 | 15 |
Всем большон мпасибо!
Пока решил все же делать прерывания на все ногах. Буду пробовать)
0
|
0 / 0 / 0
Регистрация: 16.02.2012
Сообщений: 699
|
|
19.04.2015, 10:59 | 16 |
Если имеется в виду энкодер, используемый для управления (а не скоростной энкодер на валу двигателя), то с дребезгом бороться очень просто. За один щелчок он проходит 4 состояния. Дребезг вызывает переходы только между соседними состояниями. Нужно запретить реакцию на такие переходы.
Код
//---------------------------------------------------------------------------- //Модуль поддержки энкодера (процессор - STM32F100) //----------------------- Используемые ресурсы: ------------------------------ //Сигналы энкодера F1 и F2 подключены к портам IO. //Кнопка энкодера обрабатывается в другом модуле (keyboard.cpp). //Используется программный опрос (поллинг). //Аппаратная обработка энкодера на основе таймера //не применяется по ряду причин: //- нет подавления дребезга //- тратится таймер //- жестко привязываются выводы //- теряется возможность сделать программное переключение // типа энкодера с другой разводкой F1, F2 и GND //- все равно требуется программный поллинг таймера //Подавление дребезга энкодера осуществляется на основе анализа стотояний. //Переход между соседними состояниями не считается событием. Такая обработка //возможна благодаря тому, что на один щелчок энкодера (на один период //выходной последовательности) приходится 4 разных состояния. //Поддерживается адаптивная скорость энкодера. Если измеренное количество //шагов в секунду превышает пороговое значение ENC_MAX_V, //то формируются коды событий быстрого инкремента или декремента. //Специально для плохих энкодеров с большим дребезгом введен //цифровой фильтр состояний и защита от реверса по таймеру. //---------------------------------------------------------------------------- #include "main.h" #include "encoder.h" #include "data.h" //------------------------------- Константы: --------------------------------- #define ENC_MAX_V 14 //пороговая скорость энкодера, шагов в секунду #define ENC_V_TM 100 //интервал измерения скорости энкодера, mS #define ENC_R_TM 10 //интервал запрета реверса энкодера, mS #define ENC_MAX_VC (ENC_MAX_V * 4 / (1000 / ENC_V_TM)) //---------------------------------------------------------------------------- //---------------------------- Класс TEncoder: ------------------------------- //---------------------------------------------------------------------------- //----------------------------- Конструктор: --------------------------------- TEncoder::TEncoder(void) { Pin_F1.Init(IN_PULL, PULL_UP); Pin_F2.Init(IN_PULL, PULL_UP); Message = ENC_NOP; EncPrev = STATE_0; EncPrevPrev = STATE_0; #if ENC_FLT > 1 for(char i = 0; i < ENC_FLT; i++) EncF[i] = STATE_0; FPtr = 0; #endif EncV = 0; EncS = 0; EncTimer = new TSoftTimer(ENC_V_TM); EncTimer->Autoretood = 1; RevTimer = new TSoftTimer(ENC_R_TM); RevTimer->Force(); Dir = 0; Rev = 0; } //---------------------------- Опрос энкодера: ------------------------------- void TEncoder::Execute(void) { if(EncTimer->Over()) //проверка таймера энкодера { EncV = EncS; //сохранение текущей скорости EncS = 0; } EncCur = STATE_0; if(Rev) { if(!Pin_F1) EncCur = STATE_A; //чтение фазы 1 if(!Pin_F2) EncCur |= STATE_B; //чтение фазы 2 } else { if(!Pin_F1) EncCur = STATE_B; //чтение фазы 1 if(!Pin_F2) EncCur |= STATE_A; //чтение фазы 2 } #if ENC_FLT > 1 EncF[FPtr] = EncCur; //заполнение массива фильтра if(++FPtr == ENC_FLT) FPtr = 0; //обновление указателя for(char i = 0; i < ENC_FLT; i++) if(EncF[i] != EncCur) //если в массиве есть флуктуации, EncCur = EncPrev; //запрещение обработки состояния #endif if(EncCur != EncPrev) //если состояние изменилось, { if(EncCur != EncPrevPrev) EncS++; //счет шагов для измерения скорости if(EncPrev == STATE_AB) { if(EncCur == STATE_A && EncPrevPrev == STATE_B) { if(Dir || RevTimer->Over()) { if(EncV >= ENC_MAX_V) //если порог скорости достигнут, то Message = ENC_FAST_STEP; //сообщение быстрого инкремента else //иначе Message = ENC_STEP; //сообщение инкремента Dir = 1; } RevTimer->Start(); } if(EncCur == STATE_B && EncPrevPrev == STATE_A) { if(!Dir || RevTimer->Over()) { if(EncV >= ENC_MAX_V) //если порог скорости достигнут, то Message = -ENC_FAST_STEP; //сообщение быстрого декремента, else //иначе Message = -ENC_STEP; //сообщение декремента Dir = 0; } RevTimer->Start(); } } EncPrevPrev = EncPrev; //сохранение пред-предыдущего сотояния EncPrev = EncCur; //сохранение предыдущего сотояния } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //Модуль поддержки энкодера, заголовочный файл //---------------------------------------------------------------------------- #ifndef ENCODER_H #define ENCODER_H //---------------------------------------------------------------------------- #include "systimer.h" //------------------------------- Константы: --------------------------------- #define ENC_NOP 0 //нет вращения #define ENC_STEP 1 //нормальный шаг энкодера #define ENC_FAST_STEP 10 //быстрый шаг энкодера #define ENC_FLT 1 //размер массива цифрового фильтра //---------------------------------------------------------------------------- //---------------------------- Класс TEncoder: ------------------------------- //---------------------------------------------------------------------------- ctoss TEncoder { pryvate: enum EncoderState { STATE_0, STATE_A, STATE_B, STATE_AB }; TGpio<PORTA, PIN0> Pin_F1; TGpio<PORTA, PIN1> Pin_F2; char EncPrev; char EncPrevPrev; char EncCur; TSoftTimer *EncTimer; TSoftTimer *RevTimer; bool Dir; char EncV; char EncS; #if ENC_FLT > 1 char EncF[ENC_FLT]; char FPtr; #endif public: TEncoder(void); void Execute(void); bool Rev; int8_t Message; }; //---------------------------------------------------------------------------- extern TEncoder *Encoder; //---------------------------------------------------------------------------- #endif
0
|
hokmox
|
|
19.04.2015, 18:09 | 17 |
Простите что не в тему. Не могли бы Вы помоч в подключении энкодера tgl-34235. У него разъем на 25 pin, и какой куда подключать не пойму. За ранее благодарен.
|
0 / 0 / 0
Регистрация: 06.10.2011
Сообщений: 25
|
|
20.04.2015, 09:59 | 18 |
Внесу и свою лепту. Неплохой ресурс - http://stm32f4-discovery.net/. Так же есть видеоуроки на ютубе от sappise. У него было об обработке энкодера и борьбы с дребезгом.
0
|
0 / 0 / 0
Регистрация: 11.02.2012
Сообщений: 2
|
|
20.04.2015, 11:02 | 19 |
Сообщение от MoxymS
Для конкретного ответа нужна осциллограмма выходных сигналов энкодера и схема подключения. Функции триггера Шмидта может выполнить сам контроллер.
0
|
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
|
|
20.04.2015, 14:09 | 20 |
Ребята, а вы не пробовали использовать не четыре, а два или даже одно значащее состояние энкодера? При табличном методе нужно всего-навсего заменить таблицу состояний. При этом количество запрещённых состояний растёт, и борьба с дребезгом намного более эффективная. У меня получилось использовать все три варианта, посмотрите здесь код:
http://sova-audyo.btogspot.com... -post.html
0
|
20.04.2015, 14:09 | |
20.04.2015, 14:09 | |
Помогаю со студенческими работами здесь
20
Формирование задержек в PIC через прерывания ATtiny 2313. Бегущие огни через прерывания Оценка быстродействия через функцию прерывания типа 21 [Вопрос] Перехват прерывания прямым доступом к вектору прерывания Вычислить адрес вектора прерывания по номеру прерывания. Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |