Ошибка расчета с оптическим энкодером

Я исправил свой код для чтения индекса оптического энкодера, но теперь получаю другую ошибку расчета. По индексу энкодер сбрасывается на ноль, но теперь мои показания следующие: Индексная точка – сбрасывается на ноль. - На отметке поворота 90 градусов у меня показания 180 градусов. - На отметке поворота на 180 градусов у меня отображается 0, потому что код сбрасывает его на ноль после 359 градусов. - На отметке поворота 270 градусов у меня показания 180 градусов. - На отметке 0 градусов он снова равен нулю, и именно этого я и ожидал от индекса. Если я перезапущу Arduino Mega на отметке 270 градусов, индекс обнулится, как и должно быть. Будучи новичком в этом, до того, как у меня работал индекс, он работал правильно, за исключением индексной функции, теперь, похоже, происходит двойной подсчет. Есть идеи?

// Проводные соединения для моего кодера:
// Коричневый: VCC = 5 В
// Синий + Экран: 0 В = GND
// Черный: ENCODER0PINA, контакт 20
// Белый: ENCODER0PINB, контакт 17
// Оранжевый: ENCODER0PINI, контакт 19

#define ENCODER0PINA         20      // этот вывод должен поддерживать прерывания
#define ENCODER0PINB         17      // прерывание не требуется
#define ENCODER0PINI         19      // этот вывод должен поддерживать прерывания

// переменные, измененные обработчиком прерывания, должны быть объявлены как изменчивые
volatile long encoder0Position = 0;
volatile long interruptsReceived = 0;
volatile byte INTFLAG1 = 0;

// отслеживаем последнюю позицию, чтобы знать, стоит ли печатать новый вывод
long previousPosition = 0;

void setup()
{

  // входы
  pinMode(ENCODER0PINA, INPUT);
  digitalWrite(ENCODER0PINA, HIGH);  // включаем подтягивающий резистор
  pinMode(ENCODER0PINB, INPUT);
  digitalWrite(ENCODER0PINB, HIGH);  // включаем подтягивающий резистор
  pinMode(ENCODER0PINI, INPUT);
  digitalWrite(ENCODER0PINI, HIGH);  // включаем подтягивающий резистор

  // прерывания
  attachInterrupt(3, onInterrupt, CHANGE);  // энкодер дорожки A на прерывании 3 - вывод 20
  attachInterrupt(4, onReset, CHANGE);  // Индексная дорожка энкодера на прерывании 4 - контакт 19

  // включаем диагностический вывод
  Serial.begin (115200);
  Serial.println("Ready.");
}

void loop()
{
  // отображаем информацию о позиции только в том случае, если она изменилась
  if (encoder0Position != previousPosition )
  {
    Serial.println(encoder0Position, DEC);

    previousPosition = encoder0Position;
  }
}

// функция прерывания должна делать как можно меньше

void onReset()
{
  // читаем ввод индекса
  int i = digitalRead(ENCODER0PINI);
  if (i == 1)
  {
  encoder0Position = INTFLAG1;
  }
}

void onInterrupt()
{
  // читаем оба направленных ввода
  int a = digitalRead(ENCODER0PINA);
  int b = digitalRead(ENCODER0PINB);

  if (a == b)
  {
    // b опережает a (против часовой стрелки)
    encoder0Position--;
    if (encoder0Position < 0)
    {
      encoder0Position = (encoder0Position + 360);
    }
  }
  else
  {
    // a опережает b (по часовой стрелке)
    encoder0Position++;
    if (encoder0Position >= 360)
    {
      encoder0Position = (encoder0Position - 360);
    }
  }
}

, 👍0

Обсуждение

пожалуйста, отформатируйте свой код как «код» .... выделите весь текст кода и нажмите кнопку {}, @jsotola

Я сделал это для него/нее., @Delta_G

Спасибо, мне было интересно, как отформатировать код как «код». (ему)., @Bkukuk62

Какой кодер вы используете? Есть ли приращение 0,5 градуса?, @evolutionizer

Это инкрементальный поворотный энкодер Omron E6B2-CWZ6C с индексом (360P/R)., @Bkukuk62

Еще один комментарий к приведенному выше коду. До введения Индекса он работал правильно. Я протестировал индекс, и он срабатывает только один раз за оборот., @Bkukuk62

Я провел дополнительное тестирование кода и заметил, что когда энкодер поворачивается по часовой стрелке мимо индекса, показания становятся следующими: 359, 0, 1, 2, 0, 1, 2, 3, после этого он читается правильно. При повороте энкодера против часовой стрелки происходит следующее: 1, 0, 359, 358, 0, 359, 358, 357, а затем работает правильно. Кто-нибудь понимает, почему кодер делает это, а также первоначальную проблему?, @Bkukuk62

Я разобрался со своей проблемой, по крайней мере, получаю хорошие результаты. С помощью этого кода мне пришлось изменить прерывания с CHANGE на RISING. Я хочу поблагодарить всех, кто прокомментировал этот вопрос., @Bkukuk62


1 ответ


1

Я разобрался со своей проблемой, по крайней мере, получаю хорошие результаты. С помощью этого кода мне пришлось изменить прерывания с CHANGE на RISING. Я хочу поблагодарить всех, кто прокомментировал этот вопрос. –

,