Рассмотрим как создать энкодер на Arduino. Предназначение- преобразовывать угол поворота в эл. сигнал. С энкодера получаем 2 сигнала ( А и В ). Они противоположны по фазе. Возьмем энкодер SparkFun COM-09117. У него 12 положений на оборот. Каждое положение - тридцать градусов. Диаграмма ниже показывает зависимость выходов А и В друг от друга при вращении энкодера влево или вправо.
Понятно, что при переходе сигнала от положительного к нулю, мы считываем значение В. Если В в положительном состоянии, следовательно энкодер вращается вправо. Если В в нуле - то энкодер вращается влево. Считывая оба выхода, мы при помощи МК можем определить направление вращения, и при помощи подсчета импульсов с А выхода - угол поворота.
Как мы уговорились, будем управлять яркостью светодиода используя ШИМ-выход. Для считывания данных будем использовать этот метод на программных таймерах, который рассматривали ранее. Определимся, как часто будем обращаться к выходам нашего энкодера для считывания значений. Пример: мы можем повернуть ручку энкодера на 180° за 1/10 сек, т.е. это будет 6 импульсов за 1/10 сек или 60 импульсов в секунду. В реальности быстрее вращать не сможете. Т.к. нам необходимо отслеживать все полупериоды, то частота должна быть минимум 120 Герц. Мы примем 200 Гц.
Схема энкодера Arduino
По сигналам программного таймера нам необходимо постоянно сравнивать текущее значение выхода А энкодера с предыдущим значением. Если состояние изменилось от положительного к нулю, то мы проверяем значение выхода В и смотрим положительное оно или нет. В зависимости от полученного результата мы увеличиваем или уменьшаем счетчик значения яркости светодиода.
Программа приведена ниже, используется функция millis() для задания временных интервалов. Временной интервал : 5 мс (200 Гц).
/* ** Энкодер ** Для управлением яркостью LED используется энкодер Sparkfun */ int brightness = 120; // яркость LED, начинаем с половины int fadeAmount = 10; // шаг изменения яркости LED unsigned long currentTime; unsigned long loopTime; const int pin_A = 12; // pin 12 const int pin_B = 11; // pin 11 unsigned char encoder_A; unsigned char encoder_B; unsigned char encoder_A_prev=0; void setup() { // declare pin 9 to be an output: pinMode(9, OUTPUT); // устанавливаем pin 9 как выход pinMode(pin_A, INPUT); pinMode(pin_B, INPUT); currentTime = millis(); loopTime = currentTime; } void loop() { currentTime = millis(); if(currentTime >= (loopTime + 5)){ // проверяем каждые 5мс (200 Гц) encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера encoder_B = digitalRead(pin_B); // считываем состояние выхода А энкодера if((!encoder_A) && (encoder_A_prev)){ // если состояние изменилось с положительного к нулю if(encoder_B) { // выход В в полож. сост., значит вращение по часовой стрелке // увеличиваем яркость, не более чем до 255 if(brightness + fadeAmount = 0) brightness -= fadeAmount; } } encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла analogWrite(9, brightness); // устанавливаем яркость на 9 ножку loopTime = currentTime; } } |