Некорректные данные энкодера

Тема в разделе "Arduino & Shields", создана пользователем enclouder, 5 дек 2017.

  1. AlexU

    AlexU Гуру

    Это только в том случае, если МК поддерживает 60 прерываний вида 'INTx'. А ATmega328 поддерживает только два таких прерывания -- INT0, INT1; ATmega2560 -- только восемь -- INT0 .. INT7.
    Проблема в том, что, если хотите к ATmega328 подключить более одного энкодера, то лучше использовать либо прерывания PCINT, либо таймеры. Мне больше нравятся прерывания PCINT, но это уже скорее относится к holy war-ам -- что использовать таймеры или прерывания изменения состояния пинов.
    В случае с ATmega2560 можно подключить четыре энкодера, но только к определённым пинам.
     
  2. brokly

    brokly Гик

    Я там немного выше поправил свою реплику. В случае с мегой можно подключить три энкодера. Вот кусок из утилит:

    // Arduino Mega
    #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    #define CORE_NUM_INTERRUPT 6
    #define CORE_INT0_PIN 2
    #define CORE_INT1_PIN 3
    #define CORE_INT2_PIN 21
    #define CORE_INT3_PIN 20
    #define CORE_INT4_PIN 19
    #define CORE_INT5_PIN 18

    Но при желании библиотеку можно допилить. И она очень быстрая, это я проверил в реальности.

    Кстати уж если делать чтение энкодеров , то однозначно на прерываниях. На таймере, можно только придумать что то типа подсчета импульсов за определенный промежуток времени - измерение скорости.
     
    Последнее редактирование: 12 дек 2017
  3. Onkel

    Onkel Гуру

    Если энкодер - просто крутилка, или достаточно половины макс. разрешения энкодера - можно подключить 8 энкодеров, используя прерывания по изменению одного пина из двух на энкодер. Функция отработки прерывания будет просто учитывать состояние второго пина для определения знака инкремента. А так, конечно, если умеешь работать с прерываниями - то сколько угодно, но не больше чем пинов/пополам.
     
    brokly нравится это.
  4. Onkel

    Onkel Гуру

    Посмотрите, если поможет и если разберетесь, работа с двумя энкодерами без таймеров и библиотек (взял из рабочей программы для atmega328pu), на пины A0 / A1 и A2 /A3 подключены, пины надо прописать как INPUT_PULLUP,
    Код (C++):
      pinMode(A0, INPUT_PULLUP);
      pinMode(A1, INPUT_PULLUP);
      pinMode(A2, INPUT_PULLUP);
      pinMode(A3, INPUT_PULLUP);


    никаких библиотек и никаких таймеров не задействуем, в setup прописываете прерывания от двух пинов - А0 и А3

    Код (C++):
      // here we config the interraption for encoder services
      EICRA = 0x00; //  INT0 INT1 Type didn't matter
      EIMSK = 0x00; //       INT0 INT1 disabled
      PCMSK1 = 0x09; // Pin change mask pins C0   C3 ENABLE any change
      PCIFR = 0x02; //PCINT 14-8 Flag   clear
      PCICR = 0x02; //Pins C0 - C5 interruptions enable


    и сама функция прерывания, результат пишется в переменные Position[] для каждого энкодера свой элемент массива int Position[2] (в начале конечно нужно объявить)

    Код (C++):
    ISR(PCINT1_vect)  // External interruption for Encoder service
    {

      if (OldPinc & 0x01 && (0x01 & PINC) == 0 )
      {

        if (  (PINC & 0x02) == 0x02)
          Position[0]++); //  FORWARD AZIMUT
          else
            Position[0]--); //  REVERSE AZIMUT

          }


      if (OldPinc & 0x08 && (0x08 & PINC) == 0 )
      {

        if (  (PINC & 0x04) == 0x04)
          Position[1]--);//  REVERSE TANGAGE
          else
            Position[1]++);//  FORWARD TANGAGE

          }

      OldPinc = PINC;
    }
    Если разберетесь и заработает, то можете ввести в функцию прерывания отработку и по пин вниз, и по вторым задействованным для энкодеров пинам, увеличив используемое разрешение энкодера. В приведенном примере разрешение энкодера - четверть от максимального, но начните с этого, может и хватит. А улучшить много проще чем сделать первый шаг - дополните if для других изменений пинов. И смотрите, что за энкодер. Некоторые на одно переключение дают полсотни иголок (дребезга). Правильная программа обработки сведет этот дребезг к максимум +-1 пограшности (абс), но лучше без дребезга чем с дребезгом, кондер 0,1 uF (зависит конечно от частоты импульсов, ориентируйтесь на tau=RC, где R- сопротивление подтяжки, для встроенного это примерно 30 кОм).
     
    Последнее редактирование: 12 дек 2017