Энкодер: устройство и примеры работы
Содержание:
- Выбор лучших энкодеров для Ардуино
- How to control dc motor with encoder:
- Дальнейшее описание, включая форму волны энкодера
- Принцип работы инкрементного энкодера
- Maximum Speed and CPU Usage
- Step 3: The Code
- Rotary Encoder Arduino Example
- Фильтрация дребезга контактов механического энкодера
- Типы приборов
- Варианты интерфейсов энкодеров
- Абсолютный энкодер устройство
- Принцип работы энкодера
- Example Program
- Driving the Motor with Encoder and Arduino:
- Подключение поворотного энкодера с Ардуино
Выбор лучших энкодеров для Ардуино
Чтобы упростить процесс выбора энкодера к Arduino, здесь будет подборка каждого варианта.
Поворотный энкодер EC11
Нужен простой угловой энкодер, который поможет начать распознавать вращающийся вал с помощью Ардуино? Тогда стоит выбрать EC11.
Устройство имеет в общей сложности 5 контактов, 3 с одной стороны для вращательного кодирования, которым требуется простая цепь для подачи постоянного тока 5В. Два других замыкаются при нажатии, поэтому нет недостатка в какой-либо функциональности при использовании этого энкодера с Ардуино.
Магнитный энкодер Grove AS5600
Нужно устройство, которое может одновременно работать как магнитный потенциометр или магнитный энкодер с отличной надежностью и долговечностью? Тогда это устройство отлично подойдет.
Оно не только работает в обоих направлениях, но по сравнению с традиционным энкодером/потенциометром, Grove AS5600 бесконтактный, без ограничения угла поворота, обеспечивает высокоточный сигнал. Все это стало возможным благодаря встроенному AS5600, основанному на эффекте Холла.
Grove — оптический поворотный прибор
Этот оптический датчик угла поворота (для уно, нано и других) включает в себя инфракрасный излучатель и два фототранзисторных детектора. Подходит не только для определения скорости/вращения, но и для определения направления вращения.
Его особенности:
- двойные фототранзисторные детекторы, могут определять направление вращения;
- встроенные светодиодные индикаторы;
- интерфейс Grove для простоты использования с Ардуино.
How to control dc motor with encoder:
Arduino DC Motor Speed Control with Encoder- I have been using different types of stepper motors, Servo motors, and DC Motors for quite a long time in different intermediate and advanced level projects. DC motors are more frequently used than Stepper Motors and Servo Motors. If you have watched my videos and read my articles then you should know DC motors are quite different from Stepper Motors and servo Motors. These three types of motors have a different construction. The stepper motors and servo motors are designed in a way that we can control their position. We can control the steps in the forward and reverse directions. Servos can move from 0 to 180 degrees, so you can move to any position between 0 and 180. Likewise, in stepper motors, you can control the steps precisely and this is the reason stepper motors are used in CNC machines, 3d printers, etc. On the other hand, when a dc motor is powered up it immediately starts rotating, it continuously rotates, you can’t exactly control its position until you use a specific technique. You can’t 100% control a DC motor like Stepper motor and Servo, but if you add an encoder it can really change the whole game. With an encoder being added, you can keep track of the motor revolutions, the amount of distance it has covered, and this way you can make a nice feedback system that can be used to control the DC motor. Then you can stop the DC motor at the position where you want it to stop. The control of a DC motor using an encoder is not that simple, you just simply can’t start by adding an encoder with the DC Motor and start controlling the DC motor, to use an encoder you will need a controller, the controller will read the encoder and then will accordingly control the DC motor as per the pre-defined instructions written by the programmer. for this project, you will need a microcontroller board like the Arduino Uno or Arduino Nano, or Arduino Mega, or Arduino pro mini, etc. I know beginners are more comfortable with Arduino Uno, Arduino mega, and Arduino Nano, so I will start with the Arduino Uno, the same connections and programs you can also try on Arduino Nano and Arduino Mega. To get started, you will need Arduino Uno, a Motor driver, a DC Motor, and of course an Encoder. To read the Encoder, we will connect the encoder output pins with Arduino’s pins 2 and 3 which are the interrupt pins. The power wires of the encoder will be connected with the Arduino’s 5V and GND. To keep things simpler, I will start with the simple example code in which I will use pins 2 and 3 as the normal digital pins, we won’t activate the interrupts and then in the second example code, we will use the interrupts. Without any further delay, let’s get started!!!
Дальнейшее описание, включая форму волны энкодера
Ниже приведено изображение, показывающее формы сигналов каналов A и B кодера:
Это может прояснить, как работает выше указанный код. Когда устройство обнаруживает переход от низкого к высокому уровню на канале A, он проверяет, перешел ли канал к B высоким или низким уровням. Затем происходит увеличение/уменьшение переменной, чтобы учесть направление, в котором кодер должен вращаться. Это нужно, чтобы генерировать найденную форму волны. Также на изображении показаны переходы красным или зеленым цветом. Они зависят от того, в каком направлении движется кодировщик.
Одним из недостатков приведенного выше кода является то, что на самом деле он учитывает только одну четверть возможных переходов.
Руководство по энкодерам и тому, как оно подключается к Ардуино, закончилось. Благодаря этому можно получить общее представление о том, что из себя представляют данные устройства, и как они работают.
Принцип работы инкрементного энкодера
Импульсный (пошаговый) энкодер
относится к типу энкодеров, которые предназначены для указания направления движения и/или углового перемещения внешнего механизма. Пошаговый энкодер периодически формирует импульсы, соответствующие углу вращения вала. Этот тип энкодеров, в отличие от абсолютных, не формирует выходные импульсы, когда его вал находится в покое. Пошаговый энкодер связан со счетным устройством, это необходимо для подсчета импульсов и преобразования их в меру перемещения вала.
Пошаговый оптический энкодер состоит из следующих компонентов: источника света, диска с метками, фототранзисторной сборки и схемы обработки сигнала. Диск пошагового энкодера подразделен на точно позиционированные отметки. Количество отметок определяет количество импульсов за один оборот. К примеру, если диск поделен на 1000 меток, тогда за 250 импульсов вал должен повернуться на 90 градусов.
Диск с метками инкрементного энкодера
Пошаговый энкодер может быть классифицирован в однофазный тип (только канал выход), который может быть использован, чтобы считать сумму импульсов или определять ускорение. Рассматривая интервал между импульсами и квадратурой энкодера (каналов A и выход B), можно также определить направление вращения вала (по-, или против часовой стрелки). Тип энкодера с нулевым индексом выхода (канал N) выдает импульс нулевой отметки за один оборот, чтобы корректировать ошибки в пределах каждого оборота. Более высокое разрешение (в два или в четыре) получается подсчетом как переднего, так и заднего края меток. Канал A и B генерирует импульсы с фазами, смещенными относительно друг друга на 90 градусов.
Технология
Квадратура выхода (выходы А и В)
Для квадратуры выхода энкодера используются два выходных канала, для того чтобы определить — вращается вал по часовой стрелке или против часовой стрелки, основанное на сдвиге фазы 90°±0° , допуск ±45° — приемлемый для спецификации сдвига фазы. Энкодер с единственным выходом (A) более известен как тахометр.
Максимальная частота ответа
Максимальная частота ответа является частотой, при которой вращающийся энкодер может дать электрический ответ. Такая частота имеет отношение к количеству выходных импульсов, на которые энкодер реагирует в секунду. Следовательно, энкодер пошагового типа должен удовлетворить следующее отношение: (rpm/60) x (разрешение) ≤ максимальной частоты ответа.
Указатель нулевой отметки (канал Z)
В энкодере, имеющем этот канал, импульс появляется на выходе в каждом обороте вала. Функция показателя нуля может использоваться для сброса внешне связанного счетчика или для регистрации начальной (нулевой) позиции.
Разрешение
Разрешение — это количество выходных импульсов за вращение вала.
Соединительный вал
Для механического соединения вала датчика с внешним механизмом следует использовать специальный соединитель (сцепление) гибкого типа, который предназначен для компенсации возможного биения валов, как в радиальном, так и в осевом направлении. Это позволяет резко снизить вероятность преждевременного износа подшипников вала датчика. Уже незначительный, возникший в осевом направлении вала, люфт может привести к полному электрическому отказу энкодера. Это связано с тем, что для достижения высокого разрешения, оптический диск и считывающая матрица располагаются в непосредственной близости друг от друга и минимальное осевое биение вала может привести к их механическому контакту, что в последствии приведет к разрушению нанесенных на диск меток.
Maximum Speed and CPU Usage
File > Examples > Encoder > SpeedTest
Board | MaximumInterrupt Rate(approximate) | Conditions |
---|---|---|
Teensy 2.0 | 100 kHz | Normal |
Teensy 2.0 | 127 kHz | ENCODER_OPTIMIZE_INTERRUPTS |
Emulating Quadrature Encoded Signals
FreqCount
+5V | Quadrature Encoder Signal Emulator Clock | Input o----*-------------------------- ---------------------------o Output1 | |14 | | | _______|_______ | | _______________ | | CD4013 | | | | CD4013 | | 5 | | 1 | | 9 | | 13 ---------| D Q |-----|----*----| D Q |------o Output2 | | | | | | | | | 3 | | | 11 | | | ----|> Clk | ---------|> Clk | | | | | | | 6 | | 8 | | | ----| S | ----| S | | | | | | | | | | 4 | _ | 2 | 10 | _ | 12 | *----| R Q |--- *----| R Q |---- | | | | | | | | | | |_______________| | |_______________| | | | | | | | | | 7 | | | | | | | -------------------------------------------------------------- | | | | | | ----- ----- ----- --- --- --- - - -
Measuring Maximum Interrupt Rates
SpeedTest: 147 mV (close to zero CPU remaining) at 127 kHz interrupt rate. |
If using a mechanical system where
you reach a speed limit imposed by your motors or other hardware,
the amount this voltage has decreased, compared to the baseline,
should give you a good approximation of the portion of available
CPU time Encoder is consuming at your maximum speed.
Step 3: The Code
This code is free for your use (as in no cost and to be modified as you please), please attribute where you should.
/*******Interrupt-based Rotary Encoder Sketch*******by Simon Merrett, based on insight from Oleg Mazurov, Nick Gammon, rt, Steve Spence*/static int pinA = 2; // Our first hardware interrupt pin is digital pin 2static int pinB = 3; // Our second hardware interrupt pin is digital pin 3volatile byte aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detentvolatile byte bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)volatile byte encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255volatile byte oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detentvoid setup() { pinMode(pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases) pinMode(pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases) attachInterrupt(0,PinA,RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below) attachInterrupt(1,PinB,RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below) Serial.begin(115200); // start the serial monitor link}void PinA(){ cli(); //stop interrupts happening before we read pin values reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge encoderPos --; //decrement the encoder's position count bFlag = 0; //reset flags for the next turn aFlag = 0; //reset flags for the next turn } else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation sei(); //restart interrupts}void PinB(){ cli(); //stop interrupts happening before we read pin values reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge encoderPos ++; //increment the encoder's position count bFlag = 0; //reset flags for the next turn aFlag = 0; //reset flags for the next turn } else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation sei(); //restart interrupts}void loop(){ if(oldEncPos != encoderPos) { Serial.println(encoderPos); oldEncPos = encoderPos; }}
That’s it!
Rotary Encoder Arduino Example
Let’s make a practical example of it using the Arduino. The particular module that I will use for this example comes on a breakout board and it has five pins. The first pin is the output A, the second pin is the output B, the third pin is the Button pin and of course the other two pins are the VCC and the GND pin.
We can connect the output pins to any digital pin of the Arduino Board.
You can get the components needed for this Arduino Tutorial from the links below:
- Rotary Encoder Module………………. Amazon / Banggood / AliExpress
- Arduino Board …………………………… Amazon / Banggood / AliExpress
- Breadboard and Jump Wires ……… Amazon / Banggood / AliExpress
Disclosure: These are affiliate links. As an Amazon Associate I earn from qualifying purchases.
Фильтрация дребезга контактов механического энкодера
Механические энкодеры имеют встроенные переключатели, которые формируют сигнал на квадратурном выходе во время вращения.
Дребезг контактов на выходе механического энкодера
Когда имеем дело с сигналами энкодера, основной проблемой является дребезг контактов. Он вызывает ошибочное определение направления вращения и величины поворота вала энкодера и делает использование энкодеров проблематичным. Мы можем избавиться от дребезга контактов, отфильтровывая его в программе или используя дополнительные схемы фильтрации.
Фильтрация шума в программном обеспечении микроконтроллера является одним из вариантов фильтрации, но она обладает некоторыми недостатками. Вам необходимо написать более сложный код для обработки шума. Фильтрация займет время обработки и внесет задержки в основной поток программы. Вам может потребоваться установить таймеры, чтобы игнорировать интервалы дребезга контактов. В конце концов, возможно, у вас не получится получить удовлетворительный и надежный результат.
Фильтрация шума с помощью дополнительных аппаратных средств проще, и она останавливает шум еще в его источнике. Вам понадобится RC фильтр первого порядка. На рисунке ниже вы можете увидеть, как выглядит сигнал после использования RC фильтра.
RC фильтр и форма сигнала на его выходе
RC-фильтр замедляет время спада и время нарастания и обеспечивает аппаратное удаление дребезга контактов. При выборе пары резистор-конденсатор вы должны учитывать максимальную частоту вращения. Иначе будет отфильтрован и ожидаемый отклик энкодера.
Типы приборов
Устройства бывают нескольких типов. Типы энкодеров: инкрементальные и абсолютные, оптические и механические. Далее будет рассмотрено, что такое энкодер инкрементального типа, а затем обозрены другие типы.
Инкрементальные энкодеры
Они распространены больше всего. В инкрементальном варианте вращательное движение вала преобразовывается в электрические импульсы. Его конструкция состоит из диска с прорезями и оптических датчиков.
Конструкция датчиков поворота данного типа, не позволяет им сообщать свое абсолютное состояние, а только величину изменения положения. Простой образец инкрементального устройства — шайба регулировки громкости автомобильной магнитолы.
Этот вид работает следующим образом. У него есть начальная нуль-метка, или выход Z, и два дополнительных выхода — A и B. Датчик создает две линии сигналов со смещенными на четверть фазы импульсами относительно друг друга. Разница импульсов указывает на направление вращения, а их количество — на угол поворота.
Разновидность инкрементальных энкодеров — сдвоенные, или квадратурные. Они состоят из двух датчиков, которые срабатывают со смещением в полшага. Квадратурные считают количество импульсов и учитывают направление.
У инкрементальных два главных минуса. Во-первых, нужно постоянно обрабатывать и анализировать сигнал, для чего используют контроллер и специальную программу. Во-вторых, они требуют синхронизации с нулевой меткой после включения. Для этого требуется инициализация для поиска выхода Z.
Абсолютные энкодеры
Датчики такого типа устроены более сложно. Но они позволяют определить величину угла поворота сразу после включения, не требуя синхронизации с нулевой меткой.
В основе конструкции поворотный круг, разделенный на одинаковые по размеру пронумерованные секторы. После включения устройства определяется номер сектора, на котором оно находится. Такое решение позволяет сразу зафиксировать положение, угол и направление вращения.
Принцип работы абсолютного энкодера основан на использовании кода Грея для определения текущего положения и других параметров. В них не требуется синхронизация с нулевым значением.
Единственный существенный недостаток этого типа угловых датчиков — необходимость все время переводить код Грея в двоичный код для регистрации положения датчика.
Многооборотные датчики поворота
Абсолютные энкодеры могут быть однооборотными и многооборотными.
Однооборотные показывают абсолютное значение после одного оборота. После этого код возвращается к начальному значению. Такие датчики используют в основном для измерения угла поворота.
Если нужно измерять обороты в системах с линейным перемещением, используют многооборотные энкодеры. В них есть дополнительный передаточный механизм, благодаря чему они регистрируют, помимо угла поворота, количество оборотов.
Оптические энкодеры
Диск оптического энкодера изготавливают из стекла. Отличие этого типа угловых датчиков, в наличии оптического растора, перемещающегося при вращении вала. При этом он создает поток света, который регистрирует фотодатчик.
Каждому положению энкодера соответствует определенный цифровой код, который вместе с количеством оборотов составляет единицу измерения устройства.
Оптические угловые датчики бывают фотоэлектрическими и магнитными.
В основе работающих датчиков лежит магнитный эффект Холла. Их точность и разрешение ниже, однако, и конструкция проще. Они лучше переносят сложные условия работы и занимают меньше места.
Фотоэлектрические датчики основаны на том же принципе. В них свет преобразуется в электрические сигналы.
Механические энкодеры
Также называются аналоговыми. Их диск изготавливают из диэлектрика и наносят на него выпуклые или непрозрачные области. Набор контактов и переключателей, позволяет вычислить значение абсолютного угла. Механические энкодеры также используют код Грея.
Один из недостатков этих энкодеров в том, что со временем контакты разбалтываются. В результате сигнал искажается, и прибор выдает неточные значения. А это сказывается на общей работоспособности. Оптические и магнитные энкодеры не имеют такого недостатка.
Варианты интерфейсов энкодеров
Параллельный двоичный интерфейс представляет параллельную шину данных с определенной разрядностью. Например, для чисел от 0…1024 (разрешение 0,35 градуса) достаточно 10 разрядов (210=1024), 10 проводников шины. Для чисел 0…720 к сожалению тоже придется использовать 10 проводников, потому что 29=512. Поэтому энкодеры с таким разрешением (10 бит) после числа 719 сразу переходят на число 0. Для надежного считывания некоторые производители закладывают в такие энкодеры еще один сигнал триггера-защелки, по которому блокируется изменение выходного значения. В остальных случаях рекомендуется использовать цифровые фильтры для борьбы с помехами.
Двоично-десятичным интерфейс (BCD) представляет тоже параллельную шину данных, но с более человекочитаемым форматом чисел. В BCD-представлении используются только 10 возможных комбинаций 4-битового числа вместо 16. Поэтому существуют запрещённые комбинации битов: 1010(1010), 1011(1110), 1100(1210), 1101(1310), 1110(1410) и 1111(1510). Числа в виде десятков от 10 до 90 записываются в следующие 4 бита. Числа в виде сотен от 100 до 900 записываются в следующие 4 бита. И числа в виде тысяч от 1000 до 9000 записываются в следующие 4 бита. Поэтому для комбинации энкодера с 1024 значениями потребуется 4 + 4 + 4 + 1 = 13 бит (проводов).
Интерфейс с кодом Грея также является параллельным, за исключением формата выдачи чисел. Это необходимо для максимально возможного предотвращения от ошибок считывания на критически больших скоростях вращения вала. В коде Грея изменения допускаются только в одном бите при переходе на следующее число. Действует следующее правило кодирования: старший бит остается без изменения, а каждый последующий бит инвертируется, если предыдущий бит исходного двоичного кода равен единице. Ниже представлена разница бинарного кодирования и кодирования Грея
Обычное (двоичное) кодирование | Кодирование по методу Грея | ||||
---|---|---|---|---|---|
DEC | Binary | HEX | DEC | Binary | HEX |
0000 | 0h | 0000 | 0h | ||
1 | 0001 | 1h | 1 | 0001 | 1h |
2 | 0010 | 2h | 3 | 0011 | 3h |
3 | 0011 | 3h | 2 | 0010 | 2h |
4 | 0100 | 4h | 6 | 0110 | 6h |
5 | 0101 | 5h | 7 | 0111 | 7h |
6 | 0110 | 6h | 5 | 0101 | 5h |
7 | 0111 | 7h | 4 | 0100 | 4h |
8 | 1000 | 8h | 12 | 1100 | Ch |
9 | 1001 | 9h | 13 | 1101 | Dh |
10 | 1010 | Ah | 15 | 1111 | Fh |
11 | 1011 | Bh | 14 | 1110 | Eh |
12 | 1100 | Ch | 10 | 1010 | Ah |
13 | 1101 | Dh | 11 | 1011 | Bh |
14 | 1110 | Eh | 9 | 1001 | 9h |
15 | 1111 | Fh | 8 | 1000 | 8h |
Абсолютный энкодер устройство
Рисунок 3. Абсолютный энкодер У этого типа ДУПа его поворотный круг поделён на определённые пронумерованные сектора, обычно идентичного размера. Во время работы он выдаёт конкретный секторный номер, в котором он непосредственно и находится. Именно поэтому данное устройство называют абсолютным. Благодаря его устройству можно легко определить угол/положение/направление энкодера относительно начального (нулевого) сектора.
Помимо этого абсолютный датчик угла не требует присоединения систем отсчёта к какому-нибудь нулевому значению. В нём используется специальный код Грея, позволяющий не допустить ошибки при работе. Из недостатков можно выделить только то, что микроконтроллер будет вынужден постоянно его переводить в двоичный код, чтобы выяснить положение ДУПа.
Принцип работы энкодера
Как обеспечивается работа устройства лучше всего видно, если заглянуть «внутрь». Рассмотрим типовую и самую распространенную схему построения преобразователя – оптоэлектронную с подшипниковым узлом. На рисунке ниже представлен оптический многооборотный абсолютный датчик с цельным валом.
Здесь видны практически все основные узлы современного изделия:
- – вал энкодера
- – фланец (на данном рисунке представлен зажимной тип)
- – фотоприемник инфракрасного (ИК) света
- – оптический диск с растрами (метками, если инкрементный) или кодовыми дорожками (если абсолютный)
- – ИК осветитель (LED) с линзой на плате
- – механический редуктор с зубчатыми колесами (многооборотный модуль)
- – плата обработки сигнала с выходными формирователями и конверторами интерфейса.
Элементы 1, 2, 4 формируют оптико-механический подшипниковый узел. Оптический диск (лимб) 4 может быть стеклянным, металлическим, пластиковым. В зависимости от производителя бывают конструкции, где элементы 3 и 5 поменяны местами. Механический редуктор 6 встречается только у многооборотных абсолютных преобразователей.
На рисунке выше показана работа энкодера:
- ИК свет от источника 5 проходит через кодовый диск 4, и попадает на приемник (фото матрицу) 3
- Фотоприёмник имеет нанесенную на чувствительном элементе или расположенную над ним маску (индикаторную пластину), которая также имеет «окошки», как на вращающемся диске
- Из-за поочередного перекрытия и открытия окошек маски в процессе вращения вала датчика, проходящий свет имеет аналоговую структуру. Нет света -> нарастает -> максимум света -> убывает -> нет света
- Это регистрирует фото сенсор
- Далее аналоговый сигнал с приемника преобразуется платой обработки 7 в необходимые для дальнейшей передачи информации импульсы.
Example Program
File > Examples > Encoder > TwoKnobs
/* Encoder Library - TwoKnobs Example * http://www.pjrc.com/teensy/td_libs_Encoder.html * * 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(5, 6); Encoder knobRight(7, 8); // 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); } }
Driving the Motor with Encoder and Arduino:
Now, I am sure you have completely understood how an Encoder works, how the Encoder outputs are triggered, and then how to write a simple code to count the pulses. So far we were manually rotating the DC motor shaft to trigger the Encoder outputs, now to do everything automatically it’s time to connect a motor driver so that we can read the position measurements from the Encoder. Start by connecting the DC motor wires to the outputs of the motor driver circuit. The motor driver also needs an appropriate power supply, which you will need to select as per your DC motor specs. Next, connect the Motor driver ground to the Arduino ground, the PWM input of the motor driver should be connected to an Arduino PWM pin here I have used pin 5.
The other two motor driver pins can be connected to any of the remaining Arduino digital pins. Before writing the control algorithm, Let’s test the motor driver start by defining the pins that you connected to the motor driver.
Driving the Motor with Encoder, Arduino Code:
#define ENCA 2
#define ENCB 3
#define PWM 5
#define IN2 6
#define IN1 7
int pos = 0;
void setup() {
Serial.begin(9600);
pinMode(ENCA,INPUT);
pinMode(ENCB,INPUT);
attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
}
void loop() {
setMotor(1, 25, PWM, IN1, IN2);
delay(200);
Serial.println(pos);
setMotor(-1, 25, PWM, IN1, IN2);
delay(200);
Serial.println(pos);
setMotor(0, 25, PWM, IN1, IN2);
delay(20);
Serial.println(pos);
}
void setMotor(int dir, int pwmVal, int pwm, int in1, int in2){
analogWrite(pwm,pwmVal);
if(dir == 1){
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
}
else if(dir == -1){
digitalWrite(in1,LOW);
digitalWrite(in2,HIGH);
}
else{
digitalWrite(in1,LOW);
digitalWrite(in2,LOW);
}
}
void readEncoder(){
int b = digitalRead(ENCB);
if(b > 0){
pos++;
}
else{
pos—;
}
}
1 |
#define ENCA 2 intpos=; voidsetup(){ Serial.begin(9600); pinMode(ENCA,INPUT); pinMode(ENCB,INPUT); attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING); } voidloop(){ setMotor(1,25,PWM,IN1,IN2); delay(200); Serial.println(pos); setMotor(-1,25,PWM,IN1,IN2); delay(200); Serial.println(pos); setMotor(,25,PWM,IN1,IN2); delay(20); Serial.println(pos); } voidsetMotor(intdir,intpwmVal,intpwm,intin1,intin2){ analogWrite(pwm,pwmVal); if(dir==1){ digitalWrite(in1,HIGH); digitalWrite(in2,LOW); } elseif(dir==-1){ digitalWrite(in1,LOW); digitalWrite(in2,HIGH); } else{ digitalWrite(in1,LOW); digitalWrite(in2,LOW); } } voidreadEncoder(){ intb=digitalRead(ENCB); if(b>){ pos++; } else{ pos—; } } |
It is useful to define a function that will set the motor direction and speed. The interface for the setMotor function, I have written here sets the direction and speed of a motor with the pins defined in the last three inputs. Inside the function, I have set the speed with an analog write command. if the direction integer is 1 then the motor will rotate one way by writing a high low combination to the input pins of the driver. If you reverse the order to a low-high combination the motor will rotate in the other direction. Inside the loop function, you can call the setMotor function to drive the motor also write the position to the serial line.
Подключение поворотного энкодера с Ардуино
Теперь, когда принципы работы различных энкодеров изучены, можно приступить к описанию схемы подключения к Ардуино.
Для этого понадобятся:
- любое устройство Ардуино, например, Arduino UNO, Arduino Mega, Arduino Leonardo, Arduino 101, Arduino Due;
- любой энкодер Ардуино.
Обзор поворотного энкодера
Поворотный энкодер — это датчик, используемый для определения углового положения вала, подобный потенциометру.
Пины, и что они означают:
- CLK: выход A (цифровой);
- DT: выход B (цифровой);
- SW: нажатие кнопки (цифровой);
- + : VCC-напряжение питания;
- GND: заземление.
Поворотный прибор может быть использован в основном для тех же целей, что и потенциометр. Однако потенциометр обычно имеет точку, за которую вал не может вращаться, в то время как энкодер может вращаться в одном направлении без ограничений. Чтобы сбросить показания положения, нужно нажать на вал вниз.
Данное устройство определяет угловое положение вращающегося вала с помощью серии прямоугольных импульсов. Он по существу имеет равномерно расположенные контактные зоны, соединенные с общим узлом, а также два дополнительных контакта, называемых A и B, которые находятся на 90 градусов вне фазы. Когда вал вращается вручную, контакты A и B синхронизируются с общим контактом и генерируют импульс. Подсчитав количество импульсов любого из этих выходов, можно определить положение вращения.
Чтобы определить направление и проверить, вращается ли штифт по часовой стрелке или против часовой стрелки, нужно сделать следующее:
- Если вращающийся вал движется по часовой стрелке, то сигнал A опережает B. В одни и те же моменты времени, A и B будут находиться на противоположных частях прямоугольной волновой функции.
- Если вал движется против часовой стрелки, то сигнал B опережает A.
Подключение
Если говорить в общем, то CLK, DT и SW, должны быть подключены к цифровым выводам на Ардуино, + должен быть подключен к 5V, а GND заземлен.
Пошаговая инструкция подключения проводов энкодера к Ардуино:
- CLK: подключите конец провода к пину CLK на поворотном энкодере, затем к любому цифровому выводу на Arduino (оранжевый провод).
- DT: подключите конец провода к пину DT, затем к любому цифровому контакту на Arduino (желтый провод).
- SW: подключите конец провода к пину SW, далее к любому цифровому контакту на Arduino (голубой провод).
- + : подключите провод к пину +, затем к контакту +5V на Arduino (красный провод).
- GND: подключите конец провода к пину GND на энкодер с контактом GND на Arduino. (Черный провод).
Как кодировать
Код изменяет высоту тона в зависимости от того, в каком направлении повернут энкодер. Когда он поворачивается против часовой стрелки, шаг уменьшается, а когда он поворачивается по часовой стрелке, шаг увеличивается.
Что понадобится:
- датчик поворотного энкодера;
- Ардуино;
- пьезодатчик;
- провода.
Вот сам код:
Описание кода
Итак, сначала нужно определить контакты, к которым подключен кодер, и назначить некоторые переменные, необходимые для работы программы. В разделе «Настройки» нужно определить два контакта в качестве входных данных, и запустить последовательную связь для печати результатов на последовательном мониторе. Также нужно прочитать начальное значение вывода A, затем поместить это значение в переменную aLastState.
Далее в разделе цикла снова изменить вывод A, но теперь поместить значение в переменную aState. Таким образом, если повернуть вал и сгенерировать импульс, эти два значения будут отличаться. Сразу после этого, используя второй параметр «if», определить направление вращения. Если выходное состояние B отличается от A, счетчик будет увеличен на единицу, в противном случае он будет уменьшен. В конце, после вывода результатов на мониторе, нужно обновить переменную aLastState с помощью переменной aState.
Это все, что нужно для этого примера. Если загрузить код, запустить монитор и начать вращать вал, значения станут отображаться на мониторе.
Упрощенный пример
Следующий пример кода продемонстрирует, как считывает сигналы Arduino на датчике энкодера. Он просто обновляет счетчик (encoder0Pos) каждый раз, когда энкодер поворачивается на один шаг, а параметры вращения отправляются на порт ПК.
Код:
Следует обратить внимание на то, что приведенный выше код не является высокопроизводительным. Он предоставлен для демонстрационных целей