Главная » Arduino
Призовой фонд
на май 2017 г.
1. Тестер компонентов MG328
Паяльник
2. Осциллограф DSO138
Паяльник
3. Регулируемый паяльник 60 Вт
Паяльник
4. 100 руб.
От пользователей

Похожие статьи:


Arduino UNO урок 6 - Энкодер

Энкодер

В очередном уроке мы рассмотрим работу Arduino с энкодером (который служит для преобразования угла поворота в эл. сигнал). С энкодера мы получаем 2 сигнала (А и В), которые противоположны по фазе. В данном уроке мы будем использовать энкодер фирмы SparkFun COM-09117, который имеет 12 положений на один оборот (каждое положение 30°). На приведенной ниже диаграмме вы можете видеть, как зависят выход А и В друг от друга при вращении энкодера по часовой или против часовой стрелки.

Диаграмма энкодера

Каждый раз, когда сигнал А переходит от положительного уровня к нулю, мы считываем значение выхода В. Если В в этот момент находится в положительном состоянии, значит энкодер вращается по часовой стрелке, если В нуль, то энкодер вращается против часовой стрелки. Считывая оба выхода, мы при помощи МК можем определить направление вращения, и при помощи подсчета импульсов с А выхода - угол поворота. Конечно можно пойти еще дальше и при помощи вычисления частоты, можно определить насколько быстро происходит вращение энкодера. Как вы видите, энкодер имеет много преимуществ по сравнению с обычным потенциометром.

Используя энкодер мы будем управлять яркостью LED светодиода при помощи ШИМ выхода. Для считывания данных энкодера мы будем использовать простейший метод, основанный на программных таймерах, которые мы изучали в третьем уроке.

Как было сказано выше, мы будем использовать энкодер sparkfun. Первое, что необходимо сделать, это определить как часто нам нужно обращаться к выходам энкодера для считывания значений. Итак, представим себе, что в лучшем случае, мы можем повернуть ручку энкодера на 180° за 1/10 сек, т.е. это будет 6 импульсов за 1/10 сек или 60 импульсов в секунду. В реальности быстрее вращать не сможете. Т.к. нам необходимо отслеживать все полупериоды, то частота должна быть минимум 120 Герц. Для полной уверенности, давайте примем 200 Гц. (Примечание: т.к. у нас механический энкодер, то возможен дребезг контактов, а низкая частота позволяет отфильтровывать дребезг).

Схема подключения энкодера и LED

По сигналам программного таймера нам необходимо постоянно сравнивать текущее значение выхода А энкодера с предыдущим значением. Если состояние изменилось от положительного к нулю, то мы проверяем значение выхода В и смотрим положительное оно или нет. В зависимости от полученного результата мы увеличиваем или уменьшаем счетчик значения яркости светодиода.

Устройство на макетной плате

Программа для данного урока приведена ниже. Она построена на базе предыдущего урока 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);    	// считываем состояние выхода 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;
  }                       
}

Оригинал статьи

Теги:

Колтыков А.В. Опубликована: 2011 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (11) | Я собрал (0) | Подписаться

0
DIMA #
Автор! Огромное спасибо! Я искал эту схему.

Повторил код- Всё работает!
Ответить
0
Zak #
Я новичок в ардуине и в контроллерах вообще. Но все получилось
Ответить
0
elf #
Возможно применение энкодера в изготовлении руля для компьютера?
Ответить
0
Дмитрий #
Возможно, но придётся отслеживать руль на начальное положение
Ответить
0
Артем #
Добавить на руль 2 пружины, тянущие в разные стороны. Во-первых - будут возвращать руль в исходное положение. Во-вторых - подгружать его, чтобы вращение было более тугим и приближенным к реальности
Ответить
0
ELiF #
Как изменить скетч, чтобы при вращении энкодера на двух различных пинах соответственно направлению вращения возникали импульсы по 15мс?
Т.е. вращаем влево- на одном пине появляются импульсы. Вращаем вправо- теперь импульсы появляются на втором, назначенном нами пине.
Ответить
0
Иван #
Никак. Сам энкодер работает так (подает импульсы). Чем тебе не нравится этот код? Можно пин A привязать к прерыванию.
Ответить
0
Иван #
Код:
byte pinB = 7; // Пин B - куда угодно
byte pinLed = 9; // Светодиод
byte brightness = 0; // Яркость

void setup() {
attachInterrupt(0, encoder, FALLING); // Пин А на пин 2 ардуино (можно на 3). Это 0-е прерывание (3 - это первое прерывание, меняем 0 на 1). FALLING - когда значение переходит с HIGH на LOW.
}

void loop() {
// Какой-то код...
}

void encoder() { // Функция обработки прерывания
if(digitalRead(pinB)) {
if(brightness + fadeAmount = 0) brightness -= fadeAmount;
}
analogWrite(pinLed, brightness); // устанавливаем яркость на 9 ножку
}
Ответить
0
Димон #
Иван, код не совсем точный
...
void encoder() { // Функция обработки прерывания
if (digitalRead(pinB)) {
if (brightness + fadeAmount < 255) {brightness += fadeAmount;}
} else {
if (brightness - fadeAmount > 0) {brightness -= fadeAmount;}
}
analogWrite(pinLed, brightness); // устанавливаем яркость на пин 9
}
Ответить
0
Джо Индеец #
А почему вы не использовали встроенные подтягивающие резисторы?
Ответить
+1
Denis #
Не противоположны по фазе, а фазы сдвинуты на Pi/2
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Raspberry Pi 2
Raspberry Pi 2
Сатфайндер Набор для сборки - УНЧ 2х60 Вт на TDA7294
вверх