Поддержу мысль andriano фактами. Схема из #248 наиболее правильная из простых решений. Почему, смотрим:
Осциллограмма сигнала энкодера без конденсаторов:
Синий канал без всего, жёлтый с конденсатором 100nF, но без последовательного резистора
Синий канал без всего, жёлтый с конденсатором 100nF и с последовательным резистором 2кОм
Казалось бы разница между двумя последними вариантами несущественна, но в реальности она принципиальна. Приблизим переходный процесс. С конденсатором, но без последовательного резистора имеем разряд конденсатора отрицательной полярности размахом 1 вольт! такие вещи очень недружат с прерываниями:
И вот вариант с конденсатором и с последовательным резистором:
Конечно импульс сильно растянулся - там клетка 2µS, а тут 500µS. Но зато никаких выбросов, а значит и никаких помех.
Спасибо, что не оставили без внимания мой месседж. У меня, наиболее вероятно, первый вариант энкодера, без осциллографа я точно не могу судить, но выглядит он так:
У продавца о распиновке ничего не было, предположил что выводы в последовательности ACB, средний земляной. Пробовал в двух средах, FLOWCOD и ARDUINO IDE - толком ни в одной не работает. Я даже пробовал в код #212 вставлять после проверок короткий блинк встроенным в ардуинку светодиодом - блинькает каждый щелчек, прерывание реально работает ВСЕГДА. Значиит пропуск шагов говорит о том, что ни одна из проверок не выполняется. Значит в реале существует и третья (а может и четвертая...) ситуация с входными битами порта A.
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме. Автор может обосновать их наличие? Кстати, попробовал без блокировочных конденсаторов - работоспособность почти 0%.
У продавца о распиновке ничего не было, предположил что выводы в последовательности ACB, средний земляной. Пробовал в двух средах, FLOWCOD и ARDUINO IDE - толком ни в одной не работает
Для проверки выводов достаточно омметра или батарейки со светодиодом
Qanatoz пишет:
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме. Автор может обосновать их наличие? Кстати, попробовал без блокировочных конденсаторов - работоспособность почти 0%.
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме.
Офигеть! Я целый пост посвятил рассказу зачем там дополнительный резистор, и вам всё ещё непонятно?
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме.
Офигеть! Я целый пост посвятил рассказу зачем там дополнительный резистор, и вам всё ещё непонятно?
Не надо так пафосно. Да - "фильтр низкой частоты", да - сглаживает обратный импульс тока. Ну и что? КАК напряжение ОБРАТНОЙ полярности НИЗКОГО уровня может повлиять на ЛОГИЧЕСКИЙ вход? Как "...такие вещи очень недружат с прерываниями..."? Может быть ЛОГИЧЕСКИЙ вход воспримет такой импульс как "-1"?
Теория подтверждается практикой! Две минуты работы (поиск резисторов на ДВА КИЛООМА и подпайка) и... , что и требовалось доказать - пропуски стали чаще и чаще стал появляться реверс.
Вы, в запале спора об подключении энкодера, совершенно забыли (тактично обошли проблему) о вашей РЕАЛЬНО НЕРАБОЧЕЙ программе. Программа из 72 поста РЕАЛЬНО РАБОТАЕТ, и я уверен, что она будет работать даже если я уберу блокировочные кондеры, а ваша нет. Я не могу проверить, что она будет работаь и с другим типом энкодера, но уверен, что будет работать. "Может, что-то в конскерватории подправить?" (с)
Qanatoz, да ничего не подтверждается. Обработчик "в loop" работает совершенно на других принципах и таймингах. У обработчика на прерываниях нет таких возможностей, если он расчитан на определённый тип энкодера -то с другим он работать не обязан, и это неизбежность.
Дмитрий, вы же реальный человек, а не тролль. До этого все ваши посты я воспринимал, как истину - сплошная конкретика и никакой воды. Ну почему сейчас вы хватаетесь за отдельные "проблемки" и совершенно игнорите ГЛАВНУЮ ПРОБЛЕМУ? Вы не ответили ни на один мой вопрос, ведь реально же НЕ РАБОТАЕТ обработчик. Если бы энкодер был НЕРАБОЧИЙ или НЕ ТОТ, то программа не работала бы никогда, но ИНОГДА РАБОТАЕТ же! Значит программа содержит ЛОГИЧЕСКУЮ ошибку. Но вы даже не пытаетесь ее найти. У вас есть несколько типов энкодеров и вы РЕАЛЬНО пробовали вашу программу и энкодеры работали на 100%? Ну, не верю...
Qanatoz, я ответил на ваш вопрос ещё постом #247 Посмотрите осциллограммы ещё раз - сложно написать универсальный обработчик на прерываниях по причинам которые там указаны. То, что частично работает -ни о чём не говорит. Я писал свой обработчик под тот энкодер что у меня был (ky-40), и с ним нет никаких глюков. Много других людей его использовали, и у всех работает нормально. Тем не менее даже если бы вы взяли такой же модуль энкодера(ky-40) то не факт, что всё бы работало хорошо -сегодня китайцы припаивают одну модель -завтра станут другую, и все тайминги поменяются.
Такой, да не совсем такой. Скетч с подключенной библиотекой работает, но с горем пополам. Считает по 4 за каждый щелчек, то есть все значения позиции энкодера должны быть кратны 4, но как тогда быть с позициями, например, 470 или 37?
Monday пишет:
Для проверки выводов достаточно омметра или батарейки со светодиодом
Был бы очень признателен за методу проверки. Сразу предупрежу, что ни один из выводов энкодера не звонится на корпус.
Не стОит, живите в здравом уме. Да, библиотечная реализация работает лучше на порядок (реализация в 72 посте вне конкуренции), чем местные самописки, но тоже не без греха. Как эту библиотеку использовать в серьезных программах, где без прерываний не обойтись?
Для проверки выводов достаточно омметра или батарейки со светодиодом
Для "проверки выводов", я писал о цоколевке, вы скептично ответили - значит точно имели ввиду ЦОКОЛЕВКУ, вам достаточно омметра со светодиодом? Еще раз, методу цоколевки в студию! С нетерпением жду!
Конечно импульс сильно растянулся - там клетка 2µS, а тут 500µS. Но зато никаких выбросов, а значит и никаких помех.
Только не пишите что Вас не предупреждал я о том что ФНЧ приводит к пропускам при быстром вращении ))) Попался энкодер с 96 импульсами на оборот дающий импульсы до 1-2мсек и "шеф, все пропало" А ведь элементарные вещи RC с постоянной 0,1мсек выдаст установивщийся уровень через 0,3мсек (ага 3 тау), а для фиксации импульса с определением направления вращения надо 4 фазы сигналов, а это по 0,25-0,5мсек. П ричем фазы не сильно равные по длительности, на осцилограмах хороше видно, что 01 и 01 сильно короче чем 00 и 11. Вот и пропускает.
dimax пишет:
У обработчика на прерываниях нет таких возможностей
Это ж каких, "таких" возможностей нету. Угадаю - делай не работает ;) А запустить формирование требуемого интервала (если нет тямы как без них обойтись) на таймере и отработать завершение времени в обработчике прерываний таймера - не?
dimax пишет:
и он расчитан на определённый тип энкодера -то с другим он работать не обязан, и это неизбежность.
Это называется "уменя все работает, а проблемы индейцев шерифа не волнуют". А нафиг код такой постить?
dimax пишет:
Тем не менее даже если бы вы взяли такой же модуль энкодера(ky-40) то не факт, что всё бы работало хорошо
Фу какой дешовый слив )))
ПС. Обычная история костылестроения, когда вместо понимания происходяших процессов начинают приводить реальный сигнал к идеальному. Посмотрите на свои же осцилограмы, та же очевидно видно, где сигнал шумный, а где - нет даже без ФНЧ.
Logik, ничего не понял из ваших комментариев. Кто пропускает, что пропускает? У меня ничего не пропускает. Свой обрабочик я применяю во всех своих программах именно потому, что не нужно "запускать формирование временного интервала" тем или иным способом. Про проблемы индейцев -да, если у кого-то не работает, то это не моя проблема -это точно. Предложите свой вариант, который у всех будет работать и всех устроит, я только за.
Но моя реплика относилась к тому, что сформулированой Вами "проблемы" не существует. От слова совсем. Во-первых, энкодер легко фиксируется и между "щелчками", так что получить любое из указанных Вами значений можно без труда. А во-второых, если уж Вм хочется непременно получать за один щелчок изменение на 1, а не на 4, то в арифметике есть такая операция - называется "деление". В данном случае делить нужно (кто бы мог подумать!) на 4.
Цитата:
Да, библиотечная реализация работает лучше на порядок (реализация в 72 посте вне конкуренции), чем местные самописки, но тоже не без греха. Как эту библиотеку использовать в серьезных программах, где без прерываний не обойтись?
Увы, в 72 посте данной темы никакой реализации не увидел (смотрел чисто из любопытства). По поводу библиотеки тоже ничего сказать не могу - для таких элементарных вещей, как работа с энкодерами, всегда использую "самописку". Естественно, в каждом конкретном случае решаю, что именно лучше всего использовать в данном случае. Использовал и обычные прерывания на Due, которые там на каждой ноге, и PCINT на 328, которые тоже на каждой ноге, и вообще без прерываний - опрос в цикле loop(). Согласен с dimax, что единого универсального решения здесь не существует, но всегда можно выбрать то, которое окажется наилучшим в каждом конкретном случае.
...сформулированой Вами "проблемы" не существует. От слова совсем. ... А во-второых, если уж Вм хочется непременно получать за один щелчок изменение на 1, а не на 4, то в арифметике есть такая операция - называется "деление". В данном случае делить нужно (кто бы мог подумать!) на 4.
Подкол на счет деления засчитан. Но я просто имел ввиду несовершенство библиотечной реализации, в которой возможны некратные 4 значения позиции энкодера. И остановка энкодера между фиксациями этого не объясняет. Ну сами представьте механизм такой ошибки. Энкодер остановился между щелчками, библиотека выдала некратное значение, например 7. Дальше, энкодер всегда останавливается без ошибки - строго фиксируясь. Теперь все последующие значения не будут кратны четырем - 11,...25,... и т.д. Но такого не случается - библиотека ликвидирует такую ошибку. Так, что "остановкой между" этого не объяснить.
andriano пишет:
Увы, в 72 посте данной темы никакой реализации не увидел (смотрел чисто из любопытства).
Писал по памяти, ошибся пост #74 - реализация лучше библиотечной.
Сегодня на глаза попалась статья, ну вылитый мой энкодер. Я решил, что распиновка моего энкодера ACB, а человек доказывает, что ABC. Я настолько уверовал в своей ошибке, что перерисовал и перетравил плату, вновь запаял все детали, предварительно сдув их с предыдущей. Ну и что в результате? Стало еще хуже - энкодер практически не работает. Реализации в посте #212 и #213 не работают - это для ИДЕАЛЬНОГО энкодера. Во всяком случае, я ПРАКТИЧЕСКИ доказал, что такая реализация на моем энкодере при любом подключении не работает.
PS Я все еще жду нашего "гения" Monday, котрый с помощью батарейки и светодиода сможет определить цоколевку энкодера. Ау, где ты? Что, так трудно признать, что ступил? Посыпь голову пеплом и не вякай в следующий раз неподумав.
не тема, а какой-то АдЪ - кто-то может объяснить, что за херня тут происходит? ¯\_(ツ)_/¯
*одни конденсаторы вешают на энкодеры с прерываниями, другие не могут победить /4, постоянно какая-то библиотека пострадавшим упоминается и кто-то его с распиновкой надул.
Реализации в посте #212 и #213 не работают - это для ИДЕАЛЬНОГО энкодера. Во всяком случае, я ПРАКТИЧЕСКИ доказал, что такая реализация на моем энкодере при любом подключении не работает.
Это обработчик был написан для энкодера ky-40, который за 1 щёлчок делает только одно размыкание или замыкание контактов. Тогда я ещё не знал, что существуют и другие разновидности :) Поэтому не пояснил дня какого именно типа..
Подкол на счет деления засчитан. Но я просто имел ввиду несовершенство библиотечной реализации, в которой возможны некратные 4 значения позиции энкодера. И остановка энкодера между фиксациями этого не объясняет. Ну сами представьте механизм такой ошибки. Энкодер остановился между щелчками, библиотека выдала некратное значение, например 7. Дальше, энкодер всегда останавливается без ошибки - строго фиксируясь. Теперь все последующие значения не будут кратны четырем - 11,...25,... и т.д. Но такого не случается - библиотека ликвидирует такую ошибку. Так, что "остановкой между" этого не объяснить.
Отнюдь.
Если в результате остановки в промежуточном положении мы получили 7, значит, следующей остановке на щелчке будет соответстввать 8. И дальше? 12, 16, 20, 24...
Т.е. "на щелчке" - всегда кратно 4, а "между" - все остальные значения: 7, 9, 10, 11, 13, 14, 15, 17...
Чудес не бывает.
Если у Вас сначала на щелчке было кратное, а потом вдруг перестало, значит, где-то Вы пропустили отсчет. Ищите аппаратную проблему
Некратное на щелчке может быть (при правильной работе) только в том случае, если в момент включения энкодер стоял "между". Но и в этом случае проблем не вижу, т.к. при работе энкодера остаток от деления на 4 "на щелчке" всегда будет равен одному и тому же числу (правда, не 0). Так что если Вам нужен один отсчет на щелчок, - можете смело применять ту же операцию деления: отличия от вариатнта остановки на щелчке Вы не заметите.
не тема, а какой-то АдЪ - кто-то может объяснить, что за херня тут происходит? ¯\_(ツ)_/¯
*одни конденсаторы вешают на энкодеры с прерываниями, другие не могут победить /4, постоянно какая-то библиотека пострадавшим упоминается и кто-то его с распиновкой надул.
Я сочуствую, только убогим умом. А мои дети и внуки, слава Богу, могут жить своими руками и умом. А убогоньких с НАПОЛЕОНОВСКИМИ ЗАМАШКАМИ мне жалко. Так что не переживай, бедолага, станешь ты НАПООЛЕОНОМ.
Можна конечно и так кнопку применить, но интересней другой вариант применения. В меню: без нажатия - навигация по пунктам меню; нажатие - вход в подменю или выбор конечной редактируемой величины; вращение при нажатой - навигация между уровнями меню от корня до последней выбираемой конечной величины или места где находились в меню в момент. После выбора конечной величины: вращение - изменение величины; нажатие(точней отпускание) - подтверждение ввода; вращение при нажатии - перебор вариантов ввод, отмены изменения и нескольких предустановок. Так на одном энкодере делается удобное управление многоуровневым меню. Но все зависит от задачи.
привет всем, я новичок в программирование ардуино. Кто не будь может помочь с примерам именно в этом вопросе/варианте? У меня часть "...без нажатия - навигация по пунктам меню..." работает без проблем, дальше часть "...нажатие - вход в подменю..." и навигация врашением не получается. взял за основу скетч меню с кнопками.
#include <LiquidCrystal.h> //Библиотека LCD
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
char* Efecte[]={"All","All2","VU","VU2","VU3","VU4","Ripple",
"Ripple2","Fire","Fire Blue","Sinelon","Pattern3","Twinkle",
"Balls","Blur","Matrix One","Drip"};
char* Regim[]={"Regim All","Regim VU","Regim Ripple","Regim Fire","Other Regim"};
#define PinA 14
#define PinB 15
#define PinButon 5
#define PinButon2 6
#define bounce 30 //задержка антидребезга
boolean f_key=0;//флаг для фиксации нажатия кнопки
int counter = 0;
int p0=1;
int p1=3;
int p2=7;
int p3=9;
int p4=11;
int aState;
int aLastState;
unsigned long time;
unsigned long PSTimer = 0;//таймер для обновления экрана
unsigned long KPTimer = 0;//таймер для опроса кнопок
void setup() {
pinMode (PinA,INPUT);
pinMode (PinB,INPUT);
pinMode (PinButon,INPUT_PULLUP);
pinMode (PinButon2,INPUT_PULLUP);
lcd.begin(16,2);
Serial.begin (9600);
// Reads the initial state of the PinA
aLastState = digitalRead(PinA);
}
void loop()
{
if (millis()-KPTimer>=bounce) {//опрос кнопок раз в 10мсек
KPTimer=millis();
if (f_key==false) {
key_dn();//проверка нажатия кнопки
}
if(f_key==true) {
key_up();//проверка отпускания кнопки
}
}
aState = digitalRead(PinA); // Считывает «текущее» состояние PinA
// Если предыдущее и текущее состояние PinA отличаются друг от друга, это означает, что произошел импульс
if (aState != aLastState) {
// Если состояние PinB отличается от состояния PinA, это означает, что кодер вращается по часовой стрелке
if (digitalRead(PinB) != aState) {
//action(0);
action(0);
}
else {
// action(1);
action(1);
}
}
aLastState = aState;
if (millis()-PSTimer>=50) {//вывод экрана каждые 50мсек (20к/с)
PSTimer=millis();
PreentScreen(counter);
}
}
void key_dn(){
if (f_key==false) {
if (digitalRead(PinButon)== HIGH)
{
PreentScreen2(0);
f_key=true;//устанавливаем флаг
counter=0;
}
}
}
void key_up() {
if (digitalRead(PinButon)==0) {
f_key=false;//сброс флага
}
}
void PrintLabel(char* t, byte x, byte y)
{//char* t - лейбл, x-столбец, y-строка
lcd.setCursor(x, y);
lcd.print(t);
}
void PreentScreen(int s)
{//Вывод меню
lcd.clear();//отчистка экрана
//Описание экранов меню
switch (s) {
case 0://Экран выводимый по умолчанию (не пункт меню)
PrintLabel("Regim",0,0);
break;
case 1://экран изменения переменной 1
PrintLabel("Regim",0,0);
PrintLabel(Regim[0],0,1);
break;
case 2://экран изменения переменной 2
PrintLabel("Regim",0,0);
PrintLabel(Regim[1],0,1);
break;
case 3:
PrintLabel("Regim",0,0);
PrintLabel(Regim[2],0,1);
break;
case 4:
PrintLabel("Regim",0,0);
PrintLabel(Regim[3],0,1);
break;
case 5:
PrintLabel("Regim",0,0);
PrintLabel(Regim[4],0,1);
break;
}
}
void PreentScreen2(int s)
{//Вывод меню
lcd.clear();//отчистка экрана
//Описание экранов меню
switch (s) {
case 0:
PrintLabel(Regim[0],0,0);
PrintLabel(Efecte[p0],0,1);
break;
case 1:
PrintLabel(Regim[1],0,0);
PrintLabel(Efecte[p1],0,1);
break;
case 2:
PrintLabel(Regim[2],0,0);
PrintLabel(Efecte[p2],0,1);
break;
case 3:
PrintLabel(Regim[3],0,0);
PrintLabel(Efecte[p3],0,1);
break;
case 4:
PrintLabel(Regim[4],0,0);
PrintLabel(Efecte[p4],0,1);
break;
}
}
void action(byte x)
{
switch (x) {
case 0:
counter=var(counter, 1, 5, 1, 1, 1);//увеличиваем переменную уровня меню
break;
case 1:
counter=var(counter, 1, 5, 1, 0, 1);//уменьшаем переменную уровня меню
break;
case 2:
if (counter==1){//если нажали UP когда экран с переменной р1
p0= var(p0, 1, 2, 1, 1, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
}
if (counter==2){//если нажали UP когда экран с переменной р2
p1= var(p1, 3, 6, 1, 1, 1);
}
if (counter==3){//если нажали UP когда экран с переменной р2
p2= var(p2, 7, 8, 1, 1, 1);
}
if (counter==4){//если нажали UP когда экран с переменной р2
p3= var(p3, 9, 10, 1, 1, 1);
}
if (counter==5){//если нажали UP когда экран с переменной р2
p4= var(p4, 11, 17, 1, 1, 1);
}
break;
case 3:
if (counter==1){//если нажали DOWN когда экран с переменной р1
p0= var(p0, 1, 2, 1, 0, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
}
if (counter==2){//если нажали DOWN когда экран с переменной р2
p1= var(p1, 3, 6, 1, 0, 1);
}
if (counter==3){//если нажали DOWN когда экран с переменной р1
p2= var(p2, 7, 8, 1, 0, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
}
if (counter==4){//если нажали DOWN когда экран с переменной р1
p3= var(p3, 9, 10, 1, 0, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
}
if (counter==5){//если нажали DOWN когда экран с переменной р1
p4= var(p4, 11, 17, 1, 0, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
}
break;
}
}
int var(int v, int mn, int mx, int stp, boolean pm, boolean c)
{
switch (pm) {//pm=1 увеличение pm=0 уменьшение
case 0:
v -= stp;//уменьшаем на шаг
break;
case 1:
v += stp;//увеличиваем на шаг
break;
}
switch (c) {//c-1 циклически с-0 до пределов
case 1://
if (v<mn) {
v=mx;
}
if (v>mx) {
v=mn;
}
break;
case 0:
if (v<mn) {
v=mn;
}
if (v>mx) {
v=mx;
}
break;
}
return v;
}
Фух. Я опять чуствую себя полноценным девелопером. :)
Победил!!!
Четко ловится каждый "щелчек". Без ошибок направления, без пропусков (даже если "крутить" достаточно быстры).
Общий подход такой
1. На нисходящем фронте A, смотрим состояние B и запоминаем его. А так же время "когда это произошло" (падение A)
2. На восходящем фронте A, смотрим сколько времени прошло с пукнта 1. Если меньше определенного значения (5 msec опытно подобрал) - игнорируем, если больше - меняем счетчик энкодра. Направление определяем по состоянию канала B, запомненного на пункте 1.
#define PIN_A 2
#define PIN_B 3
#define PULSE_PIN_LEN 5 // минимальная длинна импульса в миллесекундах на которую мы обращаем внимание
volatile unsigned long failingTime=0;
volatile bool fl=false; // флаг что нужно вывести
volatile bool value_b=0;
volatile byte prevA=0;
volatile int encValue=0;
volatile unsigned long pulseLen=0;
void setup(){
Serial.begin(57600);
digitalWrite(PIN_A,HIGH);
digitalWrite(PIN_B,HIGH);
attachInterrupt(0,handler_a,CHANGE);
Serial.println("Ready");
}
void handler_a(){
// byte portValue=PINE ; // для меги
// byte A= (portValue & B10000)>0 ;// digitalRead(PIN_A); PE4
byte A=digitalRead(PIN_A);
if(!fl){ // пока не отчитались ничего больше не делаем
if(prevA && !A){ // фронт упал
//value_b=(portValue & B100000)>0; // digitalRead(PIN_B); PE5 // определили направление, но пока только "запомнили его"
value_b=digitalRead(PIN_B); // определили направление, но пока только "запомнили его"
failingTime=millis(); // и запомнили когда мы "упали в ноль", начали отсчет длины импульса
}
if(!prevA && A && failingTime){ // восходящий фронт и мы в режиме "отсчет времени импульса
pulseLen=millis()-failingTime;
if( pulseLen>PULSE_PIN_LEN){ // импульс бы достаточно длинный что-бы поверить тому что мы прочитали в его начале
if(value_b)encValue++; else encValue--;
fl=true; // включаем пометку что нужно отчитатся в Serial
}
failingTime=0; // больше не ведем осчет времени импульса
}
}
prevA=A;
}
void loop(){
if(fl){
Serial.print("Enc=");Serial.print(encValue);
Serial.print(",Dir="); Serial.print(value_b?"R":"L"); // выводим направление
Serial.print(",PulseLen=");Serial.println(pulseLen); // выводим длину импульса (удобно для первоначальной настройки)
fl=false;
}
}
Выдает (сделал 10-ть щелчков по часовой и 10-ть против):
Мой вариант обработчика энкодера. Очень простой и совершенно безглючен. Обработчик сидит в теле внешнего прерывания PCINT. В нижеследующем скетче задействованы входы A0 и A1 как цифровые. Используется подтяжка к питанию (распаянная на платке стандартного энкодера), и антидребезговые конденсаторы 0,1мкф на землю. Кому нужно на другие ноги - смотреть даташит страница 73 и маскировку битов сделать по аналогии.
volatile int enc;
void setup() {
Serial.begin(9600);
PCICR=1<<PCIE1; //разрешить пренрывание
PCMSK1=(1<<PCINT9)|(1<<PCINT8); //выбрать входы
}
ISR (PCINT1_vect){
static byte old_n=PINC&3; // маска B00000011 что б читать только нужные 2 бита
byte new_n=PINC&3;
if (old_n==1&&new_n==3||old_n==2&&new_n==0) {enc++;}
if (old_n==2&&new_n==3||old_n==1&&new_n==0) {enc--;}
old_n= new_n;
}
void loop() {
Serial.println(enc);
}
А можно аналогичный пример для 5 и 6 пина, у меня получилось следующее, но пока не работает, честно сказать уже не знаю что неправильно, пробовал по разному
PCICR=1<<PCIE2; //разрешить пренрывание
PCMSK2=(1<<PCINT21)|(1<<PCINT22); //выбрать входы
ISR (PCINT2_vect){
static byte old_n=PIND&B01100000; // маска B00000011 что б читать только нужные 2 бита
byte new_n=PIND&B01100000;
if (old_n==1&&new_n==3||old_n==2&&new_n==0) {enc++;}
if (old_n==2&&new_n==3||old_n==1&&new_n==0) {enc--;}
old_n= new_n;
}
Мааленькая и быстрая. На основе 4-х комбинаций с помощью булевой алгебры и switch-case делается простейший счетчик. Все! Правда есть нюанс. Функция digitalRead() оказалась настолько медленной, что ATmega328 не успевал читать значения pinA и pinB при срабатывании внешнего прерывания на pin A. Поэтому для AVR пришлось использовать прерывание по Timer1. Каждые 0.01 секунд таймер не спеша читает состояние пинов и обновляет счетчик энкодера. Для быстрых STM32 и ESP8266 все работает на внешнем прерывании - как только энкодер начинает крутиться, срабатывает внешнее прерывание на pinA, считываются значения pinA и pinB и обновляется позиция энкодера.
В библиотеки два класса: легкий "RotaryEncoder" и тяжелый класс с "RotaryEncoderAdvanced" на template.
Легкий класс тупо счетчик кликов в диапазоне -32768..32767 и обработчик нажатия кнопки. На лету можно менять значения счетчика и сотяние кнопки. Все.
В Advanced классе можно прописывать количество шагов на клик, минимальное и максимальное значение. Получился законченный велосипед. Из-за template библиотека может занимать меньше памяти - все зависит от типа используемых переменных.
Вот так для float:
RotaryEncoderAdvanced<float> encoder(PIN_A, PIN_B, BUTTON, 0.1, 0.0, 3.3); //0.1 step per click, minimum value 0.0, maximum value 3.3
Вот так для byte:
RotaryEncoderAdvanced<byte> encoder(PIN_A, PIN_B, BUTTON, 1, 0, 255); //1 step per click, minimum value 0, maximum value 255
Добавил возможность на лету менять - step per click, minimum value и maximum value. Управляем множеством различных значений с помощью одного энкодера!!!
БЕЗ ГАСЯЩИХ КОНДЕНСАТОРОВ БИБЛИОТЕКА РАБОТАТЬ НЕ БУДЕТ, СМОТРИ ПОСТ #252!!!
Для энкодеров, которые за один щелчок совершают полный импульс (типа ec-11, подробно об этом в #247) есть более совершенный вариант обработчика. Алгоритм взял тут у Леонид Иваныча, и воткнул в прерывания. С этим методом дребезгоподавляющие конденсаторы не нужны. По аналогии можно переделать на другие пины
//Энкодер на пинах А0, А1. Используется внутренняя подтяжка.
volatile int enc;
void setup(){
Serial.begin(9600);
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание
}
ISR(PCINT1_vect){
static char EncPrev=0; //предыдущее состояние энкодера
static char EncPrevPrev=0; //пред-предыдущее состояние энкодера
char EncCur = 0;
if(!(PINC & (1 << PC0))){EncCur = 1;} //опрос фазы 1 энкодера
if(!(PINC & (1 << PC1))){ EncCur |= 2;} //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == 3 && //если предыдущее состояние 3
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == 2) //если текущее состояние 2,
enc++; //шаг вверх
else //иначе
enc--; //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
void loop() {
Serial.println(enc);
}
bwn, PCIFR=PCIFR убрать флаг (что б не влетело в прерывание сходу) -это не обязательная команда. PCICR=1<<PCIE1 разрешить групповые прерывания для второй группы.
bwn, даташит не предлагать? :) Ну гугль наверное что нить подскажет..
Ну почему не предлагать. Вполне можно. Ввиду языкового кретинизма пользуюсь Евстифеевым, а там про них ни слова. Вы сказали, в даташите есть. Полезу буквицы, бусурманские, разбирать. Спасибо.))))
Всем доброго времени суток!!! Прошу помощи допилить скетч) в общем суть такая, собираю внешнее управление для авто магнитолы, управление работает по can шине. из устройств имеется ардуино нано+can шилд mcp2515+джойстик ky-023, под эту связку я нормально скетч сделал. но мне нужно добавить энкодер KY-040 для управления громкостью. то есть при вращении энкодера в одну сторону должен в шину поступать один пакет can, в другую сторону другой пакет. Пробовал примеры работы с энкодером, но как что то изменяю в примере у меня ни чего не работает.
вот мой скетч для управления магнитолой, точнее это часть скетча:
Кстати, насчет конденсаторов: схему естественно, подключать только к тем ногам МК, у которых есть триггера Шмитта.
логично: конденсаторы - что бы убить прерывание, триггер - что бы убить плавное снижение напряжения конденсаторами.
*нафиг всю обвязку, кроме подтяжки пинов к питанию.
Поддержу мысль andriano фактами. Схема из #248 наиболее правильная из простых решений. Почему, смотрим:
Осциллограмма сигнала энкодера без конденсаторов:
Синий канал без всего, жёлтый с конденсатором 100nF, но без последовательного резистора
Синий канал без всего, жёлтый с конденсатором 100nF и с последовательным резистором 2кОм
Казалось бы разница между двумя последними вариантами несущественна, но в реальности она принципиальна. Приблизим переходный процесс. С конденсатором, но без последовательного резистора имеем разряд конденсатора отрицательной полярности размахом 1 вольт! такие вещи очень недружат с прерываниями:
И вот вариант с конденсатором и с последовательным резистором:
Конечно импульс сильно растянулся - там клетка 2µS, а тут 500µS. Но зато никаких выбросов, а значит и никаких помех.
Спасибо, что не оставили без внимания мой месседж. У меня, наиболее вероятно, первый вариант энкодера, без осциллографа я точно не могу судить, но выглядит он так:
У продавца о распиновке ничего не было, предположил что выводы в последовательности ACB, средний земляной. Пробовал в двух средах, FLOWCOD и ARDUINO IDE - толком ни в одной не работает. Я даже пробовал в код #212 вставлять после проверок короткий блинк встроенным в ардуинку светодиодом - блинькает каждый щелчек, прерывание реально работает ВСЕГДА. Значиит пропуск шагов говорит о том, что ни одна из проверок не выполняется. Значит в реале существует и третья (а может и четвертая...) ситуация с входными битами порта A.
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме. Автор может обосновать их наличие? Кстати, попробовал без блокировочных конденсаторов - работоспособность почти 0%.
такого типа энкодер работает: http://arduino.ru/forum/programmirovanie/enkoder-schitaet-cherez-4
это RC фильтр низкой частоты
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме.
Офигеть! Я целый пост посвятил рассказу зачем там дополнительный резистор, и вам всё ещё непонятно?
Ну а что касается предложенной схемы подключения энкодера, то не могу понять зачем токоограничивающие резисторы разряда конденсатора? Организм до отвращения сопротивляется такой схеме.
Офигеть! Я целый пост посвятил рассказу зачем там дополнительный резистор, и вам всё ещё непонятно?
Не надо так пафосно. Да - "фильтр низкой частоты", да - сглаживает обратный импульс тока. Ну и что? КАК напряжение ОБРАТНОЙ полярности НИЗКОГО уровня может повлиять на ЛОГИЧЕСКИЙ вход? Как "...такие вещи очень недружат с прерываниями..."? Может быть ЛОГИЧЕСКИЙ вход воспримет такой импульс как "-1"?
Теория подтверждается практикой! Две минуты работы (поиск резисторов на ДВА КИЛООМА и подпайка) и... , что и требовалось доказать - пропуски стали чаще и чаще стал появляться реверс.
Вы, в запале спора об подключении энкодера, совершенно забыли (тактично обошли проблему) о вашей РЕАЛЬНО НЕРАБОЧЕЙ программе. Программа из 72 поста РЕАЛЬНО РАБОТАЕТ, и я уверен, что она будет работать даже если я уберу блокировочные кондеры, а ваша нет. Я не могу проверить, что она будет работаь и с другим типом энкодера, но уверен, что будет работать. "Может, что-то в конскерватории подправить?" (с)
Qanatoz, да ничего не подтверждается. Обработчик "в loop" работает совершенно на других принципах и таймингах. У обработчика на прерываниях нет таких возможностей, если он расчитан на определённый тип энкодера -то с другим он работать не обязан, и это неизбежность.
Дмитрий, вы же реальный человек, а не тролль. До этого все ваши посты я воспринимал, как истину - сплошная конкретика и никакой воды. Ну почему сейчас вы хватаетесь за отдельные "проблемки" и совершенно игнорите ГЛАВНУЮ ПРОБЛЕМУ? Вы не ответили ни на один мой вопрос, ведь реально же НЕ РАБОТАЕТ обработчик. Если бы энкодер был НЕРАБОЧИЙ или НЕ ТОТ, то программа не работала бы никогда, но ИНОГДА РАБОТАЕТ же! Значит программа содержит ЛОГИЧЕСКУЮ ошибку. Но вы даже не пытаетесь ее найти. У вас есть несколько типов энкодеров и вы РЕАЛЬНО пробовали вашу программу и энкодеры работали на 100%? Ну, не верю...
Qanatoz, я ответил на ваш вопрос ещё постом #247 Посмотрите осциллограммы ещё раз - сложно написать универсальный обработчик на прерываниях по причинам которые там указаны. То, что частично работает -ни о чём не говорит. Я писал свой обработчик под тот энкодер что у меня был (ky-40), и с ним нет никаких глюков. Много других людей его использовали, и у всех работает нормально. Тем не менее даже если бы вы взяли такой же модуль энкодера(ky-40) то не факт, что всё бы работало хорошо -сегодня китайцы припаивают одну модель -завтра станут другую, и все тайминги поменяются.
Без комментария. Буду биться со СВОЕЙ проблемой САМ. Возьму у друга ригол и найду причину неработы энкодера.
такого типа энкодер работает: http://arduino.ru/forum/programmirovanie/enkoder-schitaet-cherez-4
Такой, да не совсем такой. Скетч с подключенной библиотекой работает, но с горем пополам. Считает по 4 за каждый щелчек, то есть все значения позиции энкодера должны быть кратны 4, но как тогда быть с позициями, например, 470 или 37?
Для проверки выводов достаточно омметра или батарейки со светодиодом
Был бы очень признателен за методу проверки. Сразу предупрежу, что ни один из выводов энкодера не звонится на корпус.
Считает по 4 за каждый щелчек, то есть все значения позиции энкодера должны быть кратны 4, но как тогда быть с позициями, например, 470 или 37?
А-фи-геть!
А-фи-геть!
Не стОит, живите в здравом уме. Да, библиотечная реализация работает лучше на порядок (реализация в 72 посте вне конкуренции), чем местные самописки, но тоже не без греха. Как эту библиотеку использовать в серьезных программах, где без прерываний не обойтись?
Для проверки выводов достаточно омметра или батарейки со светодиодом
Для "проверки выводов", я писал о цоколевке, вы скептично ответили - значит точно имели ввиду ЦОКОЛЕВКУ, вам достаточно омметра со светодиодом? Еще раз, методу цоколевки в студию! С нетерпением жду!
Конечно импульс сильно растянулся - там клетка 2µS, а тут 500µS. Но зато никаких выбросов, а значит и никаких помех.
Только не пишите что Вас не предупреждал я о том что ФНЧ приводит к пропускам при быстром вращении ))) Попался энкодер с 96 импульсами на оборот дающий импульсы до 1-2мсек и "шеф, все пропало" А ведь элементарные вещи RC с постоянной 0,1мсек выдаст установивщийся уровень через 0,3мсек (ага 3 тау), а для фиксации импульса с определением направления вращения надо 4 фазы сигналов, а это по 0,25-0,5мсек. П ричем фазы не сильно равные по длительности, на осцилограмах хороше видно, что 01 и 01 сильно короче чем 00 и 11. Вот и пропускает.
У обработчика на прерываниях нет таких возможностей
Это ж каких, "таких" возможностей нету. Угадаю - делай не работает ;) А запустить формирование требуемого интервала (если нет тямы как без них обойтись) на таймере и отработать завершение времени в обработчике прерываний таймера - не?
и он расчитан на определённый тип энкодера -то с другим он работать не обязан, и это неизбежность.
Это называется "уменя все работает, а проблемы индейцев шерифа не волнуют". А нафиг код такой постить?
Тем не менее даже если бы вы взяли такой же модуль энкодера(ky-40) то не факт, что всё бы работало хорошо
ПС. Обычная история костылестроения, когда вместо понимания происходяших процессов начинают приводить реальный сигнал к идеальному. Посмотрите на свои же осцилограмы, та же очевидно видно, где сигнал шумный, а где - нет даже без ФНЧ.
Logik, ничего не понял из ваших комментариев. Кто пропускает, что пропускает? У меня ничего не пропускает. Свой обрабочик я применяю во всех своих программах именно потому, что не нужно "запускать формирование временного интервала" тем или иным способом. Про проблемы индейцев -да, если у кого-то не работает, то это не моя проблема -это точно. Предложите свой вариант, который у всех будет работать и всех устроит, я только за.
А-фи-геть!
Не стОит, живите в здравом уме.
Согласен, разумное предложение.
Но моя реплика относилась к тому, что сформулированой Вами "проблемы" не существует. От слова совсем. Во-первых, энкодер легко фиксируется и между "щелчками", так что получить любое из указанных Вами значений можно без труда. А во-второых, если уж Вм хочется непременно получать за один щелчок изменение на 1, а не на 4, то в арифметике есть такая операция - называется "деление". В данном случае делить нужно (кто бы мог подумать!) на 4.
Увы, в 72 посте данной темы никакой реализации не увидел (смотрел чисто из любопытства). По поводу библиотеки тоже ничего сказать не могу - для таких элементарных вещей, как работа с энкодерами, всегда использую "самописку". Естественно, в каждом конкретном случае решаю, что именно лучше всего использовать в данном случае. Использовал и обычные прерывания на Due, которые там на каждой ноге, и PCINT на 328, которые тоже на каждой ноге, и вообще без прерываний - опрос в цикле loop(). Согласен с dimax, что единого универсального решения здесь не существует, но всегда можно выбрать то, которое окажется наилучшим в каждом конкретном случае.
...сформулированой Вами "проблемы" не существует. От слова совсем. ... А во-второых, если уж Вм хочется непременно получать за один щелчок изменение на 1, а не на 4, то в арифметике есть такая операция - называется "деление". В данном случае делить нужно (кто бы мог подумать!) на 4.
Подкол на счет деления засчитан. Но я просто имел ввиду несовершенство библиотечной реализации, в которой возможны некратные 4 значения позиции энкодера. И остановка энкодера между фиксациями этого не объясняет. Ну сами представьте механизм такой ошибки. Энкодер остановился между щелчками, библиотека выдала некратное значение, например 7. Дальше, энкодер всегда останавливается без ошибки - строго фиксируясь. Теперь все последующие значения не будут кратны четырем - 11,...25,... и т.д. Но такого не случается - библиотека ликвидирует такую ошибку. Так, что "остановкой между" этого не объяснить.
Увы, в 72 посте данной темы никакой реализации не увидел (смотрел чисто из любопытства).
Писал по памяти, ошибся пост #74 - реализация лучше библиотечной.
Сегодня на глаза попалась статья, ну вылитый мой энкодер. Я решил, что распиновка моего энкодера ACB, а человек доказывает, что ABC. Я настолько уверовал в своей ошибке, что перерисовал и перетравил плату, вновь запаял все детали, предварительно сдув их с предыдущей. Ну и что в результате? Стало еще хуже - энкодер практически не работает. Реализации в посте #212 и #213 не работают - это для ИДЕАЛЬНОГО энкодера. Во всяком случае, я ПРАКТИЧЕСКИ доказал, что такая реализация на моем энкодере при любом подключении не работает.
PS Я все еще жду нашего "гения" Monday, котрый с помощью батарейки и светодиода сможет определить цоколевку энкодера. Ау, где ты? Что, так трудно признать, что ступил? Посыпь голову пеплом и не вякай в следующий раз неподумав.
не тема, а какой-то АдЪ - кто-то может объяснить, что за херня тут происходит? ¯\_(ツ)_/¯
*одни конденсаторы вешают на энкодеры с прерываниями, другие не могут победить /4, постоянно какая-то библиотека пострадавшим упоминается и кто-то его с распиновкой надул.
Реализации в посте #212 и #213 не работают - это для ИДЕАЛЬНОГО энкодера. Во всяком случае, я ПРАКТИЧЕСКИ доказал, что такая реализация на моем энкодере при любом подключении не работает.
Это обработчик был написан для энкодера ky-40, который за 1 щёлчок делает только одно размыкание или замыкание контактов. Тогда я ещё не знал, что существуют и другие разновидности :) Поэтому не пояснил дня какого именно типа..
Подкол на счет деления засчитан. Но я просто имел ввиду несовершенство библиотечной реализации, в которой возможны некратные 4 значения позиции энкодера. И остановка энкодера между фиксациями этого не объясняет. Ну сами представьте механизм такой ошибки. Энкодер остановился между щелчками, библиотека выдала некратное значение, например 7. Дальше, энкодер всегда останавливается без ошибки - строго фиксируясь. Теперь все последующие значения не будут кратны четырем - 11,...25,... и т.д. Но такого не случается - библиотека ликвидирует такую ошибку. Так, что "остановкой между" этого не объяснить.
Отнюдь.
Если в результате остановки в промежуточном положении мы получили 7, значит, следующей остановке на щелчке будет соответстввать 8. И дальше? 12, 16, 20, 24...
Т.е. "на щелчке" - всегда кратно 4, а "между" - все остальные значения: 7, 9, 10, 11, 13, 14, 15, 17...
Чудес не бывает.
Если у Вас сначала на щелчке было кратное, а потом вдруг перестало, значит, где-то Вы пропустили отсчет. Ищите аппаратную проблему
Некратное на щелчке может быть (при правильной работе) только в том случае, если в момент включения энкодер стоял "между". Но и в этом случае проблем не вижу, т.к. при работе энкодера остаток от деления на 4 "на щелчке" всегда будет равен одному и тому же числу (правда, не 0). Так что если Вам нужен один отсчет на щелчок, - можете смело применять ту же операцию деления: отличия от вариатнта остановки на щелчке Вы не заметите.
не тема, а какой-то АдЪ - кто-то может объяснить, что за херня тут происходит? ¯\_(ツ)_/¯
*одни конденсаторы вешают на энкодеры с прерываниями, другие не могут победить /4, постоянно какая-то библиотека пострадавшим упоминается и кто-то его с распиновкой надул.
Мировой арбитр?
Мировой арбитр?
скромный русофоб.
Мировой арбитр?
скромный русофоб.
Сочуствую.
Сочуствую.
своим детям и внукам посочувствуй.
Сочуствую.
своим детям и внукам посочувствуй.
Я сочуствую, только убогим умом. А мои дети и внуки, слава Богу, могут жить своими руками и умом. А убогоньких с НАПОЛЕОНОВСКИМИ ЗАМАШКАМИ мне жалко. Так что не переживай, бедолага, станешь ты НАПООЛЕОНОМ.
Я сочуствую, только убогим умом.
я - всем аборигенам Суберии.
Я сочуствую, только убогим умом.
я - всем аборигенам Суберии.
Ты крут, ты уже почти НАПОЛЕОН. Всё, всё... все уже увидели твою крутизну, прими снотворное и слабительное и успокойся.
Ты крут, ты уже почти НАПОЛЕОН.
ты директор мокшанского дурдома?
Ты крут, ты уже почти НАПОЛЕОН.
ты директор мокшанского дурдома?
Ты помнишь меня? Я надеялся, что мы тебя подлечили, а ты опять за своё. Дебилизм неизлечим.
Дети.
Можна конечно и так кнопку применить, но интересней другой вариант применения. В меню: без нажатия - навигация по пунктам меню; нажатие - вход в подменю или выбор конечной редактируемой величины; вращение при нажатой - навигация между уровнями меню от корня до последней выбираемой конечной величины или места где находились в меню в момент. После выбора конечной величины: вращение - изменение величины; нажатие(точней отпускание) - подтверждение ввода; вращение при нажатии - перебор вариантов ввод, отмены изменения и нескольких предустановок. Так на одном энкодере делается удобное управление многоуровневым меню. Но все зависит от задачи.
привет всем, я новичок в программирование ардуино. Кто не будь может помочь с примерам именно в этом вопросе/варианте? У меня часть "...без нажатия - навигация по пунктам меню..." работает без проблем, дальше часть "...нажатие - вход в подменю..." и навигация врашением не получается. взял за основу скетч меню с кнопками.
Фух. Я опять чуствую себя полноценным девелопером. :)
Победил!!!
Четко ловится каждый "щелчек". Без ошибок направления, без пропусков (даже если "крутить" достаточно быстры).
Общий подход такой
1. На нисходящем фронте A, смотрим состояние B и запоминаем его. А так же время "когда это произошло" (падение A)
2. На восходящем фронте A, смотрим сколько времени прошло с пукнта 1. Если меньше определенного значения (5 msec опытно подобрал) - игнорируем, если больше - меняем счетчик энкодра. Направление определяем по состоянию канала B, запомненного на пункте 1.
Выдает (сделал 10-ть щелчков по часовой и 10-ть против):
Количество щелчков четко совпадет с тем что "чувствуется рукой". Крутил в темпе "что-бы самому успевать считать щелчки".
Можно попросить схему подключения энкодера?
Мой вариант обработчика энкодера. Очень простой и совершенно безглючен. Обработчик сидит в теле внешнего прерывания PCINT. В нижеследующем скетче задействованы входы A0 и A1 как цифровые. Используется подтяжка к питанию (распаянная на платке стандартного энкодера), и антидребезговые конденсаторы 0,1мкф на землю. Кому нужно на другие ноги - смотреть даташит страница 73 и маскировку битов сделать по аналогии.
А можно аналогичный пример для 5 и 6 пина, у меня получилось следующее, но пока не работает, честно сказать уже не знаю что неправильно, пробовал по разному
мошт, надо old_n и new_n на 5 бит вправо сдвигать, а потом сравнивать с 3, 2 и 1?
А хрен знает, я уже думать нехочу. Несколько часов промучался
jeka_tm,
Спасибо заработало
мой велосипед для работы с энкодером - https://github.com/enjoyneering/RotaryEncoder
Мааленькая и быстрая. На основе 4-х комбинаций с помощью булевой алгебры и switch-case делается простейший счетчик. Все! Правда есть нюанс. Функция digitalRead() оказалась настолько медленной, что ATmega328 не успевал читать значения pinA и pinB при срабатывании внешнего прерывания на pin A. Поэтому для AVR пришлось использовать прерывание по Timer1. Каждые 0.01 секунд таймер не спеша читает состояние пинов и обновляет счетчик энкодера. Для быстрых STM32 и ESP8266 все работает на внешнем прерывании - как только энкодер начинает крутиться, срабатывает внешнее прерывание на pinA, считываются значения pinA и pinB и обновляется позиция энкодера.
Вот так для byte:
Подскажите как поменять пины энкодера вместо А0 и А1 на 2 и 3 (у меня все порты А заняты)
в коде для энкодера с поста http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=2#comment-111309
голову уже сломал
в примере из кода http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=5#comment-419049
мой энкодер прибавляет или отнимает по 2 еденицы, а не по 1 за один щелчек
в примере из кода http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=5#comment-419049
мой энкодер прибавляет или отнимает по 2 еденицы, а не по 1 за один щелчек
вот костылёк))))
вот костылёк))))
ясное дело что сразу заюзал
enc / 2
Для энкодеров, которые за один щелчок совершают полный импульс (типа ec-11, подробно об этом в #247) есть более совершенный вариант обработчика. Алгоритм взял тут у Леонид Иваныча, и воткнул в прерывания. С этим методом дребезгоподавляющие конденсаторы не нужны. По аналогии можно переделать на другие пины
dimax, добрый человек, в 7-й строке, что за колдунство? Не могу у Евстифеева найти, или ищу не там????(((((
bwn, PCIFR=PCIFR убрать флаг (что б не влетело в прерывание сходу) -это не обязательная команда. PCICR=1<<PCIE1 разрешить групповые прерывания для второй группы.
Пасиб, я в виду имел, где про эти регистры почитать.
bwn, даташит не предлагать? :) Ну гугль наверное что нить подскажет..
bwn, даташит не предлагать? :) Ну гугль наверное что нить подскажет..
Ну почему не предлагать. Вполне можно. Ввиду языкового кретинизма пользуюсь Евстифеевым, а там про них ни слова. Вы сказали, в даташите есть. Полезу буквицы, бусурманские, разбирать. Спасибо.))))
Всем доброго времени суток!!! Прошу помощи допилить скетч) в общем суть такая, собираю внешнее управление для авто магнитолы, управление работает по can шине. из устройств имеется ардуино нано+can шилд mcp2515+джойстик ky-023, под эту связку я нормально скетч сделал. но мне нужно добавить энкодер KY-040 для управления громкостью. то есть при вращении энкодера в одну сторону должен в шину поступать один пакет can, в другую сторону другой пакет. Пробовал примеры работы с энкодером, но как что то изменяю в примере у меня ни чего не работает.
вот мой скетч для управления магнитолой, точнее это часть скетча:
мне нужно что бы при повороте энкодера выполнялась вот это часть программы:
ну и соответственно при повороте в другую такая же только с другим пакетом can:
свои наработки по энкодеру не выкладываю, так как дальше примеров не ушел. а в программирование не селен))
если кому не трудно помогите!!!)))
Всем доброго времени суток!!! Прошу помощи достроить баню!!!
.
.
.
свои наработки и фотки по бане не выкладываю, так как дальше фундамента не ушел. а в строительствах не селен))
если кому не трудно помогите!!!)))
Примерно так и я могу написать