Чтение сигналов энкодера

sssyura
Offline
Зарегистрирован: 30.06.2015

Здравствуйте уважаемые формумчане!

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

На диске нанесено 4800 делений. Фотодатчик (как и сам диск энкодера) был взят из принтера. К плате Arduino Nano было подключено +5V, GND, D4, D7.

От датчика приходят два сигнала с помощью которых можно определить как сам факт вращения так и его направление. Как это сделать легко понять из рисунка

Диск вращается с небольшой скоростью (до 1 оборота в секунду). По моим расчетам за один оборот при максимальной скорости нужно считать минимум 4800*4=19200 сигналов, т.е. частота входящих импульсов до 20кГц.

Обработку сигналов делаю следующим кодом:

#include "CyberLib.h"
int a=0;
int b=0;
int l=0;
int n=0;

void setup() {
    Serial.begin(57600);   
    Serial.println("Hello");
}

void loop() {
   while(1){
      a=D4_Read;
      b=D7_Read;
      if(a==0 && b==0)n=1;
      if(a==1 && b==0)n=2;
      if(a==1 && b==1)n=3;
      if(a==0 && b==1)n=4;
      if(l!=n)Serial.println(n);
      l=n;
    }
 }

При медленном вращении все отлично читается и на экране "бежит" 1234-1234... или 4321-4321... при вращинии в одну или другую сторону. Но при увеличении скорости вращения видимо пропускаются импульсы и последовательность сигналов может быть любой, например 123234-1234-124....

Возможно ли с помщью Arduino решить эту задачу и что сделать что бы при увеличении скорости импульсы не пропускались?

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

trembo, огромное спасибо!

Помогла библиотека:

http://www.pjrc.com/teensy/td_libs_Encoder.html

SLOM
Offline
Зарегистрирован: 06.11.2014

sssyura  скажите что у вас получилось в итоше сделать с энкодером от принтера, у меня у такой же есть, пока на стадии подключения, сейчас ищу какойто готовый код для тестов. 

SLOM
Offline
Зарегистрирован: 06.11.2014

sssyura пишет:

trembo, огромное спасибо!

Помогла библиотека:

http://www.pjrc.com/teensy/td_libs_Encoder.html

пробовал такую библиотеку почемуто счетчик повторяет значения, 

Left = -4842, Right = 0
Left = -4843, Right = 0
Left = -4842, Right = 0
Left = -4841, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4837, Right = 0
Left = -4838, Right = 0
Left = -4837, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4840, Right = 0
Left = -4841, Right = 0
Left = -4840, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4840, Right = 0
Left = -4839, Right = 0
Left = -4838, Right = 0
Left = -4839, Right = 0
Left = -4837, Right = 0
Left = -4838, Right = 0
 
подключил моторчик, крутил долго, и постоянно идет проскок... 
Sentiurev
Offline
Зарегистрирован: 01.08.2019
06:14:27.853 -> Left = 0, Right = -396781
06:14:27.853 -> Left = 0, Right = -396782
06:14:27.887 -> Left = 0, Right = -396783
06:14:27.921 -> Left = 0, Right = -396992
06:14:27.955 -> Left = 0, Right = -397534
06:14:27.989 -> Left = 0, Right = -398096
06:14:28.023 -> Left = 0, Right = -398653
06:14:28.023 -> Left = 0, Right = -399208
06:14:28.057 -> Left = 0, Right = -399764
06:14:28.091 -> Left = 0, Right = -400320
06:14:28.125 -> Left = 0, Right = -400874
06:14:28.159 -> Left = 0, Right = -401431
06:14:28.159 -> Left = 0, Right = -401987
06:14:28.159 -> Left = 0, Right = -402542
06:14:28.193 -> Left = 0, Right = -402944
06:14:28.227 -> Left = 0, Right = -403008
06:14:29.587 -> Left = 0, Right = -403009
06:14:29.587 -> Left = 0, Right = -403010
06:14:29.621 -> Left = 0, Right = -403012
06:14:29.621 -> Left = 0, Right = -403233
06:14:29.655 -> Left = 0, Right = -403773
06:14:29.689 -> Left = 0, Right = -404336
06:14:29.723 -> Left = 0, Right = -404891
06:14:29.723 -> Left = 0, Right = -405448
06:14:29.757 -> Left = 0, Right = -406003
06:14:29.791 -> Left = 0, Right = -406558
06:14:29.825 -> Left = 0, Right = -407114
06:14:29.859 -> Left = 0, Right = -407669
06:14:29.893 -> Left = 0, Right = -408227
06:14:29.893 -> Left = 0, Right = -408784
06:14:29.927 -> Left = 0, Right = -409177
06:14:29.961 -> Left = 0, Right = -409236
 
Sentiurev
Offline
Зарегистрирован: 01.08.2019

/* А вот сам скетч:

/* Encoder Library - TwoKnobs Example
 *
 * This example code is in the public domain.
 */
 
#include <Encoder.h>
 
// Change these pin numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder knobLeft(2, 3);
Encoder knobRight(2, 3);
// avoid using pins with LEDs attached
 
void setup() {
 Serial.begin(9600);
 Serial.println("TwoKnobs Encoder Test:");
}
 
long positionLeft = -999;
long positionRight = -999;
 
void loop() {
 long newLeft, newRight;
 newLeft = knobLeft.read();
 newRight = knobRight.read();
 if (newLeft != positionLeft || newRight != positionRight) {
 Serial.print("Left = ");
 Serial.print(newLeft);
 Serial.print(", Right = ");
 Serial.print(newRight);
 Serial.println();
 positionLeft = newLeft;
 positionRight = newRight;
 }
 // if a character is sent from the serial monitor,
  // reset both back to zero.
  if (Serial.available()) {
 Serial.read();
 Serial.println("Reset both knobs to zero");
 knobLeft.write(0);
 knobRight.write(0);
 }
}
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

9600 маловато будет
115200 попробуйте.
И код вставьте по-нормальному

Sentiurev
Offline
Зарегистрирован: 01.08.2019

Поменял. Теперь Serial.begin(115200). Все равно не понял, сколько сигналов подал энкодер.

TwoKnobs Encoder Test:
07:02:14.243 -> Left = 0, Right = 0
07:03:02.217 -> Left = 0, Right = -1
07:03:02.217 -> Left = 0, Right = -2
07:03:02.217 -> Left = 0, Right = -3
07:03:02.217 -> Left = 0, Right = -4
07:03:02.217 -> Left = 0, Right = -5
07:03:02.217 -> Left = 0, Right = -16
07:03:02.251 -> Left = 0, Right = -37
07:03:02.251 -> Left = 0, Right = -63
07:03:02.251 -> Left = 0, Right = -92
07:03:02.251 -> Left = 0, Right = -124
07:03:02.251 -> Left = 0, Right = -157
07:03:02.251 -> Left = 0, Right = -191
07:03:02.251 -> Left = 0, Right = -226
07:03:02.251 -> Left = 0, Right = -260
 
Sentiurev
Offline
Зарегистрирован: 01.08.2019
Поменял. Теперь Serial.begin(2000000).
 
TwoKnobs Encoder Test:
07:08:23.607 -> Left = 0, Right = 0
07:08:30.609 -> Left = 0, Right = -1
07:08:30.609 -> Left = 0, Right = -2
07:08:30.609 -> Left = 0, Right = -3
07:08:30.609 -> Left = 0, Right = -4
07:08:30.609 -> Left = 0, Right = -5
07:08:30.609 -> Left = 0, Right = -6
07:08:30.609 -> Left = 0, Right = -7
07:08:30.609 -> Left = 0, Right = -9
07:08:30.609 -> Left = 0, Right = -11
07:08:30.609 -> Left = 0, Right = -13
07:08:30.609 -> Left = 0, Right = -16
 
Morroc
Offline
Зарегистрирован: 24.10.2016

Что за Left, Right ? Если у вас энкодер один так и подключайте один, а то у вас как бы два, но на одинаковых ногах. Насколько я вижу оно у вас более менее работает, просто вы не успеваете выводить в Serial каждый шаг - это нормально и для рабочей программы нафиг не нужно.

>Все равно не понял, сколько сигналов подал энкодер.

Оно (имея в виду схему вместе с программой и библиотекой) не подает сигналы, а считает угол поворота в условных попугаях. Покрутите в обратную сторону чтобы убедиться, что считает и в - и в +. Если вам нужна мгновенная реакция на каждый сигнал энкодера (изменение состояния) - скорее всего обработку придется делать самому, а не библиотеку использовать (и скорее всего эта идея вообще плохая).

Sentiurev
Offline
Зарегистрирован: 01.08.2019

На энкодере два датчика: А и В, они подключены к пин 2 и 3. В зависимости от того, какой датчик сработает раньше, будет определено направление вращения.

Sentiurev
Offline
Зарегистрирован: 01.08.2019

Я так и не понял, к посчитать количество импульсов. 

Serial.begin(115200)

Right = -260

 

Serial.begin(2000000)

Right = -16

Количество оборотов в обоих случаях одинаковое.

Morroc
Offline
Зарегистрирован: 24.10.2016

Sentiurev пишет:

На энкодере два датчика: А и В, они подключены к пин 2 и 3. В зависимости от того, какой датчик сработает раньше, будет определено направление вращения.

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

Sentiurev пишет:
Я так и не понял, к посчитать количество импульсов.

Библиотека сама считает, вы только ей не мешайте постоянным выводом в порт (можно попробовать воткнуть delay). У вас энкодер как в первом посте с дохрена импульсов на обоорт ? Вы его моторчиком легко можете крутить быстрее, чем ардуина сможет переварить (до 100к импульсов в секунду) и я бы сигнал с оптопар проверил - не факт, что любая оптопара так быстро может работать.