Замена кнопок энкодером

Юный техник
Offline
Зарегистрирован: 20.06.2017

Прошу помощи. Для одного своего проекта мне понадобилось переписать в готовом коде управление энкодером вместо кнопок. Пины с прерыванием заняты и я пользуюсь библиотекой Encoder без использования прерываний.

Вот пример того как бы я хотел чтобы работал энкодер:

#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
#include <Wire.h> 

Encoder myEnc(5, 6);

void setup() {
}

void loop() {
  long oldPosition = 0;
  long newPosition = myEnc.read(); 
  if (newPosition != oldPosition) {
    if(newPosition > oldPosition) { 
    действие
   }
    if(newPosition < oldPosition) {  
    действие
   }
    oldPosition = newPosition;
   }
 }

В коде выше энкодер работает точно как кнопка.

В изменяемом мною коде структура управления энкодером (по аналогии с кнопками) следующая:

#define ENCODER_DO_NOT_USE_INTERRUPTS

#include <Encoder.h>
#include <Wire.h> 

Encoder myEnc(5, 6);

#define UP     1
#define DOWN   2
#define OK     3
#define NON    4

void setup() {
 }


unsigned char enc_pos() {
  long oldPosition = 0;
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    if(newPosition > oldPosition) return UP;
    if(newPosition < oldPosition) return DOWN;
    }
    oldPosition = newPosition;
}

void loop() {
    unsigned char key = enc_pos();
    if (key == UP){
    действие
    }
    if(key == DOWN) {  
    действие
    }
  }

В коде выше энкодер работает по принципу повернул в одну сторону - расценивается как кнопка нажата, повернул обратно - кнопка отпущена.

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

vvadim
Offline
Зарегистрирован: 23.05.2012

считать импульсы с энкодера и выводить в сериал научились?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Блин кнопкодавы. От кнопок надо ловить момент когда кнопки нажимается , а не нажата. У энкодера надо ловить повороты. В одну сторону это отработала кнопка + в другую -.

DIVGENY
Offline
Зарегистрирован: 23.08.2016
    if(newPosition > oldPosition) return UP;
    if(newPosition < oldPosition) return DOWN;

то есть проще говоря  return UP и  return DOWN заменить на действие

vvadim
Offline
Зарегистрирован: 23.05.2012

так тс хочет четыре кнопки на энкодер заменить

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

DIVGENY пишет:

    if(newPosition > oldPosition) return UP;
    if(newPosition < oldPosition) return DOWN;

то есть проще говоря  return UP и  return DOWN заменить на действие

if (UP)   {действие1;}
if (DOWN) {действие2;}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

vvadim пишет:

так тс хочет четыре кнопки на энкодер заменить

и, шо?

DIVGENY
Offline
Зарегистрирован: 23.08.2016

vvadim пишет:

так тс хочет четыре кнопки на энкодер заменить

взять энкодер с кнопкой, на короткое нажатие прлипить ок, на длительное отмена - не составит труда...

Юный техник
Offline
Зарегистрирован: 20.06.2017

В исходном коде устройство управляется кнопками, я же хочу заменить управление на энкодер. Мне нужно чтобы движение энкодера в одну сторону заменяло кнопку UP, а в другую сторону кнопку DOWN.  return UP и  return DOWN не нужно менять на действие, т.к. в другой части кода уже имеется действие:

unsigned char key = enc_pos();
    if (key == UP){
    действие
    }
    if(key == DOWN) {  
    действие
    }

Мне просто нужно чтобы поворот энкодера в одну сторону не означал вечное нажатие на кнопку.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Юный техник пишет:

Мне просто нужно чтобы поворот энкодера в одну сторону не означал вечное нажатие на кнопку.

так, не крути энкодер - прежнее значение энкодера будет равно настоящему

Юный техник
Offline
Зарегистрирован: 20.06.2017

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

#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);

Encoder myEnc(5, 6);

long oldPosition = 0;

void setup() {
  lcd.init();                     
  lcd.backlight();
}

void loop() {
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    if(newPosition > oldPosition) { 
    lcd.clear();
    lcd.setCursor(0, 1); 
    lcd.print("right");
    delay (1000);
    lcd.clear();
    }
    if(newPosition < oldPosition) {  
    lcd.clear();
    lcd.setCursor(0, 1); 
    lcd.print("left");
    delay (1000);
    lcd.clear();
    }
    oldPosition = newPosition;
    //Serial.println(newPosition);
    }

    if (!digitalRead(7) == HIGH) { 
   
    lcd.clear();
    lcd.setCursor(0, 1); 
    lcd.print("button");
    delay (1000);
    lcd.clear();
    }
  }

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017
#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);

Encoder myEnc(5, 6);

long    oldPosition  = 0;
boolean state_button = 0;

void setup() {
lcd.init();
lcd.backlight();
}

void loop() {

boolean event_click = 0;

long newPosition = myEnc.read();
if (newPosition != oldPosition) {
if(newPosition > oldPosition) {state_button = 1;}
if(newPosition < oldPosition) {state_button = 0;}
event_click = 1;
oldPosition = newPosition;
}

if( state_button && event_click) {действие1;}
if(!state_button && event_click) {действие2;}

lcd.setCursor(0, 1); 
lcd.print(state_button);

}

 

DIVGENY
Offline
Зарегистрирован: 23.08.2016
 

Юный техник пишет:

Мне просто нужно чтобы поворот энкодера в одну сторону не означал вечное нажатие на кнопку.

 if (newPosition != oldPosition) {
    if(newPosition > oldPosition) return UP;
    if(newPosition < oldPosition) return DOWN;
    }
    oldPosition = newPosition;

в коде из твоего первого сообщения никогда не выполняется последняя строка

oldPosition = newPosition;

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

  if (newPosition != oldPosition) {
    if(newPosition > oldPosition) oldPosition = newPosition; return UP;
    if(newPosition < oldPosition) oldPosition = newPosition; return DOWN;
    }

 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DIVGENY, в Вашем коде тоже никогда не выполняется последняя строка.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
if (newPosition != oldPosition) 
{
  oldPosition = newPosition;
  if(newPosition > oldPosition)  return UP; else return DOWN;
}

уж лучше так, штоли...

 

 

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016

DetSimen пишет:

if (newPosition != oldPosition) 
{
  oldPosition = newPosition;
  if(newPosition > oldPosition)  return UP; else return DOWN;
}

уж лучше так, штоли...

сначала сделать их равными а потом сравнить?

vvadim
Offline
Зарегистрирован: 23.05.2012

Клапауций всё расписал, нафига дальше изголяться))))

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016
#define ENCODER_DO_NOT_USE_INTERRUPTS

#include <Encoder.h>
#include <Wire.h> 

Encoder myEnc(5, 6);

#define UP     1
#define DOWN   2
#define OK     3
#define NON    4

void setup() {
 }


unsigned char enc_pos() {
  long oldPosition = 0;
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
    if(newPosition > oldPosition) {
      oldPosition = newPosition;
      return UP;
    }
    if(newPosition < oldPosition) {
      oldPosition = newPosition;
      return DOWN;
    }
    }
    return 0;
}

void loop() {
    unsigned char key = enc_pos();
    if (key == UP){
    действие
    }
    if(key == DOWN) {  
    действие
    }
  }

 

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

упс...  чота я сёдня идиота кусок.   нада меньше пить....

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

оптимизировал #11

#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);

Encoder myEnc(5, 6);

long oldPosition  = 0;

void setup() {
lcd.init();
lcd.backlight();
}

void loop() {

lcd.setCursor(0, 1);
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
if(newPosition > oldPosition) {lcd.print("действие1");}
if(newPosition < oldPosition) {lcd.print("действие2");}
oldPosition = newPosition;
}

}

 

Юный техник
Offline
Зарегистрирован: 20.06.2017

Большое всем спасибо за помощь! Но что-то не выходит ничего путного, может в этом моя вина.

 

 

DIVGENY
Offline
Зарегистрирован: 23.08.2016

andriano пишет:

DIVGENY, в Вашем коде тоже никогда не выполняется последняя строка.

а разве она там нужна..???

Юный техник пишет:

Эти фрагменты находятся в разных файлах. Может я неправильно имел ввиду что от энкодера нужно одновременное нажатие-отпускание

|| (логическое ИЛИ)

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

 

 if ((key == btnUP) || (enc == 1)) {  то же действие, что и при нажатии кнопки }
 if ((key == btnDOWN || (enc == 2)) { то же действие, что и при нажатии кнопки} // нажата кнопка или работал энкодер

действием может быть переменая

int enc = 0; //инициализируем в начале скетча

cработал вперед   -

enc = 1;

назад

enc = 2;

но после выполнения действия при входе в функцию обработки энкодера необходимо эту переменую заново обнулить

enc = 0;

#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
#include <Wire.h> 

Encoder myEnc(5, 6);
int enc = 0; // глобальная переменная, видима в любой функции скетча

void setup() {
}

void enc() // называем функцию своим именем и вставляем этот кусок кода между другими фунциями
{
 enc = 0; // обнуляем переменую

  long oldPosition = 0;
  long newPosition = myEnc.read(); 
  if (newPosition != oldPosition) {
    if(newPosition > oldPosition) { 
    enc = 1;
   }
    if(newPosition < oldPosition) {  
    enc = 2;
   }
    oldPosition = newPosition;
   }
 }

 

 

DIVGENY
Offline
Зарегистрирован: 23.08.2016

упс

if ((key == btnUP) || (enc == 1))

исправил выше

Юный техник
Offline
Зарегистрирован: 20.06.2017

Всем спасибо! Мне удалось всё таки приручить энкодер. Теперь устройство работает с энкодером как положено. Ещё раз всем огромное спасибо!!!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Шоб точнее было, надо энкодер шаговым мотором крутить.

vvadim
Offline
Зарегистрирован: 23.05.2012

Юный техник пишет:

Всем спасибо! Мне удалось всё таки приручить энкодер. Теперь устройство работает с энкодером как положено. Ещё раз всем огромное спасибо!!!

так поделитесь с народом))))

ded.izya.dnepr
Offline
Зарегистрирован: 03.12.2019

Привет
у вас осталос решение даной темы
если ест выложите полажуста

vvadim
Offline
Зарегистрирован: 23.05.2012

ded.izya.dnepr пишет:

Привет
у вас осталос решение даной темы
если ест выложите полажуста

Юный техник здесь давно не появлялся.

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

vvadim пишет:

Юный техник здесь давно не появлялся.

Видимо, в управление газовым котлом установил