Замена кнопок энкодером
- Войдите на сайт для отправки комментариев
Втр, 20/06/2017 - 21:31
Прошу помощи. Для одного своего проекта мне понадобилось переписать в готовом коде управление энкодером вместо кнопок. Пины с прерыванием заняты и я пользуюсь библиотекой 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) {
действие
}
}
В коде выше энкодер работает по принципу повернул в одну сторону - расценивается как кнопка нажата, повернул обратно - кнопка отпущена.
Подскажите как второй вариант кода переписать чтобы он работал по принципу первого варианта кода. Сам я только учусь и к сожалению не могу додуматься как сделать.
считать импульсы с энкодера и выводить в сериал научились?
Блин кнопкодавы. От кнопок надо ловить момент когда кнопки нажимается , а не нажата. У энкодера надо ловить повороты. В одну сторону это отработала кнопка + в другую -.
if(newPosition > oldPosition) return UP; if(newPosition < oldPosition) return DOWN;то есть проще говоря return UP и return DOWN заменить на действие
так тс хочет четыре кнопки на энкодер заменить
if(newPosition > oldPosition) return UP; if(newPosition < oldPosition) return DOWN;то есть проще говоря return UP и return DOWN заменить на действие
if (UP) {действие1;} if (DOWN) {действие2;}так тс хочет четыре кнопки на энкодер заменить
и, шо?
так тс хочет четыре кнопки на энкодер заменить
взять энкодер с кнопкой, на короткое нажатие прлипить ок, на длительное отмена - не составит труда...
В исходном коде устройство управляется кнопками, я же хочу заменить управление на энкодер. Мне нужно чтобы движение энкодера в одну сторону заменяло кнопку UP, а в другую сторону кнопку DOWN. return UP и return DOWN не нужно менять на действие, т.к. в другой части кода уже имеется действие:
unsigned char key = enc_pos(); if (key == UP){ действие } if(key == DOWN) { действие }Мне просто нужно чтобы поворот энкодера в одну сторону не означал вечное нажатие на кнопку.
Мне просто нужно чтобы поворот энкодера в одну сторону не означал вечное нажатие на кнопку.
так, не крути энкодер - прежнее значение энкодера будет равно настоящему
А управлять тогда как? ))) Просто чтобы управлять в нынешнем виде приходится энкодер крутить один щелчёк в одну сторону - один в другую, что в итоге соответствуе нажатию и отпусканию кнопки. А хотелось бы чтобы поворот в один щелчок был равен нажатию и одновременно отпусканию кнопки. Вот к примеру как в этом коде:
#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(); } }#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); }Мне просто нужно чтобы поворот энкодера в одну сторону не означал вечное нажатие на кнопку.
if (newPosition != oldPosition) { if(newPosition > oldPosition) return UP; if(newPosition < oldPosition) return DOWN; } oldPosition = newPosition;в коде из твоего первого сообщения никогда не выполняется последняя строка
и в дальнейшем две пременных будут оставаться не равны друг другу до тех пор, пока ты обратным действием не уровняешь их сам, поэтому вечное нажатие.... Из-за этого не рекомендуют Выход из функции return, дабы не возникало подобных вечных нажатий и т.п., но если этим пренебречь, то можно сделать так
if (newPosition != oldPosition) { if(newPosition > oldPosition) oldPosition = newPosition; return UP; if(newPosition < oldPosition) oldPosition = newPosition; return DOWN; }DIVGENY, в Вашем коде тоже никогда не выполняется последняя строка.
if (newPosition != oldPosition) { oldPosition = newPosition; if(newPosition > oldPosition) return UP; else return DOWN; }уж лучше так, штоли...
if (newPosition != oldPosition) { oldPosition = newPosition; if(newPosition > oldPosition) return UP; else return DOWN; }уж лучше так, штоли...
сначала сделать их равными а потом сравнить?
Клапауций всё расписал, нафига дальше изголяться))))
#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) { действие } }упс... чота я сёдня идиота кусок. нада меньше пить....
оптимизировал #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; } }Большое всем спасибо за помощь! Но что-то не выходит ничего путного, может в этом моя вина.
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; } }упс
if ((key == btnUP) || (enc == 1))
исправил выше
Всем спасибо! Мне удалось всё таки приручить энкодер. Теперь устройство работает с энкодером как положено. Ещё раз всем огромное спасибо!!!
Шоб точнее было, надо энкодер шаговым мотором крутить.
Всем спасибо! Мне удалось всё таки приручить энкодер. Теперь устройство работает с энкодером как положено. Ещё раз всем огромное спасибо!!!
так поделитесь с народом))))
Привет
у вас осталос решение даной темы
если ест выложите полажуста
Привет
у вас осталос решение даной темы
если ест выложите полажуста
Юный техник здесь давно не появлялся.
Юный техник здесь давно не появлялся.
Видимо, в управление газовым котлом установил