Подключение энкодера KY-040 в MBED

Продолжаем изучать MBED OS. Подключим энкодер к отладочной плате Nucleo F410RB. Энкодер KY-040 часто используется в проектах на Arduino, он используется в составе многих устройств в качестве интерфейса управления. С его помощью можно регулировать какие — либо параметры поворотом ручки в ту или иную сторону. При этом энкодер не ограничен количеством оборотов ручки, она может вращаться бесконечно в ту или иную сторону. Это обеспечивает как плавную так и быструю регулировку нужного параметра. Так же в этом энкодере присутствует кнопка, которая срабатывает при нажатии на вал энкодера. 

Данный энкодер механический инкрементный. На своём борту имеет пять выводов.

  • GND
  • +
  • SW
  • DT
  • CLK

Харакеристики KY-040

  • Предельное напряжение на контактах 5В 
  • Предельный ток через контакты 10 мА 
  • Формат выходного сигнала: квадратурный код 2 бит 
  • На один оборот 24 импульса 
  • Температура 
                 эксплуатации -30…70 °C 
                 хранения -40…85 °C 
  • Ресурс оборотов не менее 30 000 
  • Ресурс нажатий кнопки не менее 20 000 

Принцип работы

Основные контакты DT и CLK. В исходном положении на обоих этих контактах положительный сигнал. При вращении энкодера контакты по очереди замыкаются на землю. По тому, какой из контактов замыкается первым, можно определить в какую сторону вращается энкодер. По количеству импульсов можно определить количество щелчков(угол поворота). Для уменьшения шумов я добавил два конденсатора по 1000пФ. Один между GND и DT, второй между GND и CLK

 

Программа

#include "mbed.h"
#include "Encoder.h"

DigitalOut Plus(D4); // пины D3 и D4 будем использовать для питания энкодера
DigitalOut GND(D3);
int main()
{

    Plus = 1;
    GND = 0;
    
    EncoderAli Enc(D6, D7, D5); //DT, CLK, SW
    Enc.setRange(100,200);
    while(1)
    {
        printf("\n\r Положение: %d; состояние кнопки %d",Enc.getState(), Enc.getButtonState());
        wait(0.25);
    }
}
/*
* Автор - Железняков Андрей
* Сайт - itworkclub.ru
* Данный класс описывает энкодер с кнопкой KY-040
* Обработка вращения и нажатий происходит с помощью прерываний.
* При вращении энкодера меняется состояние переменной State
* в ту или иную сторону. Значения переменной State ограничены заданным
* диапазоном, например, от 0 до 100 или 0т 300 до 500. Диапазон задается
* функцией setRange. По умолчанию диапазон от 0 до 100.
* Узнать текущее значение энкодера можно с помощью функции getState();
* Нажата ли кнопка с помощью функции getButtonState();
* К энкодеру припаяны два дополнительных конденсатора по 1000пФ для устранения
* дребезга: один между GND и CLK, второй между GND и DT. Если этих конденсаторов
* нет, то необходимо раскомментировать задержку в функции encode. Так же 
* необохдимо проверить запаян ли подтягивающий резистор 10кОм на кнопку SW
* Его необходимо припаять.
*/

#ifndef Encoder_H
#define Encoder_H


#include "mbed.h"

class EncoderAli
{
    public:
        // В конструкторе задаем пины, к которым подключен энкодер   
        EncoderAli(PinName DT,PinName CLK1,PinName SW);
        
        int getState(); // возвращает положение энкодера 
        void setRange(int minValue,int maxValue);// задает диапазон 
        bool getButtonState();// true - кнопка нажата, false - отжата
    private:
        
        int State; // положение энкодера
        bool work; // флаг, который поднимается, когда идет обработка прерывания
                   // и опускается по заверщении прерывания.  
        int minValue_; // минимальное значение энкодера
        int maxValue_; // максимальное значение энкодера
        bool button;   //true - кнопка нажата, false - отжата
        
        DigitalIn DT_;
        InterruptIn CLK1_;
        InterruptIn SW_;
        
        void encode(void); //обработчик вызывается при повороте энкодера
        void buttonPress(void); //обработчик вызывается при нажатии кнопки
        void buttonUp(void); // обработчик вызывается при отпускании кнопки
            
};

#endif
/*
* Автор - Железняков Андрей
* Сайт - itworkclub.ru
* Данный класс описывает энкодер с кнопкой KY-040
* Обработка вращения и нажатий происходит с помощью прерываний.
* При вращении энкодера меняется состояние переменной State
* в ту или иную сторону. Значения переменной State ограничены заданным
* диапазоном, например, от 0 до 100 или 0т 300 до 500. Диапазон задается
* функцией setRange. По умолчанию диапазон от 0 до 100.
* Узнать текущее значение энкодера можно с помощью функции getState();
* Нажата ли кнопка с помощью функции getButtonState();
* К энкодеру припаяны два дополнительных конденсатора по 1000пФ для устранения
* дребезга: один между GND и CLK, второй между GND и DT. Если этих конденсаторов
* нет, то необходимо раскомментировать задержку в функции encode. Так же 
* необохдимо проверить запаян ли подтягивающий резистор 10кОм на кнопку SW
* Его необходимо припаять.
*/
#include "Encoder.h"

EncoderAli::EncoderAli(PinName DT,PinName CLK,PinName SW): DT_(DT), CLK1_(CLK), SW_(SW){
    
    // инициализация начального состояния энкодера
    work = false;
    minValue_ =0;
    maxValue_ = 100;
    button = false;
    State = minValue_;
    
    // подключение прерываний для вращения, нажатия и отжатия
    CLK1_.rise(callback(this,&EncoderAli::encode));
    SW_.fall(callback(this,&EncoderAli::buttonPress));
    SW_.rise(callback(this,&EncoderAli::buttonUp));
    
}


void EncoderAli::encode(void) // обработчик вращения
{
    if (work) return; // если идет обработка предыдущего прерывания то ничего 
                      // не делаем
    work = true;      // поднимаем флаг работы прерывания, тем самым запрещая
                      // выполнения других таких же прерываний
    int A = DT_;      // считываем значение пина DT
    //wait_us(100);
    if(A==0 && State < maxValue_) //если DT 0, то энкодер крутится вправо 
        State++;// увеличиваем значение состояния энкодера
    if (A==1 && State > minValue_) //если DT = 1, то энкодер крутится влево
        State--; // уменьшаем значение энкодера
    work = false; // освобождаем флаг работы прерывания
    

}
int EncoderAli::getState()
{
    return State; 
}
void EncoderAli::setRange(int minValue,int maxValue)
{
    minValue_=minValue;
    maxValue_=maxValue;
    State = minValue_;
}
void EncoderAli::buttonPress(void)
{
    button = true;
}
void EncoderAli::buttonUp(void)
{
    button = false;
}
bool EncoderAli::getButtonState()
{
    return button;   
}

Добавить комментарий

Закрыть меню