Подключение энкодера KY-040 к Arduino
Модуль энкодера KY-040 — это тип датчика, который преобразует угловое вращение ручки в цифровой сигнал.
Модуль энкодера KY-040 — это тип датчика, который преобразует угловое вращение ручки в цифровой сигнал. Благодаря своей надежности и точному управлению, энкодер используются во многих устройствах, таких как в робототехнике, станках с ЧПУ и принтерах.
Технические параметры
► Тип: механический, инкрементальный;
► Наличие кнопки: да;
► Поворот на: 360° в обе стороны;
► Напряжение питания: 4,5 – 5,5 В;
► Габариты: 26,2 х 18,7 х 29 мм;
► Вес: 7 г.
Обзор энкодера KY-040
Каждый энкодер имеет фиксированное количество циклов переключений на оборот, у KY-040 это число 30. Давайте рассмотрим принцип работы, внутри энкодера находится медный диск с отверстиями соединенный с общей землей, назовем этот вывод «С» (чем больше отверстия тем, точнее энкодер). Так же, есть два вывода, назовем их «А» и «B«, с которых мы снимает сигнал, так-же эти выводы подтянуты к 5 В с помощью резисторов на 10 кОм. Если контакты «А» и «В» не касаются вывода диска «С» на их выходе будет 5 В. Когда мы начнем вращать энкодер по часовой стрелке, вывод «А» коснется диска и на выходе получим «0 В», если продолжить вращать энкодер вывод «B» так же коснется диска и на выходе будет «0 В».
То есть, когда вы поворачиваете ручку по часовой стрелке, сначала подключается вывод А, а затем вывод В. Когда вы поворачиваете ручку против часовой стрелки, сначала подключается вывод B, а затем штифт A. Отслеживая, когда каждый вывод соединяется с землей и отсоединяется от нее, можно понять в каком направлении вращается ручка.
Назначение контактов:
► GND — заземляющее соединение;
► VCC (+) — напряжение питания;
► SW — вывод кнопки, когда кнопка нажата, напряжение «0 В»$
► DT (Выход B) — выход DT;
► CLK (выход А) — выход CLK.
Подключение модуля энкодера KY-040 к Arduino
Необходимые детали:
► Arduino UNO x 1 шт.
► Модуль энкодера, KY-040 x 1 шт.
► Провода DuPont M-F, 20 см x 1 шт.
Подключение:
Подключение энкодера KY-040 к Arduino не сложное. Подключим сначала вывод +V к 5V на Arduino и вывод GND к GND. Теперь соединим CLK, DT, SW с цифровыми контактами 2, 3 и 4 к Arduino. Для удобства приведу схему подключения.
Программа:
Теперь запускаем среду разработку Arduino IDE и загружаем скетч в контроллер. Программа определяет, в каком направление вращается энкодер и нажимается ли кнопка.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#define CLK 2 // Указываем к какому выводу CLK энкодер подключен к Arduino #define DT 3 // Указываем к какому выводу DT энкодер подключен к Arduino #define SW 4 // Указываем к какому выводу SW энкодер подключен к Arduino int counter = 0; // Создаем переменную counter int currentStateCLK; // Создаем переменную currentStateCLK int lastStateCLK; // Создаем переменную lastStateCLK String currentDir =""; // Создаем unsigned long lastButtonPress = 0; // Создаем переменную lastBut void setup() { pinMode(CLK, INPUT); // Указываем вывод CLK как вход pinMode(DT, INPUT); // Указываем вывод DT как вход pinMode(SW, INPUT_PULLUP); // Указываем вывод SW как вход и включаем подтягивающий резистор Serial.begin(9600); // Создаем последовательную связь lastStateCLK = digitalRead(CLK); // Считываем значение с CLK } void loop() { currentStateCLK = digitalRead(CLK); // Считываем значение с CLK // Проверяем изменилось ли состояние CLK if (currentStateCLK != lastStateCLK && currentStateCLK == 1){ if (digitalRead(DT) != currentStateCLK) { counter --; currentDir ="CCW"; } else { counter ++; currentDir ="CW"; } Serial.print("Direction: "); Serial.print(currentDir); Serial.print(" | Counter: "); Serial.println(counter); } lastStateCLK = currentStateCLK; // Запопоследнее состояние CLK int btnState = digitalRead(SW); // Считываем состояние вывода SW if (btnState == LOW){ // Если состояние LOW, кнопка нажата if (millis() - lastButtonPress > 50){ // Если состояние LOW в течении 50 мкс, кнопка нажата Serial.println("Button pressed!"); // ОТправка сообщения } lastButtonPress = millis(); } delay(1); // Пауза } |
Если все правильно собрали, в последовательно порте можно увидеть показания с энкодера.
Описание программа:
Скетч начинается с указания выводов Arduino, к которым подключены контакты CLK, DT и SW энкодера.
1 2 3 |
#define CLK 2 #define DT 3 #define SW 4 |
Далее создаем переменные в «counter» будем сохранять данные о количестве поворотов ручки энкодера (щелчок). В переменных «currentStateCLK» и «lastStateCLK» будем хранить состояние выходного сигнала CLK.
1 2 3 4 5 |
int counter = 0; int currentStateCLK; int lastStateCLK; String currentDir =""; unsigned long lastButtonPress = 0; |
Теперь в «setup()» сначала указываем выводы CLK, DT, SW как вход, а затем включаем внутренний подтягивающий резистор на выводе SW. Та кже включаем последовательную связь на скорости 9600 и в конце считываем текущее значение вывода CLK и сохраняем его в «lastStateCLK
«.
1 2 3 4 5 |
pinMode(CLK,INPUT); pinMode(DT,INPUT); pinMode(SW, INPUT_PULLUP); Serial.begin(9600); lastStateCLK = digitalRead(CLK); |
В «loop()» снова проверяем состояние CLK и сравниваем его «сlastStateCLK«. Если значение разные, то это означает, что ручка повернулась. Также проверяем, является ли значение «currentStateCLK«, чтобы избежать двойного счета.
1 2 |
currentStateCLK = digitalRead(CLK); if (currentStateCLK != lastStateCLK && currentStateCLK == 1){ |
Внутри оператора if определяем направление вращения, для этого мы просто считываем вывод DT и сравниваем его с текущим состоянием вывода CLK. Если они разные, это означает, что ручка вращается против часовой стрелки. Затем мы уменьшаем счетчик «counter—» и устанавливаем «currentDir =»CCW»«. Если значения одинаковы, это означает, что ручка вращается по часовой стрелке. Затем мы увеличиваем счетчик «counter++» и устанавливаем «currentDir =»CW»«.
1 2 3 4 5 6 7 |
if (digitalRead(DT) != currentStateCLK) { counter --; currentDir ="CCW"; } else { counter ++; currentDir ="CW"; } |
Затем мы отправляем результаты на последовательный монитор.
1 2 3 4 |
Serial.print("Direction: "); Serial.print(currentDir); Serial.print(" | Counter: "); Serial.println(counter); |
Вне оператора if мы обновляем «lastStateCLK»
1 |
lastStateCLK = currentStateCLK; |
Далее идет процедура считывания кнопки, сначала считываем текущее состояние кнопки, если оно «LOW«, ждем 50 мс (защита от дребезга). Если кнопка остается «LOW» более 50 мс, мы печатаем сообщение “Button pressed!” на последовательном мониторе.
1 2 3 4 5 6 7 8 |
int btnState = digitalRead(SW); if (btnState == LOW) { if (millis() - lastButtonPress > 50) { Serial.println("Button pressed!"); } lastButtonPress = millis(); } |
Купить на Aliexpress
Контроллер Arduino UNO R3 на CH340G
Контроллер Arduino UNO R3 на Atmega16U2
Комплект проводов DuPont, 2,54 мм, 20 см
Модуль энкодера, KY-040
Купить в Самаре и области
Контроллер Arduino UNO R3 на CH340G
Контроллер Arduino UNO R3 на Atmega16U2
Провода DuPont, 2,54 мм, 20 см
Модуль энкодера, KY-040
А с какой целью на SW надо подключать внутренний подтягивающий резистор? (строка 15)
Резистора на энкодере мало?
Здравствуйте, да можно строку удалить.