Одиночное и длительное нажатие энкодера
- Войдите на сайт для отправки комментариев
Втр, 29/10/2013 - 02:43
Всем привет. Подключаю оптический энкодер с нажатием и никак не могу решить одну задачку.
Мне нужно реализовать одиночное нажатие и длительное нажатие кнопки через 5 секунд.
Из примеров собрал скетч, который работает, но не совсем так, как нужно. Я сделал, чтобы одиночное нажатие выполнялось только после отпускания кнопки, чтобы при длительном удержании не получилось одиночного срабатывания.
Если удерживать нажатой кнопку больше 5-ти секунд, тогда срабатывает длительное нажатие, но после отпускания кнопки ещё раз выполняется одиночное.
Так вот, впорос... Как мне убрать последнее одиночное повторение?
Спасибо.
int val=0; int flag=0; long previousMillis = 0; #define encoder0PinC 4 void setup() { pinMode(13, OUTPUT); //Светодиод pinMode(encoder0PinC, INPUT); // нажатие энкодера digitalWrite(encoder0PinC, HIGH); // подключить подтягивающий резистор Serial.begin(115200); } void loop() { // Нажатие кнопки энкодера if(digitalRead(encoder0PinC)==LOW&&flag==0) //если кнопка нажата ... { flag=1; } if(digitalRead(encoder0PinC)==HIGH&&flag==1)//если кнопка НЕ нажата { digitalWrite(13,!digitalRead(13)); delay(500); digitalWrite(13,LOW);//выключаем flag=0;//обнуляем переменную flag } // End // Нажатие кнопки энкодера // Удержание кнопки энкодера if(digitalRead(encoder0PinC)==LOW) //если кнопка нажата ... { if (millis() -previousMillis >500) { previousMillis = millis(); val++; } } else { val=0; } if(val>=5) { digitalWrite(13,!digitalRead(13));//инвертируем состояние пина delay(500); digitalWrite(13,LOW);//выключаем val=0; } // End // Удержание кнопки энкодера }
поищите на форуме темку про реализацию меню однокнопочного
http://jmsarduino.blogspot.com/2009/05/click-for-press-and-hold-for-b.html
http://jmsarduino.blogspot.com/2009/05/click-for-press-and-hold-for-b.html
Спасибо за ссылку - очень помогло.
А результаты есть? А то по ссылке сейчас код как-то криво работает..
можете попробовать так:
пример использования, ссылки на библиотеки. Здесьhttp://forum.amperka.ru/threads/%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D1%8B%D0%B9-%D0%B7%D0%B0%D0%BC%D0%BE%D0%BA.4758/#post-37763
Если подключаете со стягивающим резюком, или используется оптопара, то можно сделать так
Привет! Спасибо большое за код!
Подскажи, пожалуйста, что может быть не так:
у меня кнопка работает "наоборот", тоесть на размыкание а не на замыкание...
хотя я сделал подтяжку к нулю кнопки..
Спасибо!
Может у меня на Uno какая-то стандартная подтяжка к плюсу... хз
Класс DI предполагает, что кнопка подключена с использованием встроенного подтягивающего резистора (режим INPUT_PULLUP). Т.е. при замыкании на ходе 0, при размыкании 1. Не хочу использовать лишние провода и элементы. Ссылка на то, как должна быть подключена кнопка дана посте. Метод .DI_Refresh() нормализуе сигнал INPUT_PULLUP, т.е. при нажатии будет 1, при отпускании 0.
Если, все-таки хитите со стягивающим резюком с подтяжкой к нулю, то второй предложенный код, все-таки не работает.
но работает этот, проверено:
разница с первым только в pinMode(Button, INPUT); в сетапе.
первым только в pinMode(Button, INPUT); в сетапе.
Спасибо большое! Пошел пробовать!
+ тебе в карму.
Мне нужен обратный сценарий. При любой длительности нужно, чтобы кнопка отрабатывала как одиночное нажатие. Кнопка на сенсорном дисплее и она при сработке несколько раз меняет нужный параметр, а нужно один раз менять. Буду благодарен хотя бы за вектор, куда копать.
Это у вас дребезг и лечится он задержкой.
Мне нужен обратный сценарий. При любой длительности нужно, чтобы кнопка отрабатывала как одиночное нажатие. Кнопка на сенсорном дисплее и она при сработке несколько раз меняет нужный параметр, а нужно один раз менять. Буду благодарен хотя бы за вектор, куда копать.
Нужно отслеживать не состояние кнопки, а изменение состояния с не нажатого на нажатое. И только в момент изменения состояния менять нужный параметр
Гдето так.
X - состояние кнопки. Вызываем при нажатии. Полученное значение плюсуем к необходимой переменной.
Вроде не накосячил в коде, но перепроверте.
Мда... Это специально выбраны переменные x и у? У меня и так условие сработки тача будет
if
(x == 1 & y == 0)
и потом
if (lastBt == HIGH){
// изменяем нужный параметр
}
Но параметр проматывается до конца ((
Мне кажется, что нужно отслеживать состояние из нажатого в ненажатое и только тогда менять параметр.
Мне кажется, что нужно отслеживать состояние из нажатого в ненажатое и только тогда менять параметр.
Для кого это я писал?
Мне нужен обратный сценарий. При любой длительности нужно, чтобы кнопка отрабатывала как одиночное нажатие. Кнопка на сенсорном дисплее и она при сработке несколько раз меняет нужный параметр, а нужно один раз менять. Буду благодарен хотя бы за вектор, куда копать.
Нужно отслеживать не состояние кнопки, а изменение состояния с не нажатого на нажатое. И только в момент изменения состояния менять нужный параметр
Я написал про другое изменение состояния. Возможно это и не важно, но к сожалению я не стал ближе к пониманию, как решить проблему.
У кнопки только два состояния - нажатое и не нажатое. Про какое другое состояние можно вести речь?
но к сожалению я не стал ближе к пониманию, как решить проблему.
Вот, собственно, непонимание этого и ведет к отсутствию понимания в целом ))
Вот только дурачка не нужно из меня делать. Я написал дословно "Я написал про другое изменение состояния", а не про другое состояние. Речь про передний и задний фронты сигнала. Так понятнее?
Для начала научись изъясняться внятно. Это во-первых. Во-вторых, не имеет значение какой фронт. Нужно учитывать любое изменение состояния. Изменение с не нажатой на нажатую - для отработки чего там у тебя задумано, изменение с нажатой на не нажатую - чтобы сработало при следующем нажатии. А у тебя в #14 хрень какая-то написана
Каждые 100 или 200 милис опрашиваем состояние кнопки. Так избавляемся от дребезга.
В подпрограмме кнопка переменная Y является внутренней и на глобальные переменные НЕ влияет.
Икс замените на "in" например. Это тоже внутренняя переменная.
У него нет дребезга. У него кнопка - это прямоугольник на сенсорном экране
У него нет дребезга. У него кнопка - это прямоугольник на сенсорном экране
Эту вспышку я пропустил.
Без полного кода всё равно непонятно чего надобно.
if
(x == 1 & y == 0)
и потом
if (lastBt == HIGH){
// изменяем нужный параметр
}
Но параметр проматывается до конца ((
Мне кажется, что нужно отслеживать состояние из нажатого в ненажатое и только тогда менять параметр.
Параметр нужно изменять В МОМЕНТ смены состояния кнопки, а не потом.
Выделил, где это должно делаться
Между 10 и 11 ещё одну скобку. На 17 убрать?
Или 11 сместить после 16?
Код поправлен, все скобки на месте
11 перекинуть на 16. Иначе логика теряется. Элсе идёт к игреку!
Да там вообще оба условия нужно объединить
И элсе идёт к первому ифу:(
Туда и должно. Если клик идет в пределах прямоугольника, то кнопка нажата, иначе отжата
Гдето так.
это что за бред?
весь код один сплошной косяк.
vrd - судя по вашему коду и замечаниям, языка вы не знаете, так что лучше не лезьте с советами, v258 отлично без вас справится
vrd - судя по вашему коду и замечаниям, языка вы не знаете, так что лучше не лезьте с советами, v258 отлично без вас справится
Да пофиг. Если мои действия заставят новичков глубже лезть в языки програмирования, я буду даже рад. Пусть ищут у меня ошибки. Это лучше бездумного копирования.
Нет, ваши действия вызывают недоумение, нафига вы полезли помогать, если сами ничего не знаете. и только не надо рассказывать. что ошибки в код насажены специально, чтобы стимулировать творчество новичков :)))
нафига вы полезли помогать, если сами ничего не знаете.
Так это ж основная фишка форума.
Кто знает - не помогает, помогает кто не знает )))
Так это ж основная фишка форума.
Кто знает - не помогает, помогает кто не знает )))
:-)
Итить, переитить! Так и есть.
Кто может, не видит смысла, а кто не может - имеет только смысл.
:-)
Итить, переитить! Так и есть.
Кто может, не видит смысла, а кто не может - имеет только смысл.
как назвать человека который может но не хочет... сволочь ))) (из анекдота)
Никак не могу победить одиночное нажатие на кнопке сенсорного дисплея. Немного опишу, что должно происходить при нажатии.
Есть 4 экрана (меню), которые отличаются только наличием доп записей, основные данные в т.ч. кнопка листания присутствуют на всех меню. И находится эта кнопка в одном месте на всех четырёх экранах (меню).
Нажатие кнопки должно отработать menu++; но при этом долгое нажатие продолжает отрабатывать переход в следующее меню, а должно было остановиться.
Поскольку переход между меню осуществляется не только по нажатию кнопки, но и по условиям датчиков, поэтому я создал флаг перехода и условие перехода добавил в "или" (данные с датчиков или флаг кнопки). Пробовал и без флага menu++;
Каждый этап я расписал через Switch/Case, там отрабатываются другие задачи, а нажатие этой кнопки в общем цикле
Видимо проблема одинакового расположения кнопки во всех 4-х меню (экранах) и бороться нужно, как с дребезгом
Возможно нужно возвращать flag7 или currBt в LOW в начале каждого case?
Какие ещё будут мысли? Заранее благодарен за подсказки
Кусок кода по нажатию кнопки