|
Опрос валкодера, Дребезг |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Nov 14 2007, 13:24
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 8-06-06
Пользователь №: 17 866

|
похоже, что я писал этот кусок  как часто опрашиваешь валкодер?
|
|
|
|
|
Nov 14 2007, 16:35
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374

|
Цитата(psw @ Nov 14 2007, 17:24)  похоже, что я писал этот кусок  как часто опрашиваешь валкодер? 1 раз в 1 мсек
|
|
|
|
|
Nov 15 2007, 08:27
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374

|
Валкодеры, их два, подключены по такой схеме Длительность строба 2 мс Вместе с валкодерами подключены и кнопки. Валкодеры опрашиваются, когда на их средний вывод приходит "0". Опрос валкодера, если незадействованы кнопки 1раз в 12 мс
|
|
|
|
|
Nov 15 2007, 15:24
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374

|
Цитата(alexander55 @ Nov 15 2007, 12:44)  Опрашивать надо чаще. Чем выше максимальная скорость, тем чаще. Частота опроса д.б. более, чем в 2 раза больше скорости изменения показаний. Теорема Котельникова- Шенона, однако.  Боюсь, в моём случае это не сработает! Валкодер привязан к сканированию индикатора. Схему нужно изменить, средний вывод посадить на "землю", тогда можно и скорость увеличить! Цитата(Alex B._ @ Nov 15 2007, 12:40)  Обязательно нужно через фильтр пропускать отсчеты. Ниже старый, но рабочий код. Сканируется раз в 200 мкс Код typedef struct __ENC_CB { U08 phs_sample_period;
U16 A_window; U16 B_window;
U16 A_sum; U16 B_sum;
U08 A_mask; U08 B_mask;
U08 Current; U08 Previous;
U08 State;
} ENC_CB;
ENC_CB ENC;
/* =================== */
void adsf (void) { port = ENC_PORT;
if (++ENC.phs_sample_period > (ENC_PHS_SAMPLE_PERIOD_VAL - 1)) { ENC.phs_sample_period = 0;
if (port & ENC_A_PIN) { ENC.A_sum++; ENC.A_window |= ENC.A_mask; } else { if (ENC.A_sum > 0) ENC.A_sum--; ENC.A_window &= ~ENC.A_mask; }
ENC.A_mask <<= 1; if (ENC.A_mask == 0) ENC.A_mask = 1;
if ((ENC.A_window & ENC.A_mask) && (ENC.A_sum > 0) ) ENC.A_sum--;
if (port & ENC_B_PIN) { ENC.B_sum++; ENC.B_window |= ENC.B_mask; } else { if (ENC.B_sum > 0) ENC.B_sum--; ENC.B_window &= ~ENC.B_mask; }
ENC.B_mask <<= 1; if (ENC.B_mask == 0) ENC.B_mask = 1;
if ((ENC.B_window & ENC.B_mask) && (ENC.B_sum > 0) ) ENC.B_sum--;
ENC.Current = ENC.Previous;
if (ENC.A_sum > 5) ENC.Current |= 0x01; else if (ENC.A_sum < 2) ENC.Current &= ~0x01;
if (ENC.B_sum > 5) ENC.Current |= 0x02; else if (ENC.B_sum < 2) ENC.Current &= ~0x02;
if (!ENC.Current) { if (ENC.Previous == 0x01) ENC.State |= ENC_EVENT_UP; if (ENC.Previous == 0x02) ENC.State |= ENC_EVENT_DW; }
ENC.Previous = ENC.Current; } } Спасибо за код, изучаю. Вы какой компилятор используете?
|
|
|
|
|
Nov 15 2007, 17:06
|

Частый гость
 
Группа: Новичок
Сообщений: 111
Регистрация: 10-02-07
Из: St.Petersburg, Russia
Пользователь №: 25 241

|
Цитата(Anjey_N @ Nov 14 2007, 12:49)  Вопрос такой: В системе стоит механический валкодер. Опрашиваю его я вот так Суть вопроса вот какая. Частота опроса входного сигнала должна быть минимум вдвое больше его частоты с которой он изменяется. Это очевидный факт. Но реализовать это в случае многократного пересечения валкодером края одной метки, когда он колеблется возле этого самого края сложно... И не нужно!. Тем более, если валкодер обрабатывается аппаратным прерыванием (к вопросу о том как прибору сделать "DoS" путём перепиливания тупой ножёвкой жгута проводов...) Решение, вкратце таково: алгоритм модифицируется таким образом, что при прохождении края какой-либо метки в одном направлении её прохождение в обратном направлении попросту не фиксируется (запрещается прерывание, например). А фиксируется только прохождение следующего края метки в том же направлении (+1 к позиции) или прохождение не только что пройденного, а предшествующего ему края метки в обратном направлении (-2 к позиции). Может смутно объяснил. Советую просто расписать код Грея в круге и тогда легко будет понять как это работает, и что для реализации алгоритма достаточно запретить (допустим, валкодер имеет два выхода) прерывание от того выхода, который вызвал вот прямо сейчас прерывание -- т.е. поочерёдно разрешается прерывание от первого или второго выхода. Алгоритм полностью решает проблему "дребезга", когда валкодер колеблется на краю метки (быстрая смена +1, -1, +1, -1...) -- не имея возможности его, валкодер, опрашивать с достаточно большой частотой можно потерять в точности, или же, используя прерывания легко заблокировать весь микроконтроллер исключительно в процессе обработки прерываний от валкодера. С описанным алгоритмом подобных проблем нет.
--------------------
[ZX]
|
|
|
|
|
Nov 17 2007, 18:29
|
Участник

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

|
По ссылке выше во вложении есть весь проект на С (компилируется и работает, как это было описано там) для IAR. Дальше эта работа не пошла по причинам, описанным там же.
Себе жа нашел совсем другой вариант решения опроса двух энкодеров и нескольких кнопок: - Взял Atmega48-88-168, там есть pin change interrupt. - На две линии порта повесил один энкодер, еще на две линии - другой энкодер, и на оставшиеся линии - кнопки. Затем опрос порта в обработчике прерывания.
Если это вариант интересен - могу описать подробнее.
|
|
|
|
|
Nov 18 2007, 17:44
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374

|
Цитата(676038 @ Nov 17 2007, 22:29)  По ссылке выше во вложении есть весь проект на С (компилируется и работает, как это было описано там) для IAR. Дальше эта работа не пошла по причинам, описанным там же.
Себе жа нашел совсем другой вариант решения опроса двух энкодеров и нескольких кнопок: - Взял Atmega48-88-168, там есть pin change interrupt. - На две линии порта повесил один энкодер, еще на две линии - другой энкодер, и на оставшиеся линии - кнопки. Затем опрос порта в обработчике прерывания.
Если это вариант интересен - могу описать подробнее. Извините, я сразу не заметил. Буду разбираться с программой, если будут вопросы - задам. Спасибо
|
|
|
|
|
Nov 20 2007, 15:29
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374

|
Я тут провёл один эксперимент. На макетке собрал схему: ATmega16, валкодер, индикация, кварц на 16 МГц. Валкодер подсоединил так: Выводы А и В на PA2 и PA3, средний вывод на землю. Код привожу, если кому-то интересно. Результаты такие: энкодер начал нормально работать , не так , как в предыдущих постах. Начал эксперементировать с задержкой. До 2мс энкодер работает хорошо, потом начинаются глюки. Теперь хочу посадить средний вывод на стробирование. Результаты отпишу позже.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|