Вращающийся энкодер на выходе Uno и прерывания

Этот вопрос касается проекта с использованием Arduino Uno.

У меня есть один из этих квадратурных поворотных кодеров .

Я использую слегка измененную версию кода из статьи, Квадратурный кодер слишком быстро для Arduino (с решением) , в котором используется библиотека под названием digitalwritefast .

Моя версия кода на pastebin - я модифицировал, чтобы использовать разные контакты для Uno и одного кодировщика:

 #include <digitalWriteFast.h>  // library for high performance reads and writes by jrraines

#define c_LeftEncoderInterrupt 0
#define c_LeftEncoderPinA 2
#define c_LeftEncoderPinB 3

volatile bool _LeftEncoderBSet;
volatile long _LeftEncoderTicks = 0;

void setup()
{
  Serial.begin(115200); 
  pinMode(c_LeftEncoderPinA, INPUT);      
  digitalWrite(c_LeftEncoderPinA, LOW); 
  pinMode(c_LeftEncoderPinB, INPUT);
  digitalWrite(c_LeftEncoderPinB, LOW);
  attachInterrupt(c_LeftEncoderInterrupt, HandleLeftMotorInterruptA, RISING);
}

// Interrupt service routines for the left motor's quadrature encoder
void HandleLeftMotorInterruptA()
{
  _LeftEncoderBSet = digitalReadFast2(c_LeftEncoderPinB);   // read the input pin
  _LeftEncoderTicks -= _LeftEncoderBSet ? -1 : +1;
}

void loop()
{
  Serial.print(_LeftEncoderTicks);
  Serial.print("\n");
  delay(20);
}

Я присоединяю выход A кодера к выводу 2 и выходу B к выводу 3.

Эта настройка работает нормально, и я могу обнаружить повороты в обоих направлениях, но моя проблема заключается в том, что если я установил контакт B на любой другой вывод, я получаю только положительное направление (независимо от направления, в котором кодер повернут) - как если pin B вообще не подключен (я изменяю c_LeftEncoderPinB соответственно).

Я предполагаю, что это связано с тем, что контакт 3 является единственным другим прерыванием на Uno (я не вижу ничего уникального в этом булавке). Тем не менее, я не знаю, почему, потому что прерывание находится на выводе A (хотя мы читаем значение pin B в этом прерывании).

3 голоса | спросил pat333 30 +03002014-10-30T19:20:56+03:00312014bEurope/MoscowThu, 30 Oct 2014 19:20:56 +0300 2014, 19:20:56

4 ответа


0

ОК смущающе получается, что моя проводка была неправильной! Я сбивался с пути, поскольку он работал в обоих направлениях, как описано, даже когда был подключен только один из выходов, так как длинный выход B был подключен к прерыванию. После сортировки проводки все работало отлично, в обоих направлениях, используя только один из портов прерываний.

ответил pat333 4 22014vEurope/Moscow11bEurope/MoscowTue, 04 Nov 2014 15:36:59 +0300 2014, 15:36:59
2

При повороте в один конец, A утверждается, тогда B утверждается, то A отменяется, а B отбрасывается. Вы можете обнаружить это, потому что сначала утверждается A, даже если вы не можете сказать, когда B изменился. Но если вы повернете обратный путь, вы не сможете обнаружить начальное утверждение B, и код не будет выполнен.

Что вы можете сделать, это использовать PinChangeInt , чтобы захватить прерывание смены контактов, а не внешнее прерывание. Это должно позволить вам использовать почти любые выводы ввода /вывода для Uno для кодировщика.

ответил Ignacio Vazquez-Abrams 30 +03002014-10-30T20:13:10+03:00312014bEurope/MoscowThu, 30 Oct 2014 20:13:10 +0300 2014, 20:13:10
0

Моя первая мысль заключается в том, что что-то еще отключено, потому что нет причин, по которым это не должно работать. Разумеется, он будет считать только 1/4 тиков, так как он предназначен для работы на очень быстрых двигателях. Я еще не могу прокомментировать, но Гербена выше, я думаю, что он должен быть двунаправленным, как указано тернарным оператором. Я предполагаю, что проблема связана с библиотекой digitalReadFast, и мне было бы интересно узнать, работает ли это при использовании digitalRead ().

Моя вторая мысль заключается в том, что это обычно не лучший способ сделать что-то. Во-первых, вам понадобится очень быстрый двигатель для быстрой проверки функции чтения. Во-вторых, вы жертвуете разрешением, используя только одно прерывание вместо двух. Более общепринятый метод заключается в подключении обоих контактов кодера к прерыванию. В качестве альтернативы вы можете использовать прерывания смены выводов, которые позволяют использовать любой штырь в качестве прерывания. Однако в Uno есть только 3 процедуры обслуживания прерываний, по одному для каждого порта контактов. Всякий раз, когда один контакт на этом порту запускается, ISR запускается, и вам нужно отслеживать состояния контактов, чтобы что-то с ним делать. Вот хороший пример первый и информация о второй метод.

ответил mwwalk 3 12014vEurope/Moscow11bEurope/MoscowMon, 03 Nov 2014 08:21:10 +0300 2014, 08:21:10
-2

Использовать библиотеку, прилагаемую здесь: http://forum.arduino.cc/index.php?topic=275248 .msg1938244 # msg1938244 С уважением,

ответил Jardal 3 12014vEurope/Moscow11bEurope/MoscowMon, 03 Nov 2014 23:23:53 +0300 2014, 23:23:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132