я сколько не мучался, пока кондюки по 0,1 мкФ не припоял к контактам энкодера, дребезг никак побороть не мог, но конечно при быстром вращении пропускает. Наверное самый хороший вариант - это валкодер из шаговика!
0,1 мкФ - дофига, у меня 0,01 мкФ и все работает. Конечно, неплохо бы знать, какой у тебя энкодер, у меня, например, 24 импульса на оборот. Скорость вращения прикинул - максимум 2 оборота в секунду буду крутить => tи > 5-10 мс. дребезг навскидку длится меньше миллисекунды. Надо постоянную времени выбрать больше времени дребезга, и хотя бы втрое меньше длительности импульса при макс. скорости вращения. У меги внутренняя подтяжка около 50 кОм, с кондерами 0,01 мкФ получается постоянная времени 0,5 мс - пока нормально работает.
И еще - если у тебя энкодер старый, снятый с убитого музцентра или микроволновки, наверняка контакты окислились, в этом случае у него не то что дребезг, там просто голимый неконтакт будет, который никакими программными ухищрениями не проймешь. Старый энкодер надо разобрать, протереть контакты ватной палочкой со спиртом и смазать WD-40, - будет как новый. Еще лучше смазать консистентной смазкой, но я к сожалению не знаю, какая подойдет для контактов, потому мажу вэдэшкой, с ней конечно износ несколько ускоряется
у меня энкодер новый, но совсем китайский купил за 50 руб. для экспериментов.
Цитата:
0,1 мкФ - дофига, у меня 0,01 мкФ и все работает.
пробовал 0,01 визуально ориентируясь на ЖКИ чуть чуть хуже работает появляются глюки, при 0,1 мкФ глюков не видно, но видно пропуски при быстром вращении, наверное надо что-то среднее подбирать.
сделал опрос по перрыванию на RB6 (я пики програмирую)
void interrupt enc (void){
//прерывание по RB5-RB7 if ( RBIF ==1 ) { RBIF = 0;
if (RB1 == 1) enc_data++; else {enc_data--; }
}} // конец обработки прерываний
так вот : этот код очень криво работает,то в + считает,то в - считает пропускает некоторые щелчки энкодера подскажите пожалуйсто,как его можно оптимизировать? дребезг у меня подавляеться аппаратно,на выводах энкодера висят конденсаторы по 0,1мкф спасибо
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
vovik15, сделайте примерно так (пример для энкодера подключенного к RB6,RB7):
Код:
void interrupt isr (void){ //... if ( RBIF && RBIE ) { //прерывание по RB4-RB7 if (!RB6){ enc_data++; } if (!RB7){ enc_data--; } RBIE = 0; //Запрет прерываний от энкодера RBIF = 0; } //... } void main (void){ //... while (!(RB7 && RB6)){} //Ожидание установки энкодера в "нейтраль" __delay_ms(5); RBIF = 0; RBIE = 1; //Разрешение прерываний от энкодера //... }
Прерывание должно быть настроено на отрицательный фронт. В общем случае в прерывании всегда нужно проверять не только флаг прерывания, но и бит разрешения! Иначе, если у Вас используется более одного источника прерываний, и какое-то из них запрещено, оно все равно будет обработано, если возникнет прерывание от другого источника. Обычно в пиках для прерываний делают такую конструкцию:
Код:
void interrupt isr (void){ if ( RBIF && RBIE ){ Rb_Handler(); //Обработчик RB4:RB7 return; } if ( T0IF && T0IE ){ Tmr0_Handler(); //Обработчик TMR0 return; } //... и т.д. }
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4470 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
Самый простой пример опроса - это вешаем первый выход энкодера на внешнее прерывание. А второй выход на проверяемый пин. (к примеру PA6) В обработчике прерывания сразу же проверяем вторую ногу и принимаем решение. Если на второй ноге есть ток, то значит выполняем одно действие (крутится в одну сторону), а если на ней тока нет, то принимаем другое действие (крутится в другую сторону)
Код:
INT_0: in r16, SREG push r16 sbic PinA, 6 rjmp DECREMENT inc r17 pop r16 out SREG, r16 reti DECREMENT: dec r17 pop r16 out SREG, r16 reti
Только вот дребезг надо будет кондёрами устранить.
_________________ I am DX168B and this is my favourite forum on internet!
сделал опрос по перрыванию на RB6 (я пики програмирую)
А прерывание по какому событию? должно быть на смену уровней вот эта строчка что делает?
Код:
if ( RBIF ==1 ) { RBIF = 0;
эта строчка сбрасавает флаг по прерыванию RB6
разве в пиках флаг прерывания аппаратно не сбрасывается? Ваш код тоже будет работать только настройте правильно событие вызывающее прерывание, оно должно быть по спадающему фронту.
разве в пиках флаг прерывания аппаратно не сбрасывается?
Нет, не сбрасывается, т.к. вектор прерывания всего один, поэтому источник, вызвавший прерывание определяется программно, следовательно флаг прерывания тоже сбрасывать надо "вручную".
vovik15, сделайте примерно так (пример для энкодера подключенного к RB6,RB7):
Код:
void interrupt isr (void){ //... if ( RBIF && RBIE ) { //прерывание по RB4-RB7 if (!RB6){ enc_data++; } if (!RB7){ enc_data--; } RBIE = 0; //Запрет прерываний от энкодера RBIF = 0; } //... } void main (void){ //... while (!(RB7 && RB6)){} //Ожидание установки энкодера в "нейтраль" __delay_ms(5); RBIF = 0; RBIE = 1; //Разрешение прерываний от энкодера //... }
Прерывание должно быть настроено на отрицательный фронт. В общем случае в прерывании всегда нужно проверять не только флаг прерывания, но и бит разрешения! Иначе, если у Вас используется более одного источника прерываний, и какое-то из них запрещено, оно все равно будет обработано, если возникнет прерывание от другого источника. Обычно в пиках для прерываний делают такую конструкцию:
Код:
void interrupt isr (void){ if ( RBIF && RBIE ){ Rb_Handler(); //Обработчик RB4:RB7 return; } if ( T0IF && T0IE ){ Tmr0_Handler(); //Обработчик TMR0 return; } //... и т.д. }
ЭТОТ КОД К СОЖАЛЕНИЮ НЕ РАБОТАЕТ ХОТЯ И ЕОМПИЛИРУЕТЬСЯ только что пи прошивал,проверял
разве в пиках флаг прерывания аппаратно не сбрасывается?
Нет, не сбрасывается, т.к. вектор прерывания всего один, поэтому источник, вызвавший прерывание определяется программно, следовательно флаг прерывания тоже сбрасывать надо "вручную".
у себя сделал так в главном цикле проверяется, если один из выводов энкодера сработал,ждем 1мс, приращиваем счетчик, при переполнении счетчика устанавиваем флаг нажатости ноги энкодера и наоборот, задержка при отпускании. может конечно много кода зато без дребезга. вот только очень быструю прокрутку конечно не обрабатывает
_________________ Не нужно дергать спящего тигра за усы! Не высыпается 3-ий день!
Какой компилятор у Вас? Смотрите примеры и мануал. обычно бывает что-то вроде delay.h, delay.c. Нужно подключить эти модули. В PICC все нужные модули подключаются через htc.h:
Сейчас этот форум просматривают: andrey25b и гости: 22
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения