Модуль энкодер KY-040

25-02-2020, 17:01 1 комментариев
Модуль энкодер KY-040 является электромеханическим устройством, а точнее - датчиком угла поворота и вращения оси различных девайсов. Непосредственно сам прибор представляет собой небольшую плату со встроенной кнопкой и простым механическим валкодером (к слову, он относится к датчикам накапливающего типа). Его можно добавить фактически к любой отладочной (Arduino, ARM, PIC, AVR и др.) и макетной платам.

Основным преимуществом применения подобного устройства считаются некоторые его функциональные характеристики. Например, угол поворота валкодера не ограничен, поэтому выбрав его для работы, мы обеспечиваем себе комфортный интерфейс управления. Эта особенность часто применяется для реализации удобного и простого механизма контроля в различных проектах (разработке аудио аппаратуры, электроники, роботехнике либо в конструировании промышленной техники).

Остальные технические параметры датчика выглядят следующим образом:
  • рабочее напряжение питания: 3-15В.;
  • рабочий ток: 10 мА;
  • количество импульсов ∕ фиксированных позиций: 20;
  • диапазон температур: -30°C..+70°C;
  • ресурс (минимум): 15 тыс. оборотов;
  • длина вала: 12 мм.

Подключение KY-040 к Ардуино

Ну а теперь перейдем непосредственно к инструкции по установке и подключению модуля. Он имеет 3 вывода - SW, DT, CLK. Сигналы о вращении снимаются с двух последних выводов, а с первого - информация о нажатии кнопки. На плате предусмотрено место для установки подтягивающего резистора для кнопки.

Используем популярную плату расширения Arduino Uno:

Более сложная электрическая схема подключения (для которой понадобятся сам модуль, контроллер Уно, светодиодный индикатор, соединительные провода) изложена тут:

Важно! Используется библиотека Encoder (необходимо скачать в Интернете).

Для загрузки и проверки работоспособности заливаем программный скетч:
//Подключение библиотеки для энкодера
#include <Encoder.h>
 
//пины
const int CLK_PIN = 10;
const int DT_PIN = 9;
 
 
long position  = -999; //установка значения переменной для хранения текущей позиции 
 
//создание объекта типа Экнеодер
Encoder myEnc(DT_PIN, CLK_PIN);
 
void setup() {
  Serial.begin(9600); //инициализация Serial-порта
}
 
void loop() {
  long newPosition = myEnc.read(); //считать новую позицию
  if (newPosition != position) { //если значение отличается от старого
    position = newPosition; //установить новое текущее значение
    Serial.println(position); //вывести значение в Serial - порт
  }
  // Если в код добавить существенную задержку,
  // Энкодер сможет отследить только очень медленное движение.
  // Для проверки, можно раскомментировать нижнюю строчку:
 
  //delay(50);
}

Если нужно расширить опции (необходима обработка сигналов энкодера и вывод значений счетчика на дисплей), прописываем такие коды:
#include "LedControl.h"

/*
 * Подключаем библиотеку LedControl.h
 * и создаём объект класса LedControl
 * при этом, 7-ми сегметный дисплей с драйвером MAX72xx
 * должен быть подключен к плате Arduino следующим образом:
 * Arduino[Pin 5V] -> Display Module MAX72xx[VCC]
 * Arduino[PinGND] -> Display Module MAX72xx[GND]
 * Arduino[Pin 12] -> Display Module MAX72xx[DIN]
 * Arduino[Pin 11] -> Display Module MAX72xx[CLK]
 * Arduino[Pin 10] -> Display Module MAX72xx[LOAD/CS]
 * Arduino[Pin 4]  -> Encoder Module [CLK]
 * Arduino[Pin 3]  -> Encoder Module [DT]
 * Arduino[Pin 2]  -> Encoder Module [SW]
 */

LedControl lc = LedControl(12, 11, 10, 1);

//Проименовываем адреса портов на плате Arduino
const int Dir    = 4; 
const int Step   = 3;
const int Switch = 2;

//Counter - переменная для хранения значения счетчика
static long Counter = 0;

//SW_State - флаг триггер отслеживания нажатия центральной оси 
static bool SW_State = false;

//Временные переменные для хранения уровней сигналов энкодера
unsigned char encoder_A, encoder_B, encoder_A_prev;

void setup() 
{
  //Устройство(7-ми сегментный дисплей) выводим из спящего режима
  lc.shutdown(0, false);
  //Установить яркость дисплея на 8
  //Всего возможных режимов яркости от 0 до 15
  lc.setIntensity(0,8);
  //Очистить дисплей
  lc.clearDisplay(0);
  //Конфигурируем порты для энкодера
  pinMode(Dir,    INPUT);
  pinMode(Step,   INPUT);
  pinMode(Switch, INPUT);
}

void loop() 
{
  //Считываем значения выходов энкодера
  //И сохраняем их в переменных
  encoder_A = digitalRead(Step);
  encoder_B = digitalRead(Dir);

  //Если уровень сигнала А низкий,
  //и в предидущем цикле он был высокий
  if(!encoder_A && encoder_A_prev)
  {
    //Если уровень сигнала В высокий
    if(encoder_B)
    {
      //Значит вращение происходит по часовой стрелке
      //Наше условие:
      //Если значение счетчика больше или равно максимальному числу
      if(Counter >= 99999999)
      {
        //Обнулить значение счетчика
        Counter = 0;
      }
      else
      {
        //Иначе инкрементировать при каждом щелчке на единицу
        Counter ++;
      }
    }
    //Если уровень сигнала В низкий
    else
    {
      //Значит вращение происходит против часовой стрелки
      //Если значение счетчика меньше или равно нулю
      if(Counter <= 0)
      {
        //проинициализировать значение максимальным числом
        Counter = 99999999;
      }
      else
      {
        //Иначе декрементировать при каждом щелчке на единицу
        Counter --;
      }
    }
  }
  //Обязательно нужно сохранить состояние текущего уровня сигнала А
  //для использования этого значения в следующем цикле сканирования программы
  encoder_A_prev = encoder_A;

  //Работаем с центральной осью энкодера - кнопкой
  //Этот кусок кода образует собой как бы перекидной триггер
  //Считываем значение пина 2 на плате Arduino
  //которомый проименован как Switch
  //Если центральная ось нажата - то сигнал Switch будет иметь низкий уровень
  if(!digitalRead(Switch))
  {
    //Если переменная SW_State установлена в false то установить её в true 
    if(!SW_State)
    {
      //И запомнить состояние
      SW_State = true;
    }
    //И наоборот - если переменная SW_State установлена в true, 
    //то сбросить её в false 
    else
    {
      //И запомнить состояние
      SW_State = false;
    }
  }

  //Часть программы которая заполняет разряды 
  //семисегментного дисплея значением счетчика
  long intCounter = Counter;
  int  divCounter;
  
  for(int i = 0; i < 8; i ++)
  {
    divCounter = intCounter % 10;
    intCounter = intCounter / 10;
        
    if(intCounter == 0 && SW_State)
    {
      if(divCounter == 0)
      {
        if(i == 0)
        {
          lc.setChar(0, 0, '0', false);
        }
        else
        {
          lc.setChar(0, i, ' ', false);
        }
      }
      else
      {
        lc.setDigit(0, i, divCounter, false);
      }
    }
    else
    {
      lc.setDigit(0, i, divCounter, false);
    }
  }
}
Надеемся, энкодер вам пригодится в проектировании и порадует практичностью в применении. Удачи!
Поделись в социальных сетях:
О авторе
Калугин Антон

Программист микроконтроллеров с 8-ми летним стажем, работал в таких компаниях как IBM, ASUS, Microsoft.

В комментариях с радостью отвечу на ваши вопросы.

Все статьи автора
Похожие новости

Сегодня поговорим о том, как воплотить в жизнь подключение FPM10A к Arduino, что это за модуль, где используется, каковы параметры его работы и т.д. Речь идет...

В этой статье мы хотим продолжить тему подключения шаговых двигателей к Ардуино – на очереди рассказ о ШД Nema 17. Почему именно он? Эта модель считается...

Подключение Bluetooth модуля ZS-040 к Ардуино...

Тема нашей сегодняшней статьи – подключение датчика сердечного ритма AD8232 к Ардуино. Про целесообразность и практичность подобного устройства много говорить...

Подключение джойстика к Arduino позволит просто и эффективно обмениваться информацией между человеком и электронными устройствами (компьютером, ноутбуком, тем...

1 комментария
  1. tivtom
    8 января 2022 21:22 tivtom

    Ошибка на ошибке и ошибкой погоняет....

    replyОтветить
Оставить комментарий