Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Энкодер и дребезг
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
BigCoster
Спасибо всем за ответы, многие из них очень информативные, в часности по поводу реализации
энкодеров

При частоте резонатора 12МГц один цикл равен 0,1мкс.
Уменя 6МГц значит 0,2мкс.
Померял LPT анализатором период дребезга около 0,05мкс.
Имеем апаратный фильтр, ошибка в программе.
Если ошибся поправляйте!!!

И ещё один такой вот вопрос, выходящий из всего выше сказанного :
Как (где) используется тайиер/счётчик в режиме счётчика ???
mandr
Имею по работе проекты, в которых используются датчики импульсов типа ПДФ-3. Даже оставив датчик
без приёмной цифровой схемы, он самопроизвольно генерирует импульсы, когда берёшся за вал рукой,
при этом я нахожусь на полу из металлических плит. При коммутации какой-либо нагрузки происходит аналогичное явление. Побороть данного вида помехи позволило заземление общей точки питания самого датчика. Поэтому, считаю что Вам необходимо начать поиск в начале с самого энкодера, потом схемы, на которую он работает, а затем уже саму программу.
BigCoster
Я для себя решил, что без осциллографа схему менять не буду (общая точка датчика на земле, схемы включения я приводил, сказали вроде б нормально).
Не могу понять, как правильно организовать задание расстояния, которое должен проехать моторчик.
у меня просто: пока держишь кнопку счётчик считает, а программа проверяет не отпущена ли кнопка,
бросаем кнопку, нажимаем другую и сохраняем.
после всего этого едем и видим, что не совсем так же проехали, как при настройке, а больше и тем больше проезжаем,
чем больше раз нажимали книпку задания расстояния тем .. cranky.gif cranky.gif cranky.gif
А сейчас вообще не пишет данные в EEPROM, вернее возвращает постоянно одинаковое значение.
И концевой датчик тоже сошел с ума .. cranky.gif
OlegIvanov
1. Двухканальный энкодер (о чем упоминалось выше), - там максимальная абсолютная неточность в пределах импульса (и сразу защита от всяких любых дребезгов если правильно отрабатывать).
2. В прерывании переполнения таймера-счетчика организовать программный счетчик и
считать каждый импульс (событие 255 прописанных +1 пришедший).
3. Если пункт 1 не устраивает то пункт 2 + антидребезг. Как организовать антидребезг - это насколько хватит фантазии. Триггер Шмидта помогает - стандартное решение для одноканальных энкодеров. Расчитанно именно на ситуацию когда метка в слабо-определенном состоянии.

К сожалению трудно четко представить чего там у вас происходит.
MaslovVG
Просмотрел ветку. Мое мнение. Подавить дребезг при подаче импульсов прямо на T1 програмно проблематично, если вообще возможно. Нужно искать причину возниновения.
Ничего не сказано про осветитель. Возможность посторонней засветки.
Для уменьшения влияния дрожания крыльчатки увеличить размер светового пятна у увеличить гистерезис датчика. Осцилограммы мне совсем не нравятся. Лучше всего если со светодиода (перед компаратором) при вращении крыльчатки будет идти треугольник.
vladimir_orl
Тема конечно устарела, но сейчас столкнулся с тем же. Посадил выход от энкодера на внешнее прерывание на меге128 (INT2). Сразу побежал дребезг. Сделал напрямую на порт:
Код
m_value = PIND & (1 << PD2);
        if (m_value == 0){
            m_trigger = 1;
        } else {
            if (m_trigger == 1){
                ++m_counter;
            }
            m_trigger = 0;
        }


всё хорошо стало. Потому что внешнее прерывание ещё использовать уметь надо.
Tarbal
Цитата(vladimir_orl @ Sep 3 2013, 09:44) *
.


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

Я делал обработчик в более удобной среде там было два смещенных датчика с перекрытием как синус и косинус. Правда надо было етхе регистрировать направление. Итого было четыре области, которые я мог различить. 00, 01, 11 и 10 если бит 0 еыто сигнал одного датчика, а бит 1 второго. Далее я построил машину состояний (автомат) с четырьмя состояниями и разрешил в ней переходы между состояниями, соответствующиими соседним значениям датчиков. То есть если я в состоянии 01, то переход в 11 или 00 возможен, а в 10 нет. Расстояние хемминга 1 инициирует переход. И моя модель крутилась вслед за датчиком.
Genadi Zawidowski
Какая скорость прихода импульсов с валкодера? Разрешение? Крутит человек или это колесо на производстве чего-то?
Дребезг давить аппаратно (с опичтеских не требуется), если быстродействие озволяет, оба сигнала завести на прерывания. Обработчик общий на двоих:


Код
static uint_fast8_t old_val;

void spool_encinterrupt(void)
{
    const uint_fast8_t new_val = hardware_get_encoder_bits();    /* Состояние фазы A - в бите с весом 2, фазы B - в бите с весом 1 */

    // dimensions are:
    // old_bits new_bits
    static const int_fast8_t graydecoder [4][4] =
    {
        {
            +0,        /* 00 -> 00 stopped                */
            -1,        /* 00 -> 01 rotate left            */
            +1,        /* 00 -> 10 rotate right        */
            +0,        /* 00 -> 11 invalid combination */        
        },
        {
            +1,        /* 01 -> 00 rotate right        */
            +0,        /* 01 -> 01 stopped                */
            +0,        /* 01 -> 10 invalid combination */
            -1,        /* 01 -> 11 rotate left            */
        },
        {
            -1,        /* 10 -> 00 rotate left            */
            +0,        /* 10 -> 01 invalid combination */
            +0,        /* 10 -> 10 stopped                */
            +1,        /* 10 -> 11 rotate right        */
        },
        {
            +0,        /* 11 -> 00 invalid combination */
            +1,        /* 11 -> 01 rotate right        */
            -1,        /* 11 -> 10 rotate left            */
            +0,        /* 11 -> 11 stopped                */
        },
    };


#if ENCODER_REVERSE
    position1 -= graydecoder [old_val][new_val];
#else
    position1 += graydecoder [old_val][new_val];
#endif
    old_val = new_val;
}


В инициализации не забыть
Код
    old_val = hardware_get_encoder_bits();    /* Состояние фазы A - в бите с весом 2, фазы B - в бите с весом 1 */

чтобы ложные шаги при ресете не проходили на стоящем валкодере.
Tarbal
Цитата(Genadi Zawidowski @ Sep 9 2013, 22:13) *
.


Красиво.
Дребезг даже не подавленный не будет мешать, однако будут лишние вызовы прерываний, что не есть хорошо. Если время оборота составляет несколько миллисекунд, то возможно поллинг будет лучшим подходом.
A. Fig Lee
Цитата(Tarbal @ Sep 4 2013, 16:02) *
... Далее я построил машину состояний (автомат) с четырьмя состояниями и разрешил в ней переходы между состояниями, соответствующиими соседним значениям датчиков. То есть если я в состоянии 01, то переход в 11 или 00 возможен, а в 10 нет. Расстояние хемминга 1 инициирует переход. И моя модель крутилась вслед за датчиком.

Классная идея. disco.gif
Tarbal
Цитата(A. Fig Lee @ Sep 10 2013, 05:07) *
Классная идея. disco.gif


Я на похожем алгоритме сделал модем приемник FSK 1200-2200 на PIC16C71 с системной частотой 1 мегагерц. Подобные на DSP 40 мегагерцовых делали sm.gif

У меня дома есть действующая модель. Приходи покажу.
A. Fig Lee
Цитата(Tarbal @ Sep 10 2013, 20:05) *
Я на похожем алгоритме сделал модем приемник FSK 1200-2200 на PIC16C71 с системной частотой 1 мегагерц. Подобные на DSP 40 мегагерцовых делали sm.gif

У меня дома есть действующая модель. Приходи покажу.

Мы в одном городе? sm.gif
Tarbal
Цитата(A. Fig Lee @ Sep 11 2013, 06:14) *
Мы в одном городе? sm.gif


В разных, но нет ничего невозможного sm.gif
A. Fig Lee
Цитата(Genadi Zawidowski @ Sep 9 2013, 14:13) *
.


Идея красивая, но чтото я не понял как дребезг давится.
Например, у меня 11 на входе, потом я получил 0:
11-10, далее в результате дребезга 10-11, 11-10, 10-11 и так далее.
A. Fig Lee
Добил.

В принципе, избавлятся от дребезга в енкодере проще, чем в кнопке.
Так как начало и конец импульса всегда отделены началом и концом другого импульса.
Типа:
Нажал1-Нажал2-Отжал1-Отжал2.
Между нажал1 и отжал1 всегда есть нажал2.

Вывод: надо играть на edges.
Не важен дребезг, сколько не дребезжи, после первого edge сигнал игнорируем
до активности на другом сигнале.
Еще мысль:
после первого edge имеем направление движения:
или 10, или 01, после второго edge фиксируем предыдущее состояние (направление).

Наваял код в Microchip X Lab xc8
для PIC18F14K50 - то, что под рукой было.

Преобразовывает в gray code - в зависимости от направления вращения состояния
меняются:

00
01
11
10
00

или
00
10
11
01
00

CODE
/*
* File: main.c
* Author: dmitriy
*
* Created on September 17, 2013, 10:55 PM
*/

#include <htc.h>
#include <stdlib.h>
#include <stdint.h> /* For uint8_t definition */

#include "config.h"

uint8_t values;

void Init()
{
// Input PB4, PB5 for encoder
// Output PC1, PC2
TRISC = 0xF1;
ANSEL = 0;
ANSELH = 0;

// Enable pullups on PORTB
INTCON2bits.NOT_RABPU = 0;

//Enable interrupt on change for PB4, PB5, PB6
IOCBbits.IOCB4 = 1;
IOCBbits.IOCB5 = 1;

//Enable interrupt on change
INTCON2bits.RABIP = 1;
INTCONbits.RBIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;


}

void interrupt isr(void) {
if (INTCONbits.RBIF) {
values = (PORTB & 0x30) >> 4;
INTCONbits.RBIF = 0;
}
}


/*
*
*/
int main(int argc, char** argv) {
uint8_t edges = 0;
uint8_t edge;
uint8_t old_values;
uint8_t grey = 0;
uint8_t myvalue;

Init();
old_values = (PORTB & 0x30) >> 4;

while (1) {
myvalue = values;
edge = myvalue ^ old_values;
old_values = myvalue;
if (edge) {
//activity detected
if (edge != edges) {
//activity on new edge
edges = edge;
if (!myvalue) {
//fix direction
// which depends on edge
if (edge & 0x01) {
switch (grey) {
case 00:
grey = 0x01;
break;
case 0x01:
grey = 0x03;
break;
case 0x03:
grey = 0x02;
break;
case 0x02:
grey = 0x00;
break;
} //switch
} else {
switch (grey) {
case 00:
grey = 0x02;
break;
case 0x02:
grey = 0x03;
break;
case 0x03:
grey = 0x01;
break;
case 0x01:
grey = 0x00;
break;
} //switch
} //if (edge & 0x01)
PORTC = grey << 1;
} //if (!myvalue)
} //if (edge != edges)
}
}

return (EXIT_SUCCESS);
}
A. Fig Lee
Состряпал hardware схемку.
Не тестировал, правда.
Гдето так:

Tarbal
Подавитель дребезга на стейт машине не давит дребезг каждый шаг, но за оборот (4 шага в одном направлении) давит.
Идея в том, что сумму надо поделить на 4 и если она изменилась, то достоверно было событие. При целом делении эффект дребезга становится меньше одного, а значит ноль. тем он и отфильтровывается.
Линь
Цитата(Dog Pawlowa @ Apr 12 2007, 02:00) *
Обычно нужно, чтобы на счетный вход поступал практически идеальный сигнал (с крутыми фронтами).
Иначе на пологом фронте возможно срабатывание счетчика несколько раз от незначительных помех.
Простое добавление интегрирующей цепочки не помогает, естественно.
Попробуйте включить триггер Шмитта между интегрирующей цепочкой и счетным входом, или обработать сигнал программно, как Вам советовали выше.

Согласен. Можно также попробовать поиграть током через датчик (фототранзистор как правило) до пределов по даташиту.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.