Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/132: Рейтинг темы: голосов - 132, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
1

Энкодер через прерывания / зараза дребезг

16.04.2015, 22:09. Показов 24864. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет!
Делаю обработчик сигнала с инкрементального двухфазного энкодера . Алгоритм следующий: <ul>1) на одну фазу сажаю прерывание, что позволяет вести счет тактов
2) т.к. одна фаза отстает/обгоняет другую на полшага, то в обработчике прерывания смотрю вторую фазу для определения направления вращения, если вторая фаза 0 - значит обратный ход, если 1 - значит вперед</ul>Вроде бы все прсто и красиво, но вот проблема - дребезг! Имеется дребез который создает ложные прерывания. Как от него можно избавиться?
Знаю что у STM32 есть аппаратный обработчик энкодера(пользовался и умею настраивать), но в данном случае его использовать не могу. К триггеру Шмитта и другм аппаратным решениям прибегать не хочеться. Можно ли как-то решить эту проблему програмно?

Спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.04.2015, 22:09
Ответы с готовыми решениями:

Задержки на SysTick внутри обработчика прерывания, дребезг
Доброго времени суток. 1. Пытаюсь прикрутить delay на SysTick. При вызове из main все работает...

Энкодер влияет на прерывания, хотя напрямую не подключен.
Attiny2313, к INT1 подключена оптопара в сборе как в мышке и пара резисторов на ней, если окно...

Графика через прерывания на Borland С++ 3.1
Здравствуйте форумчане! Подскажите пожалуйста, может я чего-то не понимаю. Но есть ли в С++ под DOS...

Прерывания звука через Bluetooth устройства
Столкнулся с проблемой прерывания звука на Bluetooth устройствах примерно в январе-феврале....

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

24
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
Япона мать! У STM32 есть таймеры. И у таймеров есть режим "энкодер". И аппаратная защита от дребезга!!!

Ну почему нельзя почитать даташит???

// для решения программно нужно будет реализовать алгоритм антидребезга таймера. Это — костыли и тормоза.
Уважаемый, вы наверное не дочитали пост до конца или же я плохо изъясняю свои мысли)
Знаю что у STM32 есть аппаратный обработчик энкодера(пользовался и умею настраивать), но в данном случае его использовать не могу.
Таймеров умеющих работать с энкодерами всего 4, а у меня их 6, так что на всех не хватает. Или я ошибаюсь?
Поэтому мне и нужно сваять костыли для оставшихся 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
http://asis-kbr.ru/forum/viewtopys.php?f=13&t=141
0
0 / 0 / 0
Регистрация: 21.02.2015
Сообщений: 52
16.04.2015, 23:21 10
Повесьте на таймер.
Вкратце: у вас два бита x и y, и предыдущие значения x1 и y1. Таблица:
x1 x y1 y: ymsrement
0000, 0011, 1100, 1111: - без изменений
0001, 0111, 1110, 1000: +1
1101, 0100, 0010, 1011: -1
Остальные - ошибка.
Логика понятно, но не совсем ясно что значит повесить на таймер. Можно разъяснить? Сделать прерывания по переполнению таймера таймера и там обрабатывать?
Цитата Сообщение от PRS
За эту ссылку огромное спасибо... проштудирую.
ОК, подсказываю простой вариант: в обработчике прерывания от энкодера вы запрещаете этот EXTI, а уже по прошествию, скажем, 30мс, разрешаете обратно (в основном цикле КА).
Я так на STM8 делал.
Такой вариант я тоже рассматривал, но дело в том, что мне в ручную удавалось поставить энкодер в позицию когда он не вращается а счетчик бежит вверх, причем стабильно и достаточно быстро. Поэтому думаю простой задержкой тут не помочь.
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
Делаю обработчик сигнала с инкрементального двухфазного энкодера . Алгоритм следующий: <ul>1) на одну фазу сажаю прерывание, что позволяет вести счет тактов
2) т.к. одна фаза отстает/обгоняет другую на полшага, то в обработчике прерывания смотрю вторую фазу для определения направления вращения, если вторая фаза 0 - значит обратный ход, если 1 - значит вперед</ul>...К триггеру Шмитта и другм аппаратным решениям прибегать не хочеться. Можно ли как-то решить эту проблему програмно?...
Перед разработкой программы рекомендую исследовать Ваш энкодер на предмет "чистоты" выходного сигнала каждой фазы. Если уже известно про дребезг, то дальнейшие программные улучшения внесут дополнительный дребезг уже программный.
Для конкретного ответа нужна осциллограмма выходных сигналов энкодера и схема подключения.
Функции триггера Шмидта может выполнить сам контроллер.
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.04.2015, 14:09
Помогаю со студенческими работами здесь

Формирование задержек в PIC через прерывания
Не могу понять почему период задержки формируемый микроконтроллером на выходе всегда больше в 4...

ATtiny 2313. Бегущие огни через прерывания
Помогите пожалуйста отредактировать/исправить код на авр студио. Задание было таково: - &quot;Создать...

Оценка быстродействия через функцию прерывания типа 21
На языке Си разработать функцию, которая реализует алгоритм пузырьковой сортировки. Оценить...

[Вопрос] Перехват прерывания прямым доступом к вектору прерывания
Всех приветствую! В данный момент разбираюсь с обработкой аппаратного прерывания (прерывание...

Вычислить адрес вектора прерывания по номеру прерывания.
17. По заданному номеру прерывания (13 h) вычислите логические адреса хранения исходных адресов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru