Используем Энкодер

neospromiy
Offline
Зарегистрирован: 15.07.2013

Убрал кондеры, мой вариант кода и без кондеров хорошо все отрабатывает, ни одного пропуска

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Строго говоря, контакты энкодера не из сверхпроводника, плюс провода плюс внутренне конденсатора плюс распределенная индуктивность... Не бейте за то, что "умничаю", но собирая легендарные Синклеры приходилось вешать прямо на ноги микрух памяти кондеры до 1000 пикух чтобы получить нужные задержки фронтов. Так что от 1000 пикух контактом точно не поплохеет.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

Logik пишет:

Ключевое слово - пока. У вас постоянная времени фильтра 0,5мс и разряд конденсатора на контакты из-за чего они быстрей окислятся, и дребезг усилится, пропадани контакта станет больше постоянной времени фильтра (грубо говоря) и начнет глючить.  После этого Вы станете ярым поклонником оптических энкодеров.

ага! вот ОНО - нужно землю подключать через проходной резистор 10К!

Logik пишет:
А чего сделана внешная подтяжка, а не внутренними резисторами?

ну, это отдельная философская тема - где лучше подтягивать питание: внутри контроллера или внутри источника сигнала. в плане помехозащищённости может быть применимо то или иное решение.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Ну так что, есть готовое решение с энкодером, которое будет работать и с маленткой скоростью поворота и с большой и без глюков и пропусков?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

есть. Называется оптический энкодер.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Tomasina пишет:

есть. Называется оптический энкодер.

Ну не стоит так перегибать энкодер. Может есть оптимальное решение?

neospromiy
Offline
Зарегистрирован: 15.07.2013

Так я ведь выкинул код, он идеально работает без кондеров и всякой всячины.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

ali_vlad пишет:

Tomasina пишет:

есть. Называется оптический энкодер.

Ну не стоит так перегибать энкодер. Может есть оптимальное решение?

давал же ссылку http://www.pjrc.com/teensy/td_libs_Encoder.html

ну, не ставьте конденсаторы, если найдёте энкодер без дребезга контактов

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

................   Так я ведь выкинул код, он идеально работает без кондеров и всякой всячины............
До поры-до времени будет работать
 

...........ну, не ставьте конденсаторы, если найдёте энкодер без дребезга контактов...............
Или мы не видим дребезг, или он не мешает нам.
Долглоиграющих контактов без дребезга не бывает в природе.
Всё в мире меняется...
И не в лучшую сторону...

Дребезг видишь?
Нет.....
И я нет, а он есть......

Нет абсолютно здоровых людей, есть недостаточно обследованные пациенты.

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Я понимаю, Вы профи, а я дуб дубом, но Вы меня с толку сбиваете. На чем остановиться: библиотека? кондеры?

Я не планирую использовать энкодер для управления космическим кораблем. Мне громкость регулировать. Будет медиа мини-клавиатура для ведроид аппарата.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

trembo пишет:

...........ну, не ставьте конденсаторы, если найдёте энкодер без дребезга контактов...............
Или мы не видим дребезг, или он не мешает нам.
Долглоиграющих контактов без дребезга не бывает в природе.

...или энкодер оптический(говорили же выше) - такое впечатление, что наличие механических контактов в электронном устройстве у дуиноводов на генетическом уровне забито.

defezit
Offline
Зарегистрирован: 14.12.2014

Ребятки, подскажите как энкодер подключать у меня на пять контактов(2 с одной стороны и 3 с другой), два положения крутёлки - нажатый и отжатый. Энкодер нужен для регулировки температур вкл/откл в термостате.  Даже не знаю с какой стороны подходить к нему. Ткните пожалуйста пальцем, времени на поиск оч. мало, работаю водилой.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

defezit пишет:

Ребятки, подскажите как энкодер подключать у меня на пять контактов(2 с одной стороны и 3 с другой), два положения крутёлки - нажатый и отжатый. Энкодер нужен для регулировки температур вкл/откл в термостате.  Даже не знаю с какой стороны подходить к нему. Ткните пожалуйста пальцем, времени на поиск оч. мало, работаю водилой.

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

хрустальный шар мне подсказывает, что два контакта - это кнопка, а три - сам энкодер, какой из трёх контактов энкодера общий, поймёшь методом научного тыка.

defezit
Offline
Зарегистрирован: 14.12.2014

ДЫк в том то и дело что опозновательных знаков нетути :(

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

defezit пишет:

ДЫк в том то и дело что опозновательных знаков нетути :(

ну, на нет и суда нет - мог бы и сам догадаться, что у кнопки два пина, а у энкодера - три.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

defezit пишет:

ДЫк в том то и дело что опозновательных знаков нетути :(

омметром и логикой можно выяснить все контакты...

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
defezit
Offline
Зарегистрирован: 14.12.2014

Нашел мое чудо   http://www.ecvv.com/product/2700418.html, разобрался с ним, бум дальше ковыряться...

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Что там ковыряться- они все одинаковые и отличаются только цветом пластмассы....

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

может быть так?:

#define ENCODER_DO_NOT_USE_INTERRUPTS // без прерываний.
#include <Encoder.h>
Encoder Enc_1(9, 8);

long old_pos = 0;

void setup() {Serial.begin(9600);}

void loop() {
long new_pos;
new_pos = Enc_1.read()/4;
if (new_pos != old_pos) {
if (new_pos > old_pos) {Serial.print("+");}
if (new_pos < old_pos) {Serial.print("-");}
old_pos = new_pos;
Serial.println(old_pos);
}
}

 

ali_vlad
Offline
Зарегистрирован: 20.02.2015

Совершенству нет предела. Главное энкодер победил!!!

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

Клапауций 999 пишет:

ali_vlad пишет:

Tomasina пишет:

есть. Называется оптический энкодер.

Ну не стоит так перегибать энкодер. Может есть оптимальное решение?

давал же ссылку http://www.pjrc.com/teensy/td_libs_Encoder.html

ну, не ставьте конденсаторы, если найдёте энкодер без дребезга контактов

Я правильно понимаю, что сия рассово верная библиотека будет нормально работать только в случае подключения энкодера к пинам, поддерживающим прерывание, т.е 2 и 3, т..е. на всяких nano и Pro Mini по энкодеру на ардуину и не больше?

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

SunX пишет:

Я правильно понимаю, что сия рассово верная библиотека будет нормально работать только в случае подключения энкодера к пинам, поддерживающим прерывание, т.е 2 и 3, т..е. на всяких nano и Pro Mini по энкодеру на ардуину и не больше?

ок. рассово толерантный к прерываниям друх, поясняю - библиотека имеет возможность работы в трёх режимах:

ENCODER_USE_INTERRUPTS - два пина энкодера на прерываниях.
ENCODER_OPTIMIZE_INTERRUPTS - один из двух пинов энкодера на прерывании.
ENCODER_DO_NOT_USE_INTERRUPTS - без использования прерываний.
 
соответсвенно:
первый режим является максимально скоростным.
третий режим является минимально скоростным.
второй режим является компромиссом и средним по скорости между первым и вторым.
 
т.е., если у вас энкодер представляет собой ручную крутилку, то обвешайтесь энкодерами, сколько пинов у вас доступно - в пень прерывания.
 
*чел спросил максимально оптимальное решение - я его ему дал. лично я не увидел в тырнетах ни от одного пейсателя энкодеров серьёзного отношения к результатам своего труда и аппаратного тестирования своего кода, кроме авторов приведённой мной библиотеки.
ali_vlad
Offline
Зарегистрирован: 20.02.2015

Подтверждаю!!! Рассово правильная библиотека избавила меня от большого количества гемороя. Смотри тему usb hid мультимедиа клавиатура.

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

Я все же пока остановился на варианте dimax, с PCINT, вроде ничего не глючит, все хорошо работает.

maksim
Offline
Зарегистрирован: 12.02.2012

Лично у меня (да и наверное у многих), энкодер работает вот по такому принципу:

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

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

Проверять нужно именно факт наличия полноценных импульсов:

#define pinA 4
#define pinB 5
volatile int enc = 0;

void setup() {
  Serial.begin(9600);
  
  pinMode(pinA, INPUT);
  pinMode(pinB, INPUT);
  digitalWrite(pinA, 1);
  digitalWrite(pinB, 1);
  
  // PCINT
  PCMSK2 = (1<<PCINT20)|(1<<PCINT21); // pinA 4 pinB 5
  PCICR = 1<<PCIE2;
  
  // INT
  // attachInterrupt(0, Encoder, CHANGE); // pinA 2
  // attachInterrupt(1, Encoder, CHANGE); // pinB 3
}

void loop() {
  static int pre_enc = 1;
  if(enc != pre_enc)
  {
    Serial.println(enc);
    pre_enc = enc;
  }
  //Encoder();
}

// PCINT
ISR (PCINT2_vect){
  Encoder();
}

void Encoder() {
  byte A = !digitalRead(pinA), B = !digitalRead(pinB);
  static byte preA = 0, preB = 0;
  static uint32_t milA = 0, milB = 0;

  if (!milA && ((!preA && A) || (preA && !A))) milA = millis();
  if (!milB && ((!preB && B) || (preB && !B))) milB = millis();

  if (milA && (millis() - milA >= 3))
  {
    milA = 0;
    preA = A;
    static byte pulse = 0;
    if (preA && !preB) pulse = 1;
    if (!preA && preB && pulse)
    {
      pulse = 0;
      enc--;
    }
  }

  if (milB && (millis() - milB >= 3))
  {
    milB = 0;
    preB = B;
    static byte pulse = 0;
    if (preB && !preA) pulse = 1;
    if (!preB && preA && pulse)
    {
      pulse = 0;
      enc++;
    }
  }
}

Антидребезг на все фронты по 3 мсек., на моем энкодере этого достаточно.

Функция Encoder() должна вызываться при изменениях на обоих выводах. Можно вызвать и в loop() если она работает достаточно быстро.

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

       Мой вариант, без конденсаторов и сопротивлений ,

все разъяснения в комментариях - просто и элегантно (за основу

взят код одного из участников форума).


        int encoderPin1 = 2;      //Вход А
        int encoderPin2 = 3;      //Вход В
        volatile int lastEncoded = 0;
        volatile int encoderValue = 0;
        volatile int b = 0;
        volatile int sum  ;
        int i = 0;
 
   
void setup() {
                  Serial.begin (57600);
                  pinMode(encoderPin1, INPUT);
                  pinMode(encoderPin2, INPUT);
                  digitalWrite(encoderPin1, HIGH);
                  digitalWrite(encoderPin2, HIGH);
                   
                  attachInterrupt(0, updateEncoder, CHANGE);
                  attachInterrupt(1, updateEncoder, CHANGE);
               
                  pinMode(13, OUTPUT);
                  digitalWrite(encoderPin1, HIGH);
             }
void loop()  {
   
                  if(i==1)
                   { i=0;
                    Serial.println(encoderValue);  
                   }
            }
 
void updateEncoder()
            { 
     
                 int MSB = digitalRead(encoderPin1);
                 int LSB = digitalRead(encoderPin2);
                 int encoded = (MSB << 1) |LSB; 
                 sum  = (lastEncoded << 2) | encoded;
                
   
        
  //0001  *  0001  *  0000  *  0000         Вход А
  //0001  *  0000  *  0000  *  0001         Вход В
  //----------------     
  //                ----------------        Вход А
  //--------                  ------
  //        ------------------              Вход В
  // 1 такт 2 такт  3 такт    4 такт
 
  //  11  *    10  *    00  *    01         Входы АВ
  //   1  *    2   *    3   *   4 
 
 
  //----  *  1110  *  ----  *  1101  
  //1011  *  ----  *  1000  *  ----         sum
  //----  *  0010  *  ----  *  0001  
  //0111  *  ----  *  0100  *  ----  
   
  //        1 такт           2 такт          3 такт           4 такт
  //(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
  // прямое вращение
  // if(sum == 0b****) выбрать экспериментально самый качественный такт
            if(sum == 0b0010)
                                               
                  {
                    digitalWrite(13, HIGH);
                    encoderValue ++;
                    i=1;
                  }
                        
 //        1 такт           2 такт          3 такт           4 такт    
 //(sum == 0b1110 ||sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
 //реверсное вращение
 // if(sum == 0b****) выбрать экспериментально самый качественный такт
              if(sum == 0b1000)
                                                
                  {                                             
                      digitalWrite(13, LOW);
                      encoderValue --;
                      i=1;
                  } 
               lastEncoded = encoded;
           
              while (b<2000)
              {b++;}
              b=0;
             
          }

полезная ссылка  http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html

 

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

Ребята maksim и Victorius111!

От нечего делать потестил Ваши скетчи. Интересно, а вы сами их тестили? Пробывали сделать пол оборота енкодера одним непринужденным движением за 0.2-0.5сек. Энкодер у меня почти новый но уже провереный. Работает нормально, чистый и не раздолбаный, практически без дребезга.

Скетч maksim просто игнорит такое обращение, ну максимум накинет 1. В этом я в общем не сомнивался увидев проверку на 3мс. Дребезг енкодера не такой же как у замыкающихся контактов, имеет другую физическую природу - нестабильность сопротивления контактов при скольжении а не замыкании. Поэтому он может длится долго, пока идет скольжение, >>3мс. Попытка же отсеивать дребезг по времени приводит к пропускам при быстром вращении, что и обнаружилось. И только по фронтам работать нельзя, как Вы верно пишете. Только в теме есть примеры как это делается не только по фронтам. У дребезга есть своя логика, и её нужно учитывать.

Скетч Victorius111 более "радует" выдает типа 

149
150
151
151
152
153
 
ну пропустил 2/3 шагов, особо мило дважды 151. Вобще комментарий выбрать экспериментально самый качественный такт сразу обещает геморой. Он и обнаружен опытным путем. Вы представляете чтоб в китайской автомагнитоле, где стоит такой же гавняный енкодер было написано как в коментарии? И добавлно, что по мере износа и окисления повторить! А в ней енкодер работает 10 лет без замечаний.
  В общем обе реализации страдают проблемами, ранее описаными на 4 страницах форума. Чуда не случилось.
 
Может перед тем как отложить очередную кучку гавнокода на форуме стоит задатся вопросом чего это тут 4 страницы исписано? Может есть какие сложности? Может кто чё придумал, работающее лучше? Или хотябы где отметит что этот "элегантный" код для неспешной регулировки заторможенными товарищами, которые не смотрят библиотеки и примеры с большим числом переменных.
 
 

 

 

 

 

 

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Logik, а вы видели в моей теме скриншот осциллограммы быстрого вращения энкодера? Любопытно сможет ли какой нибудь программный обработчик это переварить без глюков :) Мой конденсаторный способ вроде справляется.

Logik
Offline
Зарегистрирован: 05.08.2014

dimax пишет:

Logik, а вы видели в моей теме скриншот осциллограммы быстрого вращения энкодера? Любопытно сможет ли какой нибудь программный обработчик это переварить без глюков :) Мой конденсаторный способ вроде справляется.

Шикарные осцилограммы! Конечно сможет. А вот довести до такого состояния енкодер конденсатор  помог здорово. Во первых, в большинстве своем там порог логического уровня не достигается, (кроме 4 импульса без кондера и еще помелочам кое-где), так что в цифре картина приятней будет. Во вторых и конденсатор не способен все решить - третий импульс на картинке с кондером явно видно. Ну и 3 - заметте, уровень 1 не дребезжит :) Он этого просто никак не умеет! От этого и пляшем, от 11. Где-то среди шумов 0 возникнет 00. Чередование 11 и 00 - надежно идентифицирует шаг. Конечно возможно что среди шумов 0 возникнет ошибочно 11 и получим ошибочный шаг, но для этого два дребезга должны совпасть, что в относительно рабочеспособном енкодере маловероятно. На сколько я вижу на Вашей осцилограме такого нет. А про определение направления вращения я писать не буду;)

maksim
Offline
Зарегистрирован: 12.02.2012

Logik пишет:

Интересно, а вы сами их тестили?

А вы их тестировали?

 

Logik пишет:

Пробывали сделать пол оборота енкодера одним непринужденным движением за 0.2-0.5сек.

Нет, конечно, зачем? Зачем его вообще крутить?

 

Logik пишет:

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

Кроме вас никто не знает, что у вас там за энкодер. С моим энкодером все замечательно работатет.

 

Logik пишет:

Скетч maksim просто игнорит такое обращение, ну максимум накинет 1. В этом я в общем не сомнивался увидев проверку на 3мс. 

maksim пишет:

Антидребезг на все фронты по 3 мсек., на моем энкодере этого достаточно.

это значит, что у вас может быть и не 3 мс.

 

Logik пишет:

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

Где?

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

dimax пишет:

в моей теме скриншот осциллограммы быстрого вращения энкодера

Уважаемый dimax , Вы снимали осциллограммы с делителем или без?

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Victorius111, без делителя. Но ёмкость щупа на такой малой частоте (1 импульс = 5ms )  рояля не играет. Завтра если не забуду, попробую снять осциллограмму с такого-же, но абсалютно нового энкодера.

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

dimax проблема не в малой частоте, а в том , что импулсы дребезга , прочие короткие импульсы из-за емкости щупа неправильно отображаются на осцилографе, т. е. амплитуда их в самом деле часто достигает уровня лог. "1" . Если Вас не затруднит и есть щуп с делителем (у меня такой возможности нет), то будьте добры, поделитесь с обществом новыми скриншотами.

Logik
Offline
Зарегистрирован: 05.08.2014

Я картинку сюда перетяну, уж больно она мне нравится.

Проблема наводки на щуп через емкость - известная вещ. Но не на таких низких частотах. На низких частотах реактивное сопротивление емкости велико, наводка не пролезет.  Даже если допустить, что видим наводку, то почему она есть только на уровне 0 и отсутствует на 1? Так не может быть.

Кроме того, второй рисунок, где контакт шунтирован 0,1мкФ керамикой, ВЧ наводку задавит напроч, а не давит совсем.

Сомневатся в верности осциллограм не вижу причин. 

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

еще один код, работает идеально. не то что комар, даже Logik носа не подточит 

[code]
          int encoderPin1 = 2;      //Вход А
          int encoderPin2 = 3;      //Вход В
          int MSB ;
          int LSB ;
           volatile  int encoded = 0 ;
           volatile  int lastEncoded = 0;
           volatile  int sum  ;                
           volatile  int i = 0;
                     int a = 0;
                     int b = 0;
                     int c = 0;
                     int encoderValue = 0;

void setup() {
                  Serial.begin (57600);
                  pinMode(encoderPin1, INPUT);
                  pinMode(encoderPin2, INPUT);
                  digitalWrite(encoderPin1, HIGH);
                  digitalWrite(encoderPin2, HIGH);
                  attachInterrupt(0, updateEncoder, CHANGE);
                  attachInterrupt(1, updateEncoder, CHANGE);
                  pinMode(13, OUTPUT);
}

void loop()
  {     
                  MSB = digitalRead(encoderPin1);
                  LSB = digitalRead(encoderPin2);
                  encoded = (MSB << 1) |LSB;
                  sum  = (lastEncoded << 2) | encoded;
                 
                  if(c==1)
                   { c=0;
                   Serial.println(encoderValue); 
                   }

              if(encoded==0b0000)
              {
                                    
                if(a==0)     
                     {  encoderValue = encoderValue+i;
                         c=1; a=1;b=0;
                     }             
              }                                             

             if(encoded==0b0011)
                                                
              {
                                    
                if(b==0)     
                     {  encoderValue =encoderValue+i;
                        c=1; b=1;a=0;
                     }             
              }            
 }
                     
         void updateEncoder()                           // детектор направления
  {
                
      if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
                                                
     {
                      digitalWrite(13, HIGH);   //прямо
                      i = 1;
     }
                         
      if(sum == 0b1110 ||sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
                                                 
      {                                            
                      digitalWrite(13, LOW);  //обратно
                      i = -1;
      }
               lastEncoded = encoded;
}







[/code]

                                                                                              

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

Че?! Разбор состояния енкодера в лупе?! 8))))

Нееее.... фииии... Это ж луп гарантировано нада прокручивать наждые пару миллисекунд, чтоб недай бог не пропустить чего.. Это ж ниче ни в сириал послать, ни на экран отправить шоб енкодер не пропустить. 

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

Ну, а так все ок? румяный критик мой ты толстопузый 8?(Это из Пушкина)  


          volatile int encoderPin1 = 2;      //Вход А
          volatile int encoderPin2 = 3;      //Вход В
          volatile int MSB ;
          volatile int LSB ;
           volatile  int encoded = 0 ;
           volatile  int lastEncoded = 0;
           volatile  int sum  ;                
           volatile  int i = 0;
           volatile   int a = 0;
           volatile   int b = 0;
           volatile   int c = 0;
           volatile   int encoderValue = 0;

void setup() {
                  Serial.begin (57600);
                  pinMode(encoderPin1, INPUT);
                  pinMode(encoderPin2, INPUT);
                  digitalWrite(encoderPin1, HIGH);
                  digitalWrite(encoderPin2, HIGH);
                  attachInterrupt(0, updateEncoder, CHANGE);
                  attachInterrupt(1, updateEncoder, CHANGE);
                  pinMode(13, OUTPUT);
}

void loop()
  {     

                 
                  if(c==1)
                   { c=0;
                   Serial.println(encoderValue); 
                   }

 }
                     
         void updateEncoder()                           
  {
                      MSB = digitalRead(encoderPin1);
                  LSB = digitalRead(encoderPin2);
                  encoded = (MSB << 1) |LSB;
                 sum  = (lastEncoded << 2) | encoded;

    
             if(encoded==0b0000)
              {
                                    
               if(a==0)     
                     {  encoderValue = encoderValue+i;
                         c=1; a=1;b=0;
                     }             
              }                                             

             if(encoded==0b0011)
                                                
              {
                                    
               if(b==0)     
                     {  encoderValue =encoderValue+i;
                        c=1; b=1;a=0;
                     }             
              }  
                 


    
                
      if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
                                                
     {
                      digitalWrite(13, HIGH);   //прямо
                      i = 1;
     }
                         
      if(sum == 0b1110 ||sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
                                                 
      {                                            
                      digitalWrite(13, LOW);  //обратно
                      i = -1;
      }
              lastEncoded = encoded;
}

                                                                  

Logik
Offline
Зарегистрирован: 05.08.2014

Да. Наверно. Сплю. Вы уже в общем то в теме всех  проблем енкодеров. Вот сами. сами сами ))))

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

позанудствую:

а) отбирать на энкодер два прерывания - жалко.

б) int для этого дела тоже больно жирно, там достаточно boolean и, на крайняк, byte.

в) почему именно событие CHANGE ? Оно, получается, вызывается дважды - при замыкании и при размыкании дорожек энкодера.

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

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

ali_vlad
Offline
Зарегистрирован: 20.02.2015

А что, использовать специализированную библиотеку религия не позволяет? К чему все эти грабли?

Клапауций 777
Offline
Зарегистрирован: 21.11.2015

ali_vlad пишет:
А что, использовать специализированную библиотеку религия не позволяет? К чему все эти грабли?

это неспортивно.

Logik
Offline
Зарегистрирован: 05.08.2014

Tomasina пишет:

а) отбирать на энкодер два прерывания - жалко.

а чего их жалеть то! За них деньги всеравно заплачены - пущай работают. А если вдруг на потребуется еще прерывания от этой же группы пинов то просто в начале обработчика добавить код разруливающий от какого именно пина прерывание пришло. Тут стремней другое - из-за дребезга прерывания могут излишне часто дергатся и сжерать производительность.

 

Tomasina пишет:

б) int для этого дела тоже больно жирно, там достаточно boolean и, на крайняк, byte.

Угу. И a=!b;

Tomasina пишет:

в) почему именно событие CHANGE ? Оно, получается, вызывается дважды - при замыкании и при размыкании дорожек энкодера.

С учетом дребезга вызываются х2, но то что CHANGE верно, это наиболее универсальный и распостраняется на все PCINTxx. И нам для енкодера надо знать не о наростании или спаде а о изменении состояния.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Новые весёлые картинки. Снимал щупами с делителем 1:10. Первая фотка -старый энкодер, он уже был на фотке выше. Просто для сравнения. Очевидно, что ёмкость щупа существенно не влияет. Как было, так и осталось.

Вторая фотка он-же, но зона ноля сильно растянута.

 

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

 

 

 

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

Вах! ++++

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

Спасибо за картинки.

Victorius111
Victorius111 аватар
Offline
Зарегистрирован: 02.12.2015

и еще раз вернемся  к картинкам - то, что затянут  передний фронт (на старом энкодере), свидетельствует о том , что имеет место емкостная нагрузка.       Постоянная времени определяется по формуле      t =R*C    Определяем по картинке   t ≈100µs; подтягивающее сопротивление R=10кОм ;находим

                                                                                 С=t/R=100µs/10кОм = 0.01µF

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Victorius111, вы довольно точно вычислили) Я сейчас для проверки взял измеритель RLC и измерил ёмкость незамкнутой пары энкодера. У нового енкодера -11 pF, у старого 14,7 nF   Понятно, что во втором случае ёмкость щупа не играла роли.. Другой вопрос почему со временем увеличилась ёмкость?? Но как, Холмс? :))  Энкодеры как близнецы, производитель один и тот же.