Энкодер на EC11

Rankle
Offline
Зарегистрирован: 31.10.2020

Добрый день

https://img.banggood.com/images/oaupload/banggood/images/40/F0/f2c402a7-...

Подскажите пожалуйста зачем в данном энкодере вывод С замкнут на GND?

Как обрабатывать прерывания от нажатия кнопки?

 

 

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

Если замкнут, то никак.

А почему трава зелёная - есть предположения?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

sadman41 пишет:
Если замкнут, то никак. А почему трава зелёная

Счас точно спою - "зеленая, зеленая трава...."

Rankle
Offline
Зарегистрирован: 31.10.2020

?

Гриша
Offline
Зарегистрирован: 27.04.2014

Rankle пишет:
https://img.banggood.com/images/oaupload/banggood/images/40/F0/f2c402a7-c3f3-4e23-a24f-98f07d72cfd0.JPG

Подскажите пожалуйста зачем в данном энкодере вывод С замкнут на GND?

Вам мягко намекают, что без схемы разговора не будет, а картинка - она красивая и трава зеленая. Хотя и не лишняя, но без схемы - говорить будем о траве.  

Rankle
Offline
Зарегистрирован: 31.10.2020

Ок. Понятно.

Нашел вот такую информацию.

http://codius.ru/articles/%D0%98%D0%BD%D0%BA%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D1%8D%D0%BD%D0%BA%D0%BE%D0%B4%D0%B5%D1%80_%D0%BF%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D1%8F_%D1%81%D1%85%D0%B5%D0%BC%D1%8B_%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_%D1%81_Arduino

 

Взял оттуда вот такой пример (один в один):

int pinA      = 2; //Пин прерывания сигнальной линии
int pinButton = 3; //Пин прерывания нажатия кнопки
int pinB      = 7; //Любой другой пин
 
long timeButtonPressed = 1500;  // Долгое удержание кнопки после 1,5 секунд
 
volatile int state = 0;         // Переменная хранящая статус вращения
 
// Переменные хранящие состояние действия до его выполнения
volatile bool flagCW            = false;     // Было ли вращение по часовой стрелке
volatile bool flagCCW           = false;     // Было ли вращение против часовой стрелки
volatile bool flagButton        = false;     // Было ли нажатие кнопки
volatile bool flagButtonLong    = false;     // Было ли долгое удержание кнопки
 
volatile long timeButtonDown    = 0;         // Переменная хранящая время нажатия кнопки
volatile bool isButtonDown      = false;     // Переменная хранящая время нажатия кнопки
volatile bool longPressReleased = false;     // Переменная для фиксации срабатывания долгого нажатия
 
void setup()
{
  pinMode(pinA, INPUT);           // Пины в режим приема INPUT
  pinMode(pinB, INPUT);           // Пины в режим приема INPUT
  pinMode(pinButton, INPUT);      // Пины в режим приема INPUT
 
  attachInterrupt(0, A, CHANGE);        // Настраиваем обработчик прерываний по изменению сигнала на линии A
  attachInterrupt(1, Button, CHANGE);   // Настраиваем обработчик прерываний по изменению сигнала нажатия кнопки
 
  Serial.begin(9600);             // Включаем Serial
}
 
 
void loop()
{
  if (millis() - timeButtonDown > timeButtonPressed && isButtonDown) { // Время длительного удержания наступило
    flagButtonLong = true;
  }
 
  if (flagCW) {                           // Шаг вращения по часовой стрелке
    // ...
    Serial.println("turn_right");
    flagCW = false;                       // Действие обработано - сбрасываем флаг
  }
  if (flagCCW) {                          // Шаг вращения против часовой стрелки
    // ...
    Serial.println("turn_left");
    flagCCW = false;                      // Действие обработано - сбрасываем флаг
  }
  if (flagButton) {                       // Кнопка нажата
    // ...
    Serial.println("short_press");
    flagButton = false;                   // Действие обработано - сбрасываем флаг
  }
  if (flagButtonLong && isButtonDown) {   // Кнопка удерживается
    if (!digitalRead(pinButton) && millis() - timeButtonDown > timeButtonPressed) { // Защита от ложного срабатывания
      // ...
      Serial.println("long_press");
    }
    
    //=========================================== Настраиваем реакцию на долгое удержание кнопки ===============================================
    // Чтобы событие long_press во время удержания срботало только один раз, необходимо раскомментировать блок и закомментировать следующий
    //isButtonDown = false;                 // Программно "отжимаем" кнопку
 
    // Эти две строки отвечают за то, чтобы при долгом удержании кнопки, событие long_press повторялось каждые 1,5 секунды
    // Для того, чтобы изменить это поведение нужно закомментировать две эти строки и раскомментировать строку из предыдущего блока
    timeButtonDown = millis();            // Сбрасываем таймер
    longPressReleased = true;             // Флаг срабатывания долгого удержания, чтобы отсечь генерацию обычного нажатия при отпускании кнопки
    //==========================================================================================================================================
 
    flagButtonLong = false;               // Действие обработано - сбрасываем флаг
  }
}
 
void A()
{
  int pinAValue = digitalRead(pinA);        // Получаем состояние пинов A и B
  int pinBValue = digitalRead(pinB);
 
  cli();                                    // Запрещаем обработку прерываний, чтобы не отвлекаться
  if (!pinAValue &&  pinBValue) state = 1;  // Если при спаде линии А на линии B лог. единица, то вращение в одну сторону
  if (!pinAValue && !pinBValue) state = -1; // Если при спаде линии А на линии B лог. ноль, то вращение в другую сторону
  if (pinAValue && state != 0) {
    if (state == 1 && !pinBValue || state == -1 && pinBValue) { // Если на линии А снова единица, фиксируем шаг
      if (state == 1)   flagCW = true;      // Флаг вращения по часовой стрелке
      if (state == -1) flagCCW = true;      // Флаг вращения против часовой стрелки
      state = 0;
    }
  }
  sei();                                    // Разрешаем обработку прерываний
}
 
void Button()
{
  if (millis() - timeButtonDown < 50) return;
  int pinButValue = digitalRead(pinButton);   // Получаем состояние пина кнопки
 
  cli();                                      // Запрещаем обработку прерываний, чтобы не отвлекаться
  timeButtonDown = millis();                  // Запоминаем время нажатия/отжатия
 
  if (!pinButValue) {                         // При нажатии подается инвертированный сигнал
    isButtonDown = true;                      // Устанавливаем флаг нажатия кнопки
  }
  else if (isButtonDown) {                    // Если кнопка отжата, смотрим не было ли выполнено действие
    if (!longPressReleased) {                 // Если долгое нажатие не было ни разу отработано, то...
      flagButton = true;                      // Если не было удержания, ставим флаг события обычного нажатия
    }
    isButtonDown = false;                     // Сбрасываем флаг нажатия
    longPressReleased = false;                // Сбрасываем флаг длительного удержания
  }
  sei();                                      // Разрешаем обработку прерываний
}

 

**************

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

пин A - D2

пин С - D3

пин B - D7

Работает поворот влево и вправо, а кнопка не работает (ни короткое нажатие ни длинное нажатие).

Посмотрел внимательно на это чудо китайского ...прома и вижу что пин С напрямую соединён с GND.

Вопрос: это такое "странное устройство" мне "удалось" купить,  что оно не приспособлено обрабатывать нажатие кнопки, а работает только вправо-влево, или я что то не так делаю?

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

Rankle, прежде чем писать в форум, стоило почитать правила. Вставьте код как положено.

Чтобы получить ответ по сути - так же необходимо предоставить схему вашего устройства

Rankle
Offline
Зарегистрирован: 31.10.2020
int pinA      = 2; //Пин прерывания сигнальной линии
int pinButton = 3; //Пин прерывания нажатия кнопки
int pinB      = 7; //Любой другой пин

long timeButtonPressed = 1500;  // Долгое удержание кнопки после 1,5 секунд

volatile int state = 0;         // Переменная хранящая статус вращения

// Переменные хранящие состояние действия до его выполнения
volatile bool flagCW            = false;     // Было ли вращение по часовой стрелке
volatile bool flagCCW           = false;     // Было ли вращение против часовой стрелки
volatile bool flagButton        = false;     // Было ли нажатие кнопки
volatile bool flagButtonLong    = false;     // Было ли долгое удержание кнопки

volatile long timeButtonDown    = 0;         // Переменная хранящая время нажатия кнопки
volatile bool isButtonDown      = false;     // Переменная хранящая время нажатия кнопки
volatile bool longPressReleased = false;     // Переменная для фиксации срабатывания долгого нажатия

void setup()
{
  pinMode(pinA, INPUT);           // Пины в режим приема INPUT
  pinMode(pinB, INPUT);           // Пины в режим приема INPUT
  pinMode(pinButton, INPUT);      // Пины в режим приема INPUT

  attachInterrupt(0, A, CHANGE);        // Настраиваем обработчик прерываний по изменению сигнала на линии A
  attachInterrupt(1, Button, CHANGE);   // Настраиваем обработчик прерываний по изменению сигнала нажатия кнопки

  Serial.begin(9600);             // Включаем Serial
}


void loop()
{
  if (millis() - timeButtonDown > timeButtonPressed && isButtonDown) { // Время длительного удержания наступило
    flagButtonLong = true;
  }

  if (flagCW) {                           // Шаг вращения по часовой стрелке
    // ...
    Serial.println("turn_right");
    flagCW = false;                       // Действие обработано - сбрасываем флаг
  }
  if (flagCCW) {                          // Шаг вращения против часовой стрелки
    // ...
    Serial.println("turn_left");
    flagCCW = false;                      // Действие обработано - сбрасываем флаг
  }
  if (flagButton) {                       // Кнопка нажата
    // ...
    Serial.println("short_press");
    flagButton = false;                   // Действие обработано - сбрасываем флаг
  }
  if (flagButtonLong && isButtonDown) {   // Кнопка удерживается
    if (!digitalRead(pinButton) && millis() - timeButtonDown > timeButtonPressed) { // Защита от ложного срабатывания
      // ...
      Serial.println("long_press");
    }
    
    //=========================================== Настраиваем реакцию на долгое удержание кнопки ===============================================
    // Чтобы событие long_press во время удержания срботало только один раз, необходимо раскомментировать блок и закомментировать следующий
    //isButtonDown = false;                 // Программно "отжимаем" кнопку

    // Эти две строки отвечают за то, чтобы при долгом удержании кнопки, событие long_press повторялось каждые 1,5 секунды
    // Для того, чтобы изменить это поведение нужно закомментировать две эти строки и раскомментировать строку из предыдущего блока
    timeButtonDown = millis();            // Сбрасываем таймер
    longPressReleased = true;             // Флаг срабатывания долгого удержания, чтобы отсечь генерацию обычного нажатия при отпускании кнопки
    //==========================================================================================================================================

    flagButtonLong = false;               // Действие обработано - сбрасываем флаг
  }
}

void A()
{
  int pinAValue = digitalRead(pinA);        // Получаем состояние пинов A и B
  int pinBValue = digitalRead(pinB);

  cli();                                    // Запрещаем обработку прерываний, чтобы не отвлекаться
  if (!pinAValue &&  pinBValue) state = 1;  // Если при спаде линии А на линии B лог. единица, то вращение в одну сторону
  if (!pinAValue && !pinBValue) state = -1; // Если при спаде линии А на линии B лог. ноль, то вращение в другую сторону
  if (pinAValue && state != 0) {
    if (state == 1 && !pinBValue || state == -1 && pinBValue) { // Если на линии А снова единица, фиксируем шаг
      if (state == 1)   flagCW = true;      // Флаг вращения по часовой стрелке
      if (state == -1) flagCCW = true;      // Флаг вращения против часовой стрелки
      state = 0;
    }
  }
  sei();                                    // Разрешаем обработку прерываний
}

void Button()
{
  if (millis() - timeButtonDown < 50) return;
  int pinButValue = digitalRead(pinButton);   // Получаем состояние пина кнопки

  cli();                                      // Запрещаем обработку прерываний, чтобы не отвлекаться
  timeButtonDown = millis();                  // Запоминаем время нажатия/отжатия

  if (!pinButValue) {                         // При нажатии подается инвертированный сигнал
    isButtonDown = true;                      // Устанавливаем флаг нажатия кнопки
  }
  else if (isButtonDown) {                    // Если кнопка отжата, смотрим не было ли выполнено действие
    if (!longPressReleased) {                 // Если долгое нажатие не было ни разу отработано, то...
      flagButton = true;                      // Если не было удержания, ставим флаг события обычного нажатия
    }
    isButtonDown = false;                     // Сбрасываем флаг нажатия
    longPressReleased = false;                // Сбрасываем флаг длительного удержания
  }
  sei();                                      // Разрешаем обработку прерываний
}

 

Rankle
Offline
Зарегистрирован: 31.10.2020

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

Как мне это может помочь, извините?

у меня не сам энкодер, а готовый модуль, который я не пойму как будет работать если из 5 пинов: 2 - питание, 3 и 4 - поворот, а последний всегда замкнут на землю? Я их все и всяко местами поменял. Работают только при таком подключении. И как я уже говорил обрабатывают поворот вправо-влево (безупречно). Нажатие кнопки - никак.

Дайте ПОЖАЛУЙСТА совет по существу (а лучше объяснить на пальцах, как для суперчайников), а не про зелёную траву и рокот космодрома.

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

Это может помочь просто: берешь мультиметр, тыкаешь в плату и ищешь, на какие пины выведены контакты кнопки. Если голова на плечах есть, найдешь где они, по второму чертежу.

Если же головы нет, начинаешь писать продавцу/производителю вопросы - нахера замкнули C на GND.

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

попробуйте сами прозвонить контакты на модуле

Судя по правой части этой схемы

контакты, обозначенные на модуле как VIN GND - вполне могут быть выводами D E энкодера

Отсоедините модуль от питания и ардуины, присоедините щупы мультиметра к VIN и GND на модуле, переведите мультиметр в режим прозвонки линии или в режим измерения сопротивления и попробуйте понажимать на кнопку енкодера. Напишите результат

Green
Offline
Зарегистрирован: 01.10.2015

Или физически смотришь куда идёт С и не коротит ли на общий.

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

Или на Алиэкспрессе читаешь комментарии к модулю и узнаешь много интересного.

Гриша
Offline
Зарегистрирован: 27.04.2014

Rankle пишет:
Дайте ПОЖАЛУЙСТА совет по существу (а лучше объяснить на пальцах, как для суперчайников), а не

Rankle, в посте 9 схема, но она не соответствует картинке 8 (разводке энкодера на плате), хотя по ней уже можно опираться для поиска неисправности. Рисуйте схему вашего модуля и ищите  неисправность. За вас этого никто не сделает - ну или пришлите его мне, могу дать адрес (Новосибирск), мне не трудно будет его прозвонить и сказать - исправен он или нет.  Прозвоню бесплатно - вся пересылка за ваш счет :))))))))

sadman41 пишет:

Или на Алиэкспрессе читаешь комментарии к модулю и узнаешь много интересного.

а как без этого на алике вообще можно-что-то покупать ... там такой мрак частенько 

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

Вроде обычный энкодер, D - E кнопка на моих, марку не помню

SLKH
Offline
Зарегистрирован: 17.08.2015

ua6em пишет:

Вроде обычный энкодер, D - E кнопка на моих, марку не помню

обычный или нет - какая разница?

есть модуль с 5 контактами без активных компонентов; он доступен для разглядывания и тыкания.

ТС категорически не желает прозвонить его и нарисовать схему, но вымогает какие-то "ответы по существу"

DS: безнадежно.

Rankle
Offline
Зарегистрирован: 31.10.2020

да не путайте, пожалуйста, САМ энкодер и модуль собранный на основе этого энкодера. Как раз таки с компонентами.

 

Ладно, всем спасибо. завтра на работе возьму цэшку, буду прозванивать и рисовать. 

Кстати прочитал сейчас все комментарии и где то в самом конце один хороший человек написал что "...не выведены пины кнопки...".

значит не мне одному эта гадость досталась.  Первый раз покупаю полуфабрикат.

Придётся подпаиваться снизу.

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

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

SLKH
Offline
Зарегистрирован: 17.08.2015

Rankle пишет:

да не путайте, пожалуйста, САМ энкодер и модуль собранный на основе этого энкодера. Как раз таки с компонентами.

без активных компонентов.