Arduino UNO урок 6 - Энкодер
Категория
Ардуино начинающим
Энкодер- это устройство которое служит для преобразования угла поворота в электрический сигнал. Принцип работы его основан на образовании кратковременных импульсов при повороте ручки: чем больше угол поворота, тем больше таких импульсов.
В данном уроке мы рассмотрим как при помощи Ардуино можно реализовать функцию регулировок при помощи энкодера.
С энкодера мы получаем 2 сигнала (А и В), которые противоположны по фазе. В данном уроке мы будем использовать энкодер фирмы SparkFun COM-09117, который имеет 12 положений на один оборот (каждое положение 30°). На приведенной ниже диаграмме вы можете видеть, как зависят выход А и В друг от друга при вращении энкодера по часовой или против часовой стрелки.
Каждый раз, когда сигнал А переходит от положительного уровня к нулю, мы считываем значение выхода В. Если В в этот момент находится в положительном состоянии, значит энкодер вращается по часовой стрелке, если В нуль, то энкодер вращается против часовой стрелки. Считывая оба выхода, мы при помощи МК можем определить направление вращения, и при помощи подсчета импульсов с А выхода - угол поворота.
Конечно можно пойти еще дальше и при помощи вычисления частоты, можно определить насколько быстро происходит вращение энкодера. Как вы видите, энкодер имеет много преимуществ по сравнению с обычным потенциометром.
Используя энкодер мы будем управлять яркостью LED светодиода при помощи ШИМ выхода. Для считывания данных энкодера мы будем использовать простейший метод, основанный на программных таймерах, которые мы изучали в третьем уроке.
Как было сказано выше, мы будем использовать энкодер sparkfun. Первое, что необходимо сделать, это определить как часто нам нужно обращаться к выходам энкодера для считывания значений.
Итак, представим себе, что в лучшем случае, мы можем повернуть ручку энкодера на 180° за 1/10 сек, т.е. это будет 6 импульсов за 1/10 сек или 60 импульсов в секунду.
В реальности быстрее вращать не сможете. Т.к. нам необходимо отслеживать все полупериоды, то частота должна быть минимум 120 Герц. Для полной уверенности, давайте примем 200 Гц.
Примечание: т.к. у нас механический энкодер, то возможен дребезг контактов, а низкая частота позволяет отфильтровывать дребезг.
По сигналам программного таймера нам необходимо постоянно сравнивать текущее значение выхода А энкодера с предыдущим значением. Если состояние изменилось от положительного к нулю, то мы проверяем значение выхода В и смотрим положительное оно или нет. В зависимости от полученного результата мы увеличиваем или уменьшаем счетчик значения яркости светодиода.
Программа для данного урока приведена ниже. Она построена на базе предыдущего урока (Arduino UNO урок 5 - Fade-эффект (плавное затухание)), где использовалась функция 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 <= 255) brightness += fadeAmount; } else { // выход В в 0 сост., значит вращение против часовой стрелки // уменьшаем яркость, но не ниже 0 if(brightness - fadeAmount >= 0) brightness -= fadeAmount; } } encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла analogWrite(9, brightness); // устанавливаем яркость на 9 ножку loopTime = currentTime; } }
Источник: www.cxem.net