Подключение энкодера KY-040 к Arduino
Энкодер с кнопкой
KY-040 к Arduino Uno и Nano: CLK и DT на D2 и D3 — выводы с аппаратными внешними прерываниями, SW — на любой цифровой, питание 5 В.
Схема подключения энкодера KY-040 к Arduino
| KY-040 | Arduino Uno |
|---|---|
| CLK | D2 |
| DT | D3 |
| SW | D4 |
| VCC | 5V |
| GND | GND |
Схема из примера «Arduino Uno: энкодер — яркость ручкой».
Выводы KY-040
| Вывод | Назначение |
|---|---|
| CLK | выход A |
| DT | выход B — по нему определяют направление |
| SW | кнопка на валу, замыкает на GND |
| VCC | питание (для подтягивающих резисторов модуля) |
| GND | общий провод |
Код для Arduino
// Энкодер KY-040: яркость светодиода ручкой.
//
// Внутри энкодера два контакта, замыкающихся со сдвигом на четверть
// оборота щелчка. По часовой стрелке первым опускается CLK, потом DT;
// против — наоборот. Поэтому достаточно поймать спад CLK и посмотреть
// на DT: единица — ручку крутят по часовой, ноль — против.
//
// Спад ловит прерывание: у Uno их два, на выводах 2 и 3, и CLK сидит на
// втором. Опрос в loop() тоже работает, но пропускает щелчки, пока
// скетч занят чем-то долгим (печатью в порт, например).
//
// На схеме: возьмите ручку мышью и тяните по кругу — по часовой или
// против; кнопки ↺ ↻ под ручкой — по щелчку (держите — повторяются);
// колесо мыши над ручкой — тоже поворот; середина ручки — кнопка.
const int CLK = 2, DT = 3, SW = 4;
const int LED = 9; // вывод с ШИМ
volatile int clicks = 0; // меняется в прерывании
void onClk() {
if (digitalRead(DT)) clicks++; else clicks--;
}
void setup() {
Serial.begin(9600);
pinMode(CLK, INPUT); // подтяжка на CLK и DT есть на модуле
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP); // а на кнопке — нет
pinMode(LED, OUTPUT);
attachInterrupt(digitalPinToInterrupt(CLK), onClk, FALLING);
Serial.println("крутите ручку, нажмите — погасить");
}
int level = 0; // 0…16 ступеней по 16
void loop() {
// Щелчки забираются под запретом прерываний: int у AVR — два байта,
// и прерывание посреди чтения дало бы половину старого значения.
noInterrupts();
int n = clicks;
clicks = 0;
interrupts();
if (n) {
level = constrain(level + n, 0, 16);
Serial.print("яркость: ");
Serial.println(level * 16);
}
if (digitalRead(SW) == LOW && level) {
level = 0;
Serial.println("погашено");
}
analogWrite(LED, min(level * 16, 255));
delay(10);
}
Скетч можно править и запускать в симуляторе без платы и установки среды.
Что учесть на Arduino
- D2 и D3 — единственные выводы Uno и Nano с аппаратным внешним прерыванием (INT0 и INT1), остальные работают через PCINT.
- Дребезг контактов подавляют таблицей состояний или конденсатором 10 нФ на каждом выводе.
В железе
На модуле стоят подтягивающие резисторы 10 кОм на CLK и DT, а на SW — не у всех: для кнопки включайте
INPUT_PULLUP.Частые ошибки при подключении к Arduino
- Вызвать
attachInterrupt()для вывода, кроме 2 и 3, на Uno: прерывание не заработает. - Не подавить дребезг: счётчик прыгает на несколько шагов за один щелчок.
- Опрос в
loopсdelay()— пока скетч ждёт, щелчки пропадают. - Каждый щелчок считается дважды или через раз — контакты дребезжат. Помогает конденсатор 10–100 нФ на землю или программный фильтр по времени.
- Кнопка SW без подтяжки — в отпущенном состоянии вход висит и «нажимается» сам.
- Направление перепутано — поменяйте местами CLK и DT в коде, а не провода.
Ещё по теме
Другие детали для Arduino
HC-SR04DHT22 (AM2302)BME280DS3231SSD1306 OLED 0,96″LCD 1602 с I2CMAX7219TM1637Модуль релеКлавиатура 4×4HX711ФоторезисторМодуль microSDRGB-светодиодСервопривод SG9074HC595Шаговый двигательКнопкаПотенциометрПьезопищалкаСветодиодПолзунковый переключательHC-SR501TTP223Датчик влажности почвыMQ-2LM35Джойстик KY-023DHT11HTU21D