
Энкодеры KY-040 или EC11 – распространённые решения для считывания углового положения и скорости вращения в проектах на Arduino. Их работа основана на двух квадратурных сигналах (каналы A и B), сдвинутых на 90°, и дополнительном сигнале кнопки (SW). Для корректной обработки данных потребуется библиотека Encoder от PJRC или RotaryEncoder от Matthias Hertel, так как стандартные методы digitalRead() не справляются с дребезгом контактов и высокочастотными помехами.
Типичная ошибка – подключение энкодера напрямую к пинам без подтягивающих резисторов. Для стабильной работы используйте внутренние подтяжки Arduino (INPUT_PULLUP) или внешние резисторы на 10 кОм. Каналы A и B подключайте к прерываниям (пины 2 и 3 на Uno), чтобы избежать потери импульсов при высокой скорости вращения. Сигнал кнопки (SW) можно вывести на любой цифровой пин, но не забудьте добавить конденсатор на 0.1 мкФ для фильтрации шумов.
При настройке прерываний учитывайте, что энкодер генерирует до 2000 импульсов на оборот (для моделей с разрешением 20 PPR). Если частота превышает 1 кГц, используйте режим CHANGE вместо RISING или FALLING, чтобы не пропускать фронты сигнала. В коде обязательно реализуйте алгоритм подсчёта импульсов с учётом направления вращения – простая проверка состояния каналов A и B в прерывании позволит определить, в какую сторону крутится вал.
Для тестирования подключите энкодер к Arduino по схеме: канал A → пин 2, канал B → пин 3, SW → пин 4, GND → GND, VCC → 5V. Загрузите пример из библиотеки Encoder и вращайте вал – в мониторе порта должны отображаться точные изменения положения. Если значения «прыгают», проверьте качество пайки, экранирование проводов и наличие помех от двигателей или блоков питания.
Подключение энкодера к Arduino: пошаговая инструкция

Типовая схема подключения:
CLK→ пин2(прерывание)DT→ пин3(прерывание)SW→ пин4(обычный вход)+→5VGND→GND
Для энкодеров с разрешением 20 импульсов на оборот используйте прерывания по фронту (RISING или FALLING) на пинах 2 и 3 – это минимизирует дребезг и повышает точность. Избегайте аналоговых пинов: они не поддерживают прерывания и снижают быстродействие.
Пример кода для обработки вращения и нажатия:
const int clkPin = 2;
const int dtPin = 3;
const int swPin = 4;
volatile int counter = 0;
int lastClkState;
void setup() {
pinMode(clkPin, INPUT_PULLUP);
pinMode(dtPin, INPUT_PULLUP);
pinMode(swPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(clkPin), updateCounter, CHANGE);
Serial.begin(9600);
}
void updateCounter() {
int clkState = digitalRead(clkPin);
int dtState = digitalRead(dtPin);
if (clkState != lastClkState) {
counter += (clkState == dtState) ? -1 : 1;
Serial.println(counter);
}
lastClkState = clkState;
}
void loop() {
if (digitalRead(swPin) == LOW) {
counter = 0;
Serial.println("Сброс");
delay(200); // Антидребезг
}
}
Для фильтрации шумов добавьте в цикл loop() программный антидребезг с задержкой 5–10 мс или используйте библиотеку Encoder.h от PJRC. При работе с высокоскоростными энкодерами (>1000 имп/об) переключитесь на аппаратные таймеры Arduino (например, TimerOne) для точного подсчёта импульсов без потерь.
Выбор энкодера и необходимых компонентов для проекта

Для большинства проектов с Arduino подойдут инкрементальные энкодеры с разрешением от 20 до 600 импульсов на оборот. Модели KY-040 (20 имп/об) и EC11 (30 имп/об) – оптимальный выбор для начинающих: они дешевы, совместимы с 5V логикой и имеют встроенную кнопку. Если требуется высокая точность, рассмотрите энкодеры серии AS5600 (магнитные, 12-бит) или AMT102-V (оптические, до 2048 имп/об), но они требуют дополнительных библиотек и калибровки.
Обратите внимание на тип выходного сигнала: энкодеры с открытым коллектором (например, PEC11) требуют подтягивающих резисторов на 10 кОм к питанию. Для энкодеров с логическим выходом (TTL) резисторы не нужны, но проверьте совместимость с напряжением Arduino (3.3V или 5V). Избегайте энкодеров с аналоговым выходом – они усложняют обработку данных и снижают точность.
Помимо энкодера, потребуется макетная плата для тестирования и провода типа «папа-мама» (22 AWG) для подключения. Для стабильной работы рекомендуется использовать конденсатор 0.1 мкФ между питанием и землей энкодера – это снижает помехи от механических вибраций. Если планируется работа с высокими скоростями вращения (>100 об/мин), добавьте RC-фильтр (1 кОм + 10 нФ) на выходные сигналы A и B.
Для проектов с ограниченным пространством выбирайте миниатюрные энкодеры, например, Bourns PEC11R-4215F-S0024 (диаметр вала 6 мм). Убедитесь, что вал энкодера совместим с механикой проекта: стандартные диаметры – 4 мм, 6 мм или D-образный профиль. При использовании энкодера с металлическим корпусом заземлите его, чтобы избежать наводок.
Если энкодер будет работать в условиях вибрации или пыли, отдайте предпочтение герметичным моделям (IP65 и выше), например, Omron E6B2-CWZ6C. Для проектов с батарейным питанием выбирайте энкодеры с низким энергопотреблением (<5 мА), такие как TT Electronics EN11-HSM1BF20. Избегайте дешевых китайских аналогов без документации – они часто имеют нестабильные характеристики и короткий срок службы.
Для обработки сигналов энкодера на Arduino используйте библиотеку Encoder (автор Paul Stoffregen) – она поддерживает аппаратные прерывания и минимизирует нагрузку на процессор. При работе с энкодерами высокого разрешения (>1000 имп/об) рассмотрите возможность использования внешнего аппаратного счетчика, например, микросхемы LS7366R, чтобы разгрузить Arduino.
Схема подключения энкодера к плате Arduino

Если энкодер не имеет встроенных подтягивающих резисторов, активируйте внутренние подтяжки Arduino в коде с помощью pinMode(pin, INPUT_PULLUP). Это упростит схему, исключив внешние компоненты. Однако для энкодеров с высокой скоростью вращения (более 1000 импульсов/оборот) рекомендуется использовать внешние резисторы 1–4,7 кОм для стабильности сигнала.
При подключении энкодера с открытым коллектором (например, EC11) потребуется дополнительный резистор 1 кОм между выходом канала и 5V. Это предотвратит «плавающий» сигнал и обеспечит четкое переключение логических уровней. Проверьте даташит вашего энкодера: некоторые модели требуют напряжения 3,3V, а не 5V, иначе возможен выход из строя.
Для минимизации помех используйте экранированный кабель при длине проводов более 20 см. Заземлите экран на GND Arduino только с одной стороны, чтобы избежать контура заземления. Размещайте энкодер как можно ближе к плате или применяйте фильтрующие конденсаторы 0,1 мкФ между VCC и GND у самого модуля.
При работе с энкодерами высокого разрешения (свыше 2000 импульсов/оборот) учитывайте ограничения Arduino по скорости обработки прерываний. Оптимально использовать аппаратные прерывания на пинах 2 и 3 (для Uno/Nano), так как они поддерживают внешние прерывания INT0 и INT1. Для Mega2560 доступны прерывания на пинах 2, 3, 18, 19, 20, 21.
Если энкодер используется в проекте с двигателями или реле, разделите цепи питания: подключите Arduino и энкодер к отдельным стабилизаторам напряжения или используйте оптопару для гальванической развязки. Это устранит помехи от индуктивных нагрузок, которые могут искажать сигналы энкодера и приводить к ошибкам в подсчете импульсов.
Настройка питания и заземления для стабильной работы
Энкодеры чувствительны к помехам в цепях питания и заземления. Для Arduino Uno рекомендуется использовать стабилизированный источник напряжения 5 В с током не менее 500 мА. При питании от USB-порта компьютера убедитесь, что кабель качественный – тонкие провода или длинные кабели (более 1,5 м) могут вызывать просадки напряжения, приводящие к ложным срабатываниям энкодера.
Заземление должно быть общим для Arduino и энкодера. Используйте отдельный провод сечением не менее 0,5 мм² для соединения GND Arduino с GND энкодера. Избегайте последовательного подключения заземления через другие компоненты – это создает «земляные петли», увеличивающие уровень шумов. Для энкодеров с открытым коллектором (например, KY-040) подтягивающие резисторы на линиях сигналов (A, B) должны подключаться к тому же источнику питания, что и Arduino, чтобы избежать разности потенциалов.
При использовании внешнего источника питания (например, блока на 9 В) подключайте его через стабилизатор напряжения (например, LM7805) с конденсаторами фильтрации: 100 мкФ на входе и 10 мкФ на выходе. Это снижает пульсации напряжения, критичные для работы энкодера на высоких скоростях вращения. Для энкодеров с разрешением более 1000 импульсов на оборот добавьте керамический конденсатор 0,1 мкФ между питанием и GND энкодера – это подавляет высокочастотные помехи.
Если энкодер подключается длинными проводами (более 30 см), используйте витую пару для сигнальных линий (A, B) и экранированный кабель для питания. Экран подключайте к GND только с одной стороны (со стороны Arduino), чтобы избежать образования петли. Для энкодеров с дифференциальными выходами (например, RS-422) применяйте соответствующие приемники (например, SN75176), а не прямые подключения к пинам Arduino.
| Тип энкодера | Рекомендуемое напряжение питания | Минимальное сечение проводов питания | Дополнительные меры |
|---|---|---|---|
| Механический (KY-040) | 4,5–5,5 В | 0,35 мм² | Подтягивающие резисторы 10 кОм |
| Оптический (HEDS-5540) | 5 В ±5% | 0,5 мм² | Конденсатор 0,1 мкФ на питании |
| Магнитный (AS5600) | 3,3–5 В | 0,5 мм² | Отдельная линия питания от Arduino |
Проверяйте стабильность питания осциллографом: пульсации напряжения не должны превышать 50 мВ при вращении энкодера. Если наблюдаются скачки, увеличьте емкость конденсаторов фильтрации или добавьте ферритовые кольца на провода питания. Для энкодеров, работающих в условиях сильных электромагнитных помех (например, рядом с двигателями), используйте гальваническую развязку (оптопары или изолированные DC-DC преобразователи).
Программирование Arduino: базовый код для считывания сигналов
Для работы с энкодером на Arduino используйте библиотеку Encoder от Paul Stoffregen. Установите её через менеджер библиотек IDE: Скетч → Подключить библиотеку → Управлять библиотеками, введите «Encoder» и выберите версию 1.4.2 или новее. Библиотека оптимизирована для обработки сигналов с разрешением до 400 импульсов на оборот и поддерживает прерывания на пинах 2 и 3 для Arduino Uno.
Минимальный рабочий код выглядит так:
#include <Encoder.h>
Encoder myEnc(2, 3); // Пины A и B
void setup() {
Serial.begin(9600);
}
void loop() {
long position = myEnc.read();
Serial.println(position);
delay(50); // Задержка для стабильности
}
Метод read() возвращает текущую позицию энкодера в виде знакового целого числа. При вращении по часовой стрелке значение увеличивается, против – уменьшается. Для сброса позиции используйте myEnc.write(0).
При работе с энкодерами высокого разрешения (1000+ импульсов/оборот) добавьте фильтрацию дребезга. В библиотеке это реализуется через параметр debounceDelay в конструкторе: Encoder myEnc(2, 3, 10), где 10 – задержка в миллисекундах. Для энкодеров с кнопкой используйте отдельный обработчик прерываний или опрос в loop() с антидребезгом через millis().
Оптимизируйте код для задач реального времени. Вместо delay() применяйте неблокирующие задержки:
unsigned long lastTime = 0;
const long interval = 50;
void loop() {
if (millis() - lastTime >= interval) {
lastTime = millis();
Serial.println(myEnc.read());
}
}
Это позволяет параллельно обрабатывать другие события, например, опрос датчиков или управление моторами.
Для точной калибровки энкодера проведите серию измерений: вращайте вал на 10 полных оборотов и сравните полученное значение с ожидаемым (например, 4000 импульсов для энкодера 400 имп/об). Рассчитайте коэффициент коррекции: k = ожидаемое_значение / фактическое_значение. Умножайте результат read() на k в коде. Храните коэффициент в EEPROM, если требуется сохранение между сеансами.
Обработка данных энкодера: фильтрация шумов и дребезга контактов

Энкодеры генерируют паразитные импульсы из-за механического дребезга контактов и электромагнитных помех. Стандартный энкодер с разрешением 20 импульсов на оборот может выдавать до 100 ложных срабатываний в секунду при вращении со скоростью 300 об/мин. Для подавления шумов используйте аппаратные RC-фильтры с постоянной времени τ = 1–5 мс: резистор 1–10 кОм и конденсатор 100 нФ–1 мкФ между сигнальными линиями и землей.
Программная фильтрация реализуется через:
- Метод временных задержек: игнорируйте повторные срабатывания в течение 5–20 мс после первого импульса. Пример кода для Arduino:
unsigned long lastDebounceTime = 0; const unsigned long debounceDelay = 10; void loop() { if (millis() - lastDebounceTime > debounceDelay) { // Обработка сигнала энкодера lastDebounceTime = millis(); } } - Скользящее среднее: усредняйте показания за 3–5 последних отсчетов. Для энкодера с разрешением 360 импульсов/оборот при скорости 60 об/мин окно усреднения в 5 отсчетов снижает ошибку на 70%.
Для энкодеров с квадратурным выходом (каналы A и B) используйте конечный автомат с проверкой последовательности состояний. Ложные переходы (например, 00→11 вместо 00→01→11) отбрасывайте. Пример логики:
- Запоминайте предыдущее состояние каналов (prevA, prevB).
- Сравнивайте текущее состояние (currA, currB) с предыдущим.
- Разрешайте изменение счетчика только при корректной последовательности: 00→01→11→10→00 для вращения по часовой стрелке.
Этот метод устраняет до 95% ложных срабатываний при скоростях до 1000 об/мин.
При работе с высокоскоростными энкодерами (>5000 об/мин) применяйте аппаратные триггеры Шмитта (например, микросхемы 74HC14) для формирования четких фронтов сигнала. Пороговые напряжения триггера Шмитта (0.8 В и 2.0 В для 5 В логики) исключают влияние помех амплитудой до 1.2 В. Для энкодеров с открытым коллектором подтягивающие резисторы 4.7–10 кОм к Vcc обязательны.
Тестируйте фильтрацию с помощью осциллографа: настройте триггер по фронту канала A и наблюдайте сигнал канала B. При правильной настройке на экране должны быть видны только четыре четких перехода за полный цикл вращения. Если количество переходов превышает 4, увеличьте постоянную времени RC-фильтра или задержку в коде. Для энкодеров с разрешением выше 1000 импульсов/оборот комбинируйте аппаратные и программные методы.
