Gtlab Forum
Тематический => Негитарная электроника => Тема начата: AlKoR от Января 21, 2008, 04:27:57 pm
-
Написал в С++ функцию обработки энкодера, но иногда срабатывает в нету сторону. Энкодер имеет оду особенность, он фиксируется только когда контакт1 и контакт2 разомкнуты, а если повернуть ручку, он будет выдавать такой код:
00 - изначально разомкнуты,
01 - если влево
10 - если влево
или наоборот
00 - изначально разомкнуты,
10 - если вправо
01 - если вправо
фрагмент кода:
{ // функция обрабатывает энкодер, подключенный к линиям порда Д 0 и 1
int val1=0;
int val2=0; //флаги срабатывания контакта энкодера
int d;
if (PIND.0 ==1 && PIND.1 == 0) val1=1;
if (PIND.0 ==0 && PIND.1 == 1) val2=1;
d=0; //флаг выхода из цикла
if(val1==1 ) //если пришел сигнал с первого контакта
{while (d==0) //пока не пришел сигнал с друого контакта, ждать его
{if (PIND.0 ==0 && PIND.1 == 1 && val1 == 1 ) {val2=0; d++;}
if (PIND.0 ==1 && PIND.1 == 0 && val2 == 1 ) {val1=0; d++;}
}
}
if(val2==1 )//если пришел сигнал с второго контакта
{while (d==0)//пока не пришел сигнал с друого контакта, ждать его
{
if (PIND.0 ==0 && PIND.1 == 1 && val1 == 1 ) {val2=0; d++;}
if (PIND.0 ==1 && PIND.1 == 0 && val2 == 1 ) {val1=0; d++;}
}
}
if (val1==1) {return 1;} //если сработало по первому контакту, вернуть 1
if (val2==1) {return 2;}//если сработало по второму контакту, вернуть 2
if (val1==0 && val2==0) return 0; //если небыло сигнала, вернуть 0
val1=0; val2=0; обнуление флагов
}
Вроде, работоспособность такого решения большая, но ошибается... Правда, только один раз. Может быть, функция вызывается тогда, когда валкодер вращается? Помогите...
-
не много не верно. надо отслеживать не код, а фазу следования импульсов. тогда никаких проскакиваний не будет.
энкодеры этого типа при вращении выдают импульсы а не код. при вращении фронт одного приходт с опережением.
-
Для этого уже нужно работать с прерываниями МК, как я понимаю?
Но проблему решил - в начале поставил две строчки -
...
if (PINC.4==0) exit++;
if (PINC.5==0) exit++;
Стал работать как положено (доволен как слон).
Если не трудно, выложите фрагмент кода с отслеживанием по фронту, заранее спасибо.
-
эх, если бы я был програмером, то выложил бы :-)
а так - просто знаю как оно работает
-
Эх, если б я умел программить МК, то выложил бы... :-)
А так - да, прерывание юзать нужно. Вроде у МК есть прерывания по сигналу с порта (мне казалось, есть такая штука). Ну вот на него и вешать.
-
В конечном итоге количество внешних прерываний ограничено, поэтому желательно без них. Я пока мега8 пробую запрограмммировать.
-
Если энкодеров много, то можно использовать только одно прерывание. Простой сумматор со всех энкодеров (который выдает "1" при появлении сигнала хотя бы с одного энкодера), затем этот "суммированный" сигнал подается на отдельный порт, который вызывает прерывание. По прерыванию запускается процедура, считывающая сигналы со всех энкодеров и "выявляющая", который из них и куда был повернут.
Хм.. по правде сказать, я не совсем понимаю, как работает энкодер. Как регистрируется угол поворота? От него зависит задержка между импульсами или что?.. не совсем понимаю.
-
энкодер - по сути, это механический переключатель без ограничения вращения, при вращении ручки замыкает пару контактов, причем замыкание одного из них сдвинуто по углу вращения, вследствие чего он выдает последовательность , соответствующая вращению, например:
00
10
11
01
00
как видно, первый бит просто опаздывает на один шаг, если крутить ручку в одну сторону, и будет спешить, если в другую ... Аааа, ну наконец-то до меня дошло... Верно говорят, поставь правильно задачу - и она будет решена :)
Хотя, с добавлением тех двух строчек, все работает без ошибок, как ни странно. Логика - страшная вещь, никогда не знаешь, куда она тебя заведет ...
-
http://www.stas633.narod.ru/ProVse/Valcoder/Valcod.html
Совсем хорошо...
-
Спасибо за линк, все ясно стало сразу. Хм... там приведен и алгоритм обработки ;-)