Продолжаем изучать 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; }