-
Вложений: 2
Управление при помощи поворотного энкодера (Rotary Encoder)
Давно хотел провести эксперимент с энкодером и прикрутить его к Arduino Nano
Но все никак не удавалось его приобрести .
Вчера разобрал старую убитую мышку и выпаял из нее Энкодер для экспериментов. Все оказалось достаточно просто . Написал скетч для cArduino / Arduino, взял уже готовую программу для ПК написанную для другого проекта и через 15 мин. я уже регулировал громкость при помощи энкодера.
Недавно приобрел энкодер с нажатием и подправил Sketch под него, теперь можно назначать вращение энкодера с нажатием и без него или назначать комбинацию клавишь только на нажатие
Программу скачиваем здесь
Код для Arduino Nano:
PHP код:
#define encoder0PinA 2
#define encoder0PinB 3
#define encoder0PinC 4
byte bytes[2]={0,7} ;
void setup()
{
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // подключить подтягивающий резистор
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // подключить подтягивающий резистор
pinMode(encoder0PinC, INPUT);
digitalWrite(encoder0PinC, HIGH); // подключить подтягивающий резистор
attachInterrupt(0, doEncoderA, FALLING); // настроить прерывание interrupt 0 на pin 2
attachInterrupt(1, doEncoderB, FALLING); // настроить прерывание interrupt 0 на pin 3
Serial.begin (115200);
}
void loop()
{
if(digitalRead(encoder0PinC)==LOW)
{
bytes[1]=8;
Serial.write( bytes,2);
while(digitalRead(encoder0PinC)==LOW){delay(50);}
bytes[1]=7;
}
}
// обработка прерывания
void doEncoderA()
{
if(digitalRead(encoder0PinB)==HIGH){bytes[0]=25;}else{bytes[0]=5;}
Serial.write( bytes,2);
bytes[0]=0;
}
// обработка прерывания
void doEncoderB()
{
if(digitalRead(encoder0PinA)==HIGH){bytes[0]=5;}else{bytes[0]=25;}
Serial.write( bytes,2);
bytes[0]=0;
}
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
А когда появится сам энкодер в кармониторе?:)
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Уже приехали, нужно только поехать забрать.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Я подключал энкодер с помощью резисторов на один аналоговый канал. На нем же все остальные резистивные кнопки. Работает достаточно четко.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Тоже интересное решение, только не совсем понял как контроллер определит в каком направлении энкодер вращается. Можно схему подключения глянуть?
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Цитата:
Сообщение от
Chip
Тоже интересное решение, только не совсем понял как контроллер определит в каком направлении энкодер вращается. Можно схему подключения глянуть?
Ну вот как то так. Еще резистор на землю надо чтобы наводки убрать (не стал его рисовать). В общем ардуино смотрит момент перехода - если сначала 0 потом 200 потом 600 значит в одну сторону крутится, а если 0 потом 400 потом 600 значит в обратную. Цифры с потолка для наглядности.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Это понятно, я так сразу и представлял, сбило с толку твое сообщение
Цитата:
На нем же все остальные резистивные кнопки
Прерывание как реализовал для аналого входа ?
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Цитата:
Сообщение от
Chip
Это понятно, я так сразу и представлял, сбило с толку твое сообщение
Прерывание как реализовал для аналого входа ?
а никак. я чайник пока. вот кусочек скеча
val = analogRead(0);
if (val < 60)
pos = 3;
if (val < 50)
pos = 4;
if (val < 35)
pos = 2;
if (val < 10)
pos = 1;
if ((pos == 1) && (pos0 == 4))
Serial.println('<');
if ((pos == 3) && (pos0 == 2))
Serial.println('<');
if ((pos == 1) && (pos0 == 2))
Serial.println('>');
if ((pos == 3) && (pos0 == 4))
Serial.println('>');
pos0 = pos;
delay(2);
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Энкодер на резисторы вешать несколько некорректно - энкодер может давать такую частоту, что она будет "сьедаться" ацп - суть есть конденсатором + обработчиком напряжения на этом конденсаторе.
Если есть возможность, то надо делать на цифровых входах.
В схеме еще хорошо бы повесить сопротивления с сигналов энкодера на питание, для пущей надежности.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Внутренняя подтяжка подключена
PHP код:
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // подключить подтягивающий резистор
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // подключить подтягивающий резистор
А вот с дребезгом нужно что то делать, лучше наверно подправить немного код, чем кондеры вешать
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Прост внутренняя подтяжка слабенькая. Я хочу сказать, что хуже не будет.
Дребезг примерно так:
Код:
#define ENCODER_DEBOUNCE 3
byte oldval=0;
byte encdeb=0;
void doEncoder(){
byte val=0;
if (digitalRead(encoder0PinA) == HIGH)
{
if (digitalRead(encoder0PinB) == LOW)
{
val=15;
}
else
{
val=24;
}
}
else
{
if (digitalRead(encoder0PinB) == LOW)
{
val=24;
}
else
{
val=15;
}
}
if(oldval != val)
{
if (encdeb < ENCODER_DEBOUNCE)
{
encdeb++;
return;
}
else
{
Serial.print(val,BYTE);
Serial.print(val,BYTE);
oldval=val;
encdeb =0;
}
}
}
Кондеры на 10 нФ устраняют дребезг, но при этом снижают максимальную частоту вращения ручки.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Спасибо .
Попробую.
Внутренняя подтяжка 20 ком , что вполне достаточно
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Цитата:
Сообщение от
Urvin
Энкодер на резисторы вешать несколько некорректно - энкодер может давать такую частоту, что она будет "сьедаться" ацп - суть есть конденсатором + обработчиком напряжения на этом конденсаторе.
Если есть возможность, то надо делать на цифровых входах.
В схеме еще хорошо бы повесить сопротивления с сигналов энкодера на питание, для пущей надежности.
понимаю что лучше на цифровые входы повесить. Да энкодер размещаться на руле будет, а с руля 3 провода всего идут, так что вариант только с резисторами. К тому же цифровых входов на ардуине итак впритык, еще двух для энкодера просто нету.
На счет скорости - все ок. Проверял. Даже при быстром вращении все ловится корректно, проц успевает отловить.
-
Энкодеры появится или нет?
-
Энкодеры, TSOP, ФОТОРЕЗИСТОРЫ появились
Завтра на кармонитор занесут
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Ничерта короче не пойму.
Перепробовал кучу примеров работы с энкодерами.
Этот исходник, из проекта где все функции объеденены в ардуине.
Кондеры ставил которые по 0,1мкф.
Делал доп. анализ для дребезга, пропуска ложных срабатываний и.т.д.
СИтуевина одна и та же. Если просто вращать энкодер(хоть медленно), вперед то шаги выглядят примерно так (счетчик шагов):
..0
1
2
3
4
3
4
5
6
...
..20
19
18
17
18
17
16
15
Короче крутишь в одну сторону а он в противоположную срабатывает часто. Программа абсолютно симметрична в работе для направления по часовой и против. НО по часовой меньше ошибочных срабатываний энкодера.
Я вращаю энкодером шаговый. В итоге шпиндель шагового то нормально едет, то его колбасит. Не серьезно.
Последний исходник, который использовал:
Цитата:
volatile int encoder0Pos = 0;
void setup()
{
encoder0Pos = 0;
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH);
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH);
attachInterrupt(0, doEncoderA, CHANGE);
attachInterrupt(1, doEncoderB, CHANGE);
}
void doEncoderA()
{
if (digitalRead(encoder0PinA) == HIGH) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
else
{
if (digitalRead(encoder0PinB) == HIGH) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
}
void doEncoderB()
{
if (digitalRead(encoder0PinB) == HIGH) {
if (digitalRead(encoder0PinA) == HIGH) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
else {
if (digitalRead(encoder0PinA) == LOW) {
encoder0Pos = encoder0Pos + 1; // CW
}
else {
encoder0Pos = encoder0Pos - 1; // CCW
}
}
}
void loop()
{
//Rotate
if (encoder0Pos<0)
{
encoder0Pos++;
rotate_left(1);
}
if (encoder0Pos>0)
{
encoder0Pos--;
rotate_right(1);
}
}
Я уже подумываю что энкодер бракованый.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
У меня код из шапки, с конденсаторами работает нормально, без кондеров глючит.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
по 0,1 мкф к центральному, а его на землю?
кстати почему 24 и 15? просто так? :) почему не 0 и 1 к примеру?
или ты этот байт просто еще для чего-то используешь?
Можно еще вопросец по языку?
Цитата:
attachInterrupt(0, doEncoderA, FALLING); // настроить прерывание interrupt 0 на pin 2
где указывается что на пин №2? Как он определяет что прерывание по спаду именно на 2ом пине ? doEncoderA ведь просто имя функции, а дефайн encoder0PinA никуда в этом случае не подставится.
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Конденсаторы на землю и выход "C" энкодера на землю
Вот этот код
PHP код:
#define encoder0PinA 2
#define encoder0PinB 3
byte bytes[1] ;
void setup()
{
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // подключить подтягивающий резистор
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // подключить подтягивающий резистор
attachInterrupt(0, doEncoderA, FALLING); // настроить прерывание interrupt 0 на pin 2
attachInterrupt(1, doEncoderB, FALLING); // настроить прерывание interrupt 0 на pin 3
Serial.begin (115200);
}
void loop()
{
}
// обработка прерывания
void doEncoderA()
{
if(digitalRead(encoder0PinB)==HIGH){bytes[0]=24;}else{bytes[0]=15;}
Serial.write( bytes,1);
}
// обработка прерывания
void doEncoderB()
{
if(digitalRead(encoder0PinA)==HIGH){bytes[0]=15;}else{bytes[0]=24;}
Serial.write( bytes,1);
}
Использую программу Carduino монитор
Вот результат, как видишь нет пропусков ни в одну ни в другую сторону
Вложение 8022
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
мдя, видать чето я напутал в схеме.
вот я кручу по часовой стрелке энкодер, постепенно увеличивая скорость вращение
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
А ты A,B,C правильно подключил?
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
там они на энкодере по порядку же идут? сначала контакт для вращения в одну сторону, потом общий, потом для вращения в др. сторону. так? подрубил к 2 и 3 пину на ардуине.
кондеры керамические, на них написано 104K400V
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Цитата:
Сообщение от
Except
там они на энкодере по порядку же идут? сначала контакт для вращения в одну сторону, потом общий, потом для вращения в др. сторону. так? подрубил к 2 и 3 пину на ардуине.
Не факт , смотри по DS
Кондеры подойдут.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
На нем ниодной надписи :) В Кармониторе числился как "Incremental Encoder (Инкрементный Энкодер)".
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
С 3-мя выводами или с 5-ю ?
Я сейчас тестирую из кармонитор с 5-ю выводами
Хотя с 3-мя выводами тоже проверял, проблем небыло, а вот его распиновку не помню, попробуй поищи вывод "С" по краям методом тыка
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
3 с одной стороны. и для нажатия два с другой.
Отрубил один провод. т.е. оставил 2: сигнальный и землю. Поигрался, максимум чего добился на скрине. но се равно косячит.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Ну тогда остается два варианта ,
1 - Энкодер плохой
2 - Конденсаторы плохие
Судя по скриншоту дребезг контактов не уменьшился
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Я попробовал другие кондеры, из дому притащил по 0,05мкф. Правдо они еще советские. Но ситуёвина та же самая.
Самое интересное что у нас в городе энкодеры не продают(( из москвы 1-2 энкодера заказывать тупость.
Можно правда выпаять из штатной магнитолы (все равно не использую). Но курочить неохота.
Попробую рулить шаговиком с помощью переменного сопротивления. Но уже не так круто, там же блин крайние положения.
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Попробуй энкодер из мышки
Конднры еще можно побольше емкостью попробовать 0,22м, 0,33м, 0,47м, 1м
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Подскажи, есть по паре каких-то старых кондеров, там написано 220 +- 10 и 82 +- 10.
Это не то? Пикофарады чтоли?
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Кондеры эти не помогут
А мышка старая есть?
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Да, есть. Завтра притащу, попробую. Я в мышке помню тока приемник и передатчик, между ними зубчатое колесо вращается от ролика. Это и есть энкодер?
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Энкодер в мышке это колесо прокрутки , смотри на фото
Вложение 8090
-
Вложений: 2
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
У меня тоже с энкодором, к томуже не определяется нажатие на нем и не определяются резисторные кнопки. Идет постоянный дребизг, запускаю ALL_config - все нормально, как только нажимаю кнопку или поворачиваю энкодор, в страке со значением начинают прыгать цифры от 278 до 320.
Поворот энкодора отрабатывает значения, но не устойчиво.
Рисунок 2: это значения, которые посылает Arduino когда к нему ничего не подключено (я думал должны быть все нули)... Кстати, при запуске программы ALL_IN_ONE начинает изменяться яркость монитора, хотя фоторезистор не подключен...
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Давай в этой теме не будем обсуждать AII_IN_ONE и разберемся с энкодером.
Пробовал вот этот скетч?
Попробуй с "Carduino monitor" и отпиши результат.
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Все понял, обсуждаем по отдельности.
Попробовал, все нормально, только нажатие не работает...
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Ну вот отлично работает, ни одного сбоя.
Нажатие в тесте не реализовал. Это самое простое , ты и сам сможешь это сделать
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
К сожалению мои познания в программировании не позволят мне этого сделать :-(
К томуже у меня не регулируется громкость в системе с помощью HotKey.
Запускаю HKey_config - все отлично, дребезга нет, при повороте энкодера кады определяются, задаю им значения. Запускаю HotKey - ничего не происходит при повороте энкодера. Драйвер установил, перегрузился согласно инструкции :-(
-
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Надеюсь код из шапки с хоткейем проверял?
Проверю позже
-
Вложений: 1
Re: Управление при помощи поворотного энкодера (Rotary Encoder)
Дела....
Вытащил из машины штатную магнитолу. Подрубился к энкодеру громкости (предвартельно обрезав провода от него). То же самое. Даж не знаю чего делать. Извиняюсь за ужасную схему.