Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AVR-MT-128 и энкодер
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
PaulB
Есть отладочная плата AVR-MT-128 и подключоный к ней энкодер вращения ЛИР-158 2500имп/мин. Написал прошивку но она неуспевает считать все импульсы и зависает, при установке более простого энкодера прошивка работает исправно. Вопрос: как увеличить быстродействие контроллера?
konstan
Цитата(PaulB @ May 7 2010, 16:46) *
ЛИР-158 2500имп/мин.


может 2500 имп/оборот?
Какова скорость вращения вала энкодера и какова частота импульсов.

А вы устраняли "дребезг"?
x736C
И на чем написана программа, и каким образом она написана? Может можно оптимальней.
PaulB
Цитата(konstan @ May 7 2010, 17:15) *
может 2500 имп/оборот?
Какова скорость вращения вала энкодера и какова частота импульсов.

А вы устраняли "дребезг"?


Да, Вы правы2500имп/оборот
В паспорте написано что мах.частота вращения вала 10000об/мин и выходного сигнала 2,5МГц

Пишу в кодвижене
вот часть кода:
CODE
while(PINA.1==1){ //Стоп
if (PINB.2==1) {
while(PINB.2==1){

}
q=q+1;
}}
haker_fox
Цитата(PaulB @ May 8 2010, 02:32) *
Да, Вы правы2500имп/оборот

Однако, такие частоты нужно обрабатывать аппаратно, а не программно (ИМХО).
Как вариант, Вы можете использовать специализированные микросхемы, предназначенные для этого, либо (если нет дребезга) что-нибудь на базе D-триггеров и счетчиков из дискретной логики. Но еще лучше, опять же ИМХО, взять CPLD и организовать на ней необходимые функции.
Если нужно программно, то не следует забывать, что частота опроса энкодера должна быть в несколько раз выше максимальной частоты импульсов с энкодера для конкретного случая. Например, если Вы будете вращать вал с максимальной скорость 10 об/сек, то частота опроса может быть 10 * 2500 *4 = 100 кГц. Т.е. в 4 раза больше. А с учетом цифровой фильтрации различных помех и еще выше. Таким образом, все ресурсы МК будут затрачены на обработку энкодера.
PaulB
Понятно, лучше обрабатывать энкодер аппаратно, значит датчик подключаем к спецовой микрухе (вопрос только к какой и какая лучше?) и микруху к выводам прерывания на мк, или можно к любым выводам?
Хотя для моих целей наверное и программное решение пойдет, только вот как это сделать? - не представляю.
Duhas
не мегу мона на прерывание повесить один канал, второй читать в прерывании..

а вообще для норм энкодеров с приличным разрешением - нужно хардварное считывание... либо как писали выше.. либо менять МК ...
RW9UAO
на INT0 повесить и не париться.
Stas
Для ЛИР-158 на 5000 дискрет на оборот делал энкодер со счетчиком приращения на max7128s, считывал контроллером уже обработанные данные.
При реализации программы энкодера обратите внимание на следующий нюанс - при неподвижном вале ЛИРА по одной из линий возможно прохождение ложных импульсов, которые вызовут ошибку подсчета перемещения. В принципе видел эту ошибку и при вращении вала ЛИР шаговым приводом. Поэтому инкремент/декремент счетчика положения следует осуществлять при смене состояния на обеих линиях датчика.
=GM=
Цитата(PaulB @ May 7 2010, 11:46) *
Есть отладочная плата AVR-MT-128 и подключеный к ней энкодер вращения ЛИР-158 2500имп/об, как увеличить быстродействие контроллера? В паспорте написано что мах. частота вращения вала 10000об/мин и выходного сигнала 2,5МГц


Что если для увеличения быстродействия сигнал канала А подать на int0 и counter1, а сигнал канала B на int1 и counter3? Почти аппаратное решение без всяких затрат :-).

Кстати, откуда 2.5 МГц, если 2500*10000/60=416667=417кГц максимум?
PaulB
Натолкнули меня на идею использовать D-триггер, а в прошивке домножать на коэффициент деления. Что думаете по этому поводу?
=GM=
Ну так, timer/counter1 и есть цепочка D-триггеров.
PaulB
В паспорте на датчик рекомендуется использовать ИС AM26LS32 и AM26C32, но толком не чего на них найти не могу. Может кто нибудь работал с ними или знает о них что нибудь?
SysRq
Цитата(PaulB @ May 11 2010, 20:17) *
..AM26LS32 и AM26C32 ..кто нибудь работал с ними или знает о них что нибудь?
А что конкретно интересует? Это всего лишь приёмники дифференциального сигнала (пара A+\A- в один A), они ничего не считают. Даташиты Google укажет при поиске по названию м\с.
PaulB
Да даташиты в основном все на буржуйском. Рас они ничего несчитают, то к чорту их.
Значит надо какуюто схему на логике искать.
PaulB
А можно просто сделать на логике счетчик и снимать с него данные с помощью мк?
haker_fox
Цитата(PaulB @ May 13 2010, 01:37) *
А можно просто сделать на логике счетчик и снимать с него данные с помощью мк?

Цитата(haker_fox @ May 8 2010, 13:10) *
Как вариант, Вы можете использовать специализированные микросхемы, предназначенные для этого, либо (если нет дребезга) что-нибудь на базе D-триггеров и счетчиков из дискретной логики. Но еще лучше, опять же ИМХО, взять CPLD и организовать на ней необходимые функции.
Vetal-Soft
Вот так я делал на Mega16.
Работает без глюков при частоте импульсов 500 Гц. Тактовая МК 16МГц.
Фаза А сидит, одновременно, на INT0 (нарастание) и INT1 (спад).

Код
#include <avr/io.h>
#include <avr/interrupt.h>
  ...
#define PHASA_B_PORT     PORTD
#define PHASA_B_DDR      DDRD
#define PHASA_B_PIN      PIND
#define PHASA_B_n        1  
  ...
volatile signed char count_temp;
  ...
ISR (INT0_vect)
{
    if (bit_is_clear(PHASA_B, PHASA_B_n))
        count_temp++;    
}

ISR (INT1_vect)
{
    if (bit_is_clear(PHASA_B, PHASA_B_n))
        count_temp--;
}

void int_init ( void )
{
    PHASA_B_DDR  &= ~(1 << PHASA_B_n);
    PHASA_B_PORT &= ~(1 << PHASA_B_n);
    count_temp = 0;
    MCUCR = (1 << ISC01) | (1 << ISC00) | (1 << ISC11) | (0 << ISC10);
    GICR  |= (1 << INT0) | (1 << INT1);    
}

int main ( void )
{
    signed char count_temp2;
    long counter;
    ...
    int0_init();
    sei();
    ...
    while(1)
    {
        ...
        cli();
        count_temp2 = count_temp;
        sei();
        counter += count_temp2;
        cli();
        count_temp -= count_temp2;
        sei();
        ...
    };
    return 0;
}
PaulB
C вывода каждого триггера счетчика, сигнал идет параллельно счетчику на МК?
На мк снимаем двоичный сигнал и переводим его в десятиричный формат, тем самым узнаём сколько импульсов мы имеем в данный момент?
arisov
PaulB вот эту темку http://electronix.ru/forum/index.php?showtopic=60502 посмотрите (если конечно раньше не видели).
PaulB
Нашел схемку, думаю выдернуть из неё счетную часть. Что вы об этом думаете?
http://radiokot.ru/circuit/digital/measure/07/index.shtml
PaulB
А кто нибудь, что нибудь, о таких микросхемах слыхал?
LS7084
HCTL 2032
haker_fox
Цитата(PaulB @ May 18 2010, 16:26) *
А кто нибудь, что нибудь, о таких микросхемах слыхал?
LS7084
HCTL 2032

Да, но не применял.
Maik-vs
Оба вывода энкодера подаются на 2 прерывания по обоим фронтам. Или (лучше) опрашивать энкодер с частотой, достаточной для ловли его состояний. Обработчик прерывания один и тот же:

Читаем энкодер. При вращении вперёд он проходит значения 1-0-2-3-1-0-2-3..., назад - наоборот. Если считанное состояние 2, предыдущее 0, пред-предыдущее 1 то шаг++. Если текущее 1, предыдущее 0, пред-предыдущее 2 то шаг--. Всё другое - это дрожание вала ака "дребезг". Регистровая переменная "шаг" изменяется в прерывании, переменная "шаги" в основной программе не реже, чем 100 шагов: шаги+= шаг; шаг=0.
Анализ, изменилось ли состояние, занимает 9 циклов контроллера и шаг++/шаг-- ещё 14. Ну и на вход-выход в прерывание ваш С-компилятор накрутит не знаю сколько smile.gif
PaulB
Сделал счетчик от прерывания, оказалось что такого вполне должно хватить.
Энкодер подключен напрямую к мк без логики т.к. сначало хочется хотябы просто считать импульсы в одном направлении.
Считать то вроде считает, но неправильно. энкодер отключил, после включения питания на дисплее показания сразу добегают до пары тысяч, и изменяются каждую секунду.
значит дело в коде?
Код
#include<mega128.h>
#include <delay.h>
#include <stdlib.h>  
#include <stdio.h>  
#include <lcd.h>

#asm
.equ __lcd_port=0x15;PORTC
#endasm

unsigned long q;        
interrupt [EXT_INT0] void ext_int0_isr(void)   // процедура обработки прерывания
{
  
          q++;             //с каждым прерыванием значение переменной увеличивается на 1
          
}
                
int main()
{
         char w[32];    //для преобразования числа в строку/символы
DDRA=0x00;
PORTA=0x00;
DDRB=0xF0;
PORTB=0x00;
DDRE = 0b00110000;
PORTE = 0b00100000;
lcd_init(16);


  lcd_gotoxy(5,0);
      lcd_putsf("Hello!");
   Privet();    
     delay_ms(3000);
      
       while(1) {
       q=0;
      lcd_clear();
    
      Go();
      lcd_putsf(" ");
      Stop();
       lcd_putsf(" ");
      Reset();
      delay_ms(10);
            
    if  (!(PINA & 0b00000001))  {                //Пуск
    lcd_clear();
      Go();
      delay_ms(1000);
          SREG.7 = 1;
        EIMSK = 0x01;
        EICRA = 0x0C;
        EICRB = 0x0C;  
          
       while(PINA & 0b00000100){                 //Сброс
         lcd_clear();
        sprintf(w,"adc= %d\n",q);
        lcd_puts(w);
         delay_ms(50);
        }
       lcd_clear();          
         Reset();
         delay_ms(2000);
         }
          
      }        
  return 0;

}
sKWO
Цитата
значит дело в коде?

Риторический вопрос laughing.gif
Вы дребезг как давите?
Датчик кодируется кодом Грея?
Попробуйте применить RC-цепочку на входе ИНТ0 с постоянной цепи скажем так в 5 раз меньшей максим. частоты импульсов, или примените логику на входе для подавления дребезга например на елементах исключающее ИЛИ.
PaulB
я же вроде указал что датчик от платы совсем отключил, а прошивка в момент работы сама считает не пойми какие прерывания, хотя должна показывать 0 т.к. энкодер отключон и прерываний не происходит.

о дребезге позже, как будет хотябы болие менее работать с датчиком.
sKWO
Цитата(PaulB @ Aug 11 2010, 19:04) *
я же вроде указал что датчик от платы совсем отключил, а прошивка в момент работы сама считает не пойми какие прерывания, хотя должна показывать 0 т.к. энкодер отключон и прерываний не происходит.

о дребезге позже, как будет хотябы болие менее работать с датчиком.

Посмотрите для начала как генерирует код начальной инициализации Ваш помощник встроенный в Вашем компиляторе.
Посмотрите как опрашиваются кнопки.
Что такое Go(); , Stop();, и Reset(); остаётся только догадываться.
Ваши значения счётчика могут так изменятся из-за наводок на входе ИНТ0 или неправильной инициализации МК.
Что в MCUCR и GICR ? ЗачемВам здержки? посмотрите хотябы код предложенный Vetal-Soft. прочитайте ссылку данную выше. Обнлвление на ЖКИ сделайте к примеру по прерыванию таймера а не в цикле
PaulB
Все заработало. считает нормально smile.gif
теперь незнаю как сделать реверс, чтобы сначало при вращении вала значение увеличивалось, а при в ращении в другую сторону уменьшалось. наверное надо использовать логику?
backa
я когда-то делал на асм для старой 8515 - тоже через прерывания - датчики положения для станков ЧПУ по принципу sin-cos - всё работало как часы - в любую сторону - делал по фронту .
Мой коллега сделал на рассыпухе (ИЕ7 и другая логика) а я программно реализовал на аврке
PaulB
А поподробнее описать можете, как по фронту ?
backa
Идея в следующем - там были разнесённыу по фазе 2 сигнала sin и cos - и в зависимости который из них первый по фазе соответственно получаем направление движения(вращения) - я не стал мудрить и повесил оба сигнала на прерывания 8515 - их там как раз 2 вывода и в начальный пуск настраивал сработку прерывания по нарастающему фронту . Как только приходил один из импульсов в обработчике прерывания менял на сработку этого вывода на уже спадающий фронт - дабы дождаться либо окончания импульса или наоборот если пошёл реверс то отмену прибавки в счётчике и уже ожидания окончания импульса для того что-бы его вычесть из текущего числа импульсов
Наверно несколько сумбурно но всё вроде просто и работает - единственно что не устранил - это всегда была погрешность +-1 - тутелька в тютельку не получилось - да и не надо это было - девайс нужен был для проверки датчиков перемещения на станке не снимая их (иногда пол станка для этого нужно было разобрать что-бы снять "линейку" - кто знает меня поймёт)
PaulB
А кодом неподелитесь, может легче будет? А то все равно что то недопойму во эту часть:
Цитата(backa @ Aug 13 2010, 11:20) *
Как только приходил один из импульсов в обработчике прерывания менял на сработку этого вывода на уже спадающий фронт - дабы дождаться либо окончания импульса или наоборот если пошёл реверс то отмену прибавки в счётчике и уже ожидания окончания импульса для того что-бы его вычесть из текущего числа импульсов

backa
код надо искать - давно было и разово делась - про реверс - датчик может двигаться в противоположные стороны поэтому импульсы прибавляются в счётчике или отнимаются - когда импульс отсчёта прошёл то всё просто а если во время действия импульса отсчёта произошёл реверс движения то тут только по фронтам можно отследить с точностью до +-1 ....Если по-простому - настраиваем изначально на сработку прерывания по нарастающему фронту... как только произошло прерывание то запоминаем что импульс начался и в теле прерывания меняем срабатывание прерывания на спадающий - т.е. ждём завершения импульса ...всё .
PaulB
получилось и вроде работает! smile.gif
backa
если с помощью моих не очень "понятных разъяснений" то я рад ....
PaulB
Разяснения то были понятны, вот только программно это реализовать не мог до недавнего времени.
СПАСИБО!!!!!!
PaulB
Возникла очередная проблемка, да бы не создавать новую тему и не захламлять форум, задам вопрос тут: Данные с датчика требуется отправлять на комп - с этой задачей с горем на пополам справился. Так же требуется кое какие данные отправлять на внешнее устройство, обмен данными ведется через интерфейс 232 по USART, но вот эту задачу почему то не удается реализовать.При использовании процедуры getchar() программа виснет. помогите плиз.
Vetal-Soft
Видимо ждет данных ))
Прочиайте это: http://chipenable.ru/index.php/programming...uart-queue.html
PaulB
Сделал вот таким образом, виснуть перестало, но и непринимает нечего:
if (rx_counter1 !=0){
a=getchar1();
putchar1(a);
}
else putchar1('a') ;
PaulB
Продоржаю тему подключения энкодера ЛИР к контроллеру.
Немного истории: предидущее подключение энкодера было "прямым", датчик напрямую подключался к контроллеру и сигналы считались от прерывания (счетчик был реверсивным), однако счет был неверным так как в датчике наблюдался дребизг.
параметры:
мах. частота вращения вала на который закреплен датчик: 5000 об/мин
датчик: 2500 имп. на оборот
частота работы мк: 16МГц

Что хочется сделать теперь:
1. Избавиться от дребизга и осуществить реверс
2. Использовать Для счета таймер/счетчик
3. Исбользовать в качестве контроллера Xmega c частотой работы в 32МГц, так как помимо счета надо выполнять еще и другие операции.

==================================
начнем с пункта №1.
Для избежания дребизга планируется использовать оптопары, то есть каждый сигнал канала будет проходить через свою оптопару. Кто что об этом думает? Как лучше избавиться от дребезга? Аппаратно или программно?

Реверс планирую осушествить добаврением к схеме двух корпусов логики триггера и элемента "И".

Жду коментариев, предложений?
ILYAUL
Цитата
5000 об/мин

Это 83,33.... об/сек - зачем Xmega с 32 000 000 операций за секунду , на что может не хватить 16 000 000 оп/сек?
А от датчика придёт только ~ 42 импульса за секунду.

Цитата
Для избежания дребЕзга планируется использовать оптопары
и чем это должно помочь?
PaulB
это как это вы водсчитали что 42 импульса в секунду?
В секунду с датчика придет: 83.33*2500=300имп в сек

оптопара: зглаживание пульсаций
ILYAUL
Цитата(PaulB @ Nov 28 2010, 01:17) *
В секунду с датчика придет: 83.33*2500=300имп в сек


Да, правильно, посмотрел в этот момент на об.мин, правильно 300 . И что это меняет из 16 000000?

Цитата
оптопара: зглаживание пульсаций

За счёт чего , ёмкости самой оптопары, ну очень острые пички он уберёт , остальное пропустит
PaulB
Да, чисто для счета 16 МГц хватит, но мне надо будет еще проделать несколько операцай помимо счета, для которых может и нехватить такой скорости. А если и хватит то впритык.

И как же посоветуете избавиться от дребезга?
Vasily_
Цитата
как же посоветуете избавиться от дребезга?


У вас энкодер уже оптический, откуда там дребезг?
_Pasha
Ну, ребята, вы и жжете!
Темы по форуму бродят аки призраки. Поиск рулит.
Блин, на что может не хватать 16Мгц? cranky.gif
ILYAUL
Цитата
Да, чисто для счета 16 МГц хватит, но мне надо будет еще проделать несколько операцай помимо счета, для которых может и нехватить такой скорости. А если и хватит то впритык.

Цитата
_Pasha Блин, на что может не хватать 16Мгц?

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

Цитата
Vasily_ У вас энкодер уже оптический, откуда там дребезг?

Цитата
PaulB однако счет был неверным так как в датчике наблюдался дребизг
Duhas
83.33*2500=300имп в сек

это очень интересно... как при 83 оборотах в секунду при 2500 импульсов на оборот получается 300 импульсов в секунду ? может 207500?

а теперь глядим.. на 1 импульс с обычной мегой надо - войти в прерывание, прочитать пин, по условию уменьшить или увеличить счетчик. выйти.. повыполнять основную прогу.. ну тактов в 20 могет прерывание обойдется по минимуму.. в принципе тянет.. могет еще успеть чота чуток поделать.. по грубым прикидкам..
ILYAUL
Цитата(Duhas @ Nov 28 2010, 14:03) *
83.33*2500=300имп в сек

это очень интересно... как при 83 оборотах в секунду при 2500 импульсов на оборот получается 300 импульсов в секунду ? может 207500?

Помоему запутались совсем и начнём считать с этих данных
Цитата
Есть отладочная плата AVR-MT-128 и подключоный к ней энкодер вращения ЛИР-158 2500имп/мин

Отсюда 41,66666.... импульсов в секунду, которые по идее и надо считать, а сколько их будет за N- ое количество оборотов , не столь важно
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.