Используем Энкодер

son32
Offline
Зарегистрирован: 04.12.2017

Если что то не написал или неправильно написал, приношу извинения!!! я написал что не силен в программирование, и если бы знал что и куда в скетче добавить по энкодеру то попытался бы дописать и уже тогда бы спрашивал по чему не работает. для этого я и обратился в эту ветку за помощью а не для того что бы узнать кто также может писать)) Но все равно спасибо за участие!!!

MaksVV
Offline
Зарегистрирован: 06.08.2015
что нельзя найти пример с энкодером, где в сериал порт пишется что то типа "щелчок  влево" или "щелчок  вправо" и вместо этих Serial.println ов со щелчками вставить свой mcp2515.sendMessage(&canMsg7);
 
son32
Offline
Зарегистрирован: 04.12.2017

в том то и дело что если в пример добавляю свой тот кусок кода то либо компеляцию не проходит либо ни чего вообще не работает.

son32
Offline
Зарегистрирован: 04.12.2017

мне не нужно что бы за меня писали весь скетч. мне бы пример как это должно выглядить в моем скетче, а там я уже смогу разобраться как под свои нужды его адаптировать.

MaksVV
Offline
Зарегистрирован: 06.08.2015

son32 пишет:
если бы знал что и куда в скетче добавить по энкодеру, то попытался бы дописать

дак ведь всё же 

son32 пишет:
в пример добавляю свой тот кусок кода то либо компеляцию не проходит либо ни чего вообще не работает.

тогда может нужно 

son32 пишет:
и уже тогда бы спрашивал по чему не работает

 

son32
Offline
Зарегистрирован: 04.12.2017

Ладно, понял!!! Спасибо что не отказали!!!

kolyn
Offline
Зарегистрирован: 18.01.2019

dimax пишет:

Для энкодеров, которые за один щелчок совершают полный импульс (типа ec-11, подробно об этом в #247) есть более совершенный вариант обработчика. Алгоритм взял тут у Леонид Иваныча, и воткнул в прерывания. С этим методом дребезгоподавляющие конденсаторы не нужны. По аналогии можно переделать на другие пины


Спасибо за код, энкодер ес-11, правда новый. Крутил во все стороны с различной скоростью минут 10. Всегда возвращал "0" в одном и том же положении, т.е. ни одного пропуска или ложного срабатывания!

Совместно с титановой кнопкой ув. Клапы отличная основа для написания  многоуровнего меню.

MuckS
MuckS аватар
Offline
Зарегистрирован: 13.04.2015

Уважаемый dimax!

Не раз использовал Ваши коды и очень Вам благодарен, но энкодер почему-то не даётся. Подскажите, если можете - в чём может быть дело? Переключения энкодера нечёткие. какое-то время он переключается и по одному шагу и по несколько нормально, но если крутить быстро - только уменьшает значение переменной. При чём в какую бы сторону я его ни поворачивал.

 

Заранее спасибо!

bwn
Offline
Зарегистрирован: 25.08.2014

MuckS пишет:

 но если крутить быстро - только уменьшает значение переменной. При чём в какую бы сторону я его ни поворачивал.

Не dimax, но задам наводящий вопрос - какой код используете?

MuckS
MuckS аватар
Offline
Зарегистрирован: 13.04.2015

volatile int enc;
void setup() {                
Serial.begin(9600);
PCICR=1<<PCIE1; //разрешить пренрывание
PCMSK1=(1<<PCINT9)|(1<<PCINT8); //выбрать входы
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
pinMode(A2,INPUT_PULLUP);
}

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) {PINC&4? enc++ : enc+=100 ;}
if (old_n==2&&new_n==3||old_n==1&&new_n==0) {PINC&4? enc-- : enc-=100 ;}
old_n= new_n;
}

void loop() {
Serial.println(enc);

 

Такой. Уже и аппаратный пулап пробовал - примерно тот же результат.. И из библиотеки "encoder" пробовал.. И всё равно неточности в распозновании. Что-то делаю не так, а что именно понять не могу-(

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

MuckS пишет:

Такой. Уже и аппаратный пулап пробовал - примерно тот же результат.. И из библиотеки "encoder" пробовал.. И всё равно неточности в распозновании. Что-то делаю не так, а что именно понять не могу-(
 

Попробуй так:

#define pinA 3
#define pinB 4
#define EncActive 0

int16_t EncVal = 0;
int16_t EncMin = 0;
int16_t EncMax = 1000;

void do_encoder()
{
  enum {
    WaitingForTransition,
    WaitingForBothActive,
    WaitingForBothInactive,
  };

  static uint8_t state = WaitingForTransition;

  switch (state)
  {
    case WaitingForTransition:
      cli();
      if (digitalRead(pinA) == EncActive)
      {
        state = WaitingForBothActive;
        if (digitalRead(pinB) == EncActive)
          EncVal++;
        else
          EncVal--;
      }
      sei();
      if (EncVal < EncMin) EncVal = EncMin;
      if (EncVal > EncMax) EncVal = EncMax;
      break;
      
    case WaitingForBothActive:
      cli();
      if ((digitalRead(pinA) == EncActive) && (digitalRead(pinB) == EncActive))
      {
        state = WaitingForBothInactive;
      }
      sei();
      break;

    case  WaitingForBothInactive:
      cli();
      if ((digitalRead(pinA) != EncActive) && (digitalRead(pinB) != EncActive))
      {
        state = WaitingForTransition;
      }
      sei();
      break;  
  }
}


void setup() {
  pinMode(pinA, INPUT_PULLUP);
  pinMode(pinB, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Start");

}

int16_t oldEnc = EncVal;

void loop() {
  do_encoder();
  if (oldEnc != EncVal)
  {
    Serial.println(EncVal);
    oldEnc = EncVal;
  }
  delay(1);


}

 

Logik
Offline
Зарегистрирован: 05.08.2014

MuckS пишет:

volatile int enc;
void setup() {                
Serial.begin(9600);
PCICR=1<<PCIE1; //разрешить пренрывание
PCMSK1=(1<<PCINT9)|(1<<PCINT8); //выбрать входы
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
pinMode(A2,INPUT_PULLUP);
}

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) {PINC&4? enc++ : enc+=100 ;}
if (old_n==2&&new_n==3||old_n==1&&new_n==0) {PINC&4? enc-- : enc-=100 ;}
old_n= new_n;
}

void loop() {
Serial.println(enc);

 

Такой. Уже и аппаратный пулап пробовал - примерно тот же результат.. И из библиотеки "encoder" пробовал.. И всё равно неточности в распозновании. Что-то делаю не так, а что именно понять не могу-(

 

Этот код не годный, он рассчитан на использование енкодера с конденсаторами, что полное гониво, что в конце концов признал и сам автор. Внимательно прочитайте тему, в том числе и пост где брали этот код.

Logik
Offline
Зарегистрирован: 05.08.2014

asam пишет:

Попробуй так:...

Не советуй херню, энкодер только через прерывания можно подключать.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Не советуй херню, энкодер только через прерывания можно подключать.

ты попробуй сначала, а потом менторствуй.

Если луп крутится не медленнее чем за 1 милисекунду, то все работает прекрасно и без прерываний.  А если медленнее, то можно так:

  void setup() {
    pinMode(pinA, INPUT_PULLUP);
    pinMode(pinB, INPUT_PULLUP);
    Serial.begin(9600);
    Serial.println("init1");
    Timer1.initialize(1000);
    Timer1.attachInterrupt(do_encoder);
    Serial.println("Start");

  }
int16_t oldEnc=EncVal;

  void loop() {

    if (oldEnc != EncVal)
    {
      Serial.println(EncVal);
      oldEnc = EncVal;
    }
    delay(10);                     
  }

 

Logik
Offline
Зарегистрирован: 05.08.2014

asam пишет:

ты попробуй сначала, а потом менторствуй.

Если луп крутится не медленнее чем за 1 милисекунду, то все работает прекрасно и без прерываний.  А если медленнее, то можно так:

  void setup() {
    pinMode(pinA, INPUT_PULLUP);
    pinMode(pinB, INPUT_PULLUP);
    Serial.begin(9600);
    Serial.println("init1");
    Timer1.initialize(1000);
    Timer1.attachInterrupt(do_encoder);
    Serial.println("Start");

  }
int16_t oldEnc=EncVal;

  void loop() {

    if (oldEnc != EncVal)
    {
      Serial.println(EncVal);
      oldEnc = EncVal;
    }
    delay(10);                     
  }

 

т.е. и про атомарность переменной  EncVal и доступ к переменным изменяемым в прерывании тоже не знаешь. Я не менторствую, я предлагаю не прыгать по граблям, тут все уже разобрано. А на счет попробовать - так я уже пробовал тут пару таких поделок http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=3#comment-151742 все печально, больше не хочу. Согласись, зачем мне это - тестить сырой код, который сам автор не тестировал и дописывает по ходу замечаний ;) А для себя я энкодер давно победил.

bwn
Offline
Зарегистрирован: 25.08.2014

MuckS пишет:

void loop() {
Serial.println(enc);

Такой. Уже и аппаратный пулап пробовал - примерно тот же результат.. И из библиотеки "encoder" пробовал.. И всё равно неточности в распозновании. Что-то делаю не так, а что именно понять не могу-(

Сериалпринтом не долби бесконечно, а выводи только при изменении.

С этим вариантом, по конденсаторам, logik прав. У меня он нормально работает, но девайс - электронная нагрузка, раз-три в месяц попользовался и дальше пыль собирать. При постоянной работе сдохнет энкодер, и быстро. 

ИМХО.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

т.е. и про атомарность переменной  EncVal и доступ к переменным изменяемым в прерывании тоже не знаешь. Я не менторствую, я предлагаю не прыгать по граблям, тут все уже разобрано. А на счет попробовать - так я уже пробовал тут пару таких поделок http://arduino.ru/forum/apparatnye-voprosy/ispolzuem-enkoder?page=3#comment-151742 все печально, больше не хочу. Согласись, зачем мне это - тестить сырой код, который сам автор не тестировал и дописывает по ходу замечаний ;) А для себя я энкодер давно победил.

Ну да если переделывать под прерывания то надо указать EncVal как volatile. Ну я ж начальный вариант не для прерываний публиковал. Так что не надо тут пальцы топырить. 

А ты все ж поробуй. Дел то на 5 минут. А потом уже критикуй. А то "мы Пастернака не читали, но ..."

PS Про атомарность, ты код-то посмотри.  То еще критик ...

PPS Я много чего с энкодером перебровал и этот алгоритм (идея, к сожалению, не моя, моя только конкретная реализация) лучший для энкодеров с аппаратно не подавленным дребезгом.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Ты тему таки читать не собираешся я гляжу. Тока про Пастернака трепать. Сам сразу тему почитай то. Там уже все есть. Ты сейчас не изобретай велосипед, а посмотри  на те ошибки, которые уже пройдены. Потому как покуда ты их последовательно повторяеш. Например где-то в раене стр. 4 есть осцилограммы с енкодера. Я их с другой темы, от димаса кажется, сюда спецем притащил. Порассматривай их. А потом свой код проанализируй и поймеш глядиш чего.

// я много чего с энкодером перепробовал...

А я нет. Я себе либу написал, с третей попытке кажись. Пять лет прошло, а ниче не менял в ней, работает. Тока добавил возврат значений чтоб не только 4 единицы на щелчек, а и 1 единицу, как по классике. Так чаще востребовано. И

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Ты тему таки читать не собираешся я гляжу. Тока про Пастернака трепать. Сам сразу тему почитай то. Там уже все есть. Ты сейчас не изобретай велосипед, а посмотри  на те ошибки, которые уже пройдены. Потому как покуда ты их последовательно повторяеш. Например где-то в раене стр. 4 есть осцилограммы с енкодера. Я их с другой темы, от димаса кажется, сюда спецем притащил. Порассматривай их. А потом свой код проанализируй и поймеш глядиш чего.

 

Ну осцилограммы я на своем скопе насмотрелся. И что? Что конкретно не так с моим кодом. Где я чего повторяю? Ты же нифига логики работы не понял, как я посмотрю.

Logik
Offline
Зарегистрирован: 05.08.2014

Действительно ничего наверно. Один смотрит и видит. Другой нет. Так бывает. Ты наверно и не видеш что дребезг (это вообще не совсем дребезг как у кнопки но ладно пока) наблюдается не во всех состояниях, что не все состояния энкодера имеют равную длительность. А это твой код никак не учитывает. А без учета этого пропуски гарантированы. Знаеш, у меня тут ночь и разжевывать подробней не самое время, тем более что ты и сам этого наверно не хочеш, раз тему читать для тебя слишком недостойное занятие. Ещё раз - прочти тему с начала!

Logik
Offline
Зарегистрирован: 05.08.2014

Ну и прежде чем код рекомендовать и тем более настоятельно просить других потестить неплохо бы автору самому проверить. А то тут легко добавить, здесь переменную поправить а там рыбу заворачивали. Собери с прерываниями и расскажеш. Код с лупом быстрей 1мсек сам понимаеш, не востребован.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Ну и прежде чем код рекомендовать и тем более настоятельно просить других потестить неплохо бы автору самому проверить. А то тут легко добавить, здесь переменную поправить а там рыбу заворачивали. Собери с прерываниями и расскажеш. Код с лупом быстрей 1мсек сам понимаеш, не востребован.

 

Я этот код во  всех своих проектах с энкодером использую. Только читаю напрямую из регистров, а не digitalRead(). Все замечательно работает. Сажаю его, обычно на Timer0, там как раз в районе 1мс

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

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

Так на этом идея алгоритма и основана. Ты просто не вьезжаешь. А с энкодерами я уже лет 15 как работаю.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Ну и прежде чем код рекомендовать и тем более настоятельно просить других потестить неплохо бы автору самому проверить. А то тут легко добавить, здесь переменную поправить а там рыбу заворачивали. Собери с прерываниями и расскажеш. Код с лупом быстрей 1мсек сам понимаеш, не востребован.

Ну собрал. 

 

#define pinA 3
#define pinB 4
#define EncActive 0

volatile int16_t EncVal = 0;
int16_t EncMin = 0;
int16_t EncMax = 1000;

void do_encoder()
{
  enum {
    WaitingForTransition,
    WaitingForBothActive,
    WaitingForBothInactive,
  };

  static uint8_t state = WaitingForTransition;

  switch (state)
  {
    case WaitingForTransition:
      cli();
      if (digitalRead(pinA) == EncActive)
      {
        state = WaitingForBothActive;
        if (digitalRead(pinB) == EncActive)
          EncVal++;
        else
          EncVal--;
      }
      sei();
      if (EncVal < EncMin) EncVal = EncMin;
      if (EncVal > EncMax) EncVal = EncMax;
      break;

    case WaitingForBothActive:
      cli();
      if ((digitalRead(pinA) == EncActive) && (digitalRead(pinB) == EncActive))
      {
        state = WaitingForBothInactive;
      }
      sei();
      break;

    case  WaitingForBothInactive:
      cli();
      if ((digitalRead(pinA) != EncActive) && (digitalRead(pinB) != EncActive))
      {
        state = WaitingForTransition;
      }
      sei();
      break;
  }
}

ISR (TIMER0_COMPA_vect)
{
  do_encoder();
}

void setup() {
  pinMode(pinA, INPUT_PULLUP);
  pinMode(pinB, INPUT_PULLUP);
  OCR0A = 0xAF;           
  TIMSK0 |= _BV(OCIE0A);
  Serial.begin(115200);
  Serial.println("Start");
}

int16_t oldEnc = EncVal;

void loop() {
  if (oldEnc != EncVal)
  {
    Serial.println(EncVal);
    oldEnc = EncVal;
  }
  delay(10);
}

Рассказываю - работает замечательно.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

 Ещё раз - прочти тему с начала!

Ну посмотрел. Картинки прикольные. Понял причину твоих наездов - увидел твой код. Ревнуешь похоже. Попробовал твое творчество на том же самом энкодере что и с моим кодом. Работает очень хреново.

Logik
Offline
Зарегистрирован: 05.08.2014

Давай от это без ну! Если выкладываешь код после 15 лет работы над ним, то он должен блистать. Тебя кстати никто не заставляет это делать. Дидлайнов здесь нет и позорится на шару не обязательно. И шо мы имеем. digitalRead не убран. Нахерато в обработчике прерываний эти самые прерывания то запрещаются то разрешаются. Это юмор такой. В алгоритм смотреть желания нет, сразу ж видно что все недоделаное. Поверхностно  видно что в нем ничего нового нет (проход по трем состояниям без попыток борьбы с дребезгом). Я зачем тебе писал тему почитать? Чтоб ты убедился что так уже делали. Делали другие и многие. И безтолку, дребезг при медленном повороте "туды-сюды" вылезет.  

Может хоть работает? Так и быть попробую, вижу ты не успокоишься без мокания ;)

asam пишет:

Ну посмотрел. Картинки прикольные.

Сударь ценит визуальные образы выше текстовых смыслов?! Ни вопрос. 

https://www.youtube.com/watch?v=giRLpaZ7QIM

Достаточно? С меня да, потому будь любезен, с криками "А ты все ж поробуй. Дел то на 5 минут." после того как снова чего допиляешь - не ко мне. Ок?

ПС. Про енкодер на котором тестил. Почти идеальное состояние, хотя и пользую несколько лет. Лежит на столе для проверок и разработок. Наработка в смысле оборотов - мизер.  Большие токи и конденсаторы - не было.

ППС. Если в теме 300 с хреном постов и много лет, то вопрос не так прост чтоб твой код написанный с лету их решил. Про 15 лет коду - не трынди. Но если это не трындеж, то тогда как в песне поется "а лучше б мусор выносил" ;)

 

 

 

MuckS
MuckS аватар
Offline
Зарегистрирован: 13.04.2015

Ok.. Пока попробую так с дребезгом побороться. Посмотрим что выйдет..

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

У Пуха все есть, чтоб вам не ругацца. :-)  Спрашивайте. 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:
Достаточно? С меня да, потому будь любезен, с криками "А ты все ж поробуй. Дел то на 5 минут." после того как снова чего допиляешь - не ко мне. Ок?

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

А вообше спасибо за тестирование. Даже видео не поленился запилить. Кстати, если то что ты показал ты считаешь главной проблемой, то я очень удовлетворен. 

MuckS
MuckS аватар
Offline
Зарегистрирован: 13.04.2015

Код, который я постил выше + схема с картинки выше сработали! Всё очень чётко с точностью до шага. Всех благодарю! Доброго вечера!

RG22EM
Offline
Зарегистрирован: 27.08.2016

DetSimen пишет:

У Пуха все есть, чтоб вам не ругацца. :-)  Спрашивайте. 

да нету, он Гайверовский пользует, кнопки я у него содрал, а энкодер пришлось самому писать )))

sadman41
Offline
Зарегистрирован: 19.10.2016

Давай-ка на квона не кати бочку, он сам всё выдумывает после чтения "Вестника рыболова".

RG22EM
Offline
Зарегистрирован: 27.08.2016

sadman41 пишет:

Давай-ка на квона не кати бочку, он сам всё выдумывает после чтения "Вестника рыболова".

ну не знаю, я жеж просил, просил, а нет, а что за вестник рыболова? может моему приятелю нужон, я ему на новую посудину автоматику запрограммировал

Logik
Offline
Зарегистрирован: 05.08.2014

asam пишет:

Logik пишет:
Достаточно? С меня да, потому будь любезен, с криками "А ты все ж поробуй. Дел то на 5 минут." после того как снова чего допиляешь - не ко мне. Ок?

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

А вообше спасибо за тестирование. Даже видео не поленился запилить. Кстати, если то что ты показал ты считаешь главной проблемой, то я очень удовлетворен. 

Не знаю главная или нет, 5 минут, как просил на этом закончились. 

Logik
Offline
Зарегистрирован: 05.08.2014

asam пишет:

Logik пишет:
Достаточно? С меня да, потому будь любезен, с криками "А ты все ж поробуй. Дел то на 5 минут." после того как снова чего допиляешь - не ко мне. Ок?

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

А вообше спасибо за тестирование. Даже видео не поленился запилить. Кстати, если то что ты показал ты считаешь главной проблемой, то я очень удовлетворен. 

Не знаю главная или нет, 5 минут, как просил на этом закончились.  А еще чето главней есть? Не стесняйся, пиши о достижениях за 15 лет.

asam пишет:

твой код, который работает отвратительно

Никогда не сдавайся! Обвиняй в пустую без подтверждений и подробностей! Помни "самдурак! - универсальный вариант! 
;)
Logik
Offline
Зарегистрирован: 05.08.2014

MuckS пишет:

Ok.. Пока попробую так с дребезгом побороться. Посмотрим что выйдет..

 

Получатся пропуски при быстром вращении. Как минимум. Читай тему, там все это обсосано.

Qanatoz
Offline
Зарегистрирован: 24.05.2017

Дебильнейшая схема! Кто мне объяснит, нафига здесь горизонтальные резисторы? Какой дебил придумал эту схему? Покажите мне хоть одно действующее заводское устройство с такой схемой!

sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

Дебильнейший вопрос! Кто мне объяснит, нафига здесь такие вопросы задавать? Какой дебил придумал этот вопрос? Покажите мне хоть одно разумного (не дебила) кто пользуется подобным стилем изьяснения!!! :о)

следуя вашей логике то и самолеты не могут летать, они-же железные, огромные, тяжелые! а что говорить об ветролетаХ и ракетаХ? просто мрак! :о)...

1. RC-цепочка

2. "расчитайте" закон изменения тока в цепи (при замыкании/размыкании)

3. какой будет мгновенный ток в цепи при забМыкании контакта?

п.с. в школе надо вдумчиво учиться а не как теперь это принято, а уж если это высшее учебное заведение...

дуца не надо, тут будет смайлик :о) ... и да, "дима" на пальцах с картинками немного уже обьяснил "чедакакь"! если не понятно,  то можно набросать схемы на бумаге, посмотреть как будет заряжаться/разряжаться конденсатор... итд...

 

> Получатся пропуски при быстром вращении. Как минимум. Читай тему, там все это обсосано.

отличная схема, только надо параметры RC-цепи подогнать под "реальные задачи", ну или если не хочется "напрягаться" - набросайте на макетке и подбирайте на здоровье (пользуюсь подобным подключением с "самых детсадовских времен", хотя и были потуги использовать вх.тригеры-формирователи сигнала, но решил, что это слишком для "своей" задачи)

всем нам надо "MTV"... пардон, MTV зачеркнуто ... УЧИТЬСЯ!

Qanatoz
Offline
Зарегистрирован: 24.05.2017

sunjob пишет:

1. RC-цепочка

2. "расчитайте" закон изменения тока в цепи (при замыкании/размыкании)

3. какой будет мгновенный ток в цепи при забМыкании контакта?

п.с. в школе надо вдумчиво учиться а не как теперь это принято, а уж если это высшее учебное заведение...

Вот только не надо про школу! Там таких опытных теоретиков-радиоэлектронщиков, как ты готовят. Причем тут RC цепочка? Нафига к цифре приплетать аналог? Дима объяснил))) Что он объяснил? То что нужно бояться на входе -1 (МИНУС ЕДИНИЦЫ)? Все дребезга боятся, когда пучок единиц/нулей валит на вход, а вы МИНУС ЕДИНИЦУ фильтруете. "Какой будет мгновенный ток?" Я думаю, ты предполагаешь, что будет охуенный и без этого сраного резистора из энкодера искры полетят. "...расчитайте" закон изменения тока..." А что его читать? Или ты - великий грамотей и отличник в школе, имел ввиду расСчитайте?  Лепите горбатого, теоретики-переучки?

Дима, я думаю, не обижается на меня. Он и сам понимает, что он просто хороший программист, а практик - никакущий.

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Если что, сам я уже не пользуюсь схемой включения энкодера с аппаратным дребезгоподавлением после того, как перешёл алгоритм от Леонид Иваныча (подробности в  #293 ) .

b707
Offline
Зарегистрирован: 26.05.2017

Цитата:

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


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

Ну как успехи? - покажете свою реализацию энкодера?
"Самый умный - Докажи!"

MuckS
MuckS аватар
Offline
Зарегистрирован: 13.04.2015

dimax пишет:

Если что, сам я уже не пользуюсь схемой включения энкодера с аппаратным дребезгоподавлением после того, как перешёл алгоритм от Леонид Иваныча (подробности в  #293 ) .

Ещё раз благодарю! Но вот уже аппаратно решилось.. Код сохраню - энкодеры удобны для управления.

sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

- лягушка, тебе плохо?

- это мне-то плохо, мне то?!!! да мне вообще пиз..ць!

...

ув. Qanatoz! не расстраивайтесь так, не зазорно быть неучем, зазорно не учиться! а вот так по хамски будете себя вести с кем останетесь? один!!!! представьте какого вам будет тогда с самим собой?!

https://postimg.cc/gallery/i8zb0cbw/

Logik
Offline
Зарегистрирован: 05.08.2014

sunjob пишет:

ув. Qanatoz! не расстраивайтесь так, не зазорно быть неучем, зазорно не учиться! а вот так по хамски будете себя вести с кем останетесь? один!!!!

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

dimax пишет:

Для энкодеров, которые за один щелчок совершают полный импульс (типа 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); 
}

К этому коду добавить эту картинку и вообще огонь будет

sunjob
sunjob аватар
Offline
Зарегистрирован: 18.07.2013

в догонку, по "типа, неправильной схеме подключения энкодера"

avr-тестер, энкодер так-же был подключен "таким-же образом", тестеру уже лет 6-7, энкодер работает отменным образом

...

из промышленных (реализация как раз на AVR-ATmega, любители "манадарины", видимо, делали)

VST-климат контроль, блок управления

схема "снятая" с печатки

 

...

проблема с энкодером не в реализации алгоритма, а в том, что со временем он изнашивается, и пофигу это "китаський" или "фирменный" (кот. сделан там-же, только, возможно, "первичный отбор" прошел)

вот тут и начинаются "мудеса в чудесe", недосчет/пересчет, вообще не логичное поведение и никакие программные хитрушки не помогут, будут так-же подтупливать, может чуть меньше

как вам такой энкодер?

поэтому и нужна "входная схема формирования импульсов", тригеры, RC-цепи

... скрины

https://postimg.cc/gallery/263g6snvw/

 

tolyan23
Offline
Зарегистрирован: 29.12.2020

Logik пишет:

Получил с Китая это чудо, такое - http://www.doneathome.ru/wp-content/uploads/2013/11/Encoder5.jpg.

Библиотеки, что нашел не очень, взялся сам писать, получилось очень даже прикольно. Исходные мысли:

1. Подключаем к "малоценным" пинам.

2. Работаем через прерывания.

3. Защита от дребезга логическая, не по времени. Чтоб исключить проблемы при быстром вращении.

Можите объяснить в чем логика работы кода?

насколько я понял вся магия происходит тут

  byte tmp=ENCODER_INPUT_PORT;  //текущее состояние порта
022   signed char d=-1;
023   word t;
024  
025   if (bit_is_set(PCMSK0, ENCODER_INPUT_PIN2)) //разрешено было прерватся по ENCODER_INPUT_PIN2
026   {
027       ENCODER_INTERRUPT_PIN1
028       
029       //уровень пина, прерывание которого будем ожидать
030       tmp=tmp & _BV(ENCODER_INPUT_PIN1)?1:0;
031  
032   }
033   else
034   {
035       ENCODER_INTERRUPT_PIN2
036  
037       //уровень пина, прерывание которого будем ожидать
038       tmp=tmp & _BV(ENCODER_INPUT_PIN2)?1:0;
039  
040       Flags^=1;
041   }

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Логик слово малоценным закавычил не напрасно )))

чуток добавил к коду DIMAX
 

// https://tsibrov.blogspot.com/2019/06/arduino-interrupts-part2.html
// PCINT0 (D8...D13) пины PCINT0...PCINT5 (PCMSK0,PINB PB0...PB5)
// PCINT1 (A0...A5) пины PCINT8...PCINT13 (PCMSK1,PINC PC0...PC6)
// PCINT2 (D0...D7) пины PCINT16...PCINT23 (PCMSK2,PIND PD0...PD7)

//Энкодер на пинах D8, D9. Используется внутренняя подтяжка.
//Энкодер на пинах А0, А1. Используется внутренняя подтяжка.
//Энкодер на пинах D2, D3. Используется внутренняя подтяжка.

volatile int enc;
volatile uint8_t state;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  /*
    pinMode(8,INPUT_PULLUP);
    pinMode(9,INPUT_PULLUP);
    PCIFR=PCIFR; PCICR=1<<PCIE0; //разрешить прерывание
    PCMSK0=1<<PCINT0 | 1<<PCINT1; //выбрать вход на котором сработает прерывание

    pinMode(A0,INPUT_PULLUP);
    pinMode(A1,INPUT_PULLUP);
    PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
    PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание
  */
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  PCIFR = PCIFR; PCICR = 1 << PCIE2; //разрешить прерывание
  PCMSK2 = 1 << PCINT18 | 1 << PCINT19; //выбрать вход на котором сработает прерывание
}

//ISR(PCINT0_vect){
//ISR(PCINT1_vect){
ISR(PCINT2_vect) {
  static char EncPrev = 0;    //предыдущее состояние энкодера
  static char EncPrevPrev = 0; //пред-предыдущее состояние энкодера

  char EncCur = 0;
  //  if (!(PINB & (1 << PB0))) {
  //  if (!(PINC & (1 << PC0))) {
  if (!(PIND & (1 << PD2))) { //D2
    EncCur  = 1; //опрос фазы 1 энкодера
  }
  //  if (!(PINB & (1 << PB1))) {
  //  if (!(PINC & (1 << PC1))) {
  if (!(PIND & (1 << PD3))) { //D3
    EncCur |= 2; //опрос фазы 2 энкодера
  }
  if (EncCur != EncPrev)            //если состояние изменилось,
  {
    state = !state;
    if (EncPrev == 3 &&       //если предыдущее состояние 3
        EncCur != EncPrevPrev )      //и текущее и пред-предыдущее не равны,
    {
      if (EncCur == 2)         //если текущее состояние 2,
        enc++;            //шаг вверх
      else                          //иначе
        enc--;            //шаг вниз
    }
    EncPrevPrev = EncPrev;          //сохранение пред-предыдущего состояния
    EncPrev = EncCur;               //сохранение предыдущего состояния
  }
}



void loop() {
  Serial.println(enc);
  digitalWrite(LED_BUILTIN, state);
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em, я этот алгоритм с радиокота взял,  автор как я понял Леонид Иваныч https://radiokot.ru/forum/viewtopic.php?p=1352349#p1352349  

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

dimax пишет:

ua6em, я этот алгоритм с радиокота взял,  автор как я понял Леонид Иваныч https://radiokot.ru/forum/viewtopic.php?p=1352349#p1352349  

да, я видел, уже поправляться не буду, надеюсь Леонид Иванович не обидится...