Как работать с инкрементальным энкодером


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Алексей: Цифровой термометр с уличным датчиком на bluetooth модулях
Не. Там было мног...

Руслан: AVR против STM32
А будет у вас про...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


   
				

Как работать с инкрементальным энкодером

	
	
	

Дата: 3 Сентября 2014. Автор: Алексей

	
	
Попросили меня тут помочь с энкодером. Ну раз просят, так значит надо помочь. Достал из запасов деталюху, повертел, подключил. Далее за малым, программа. Подключил осцил к ножкам энкодера, записал уровни. По уровням накидал табличку, а по ней программу. Теперь думаю надо все это собрать в кучу и описать как все работает, а после все это дело выложить на форуме. В итоге посмотрев на все это я решил выложить здесь в виде статьи. Раз уж у одного возникли вопросы, то я думаю пусть и другие посмотрят.

Инкрементальный энкодер - это цифровое устройство, которое может определить угол поворота вращающегося вала, выдавая цифровой код.

Энкодер

Как выводится цифровой код. Как видно из картинки выше у энкодера есть три вывода. Для того чтобы получить код при вращении требуется по хитрому подключить эти три ножки. Центральная ножка общая и подключается к нулю, а крайние две ножки нужно подтянуть к плюсу питания через резистор, 1 кОм будет вполне достаточно. Теперь если замерить уровни на крайних ножках то на них будут две единицы(плюс питпния). Если немного повернуть ручку, то можно заметить что на одной ножке пропадет единица. если дальше вращать, то пропадет вторая единица, а если еще повернуть то появится единица на предыдущей ножке. Чтобы было более понятно смотрим на картинку осциллограммы.

Осциллограмма работы энкодера

Такая картинка получилась когда я резко крутанул энкодер по часовой стрелке. Теперь давайте разберем тот самый цифровой код. Так как у нас выходных ножек две, значит и цифровой код будет двух-битным. Отсюда видно что значения энкодер может принимать 00, 01, 10, 11. Ну или по нашему 0, 1, 2 и 3. Глядя на осциллограмму давайте примем за нулевой разряд синий канал, а за первый желтый канал. Теперь давайте построим последовательность сигналов. Идем слева на право. Синий ноль, а желтый единица. Так и запишем 10. Дольше, синий единица и желтый тоже единица. Значит 11. Теперь желтый стал ноль, а синий все еще единица. Значит 01. Дальше желтый в нуле и синий упал в ноль. Значит 00. Смотрим дальше, синий в нуле, а желтый единица. Ага... Такое уже было. Значит мы пошли по второму кругу. Собираем все в кучу по очереди. 10, 11, 01, 00. Или по русски 2, 3, 1, 0. Вот теперь стало ясно что за код нам выдает энкодер. А что будет если энкодер провернуть против часовой стрелке? А ничего нового, та же последовательность кодов но в другую сторону. Теперь зная какие коды нам шлет энкодер мы можем определить направление вращения. Как это сделать. Для этого нам нужно создать три переменные:
input - переменная в которой будет хранится текущее значение энкодера.
buf - переменная хранящая предыдущее значение энкодера.
data - переменная которую нужно увеличить при вращении по часовой стрелке и уменьшить при вращении против часовой стрелке.

Смотрите, нам нужно взять текущее значение от энкодера, сравнить с записаным ранее значением и если оно разное значит энкодер повернули. Далее нам нужно узнать куда именно его повернули. Для этого смотрим предыдущее значение энкодера. Например оно равно 00, далее смотрим текущее значение которое возможно либо 1, либо 2.
Помните последовательность 2, 3, 1, 0. То есть это соседи с нулем. Из этого значения мы можем смело узнать куда повернули энкодер, если 1, то против часовой стрелке, если 2, то по часовой. Так как для контроллера направление так сказать пофигистическое значение, то нам надо как-то его задать правильно. Ну например при повороте по часовой будем увеличивать на 1 значение переменной, а против часовой уменьшать на 1. Для этих целей и создана переменная data. Теперь как все это будет выглядеть в коде.


		input = PINC & 0x03; 

		if(buf != input) 
		{
			 switch(buf) 
			 {
				 case 0:
				 {
					 if(input == 2) data++;
					 if(input == 1) data--;
					 break;
				 }
				 case 1:
				 {
					 if(input == 0) data++;
					 if(input == 3) data--;
					 break;
				 }
				 case 2:
				 {
					 if(input == 3) data++;
					 if(input == 0) data--;
					 break;
				 }
				 case 3:
				 {
					 if(input == 1) data++;
					 if(input == 2) data--;
					 break;
				 }
			}
			
			buf = input;
		} 

Теперь разберем этот код. Первое что мы сделали это занесли в переменную input текущее значение энкодера. Далее сравниваем с переменной buf(предыдущее значение энкодера). Если значения этих переменных равны, то ничего не делаем, а лишь идем снова смотреть значение энкодера. Так крутимся до тех пор пока значения текущие не станут различны с предыдущими. То есть если текущее значение изменилось и не совпало со старым, то переходим в тело if и определяем направление вращения. Для этого, как я уже раньше говорил, нам нужно посмотреть на текущее значение относительно предыдущего. Например если предыдущее значение было 0, то мы смотрим на текущее значение и если оно равно 2, то увеличиваем data, а если 1, то уменьшаем data. Тоже самое делаем с 1, 2 и 3 лишь проверяем их соседей. Далее снова сохраняем в переменную buf значение input и топаем читать текущее значение энкодера(вдруг его повернули) Вот и вся премудрость в работе с энкодером. Ниже я записал видео-ролик в котором вывожу на светодиоды значение переменной data. Очень наглядно видно как переменная увеличивается или уменьшается в зависимости от направления вращения. На вопрос что делать с переменной data дальше. Да хотя бы заносить ее значение в регистр OCRn и менять яркость светодиода, скорость вращения мотора, да чего угодно.
Так же выкладываю проект в AtmelStudio 6.2
JW Player goes here






Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  








Вверх


Рейтинг@Mail.ru Яндекс.Метрика