SHipa

Подключение и работа с энкодером

28 сообщений в этой теме

SHipa    0

Проблема с состовлением прошивки для энкодера (фирмы PEPPERL+FUCHS по данной программе выдает примерно 330-340 импульсов на оборот) линии данных подключил на int0 и int1 atmega8 прошивку пишe в codevision avr 
Включил прерывания int0 и int1 по любому изменению состояния и повешал на оба прерывания функцию обработки
void enkoder(){
    if((PIND.2==0)&&(PIND.3==0)){input = 0;
    }else if((PIND.2==1)&&(PIND.3==0)){input = 1;
    }else if((PIND.2==1)&&(PIND.3==1)){input = 2;
    }else if((PIND.2==0)&&(PIND.3==1)){input = 3;
    };
    if(input!=buf){
        switch(buf) {
            case 0:{
                if(input == 1) impuls++;
                if(input == 3) impuls--; 
                break;
            }case 1:{
                if(input == 2) impuls++;
                if(input == 0) impuls--;  
                break;
            }case 2:{
                if(input == 3) impuls++;
                if(input == 1) impuls--;  
                break;
            }case 3:{
                if(input == 0) impuls++;
                if(input == 2) impuls--; 
                break;
            };
            buf = input;
        };
    }; 
    ugol=impuls;
};

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    546

Дребезг контактов учитываете ?
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
SHipa    0

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

насчет друбезга ставил сглаживающие конденсаторы на контакты ситуация ухудшалась (от 0,1 до 1мкф) да и энкодер не замыкает контакты а выдает напряжение (не механические контакты) на осцилографе смотрел сильного дребезга незаметно

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Yurkin2015    309

Как только выполняется break, программа выходит из switch{}. Поэтому строчка

buf = input;

не работает. Её надо передвинуть за следующую фигурную скобку, иначе это присваивание никогда не исполняется.

  • Одобряю 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
SHipa    0
10 минут назад, Yurkin2015 сказал:

Как только выполняется break, программа выходит из switch{}. Поэтому строчка


buf = input;

не работает. Её надо передвинуть за следующую фигурную скобку, иначе это присваивание никогда не исполняется.

после перемещения отроки вообще все перестало работать  теперь 1-2 импульса на 1 оборот энкодера

попробую еще раз проверить осцилографом на дребезг и помехи

Изменено пользователем SHipa

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    546

Тут точно правильно :

1 час назад, SHipa сказал:

    if((PIND.2==1)&&(PIND.3==1)){input = 2;
    if((PIND.2==0)&&(PIND.3==1)){input = 3;

?

А

buf = input;

вынесите за switch. Иначе, как уже сказали выше, точно ничего работать не будет.

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Yurkin2015    309

Да и много лишних телодвижений, эти input и buf тут совсем не нужны по-моему.

Надо сделать проще. Например так

void enkoder(){
    if(PIND.2==0)
    {
        if(PIND.3==0)ugol++;
        else ugol--;
    }
    else
    {
        if(PIND.3==0)ugol--;
        else ugol++;
    }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alex    546

Ну buf, по всей видимости, нужен для сохранения предыдущего состояния.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Yurkin2015    309

Да, чёт я погорячился. Надо использовать разные процедуры прерывания для разных входов.

Вот, пусть int0 для ноги PIND.2. Если на ноге фронт импульса и другая нога PIND.3 = 0, то прибавляем. Если спад импульса и другая нога = 1, то тоже прибавляем. В остальных случаях - вычитаем.

void enkoder0()
{
    if(PIND.2==1) 
   {
        if(PIND.3==0)ugol++;
        else ugol--;
    }
    else
    {
        if(PIND.3==1)ugol++;
        else ugol--;
    }
}

Аналогично для другого прерывания int1 для ноги PIND.3

void enkoder1()
{
   if(PIND.3==1)
    {   
        if(PIND.2==1)ugol++;
        else ugol--;
    }
    else
    {
        if(PIND.2==0)ugol++;
        else ugol--;
    }
}

 

Изменено пользователем Yurkin2015

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
SHipa    0

спасибо помогли переместил переменную и прерывания стояли по наростающему фронту поменял на любое изменение сигнала

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326

энкодер по таймеру

void encoder_read(void)
{unsigned char tempPORT;	
 static unsigned char encoder; 
    tempPORT=PORTB;
    encoder<<=2;
    if(tempPORT&((1<<2)) encoder |=(1<<0);
    if(tempPORT&((1<<3)) encoder |=(1<<1);

      switch (encoder & 0x0F) {
     
      // UP  
      case 0b0001:
      case 0b0111:
      case 0b1000:
      case 0b1110:          
          impuls++;
        break;
        
      // DOWN 
      case 0b0000:
      case 0b0100:
      case 0b1011:
      case 0b1101: 
          impuls--;
        break;

     // nothing happened      
      case 0b0000:
      case 0b0101:      
      case 0b1010:      
      case 0b1111:
            
      // error
      case 0b0011:
      case 0b0110:
      case 0b1001:
      case 0b1100:      
        break;

         default:
         break;
      }   // switch encoder 6 state

}//end void encoder_read(void)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zhuk72    12

Мой вариант сканирования энкодера по таймеру, 1 мс достаточно для отлова самых быстрых вращений рукой. При более длинных не проверял.

uint16_t enc, enc_prev;
int8_t turn = 0;

void encoder (void)   // Scan encoder
{
  uint16_t r;

// Энкодер подключен к портам PA0 и РA1 с внешними подтяжками на +5В через 10к резисторы.
// Никакие дополнительные фильтрующие конденсаторы не требуются. 
  r = (uint16_t)GPIOA->IDR & 3;  // Для других портов/битов/МК, применить соответствующую 
				//команду чтения, маску и сдвиг для помещения результата в младшие разряды.
  if (enc_prev != r)
	{
		enc_prev = r;
		enc = ((enc | r) << 2) & 0xFFF;	// применил маску для страховки, можно попробовать без нее
		if (enc == 0x0E1C) // 0x11_10_00_01_11_00, фазы состояний энкодера 3-2-0-1-3
		{
			r = enc = enc_prev = 0;
			turn = 1; // Поворот по часовой стрелке.
		}
			else if (enc == 0x0D2C) // 0x11_01_00_10_11_00, фазы состояний энкодера 3-1-0-2-3
			{
				r = enc = enc_prev = 0;
				turn = -1; // Поворот против часовой стрелки.
			}
				// else turn = 0;  // Энкодер в простое. Обнулить после использования.
	}
}

Естественно, что указанные "против" и "по часовой стрелке" условны, зависят от того, какой вывод энкодера к какому пину МК подключен.

Изменено пользователем Zhuk72

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326

мягко сказать странный алгоритм... исходящий из предположений

1. начальное состояние энкодера 3

2. в момент получения кодовой посылки ошибки отсутствуют.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zhuk72    12

Ну и что с того, что 3? Его контакты подтянуты к питанию, стало быть на них "1". Главное отлавливать изменение состояний и их правильную последовательность.

Второй момент не понял. Что вы имели в виду? Если есть сомнения в работоспособности, попробуйте в железе. Железозависимая строка тут только одна, меняется элементарно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326

1. с того что это работает только на энкодерах с положениями(тактильные щелчки)

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zhuk72    12

1. Других не имею.

2. У меня все работает даже на дешевом китайском энкодере. И ваше сомнение никак на это не влияет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326

то что из-за высокой скорости опроса вы не видите глюков ее не означает что их нет :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zhuk72    12

Специально для вас при первом же удобном случае сделаю опрос каждые 10 мс.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
mail_robot    1 407

судя по всему у товарища энкодер "на станке" стеклянно-оптический (тип чисто условно рабочекрестьянский). И скорее всего контроллер за ним банально не успевает и пропускает шаги. Поэтому при возврате в ноль, нуля там и в помине не будет. Туда бы железку с аппаратным модулем энкодера. Софтовый опрос с такими приборами не прокатывает

On 10.07.2017 at 11:21 PM, SHipa said:

по данной программе выдает примерно 330-340 импульсов на оборот

таких что-то не припомню. А вот 360 импульсов на оборот да (это импульсов на фазу)

On 10.07.2017 at 12:10 AM, Alex said:

Дребезг контактов учитываете ?

там дребезга не будет. Оптроны

Изменено пользователем mail_robot

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326
3 минуты назад, mail_robot сказал:

там дребезга не будет. Оптроны

да ну...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
mail_robot    1 407

ну если энкодер "фирменный", то да. Скорее всего да ну

но в аппаратке обычно стоит фильтр на это дело. Причем такецкий фильтр, что даже от обычного ручного энкодера звон отрабатывает. Мега тут полюбому сдуется, как ни крути. Так что смысла качать эту тему на таком железе думаю нет. Можно конечно попробовать воткнуть на каждую фазу по емкости, но тогда фронты могут начать заваливаться на приемлемом подавлении. Ну можно тогда воткнуть ТШ, это поможет. Но все равно надо будет успевать отрабатывать по 360 импульсов на фазу. Причем и по фронту и по срезу. И это еще не известно какая скорость вращения

Оговорка - если мега будет работать только на энкодер, то сколько то оборотов/секунду она сдюжит. Не выполняя основной код )

Изменено пользователем mail_robot

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326
Только что, mail_robot сказал:

Мега тут полюбому сдуется, как ни крути.

ну по поводу меги не знамо, а первоисточник для ПЫХ на приведенный мной код утверждает работоспособность по изменению порта до 13кГц при 4,096МГц тактовой

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
mail_robot    1 407

это с учетом основного кода? Или чисто при работе на энкодер и не по прерываниям?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 326

это в прерывании , судя по коду обработка максимум 38мкс , на основной код остается еще 39мкс

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: KVN
      Всем привет.
      Застрял на подключении 2 датчиков HC-SR04 к Atmega8 (CVAVR 3.12).
      1 настроен на прерывание 0, работает на таймере 0. (работает нормально)
      2 настроен на прерывание 1, работает на таймере 1. (показывает ерунду если рассчитанное расстояние 1 датчика меньше чем расстояние 2 датчика). 
      Фото прилагаю, видна часть кода. Прошу направить на путь истинный.
       
       


    • Автор: DimonRX
      Всем доброго времени суток!
      В AVR-ках я новичёк и очень нуждаюсь в вашей помощи.
      Задача у меня следующая. Есть драйвер управления серводвигателем на ATmega88. Помимо основной задачи ATmega88 через 74HC164D выводит на сдвоенный 7-ми сегментный индикатор направление вращения мотора в виде анимации (вращает сегмент по или против часовой стрелки). Рядом есть некая поделка на ATmega8, одной из задач которой является определение направления вращения мотора и, в зависимости от направления, выполнение различных действий. Как мне это сделать? Как подружить две меги? Всем заранее спасибо.
    • Автор: 12312313
      Добрые люди. Собрал данную схему. В протеусе все нормально работает. А вот когда прошиваю мк не работает. Принцип такой : если на первом входе компаратора сигнал больше второго то загорается первый если наоборот то второй. Где ошибка? Заранее благодарю

    • Автор: Melandr
      Добрый день, уважаемые форумчане. Подскажите по такому вопросу. Есть девайс, управляет автоматикой гелиосистемы (4 датчика DS1820, два насоса, индикация на семисегментном индикаторе). В первой реализации был установлен микроконтроллерATtiny2313, но памяти уже не хватало. чтобы не переделывать плату, было принято решение заменить микроконтроллер на ATtiny4313. Но возникла одна проблема. Так как девайс уже установлен на объекте, все изменения нужно как-то проверить, а уже потом на месте прошивать. Но для проверки прошивки в Proteus модели ATtiny4313 нет, поэтому есть мысль сделать директивы условной компиляции, допустим в начале выбор целевого микроконтроллера и дефайны по используемым регистрам. Чтобы изменением одной строчки можно было компилировать либо под ATmega8 либо под ATtiny4313. Как добавить в Proteus больше памяти на основе ATtiny2313 не знаю. Если можно какой-то простой пример, чтобы на его основе сделать условную компиляцию.
    • Автор: Oleg031
      Прошу Вашей помощи уважаемые форумчане!
      Автором В. Нефёдовым, г. Брянск была предложена интересная схема "Универсального микроконтроллерного зарядного устройства", http://www.radioradar.net/radiofan/power_supply/microcontroller_universal_charger.html#comment,
      которая была мной повторена. Схема рабочая, но по причине моей неграмотности в программировании - работает у меня не корректно! А именно не могу правильно записать при программировании через eXtreme Burner в EEPROM приведенные им коды: по адресу 00H - 2СН, по адресу 01H - 03H, по адресу 02H - 0BEH, по адресу 03H -64H. Не понимаю что, как и куда писать. Не судите строго!
      Прошу либо скиньте фотку как это должно выглядеть в программе, либо файл .eep
  • Сообщения

    • Покритикуйте плз печатки... Рисовальщик из меня тот еще (хотя я не с нуля рисовал). Понимаю, что печатка с лампами "не тру", но все же Преамп "томато" (с 6н2п и без умножителя) На 6ф5п (в стиле Борисова) Хотелка собрать уже как год живет в голове, но как-то не срастается, может добью, если все ок...Останется впаять) Только с печатками меня невнимательность вечно подводит. Если кому не влом, гляньте опытным взглядом, пожалуйста. Guitar preamp tomato.lay6 6f5p.lay6  
    • "Сороковой" не был рассчитан на  такой способ "заводки", в отличии от трактора на видео. У того это штатный способ старта движка, посредством порохового заряда. P.S. Да и завести "беларуса" задачи не было.  Ехали мимо, пофоткались, поехали далее. То шЮтка была.
    • Можно попробовать тут купить http://www.ligra-spb.ru/Profile.htm Для физ лиц https://1radcom.ru/category/radiatorniy-profil/
    • Абборигены до сих пор используют муравьёв для получения чистых и гладких костей животных. Полинезийцы используют обглоданные муравьями кости рыб для наконечников стрел, игл и украшений. Костяное оружие опаснее металлического. При ударе в теле остаются осколки и кончик. После удара оружие приводиться в боевой режим простым ударом камня по торцу оружия. В Японии и Голландии продаются конструкторы- рыбьи кости и клей. Склеиваешь сувенир на свою фантазию. В смысле нет задачи быстрого умервщления. Гвозди в руку вбивают оч умело не нарушая вены и сосуды. Крови вытекает мало. Палач-профи тех времён знал строение человека и знал множество способов быстрой и медленной казни. Спецов по пыткам ценили как самородок золота. В рейхе подобными делами занимались люди с медицинским образованием. Самый мразь был доктор Менгиле.
    • Судмедэксперт полагает, что можно и помереть. ТЫЦ.