Логотип


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

 

Почта сайта