Немного переделал исходный скетч автора. Теперь есть отрабатывание нажатия кнопки, долгого нажатия, быстрого считывания и неактивности. Быстрое считывание - актуально например для кнопок влево-вправо изменения каких-то значений(например емкости, нужно от 100 дойти до 500, пока прощелкаешь.....): А так нажал кнопку, держишь - и через определенное время (click_fast) начинает очень быстро меняться значение (измеряеться раз в time_fast - например раз в 75мс - чтобы не менялось с реактивной скоростью).
Использую для кнопок ВЛЕВО-ВПРАВО нажатие и быстрое считываение (изменять быстро значения), а для ВВОД-НАЗАД - нажатие и долгое нажатие (для сохранения настроек или выйти в главное меню)
Сам класс (значения временных переменных выставлены очень неплохо, брал на глаз с Skymax RC)
class BUTTON {
public:
//============================================================================================
// константы настроек класса.
static const byte bounce_ = 50; // длительность отслеживания дребезга.
static const unsigned long sleep_ = 10000; // длительность отслеживания неактивности.
static const unsigned int click_long_ = 1000; // длительность отслеживания нажатия и удержания.
static const unsigned int click_fast_ = 500; // длительность нажатия для старта быстрого считывания.
static const unsigned int time_fast_ = 75; // длительность обновления значения быстрого считывания.
//============================================================================================
unsigned long start; // старт отсчёта времени.
unsigned long stop_fast; // стоп отсчёта быстрого считывания
boolean p; // состояние пина кнопки.
boolean s; // программное состояние кнопки.
boolean b; // состояние таймера фильтра дребезга.
boolean t; // состояние таймера неактивности.
boolean r; // состояние таймера нажатия и удержания.
boolean x; // состояние таймера быстрой прокрутки.
boolean flag_long; // флаг состояния длинного нажатия кнопки.
boolean flag_fast; // флаг состояния быстрого считывания кнопки.
//============================================================
boolean click_down; // событие нажатия.
boolean click_long; // событие нажатия и удержания.
boolean click_fast; // событие быстрого считывания.
boolean sleep; // событие неактивности.
//============================================================
byte _pb;
//============================================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//===================
start = millis();
p = digitalRead(_pb);
s = p;
b = 0;
t = 0;
r = 0;
x = 0;
flag_long = 0;
flag_fast = 0;
//==============
click_down = 0;
sleep = 0;
click_long = 0;
click_fast = 0;
//==============
}
void read() {
//==============================================================================
boolean np = digitalRead(_pb); // текущее состояние пина кнопки.
unsigned long stop = millis(); // стоп отсчёта времени.
//==============================================================================
click_down = 0;
sleep = 0;
click_long = 0;
click_fast = 0;
//==============================================================================
if (np != p) {p = np; click(); start = stop; b = 1; t = 1; r = 1; x = 1;} // состояние цифрового пина изменилось.
//==============================================================================
if (b != 0 ) {if (stop - start > bounce_ ) {b = 0; click(); }} // фильтр дребезга.
if (t != 0 && s == 1) {if (stop - start > sleep_ ) {t = 0; sleep = 1;}} // неактивность.
if (r != 0 && s == 0) {if (stop - start > click_long_ ) {r = 0; click_long = 1; flag_long = 1;}} // нажатие и удержание.
if (x != 0 && s == 0) {if (stop - start > click_fast_ ) {x = 0; flag_fast = 1; stop_fast=millis();}} // включение быстрого считывания.
if (flag_fast == 1 ) {if (millis() - stop_fast > time_fast_ ) { stop_fast=millis(); click_fast = 1;} else {click_fast = 0;}} // быстрое считывание.
//==============================================================================
}
void click() { // нажатие, долгое нажатие, быстрое считывание.
if (b == 0 && s != p) {
s = p;
if (s == 1 && flag_long !=1 && flag_fast !=1) {click_down = 1;}
if (s == 1 && flag_long !=0) {click_long = 0; flag_long = 0;} // очистка флагов долгого нажатия.
if (s == 1 && flag_fast !=0) {click_fast = 0; flag_fast = 0;} // очистка флагов быстрого считывания.
}
}
};
И кусочек программы (сам код сверху включает входа, подтягивающие резисторы, кнопки просто на землю)
BUTTON ENTER(14); //A0
BUTTON LEFT(15); //A1
BUTTON RIGHT(16); //A2
BUTTON BACK(17); //A3
void setup()
{
}
void loop() {
ENTER.read();
LEFT.read();
RIGHT.read();
BACK.read();
if (ENTER.click_long) { }
if (LEFT.click_fast) { }
if (RIGHT.click_down) { }
if (BACK.sleep) { }
}
Где-то тут писали что исходник автора после долгого нажатия отрабатывает событие еще и отжатия кнопки. Убрал. И было когда когда нажимаешь и жмешь долго, то сначало событие нажатия, а потом уже событие долгое нажатие. Убрал - сразу идет долгое нажатие.
+ думаю кому надо, можна в самой программе по условию вычислять нажатие двух кнопок одновременно.
neoblack2 поковырял твою библиотеку и сделал вывод, что у Клапауцего 112 библиотека более универсальна. Вот практически все твои изменения реализованы в коде с помощью библиотеки Клапауций 112 с минимумом кода. Кусок из рабочей программы работающего устройства Экструдер.
//-------------------------------------------------------------
void MyButton(void)
{
bt.read();
// оснавная кнопка старт несколько функций
if (bt.button[0].event_click_Dn () && m)(flag == 0)?flag = 1: flag = 0;// Вкл\Выкл. устройства
if (bt.button[0].event_click_Up() == 1) mm = m = true;// Пока не отпустили, второй раз в ЕЕПРОМ не пишим
if (bt.button[0].event_inactivity_Up() == 1){ m = false; flag = 2;}// Если держать 10сек то все запоминаем в ЕЕРОМ
//------------
if(flag > 0){//------------------------------------ Устройство включено ---------------------------------------
if (bt.event_click_Dn () == 1){tbt = millis();fg = true;} //Была нажата кнопка запомнили когда взвели курок
//------------ переходим в режим изменения уставок
if (bt.button[1].event_click_Dn() == 1 && flag == 1)flag = 3;
if (bt.button[2].event_click_Dn() == 1 && flag == 1)flag = 3;
}
(flag == 3)? a = 1: a = 0.1; // Температуру меняем на 1 градус остальные уставки на 0.1
//------------
if(flag > 2){
// изменяем активную уставку 1 нажатием на значение а
if (bt.button[1].event_click_Dn() == 1) temp[flag - 3] += a;
if (bt.button[2].event_click_Dn() == 1) temp[flag - 3] -= a;
// изменяем активную уставку 1 удержанием на значение а
if (bt.button[1].event_inactivity_Dn() && tbt +1500 < millis()){tbt = millis(); temp[flag - 3] += a;}
if (bt.button[2].event_inactivity_Dn() && tbt +1500 < millis()){tbt = millis(); temp[flag - 3] -= a;}
//------------
// переходим к другой уставке
if (bt.button[3].event_click_Dn() == 1) flag++; //перемещаемся по меню в верх
if (bt.button[4].event_click_Dn() == 1 && flag > 3)flag--; //перемещаемся по меню в низ не ниже 3 строки
if (flag > 6)flag = 1; // всего 6 строк меню
}
else {
// если в рабочем режиме то вкл\выкл мотора подачи
if (bt.button[3].event_click_Dn() == 1) {spd = true; words =String("0n");} // или вкл. мотор
if (bt.button[4].event_click_Dn() == 1 || flag == 0) {spd = false; words =String("0f");} // или выкл. мотор
}
//------------
// Если ни чего не трогать то вернуть экран номер 1
if (tbt + 7000 < millis() && fg){flag = 1; fg = false; Serial.println("The device works well");}
}
//-------------------------------------------------------------
молодец, теперь, когда думаешь и держишь кнопку, что делать дальше - кнопка у тебя не отжимается.
и, происходит это у тебя в том месте кода меню, где удержание нафиг не нужно, но нажатие/отпускание должно работать полюбому.
А зачем мне анализировать отжимание? Я анализирую нажим и долгое нажимание. В зависимости от того нажал ли я кнопку быстро или долго держал - то и сработает. Для полной перестраховки если не нужно долгого нажимания - то сделаю if (нажим или долгий нажим) и все.
Клапауций 112 пишет:
И было когда когда нажимаешь и жмешь долго, то сначало событие нажатия, а потом уже событие долгое нажатие. Убрал - сразу идет долгое нажатие.
т.е., когда через, допустим 5 секунд, отпускаешь кнопку, то она у тебя делает клик в -5 секунд в прошлом?
Нет конечно же. Если долгое нажатие у меня 1 секунда, а я держу кнопку 5 секунд - то после держания 1 секунды сработает долгое нажатие, а дальше ничего, просто держиться кнопка еще 4 секунды, и ни во время ее этого ее супер долгого нажимания, ни после - ничего больше не происходит.
neoblack2 поковырял твою библиотеку и сделал вывод, что у Клапауцего 112 библиотека более универсальна. Вот практически все твои изменения реализованы в коде с помощью библиотеки Клапауций 112 с минимумом кода. Кусок из рабочей программы работающего устройства Экструдер.
Пока буду использовать его библиотеку.
Не спорю, я сделал для простоты. Я убрал анализ отпускания и двойной клик + доработки.
а выше еретикам не нужно было нажатие, но они называли это длинным и коротким нажатием.
нужно вас свести вместе, что бы вы написали библиотеку без функций нажатия и отпускания.
neoblack2 пишет:
Если долгое нажатие у меня 1 секунда, а я держу кнопку 5 секунд - то после держания 1 секунды сработает долгое нажатие, а дальше ничего, просто держиться кнопка еще 4 секунды, и ни во время ее этого ее супер долгого нажимания, ни после - ничего больше не происходит.
дальше ничего - просто 4 секунды... чего не происходит? ты на 4-ре секунды блокируешь кнопку?
*кароче. еретиков - в пропасть с их сумасшедшими прожектами.
Клапауций 112 извини, но ты реши для чего ты написал библиотеку. ХОРОШУЮ БИБЛИОТЕКУ. Если для всех и без обсуждения то так и напиши, берите и пользуйтесь как есть и не .... мне мозг. Если для себя то и не показывал бы. А если для всех и выставил на обсуждение то этого высказывания я не совсем понял.
[/quote]
*кароче. еретиков - в пропасть с их сумасшедшими прожектами.
[/quote]
Совсем универсальных библиотек не может быть в принципе но стримица к этому нужно.
Клапауций 112 извини, но ты реши для чего ты написал библиотеку. ХОРОШУЮ БИБЛИОТЕКУ. Если для всех и без обсуждения то так и напиши, берите и пользуйтесь как есть и не .... мне мозг. Если для себя то и не показывал бы. А если для всех и выставил на обсуждение то этого высказывания я не совсем понял.
библиотека позволяет оперировать следующими переменными-производными логического состояния кнопки по времени:
программное состояние кнопки
состояние таймера неактивности ненажатой кнопки
состояние таймера неактивности нажатой кнопки
событие отпускания кнопки
событие нажатия кнопки
событие двойного щелчка кнопки
событие неактивности ненажатой кнопки
событие неактивности нажатой кнопки
===========================================
и, что же мне пердлагается в ответ?:
а, давай, говорят, зафильтруем нажатие/отпускание для юзера, сделаем нажание/отпускание служебным флагом внутри библиотеки, а наружу пустим производную нажатия/отпускания по времени удержания/неактивности кнопки. ¯\_(ツ)_/¯
одни из вас не понимают причинно-следственных связей и пытаются отменить нажатие/отпускание кнопки как первопричину всего происходящего.
другие не отличают нажатие от отпускания.
третьи сами не знают, чего хотят и пишут сюда шопопало.
Чаще (вроди меня) умничают те, кто незнает как сделать, то что они хотят (лень подумать). Вот и предлагают чтоб за них сделали (изминили под них библиотеку), а ты им кодом, как сделать то что они хотят, не залазя в библиотеку. Больше уважухи тебе и твоей библиотеке и меньше идиотов туда полезет.
Чаще (вроди меня) умничают те, кто незнает как сделать, то что они хотят (лень подумать). Вот и предлагают чтоб за них сделали (изминили под них библиотеку), а ты им кодом, как сделать то что они хотят, не залазя в библиотеку. Больше уважухи тебе и твоей библиотеке и меньше идиотов туда полезет.
ты думаешь, что я всё брошу и буду тут писать цирк с конями каждому юзеру, который не отличает нажатие от отпускания?
библиотека самодостаточна и позволяет реализовать любые хотелки.
мои камменты здесь никак не влияют на дизайн поведения библиотеки.
Ну да, так может и правильнее будет. Сам не допер маленько. Для себя я такую конструкцию буду юзать, а для других - в посте #522 строками 12 и 40, я тоже самое делаю. И мне кажется, у меня более читабельнее алгоритм. Там кстати, можно было сделать одной строкой, но мне влом было переписывать.
Хотя нет, твою конструкцию проверять нужно(в данный момент нечем). Две кнопки, я нажал одну и сразу начинаю многократно нажимать вторую, и если test.event_inactivity_Up() от первой кнопки приходит между нажатиями второй, то твоё условие сработает, а нехотелось бы (опять хателки :)). Проверить нужно.
Две кнопки, я нажал одну и сразу начинаю многократно нажимать вторую, и если test.event_inactivity_Up() от первой кнопки приходит между нажатиями второй, то твоё условие сработает, а нехотелось бы
event_inactivity_Up - опять путаем нажатие и отпускание?
последней нажатой кнопкой считается нажатая кнопка.
если ты отпустил одну кнопку из двух, то условие будет обрабатываться для одной кнопки, поэтому кликай поочерёдно двумя кнопками.
ты же правильно хотел, что бы:
Dmti пишет:
Правильнее было бы если сработка происходила один раз по истечении времени duration_inactivity_Dn после последней нажатой кнопки.
Все правильно, название этому обязывает. Мне больше интересно, что получу в ответ, если нажал кнопку и отпустил, а после этого спросил чему равно test.button1.event_click_Dn () == ? ведь во время опроса кнопка отжата но событие имело место быть. И что будет если после нажатия кнопки но перед верхним опросом спросил test.event_click_Dn () чему равно test.button1.event_click_Dn () == ?
Мне больше интересно, что получу в ответ, если нажал кнопку и отпустил, а после этого спросил чему равно test.button1.event_click_Dn () == ? ведь во время опроса кнопка отжата но событие имело место быть.
ты пытаешься существовать одновременно в прошлом, настоящем и будущем?
если кнопка была нажата, то ты знал об этом и код отработал это нажатие - в настоящем ты можешь работать с последсвиями этого нажатия - таймерами неактивности нажатия/отпускания.
И ещё вопрос могу создавать два разных масива кнопок button(test, ...) и button(Mybtn,...) не будут мешать друг другу?
цитата из файла описания:
настройка параметров:
---------------------
button(*, ...) - настройка номеров пинов, подключенных к кнопкам
настройка параметров приводит к активации настроек по-умолчанию
последующая настройка параметров и явная активация настроек приводит к их
обновлению
порядок настройки параметров и активации настроек не имеет значения
вызов button() без параметров приводит к удалению массива button
если ты желаешь два массива кнопок, то тебе нужно объявлять два экземпляра класса:
#include <Button.h>
Button test0;
Button test1;
далее можешь их настраивать или перенастраивать - не обязательно в сетапе, в любом месте, можно заюзать одноименные пины, всё будет динамически перенастраиваться на лету.
но... нужно учитывать, что при перенастройке, ты потеряешь значения таймеров неактивности кнопки.
не осилил всю тему, может уже появилась такая настройка в этой библе. Но меня всё ещё волнует этот воспрос
vvadim пишет:
при двойном клике или удержании кнопки одиночное нажатие всё равно срабатывает, что иногда не приемлемо
библиотекой организовано подключение нефиксируемых выключателей света. На даблклике висит функция изменения количества горящих ламп в люстре. Так раздражает, что при выборе количества ламп свет мигает, т.к. выполняется одиночное нажатие. Время реакции опроса короткого нажатия для меня не очень важно, поэтому
хотелось бы всё таки решить мою проблему таким способом:
trembo пишет:
Если после обнаружения первого клика прошло время большее того в течении котороговозможно второе нажатие кнопки и кнопка не нажалась- значит возвращаем простой клик.А нажали - возвращаем дабл....Может так?
Клапауций 999 пишет:
я уже говорил, что будет, если так сделать - мы затупим базовый функционал click_down кнопки на время отслеживания даблклика.
т.е. немного затупить click_down. Клапауций, подскажи как это сделать. За велик спасибо, крутая штука.
MaksVV]</p>
<p>не осилил всю тему, может уже появилась такая настройка в этой библе. Но меня всё ещё волнует этот воспрос</p>
<p>[quote=vvadim пишет:
при двойном клике или удержании кнопки одиночное нажатие всё равно срабатывает, что иногда не приемлемо
Я недавно делал кодовый замок к сейфу, там кроме кода 12345, надо ещё и цифры по-разному набирать: 1-двойной клик, 2-просто клик, 3-двойной клик, 4-длинный клик ... и последний ОООчень длинный клик. Так вообще не заморачивался - все работало на ура, просто короткое нажатие происходит при отпускании, а длинное - при НЕ отпускании.
а такую создам? И потом, опросы отдельно по группам. И идея моего примера выше, спросил кнопки, были нажаты - если нет, то и 100 if-ов нет смысла опрашивать, если да, то проверяем.
я же тебе ответил, что каждый экземпляр класса работает с одним списком(массивом) кнопок, который передаётся функцией настройки: например test.button(1, 2, 3, ...);.
прередача другого массива кнопок функцией настройки: например test.button(4, 5, 6, ...); удалит предыдущий массив и пересоздаст новый.
т.е. для того, что бы тебе начать работать с n-количеством списков(массивов) кнопок - тебе нужно объявить n экземпляров класса Button.
объявлять экземпляры класса можно явно:
Button test1;
Button test2;
или в как массив:
Button test[2];
и обращаться к функциям экземпляров класса соответсвенно - по явным именам test1, test2 или как к к элементам массива эекземпляров класса test[0], test[1].
Dmti пишет:
И потом, опросы отдельно по группам. И идея моего примера выше, спросил кнопки, были нажаты - если нет, то и 100 if-ов нет смысла опрашивать, если да, то проверяем.
я не понимаю, что ты хочешь - переформулируй мисль и пиши примеры или нормальным текстом или в теге код. выделение жирным вырывает мне глаза.
не осилил всю тему, может уже появилась такая настройка в этой библе. Но меня всё ещё волнует этот воспрос
отсюда можно почитать #451 , почему не существует длинных и коротких кликов - существуют исключительно событие нажатия/отпускания и событие неактивности нажатой/отпущенной кнопки. народ упоминаемыми там библиотеками делает нажатие служебным флагом и заменяет его производной по времени удержания кнопки и отпускания. здесь #468 я написал пример для велосипеда, как они это делают - нажатие и отпускание менее 1 секунды управляет одним светодиодом, нажатие и отпускание более 1 секунды управляет вторым светодиодом.
хотел написать ещё шуточный пример, что бы и после дабл-клика, а не удержания кнопки такой фокус делать, но ты подтвердил, что дела тут совсем не шуточные, а в всё очень даже всерьёз - осталось определиться: нужно нам событие нажатия кнопки или заменим событие нажатия например: нужно кнопку подержать 1 секунду, затем сделать четыре даблклика, затем отпустить кнопку на 1 секунду, затем совершить танец с бубном вокруг сосны против часовой стрелки при полнолунии в одном красном носке и после всё произойдёт.
MaksVV пишет:
библиотекой организовано подключение нефиксируемых выключателей света. На даблклике висит функция изменения количества горящих ламп в люстре. Так раздражает, что при выборе количества ламп свет мигает, т.к. выполняется одиночное нажатие. Время реакции опроса короткого нажатия для меня не очень важно, поэтому
хотелось бы всё таки решить мою проблему таким способом:
затупленный click_down(теперь event_click_Dn()) событие "нажатие кнопки" - это и есть "событие удержания кнопки" event_inactivity_Dn()
т.е. даблкликами переключаешь какой лампой ты управляешь, а удержанием кнопки, допустим в 1 секунду - включаешь/выключаешь выбранную лампу... или "количество" ламп.
ну, или я тебе дал пример #468 бубна, как флагами фильтровать ненужные тебе события.
я не понимаю, что ты хочешь - переформулируй мисль и пиши примеры или нормальным текстом или в теге код. выделение жирным вырывает мне глаза.
Наверно шрифт неправильно подобран, вот и вырывает глаза :)
Button test1;
Button test2;
test1.button(1, 2,3 ... 50);
test2.button(51, 52, 53, ... 100);
// было-ли нажатие первой группы если нет то и не опрашиваем
// идем сразу к следущей группе
if(test1.event_click_Dn()==1){
if(test1.button1.event_click_Dn()){}
if(test1.button2.event_click_Dn()){}
if(test1.button3.event_click_Dn()){}
..............................
if(test1.button100.event_click_Dn()){}
// смотрим было-ли нажатие во второй группе если нет
// то и не опрашиваем вообще.
if(test2.event_click_Dn()==1){
if(test2.button1.event_click_Dn()){}
if(test2.button2.event_click_Dn()){}
if(test2.button3.event_click_Dn()){}
..............................
if(test2.button100.event_click_Dn()){}
пытаюсь сокротить время общего цикла, на времени опроса кнопок. Получится, нет ?
т.е. даблкликами переключаешь какой лампой ты управляешь, а удержанием кнопки, допустим в 1 секунду - включаешь/выключаешь выбранную лампу... или "количество" ламп.
нет даблкликами - просто меняется переменная int , в зависимости от которой меняется количество ламп в люстре, когда состояние света - вкл. Коротким нажатием, меняется как раз это состояние на противоположное, т.е. вкл или выключаем свет. А на длительном нажатии у меня вкл/выкл функции "автосвет" - от датчиков движения.
Спасибо за развернутый ответ! Вел да, старый ещё там, давно делал. Перейду на новую версию.
видяху потом засниму как все эти функции на выключателе работают. Посмотришь как вел в реальной работе. За год ниразу косяков не было, даже в грозу. Хотя аппаратную часть тоже долго мучал, всё в экране и т.д.
продолжение эпопеи с длинными и короткими нажатиями...
после внимательного анализа сути хотелок свидетелей длинного и короткого нажатия(на самом деле "удержания кнопки в нажатом состоянии более или менее определённого времени") пришёл к выводу, что всё, чего не хватает еретикам - это настраиваемый таймер, запускаемый по нажатию или отпусканию кнопки.
теперь можно разделить удержания кнопки в нажатом состоянии(или в отпущенном) на длинные и короткие - до обнуления таймера и после.
...и, пофиксил state_inactivity_Up()/state_inactivity_Dn() - теперь значение state_inactivity_Up нажатой кнопки равно 0, значение state_inactivity_Dn() отпущенной кнопки равно 0.
прописал в классы-оболочки Button, Matrix деструкторы, утилизирующие массивы класса Click из памяти.
теперь можно на лету генерить или удалять матрицу или массив кнопок из памяти вместе с классом-оболочкой, когда это нужно... ну, например: горячее подключение или отключение расширенного пульта кнопок для комфортной настройки устройства.
всегда можно было аппаратно отключать, но память использовалась, ресурсы контроллера тратились на опрос пинов кнопок - сейчас это всё можно деактивировать программно и освободить память от неиспользуемых переменных. а, в случае необходимости - вернуть всё взад.
Есть вилосипед и что теперь его гвоздем нельзя поковырять. Я сейчас ни чиго не пишу, просто ковыряю и примеряю что куда можно присопливить.
Есть вилосипед и что теперь его гвоздем нельзя поковырять. Я сейчас ни чиго не пишу, просто ковыряю и примеряю что куда можно присопливить.
гвоздём у себя в ухе будешь ковырять, а здесь ты будешь уважительно относиться к чужому труду.
А я очень уважаю тебя, за очень удобную библиотеку, но хочу разобраться, что здесь, зачем и почему. Или это есть не гуд. А для уха есть пасатижи.
Радует, что тема с моими библиотеками лежит глубоко. Да и ковырятся там сложно. ;)
А я очень уважаю тебя, за очень удобную библиотеку, но хочу разобраться, что здесь, зачем и почему. Или это есть не гуд. А для уха есть пасатижи.
ок. и тебе спасибо, что обратил моё внимание на недостатки - попробую выровнять логические нестыковки.
Немного переделал исходный скетч автора. Теперь есть отрабатывание нажатия кнопки, долгого нажатия, быстрого считывания и неактивности. Быстрое считывание - актуально например для кнопок влево-вправо изменения каких-то значений(например емкости, нужно от 100 дойти до 500, пока прощелкаешь.....): А так нажал кнопку, держишь - и через определенное время (click_fast) начинает очень быстро меняться значение (измеряеться раз в time_fast - например раз в 75мс - чтобы не менялось с реактивной скоростью).
Использую для кнопок ВЛЕВО-ВПРАВО нажатие и быстрое считываение (изменять быстро значения), а для ВВОД-НАЗАД - нажатие и долгое нажатие (для сохранения настроек или выйти в главное меню)
Сам класс (значения временных переменных выставлены очень неплохо, брал на глаз с Skymax RC)
И кусочек программы (сам код сверху включает входа, подтягивающие резисторы, кнопки просто на землю)
Где-то тут писали что исходник автора после долгого нажатия отрабатывает событие еще и отжатия кнопки. Убрал. И было когда когда нажимаешь и жмешь долго, то сначало событие нажатия, а потом уже событие долгое нажатие. Убрал - сразу идет долгое нажатие.
+ думаю кому надо, можна в самой программе по условию вычислять нажатие двух кнопок одновременно.
Теперь есть отрабатывание нажатия кнопки, долгого нажатия,
быстрого считыванияи неактивности.Теперь есть отрабатывание нажатия кнопки, долгого нажатия,
быстрого считыванияи неактивности.? LEFT.click_fast
? LEFT.click_fast
я спросил, что: раньше нажатия, удержания, неактивности не было, а теперь есть?
сказал бы, что добавил повтор... молодец. теперь добавь повтор очередями по 3-5-12 выстрелов.
так никто и не посоветовал, как заставить кнопки ходить строем. пичалька.
ок. давай посмотрим на самое простое.
допустим, у нас две кнопки, одна нажата, вторая отпущена - что должна вернуть test.state_soft() ?
Где-то тут писали что исходник автора после долгого нажатия отрабатывает событие еще и отжатия кнопки.
молодец, теперь, когда думаешь и держишь кнопку, что делать дальше - кнопка у тебя не отжимается.
и, происходит это у тебя в том месте кода меню, где удержание нафиг не нужно, но нажатие/отпускание должно работать полюбому.
И было когда когда нажимаешь и жмешь долго, то сначало событие нажатия, а потом уже событие долгое нажатие. Убрал - сразу идет долгое нажатие.
т.е., когда через, допустим 5 секунд, отпускаешь кнопку, то она у тебя делает клик в -5 секунд в прошлом?
Всем доброго время суток.
neoblack2 поковырял твою библиотеку и сделал вывод, что у Клапауцего 112 библиотека более универсальна. Вот практически все твои изменения реализованы в коде с помощью библиотеки Клапауций 112 с минимумом кода. Кусок из рабочей программы работающего устройства Экструдер.
Пока буду использовать его библиотеку.
молодец, теперь, когда думаешь и держишь кнопку, что делать дальше - кнопка у тебя не отжимается.
и, происходит это у тебя в том месте кода меню, где удержание нафиг не нужно, но нажатие/отпускание должно работать полюбому.
А зачем мне анализировать отжимание? Я анализирую нажим и долгое нажимание. В зависимости от того нажал ли я кнопку быстро или долго держал - то и сработает. Для полной перестраховки если не нужно долгого нажимания - то сделаю if (нажим или долгий нажим) и все.
И было когда когда нажимаешь и жмешь долго, то сначало событие нажатия, а потом уже событие долгое нажатие. Убрал - сразу идет долгое нажатие.
т.е., когда через, допустим 5 секунд, отпускаешь кнопку, то она у тебя делает клик в -5 секунд в прошлом?
Нет конечно же. Если долгое нажатие у меня 1 секунда, а я держу кнопку 5 секунд - то после держания 1 секунды сработает долгое нажатие, а дальше ничего, просто держиться кнопка еще 4 секунды, и ни во время ее этого ее супер долгого нажимания, ни после - ничего больше не происходит.
Всем доброго время суток.
neoblack2 поковырял твою библиотеку и сделал вывод, что у Клапауцего 112 библиотека более универсальна. Вот практически все твои изменения реализованы в коде с помощью библиотеки Клапауций 112 с минимумом кода. Кусок из рабочей программы работающего устройства Экструдер.
Пока буду использовать его библиотеку.
Не спорю, я сделал для простоты. Я убрал анализ отпускания и двойной клик + доработки.
А зачем мне анализировать отжимание?
Если долгое нажатие у меня 1 секунда, а я держу кнопку 5 секунд - то после держания 1 секунды сработает долгое нажатие, а дальше ничего, просто держиться кнопка еще 4 секунды, и ни во время ее этого ее супер долгого нажимания, ни после - ничего больше не происходит.
дальше ничего - просто 4 секунды... чего не происходит? ты на 4-ре секунды блокируешь кнопку?
*кароче. еретиков - в пропасть с их сумасшедшими прожектами.
Клапауций 112 извини, но ты реши для чего ты написал библиотеку. ХОРОШУЮ БИБЛИОТЕКУ. Если для всех и без обсуждения то так и напиши, берите и пользуйтесь как есть и не .... мне мозг. Если для себя то и не показывал бы. А если для всех и выставил на обсуждение то этого высказывания я не совсем понял.
[/quote]
*кароче. еретиков - в пропасть с их сумасшедшими прожектами.
[/quote]
Совсем универсальных библиотек не может быть в принципе но стримица к этому нужно.
Клапауций 112 извини, но ты реши для чего ты написал библиотеку. ХОРОШУЮ БИБЛИОТЕКУ. Если для всех и без обсуждения то так и напиши, берите и пользуйтесь как есть и не .... мне мозг. Если для себя то и не показывал бы. А если для всех и выставил на обсуждение то этого высказывания я не совсем понял.
я уже на всех заборах написал, что:
https://github.com/Klapautsiy/titanium-bicycle-for-button/wiki
библиотека позволяет оперировать следующими переменными-производными логического состояния кнопки по времени:
===========================================
и, что же мне пердлагается в ответ?:
а, давай, говорят, зафильтруем нажатие/отпускание для юзера, сделаем нажание/отпускание служебным флагом внутри библиотеки, а наружу пустим производную нажатия/отпускания по времени удержания/неактивности кнопки. ¯\_(ツ)_/¯
Чаще (вроди меня) умничают те, кто незнает как сделать, то что они хотят (лень подумать). Вот и предлагают чтоб за них сделали (изминили под них библиотеку), а ты им кодом, как сделать то что они хотят, не залазя в библиотеку. Больше уважухи тебе и твоей библиотеке и меньше идиотов туда полезет.
Чаще (вроди меня) умничают те, кто незнает как сделать, то что они хотят (лень подумать). Вот и предлагают чтоб за них сделали (изминили под них библиотеку), а ты им кодом, как сделать то что они хотят, не залазя в библиотеку. Больше уважухи тебе и твоей библиотеке и меньше идиотов туда полезет.
исправлено: state_inactivity_Dn() - см. пост ниже
о пользе юзеров-тестировщиков - неправильно работала функция state_inactivity_Dn(), поэтому отвечаю после исправления:
Возник неожиданный вопрос по test.event_inactivity_Dn(). Ща это событие работает так, сколько кнопок было нажато, столько раз оно и ответит.
верно - так и должно работать
Правильнее было бы если с работка происходила один раз по истечении времени duration_inactivity_Dn после последней нажатой кнопки.
если желается, что бы что-то происходило по истечении работы таймера state_inactivity_Up или state_inactivity_Dn, то:
Ну да, так может и правильнее будет. Сам не допер маленько. Для себя я такую конструкцию буду юзать, а для других - в посте #522 строками 12 и 40, я тоже самое делаю. И мне кажется, у меня более читабельнее алгоритм. Там кстати, можно было сделать одной строкой, но мне влом было переписывать.
Хотя нет, твою конструкцию проверять нужно(в данный момент нечем). Две кнопки, я нажал одну и сразу начинаю многократно нажимать вторую, и если test.event_inactivity_Up() от первой кнопки приходит между нажатиями второй, то твоё условие сработает, а нехотелось бы (опять хателки :)). Проверить нужно.
Две кнопки, я нажал одну и сразу начинаю многократно нажимать вторую, и если test.event_inactivity_Up() от первой кнопки приходит между нажатиями второй, то твоё условие сработает, а нехотелось бы
event_inactivity_Up - опять путаем нажатие и отпускание?
последней нажатой кнопкой считается нажатая кнопка.
если ты отпустил одну кнопку из двух, то условие будет обрабатываться для одной кнопки, поэтому кликай поочерёдно двумя кнопками.
ты же правильно хотел, что бы:
Правильнее было бы если сработка происходила один раз по истечении времени duration_inactivity_Dn после последней нажатой кнопки.
Dmti, теперь, когда всё работает правильно - колись, зачем тебе это было нужно?
Правильнее было бы если сработка происходила один раз по истечении времени duration_inactivity_Dn после последней нажатой кнопки.
так и не получил я ответ на простой вопрос...
допустим, у нас две кнопки, одна нажата, вторая отпущена - что должна вернуть test.state_soft() ?
в посте #522 строки 12 и 40. Мне кажется более чем очевидно.
что должна вернуть test.state_soft() ? дожна вернуть что кнопка нажата.
в посте #522 строки 12 и 40. Мне кажется более чем очевидно.
очевидно, что сломается во время переполнения millis() - нужно так: millis() - tbt > 7000
и неочевидно, зачем это всё, если есть test.state_inactivity_Up(), которая как раз и работает, Если ни чего не трогать.
что должна вернуть test.state_soft() ? дожна вернуть что кнопка нажата.
ок. подойдём с другой стороны - когда кнопка отжата, что должна вернуть test.state_soft() ?
ок. подойдём с другой стороны - когда кнопка отжата, что должна вернуть test.state_soft() ?
48 кнопок нажал 47 отпустил test.state_soft() == нажата. В момент когда ты отпустил последнюю кнопку test.state_soft() == отжата.
У меня на руках щас нет ни одной ардуинки, все использовал, чтоб погонятьтвою библиотеку. Щас три на разтоможки, на следущей недели подойдут.
48 кнопок нажал 47 отпустил test.state_soft() == нажата.
В момент когда ты отпустил последнюю кнопку test.state_soft() == отжата.
т.е. не смущает следующая несимметричность?:
что бы получить test.state_soft() == нажата - достаточно нажать одну кнопку.
что бы получить test.state_soft() == отжата - нужно отжать все кнопки.
Все правильно, название этому обязывает. Мне больше интересно, что получу в ответ, если нажал кнопку и отпустил, а после этого спросил чему равно test.button1.event_click_Dn () == ? ведь во время опроса кнопка отжата но событие имело место быть. И что будет если после нажатия кнопки но перед верхним опросом спросил test.event_click_Dn () чему равно test.button1.event_click_Dn () == ?
Мне больше интересно, что получу в ответ, если нажал кнопку и отпустил, а после этого спросил чему равно test.button1.event_click_Dn () == ? ведь во время опроса кнопка отжата но событие имело место быть.
ты пытаешься существовать одновременно в прошлом, настоящем и будущем?
если кнопка была нажата, то ты знал об этом и код отработал это нажатие - в настоящем ты можешь работать с последсвиями этого нажатия - таймерами неактивности нажатия/отпускания.
И ещё вопрос могу создавать два разных масива кнопок button(test, ...) и button(Mybtn,...) не будут мешать друг другу?
Хорошо переиначу вопрос.
if(test.event_click_Dn()==1){
if(test.button1.event_click_Dn()){}
if(test.button2.event_click_Dn()){}
if(test.button3.event_click_Dn()){}
..............................
if(test.button100.event_click_Dn()){}
}
в такой конструкции не будет проколов ведь практически я два раза спрашиваю про нажатие кнопки.
И ещё вопрос могу создавать два разных масива кнопок button(test, ...) и button(Mybtn,...) не будут мешать друг другу?
цитата из файла описания:
если ты желаешь два массива кнопок, то тебе нужно объявлять два экземпляра класса:
далее можешь их настраивать или перенастраивать - не обязательно в сетапе, в любом месте, можно заюзать одноименные пины, всё будет динамически перенастраиваться на лету.
но... нужно учитывать, что при перенастройке, ты потеряешь значения таймеров неактивности кнопки.
Хорошо переиначу вопрос.
if(test.event_click_Dn()==1){
test.event_click_Dn() работает только в отношении экземпляра класса с именем test
if(test.button1.event_click_Dn()){}
if(test.button2.event_click_Dn()){}
if(test.button3.event_click_Dn()){}
..............................
if(test.button100.event_click_Dn()){}
}
в такой конструкции не будет проколов ведь практически я два раза спрашиваю про нажатие кнопки.
такую конструкцию ты не создашь практически - такую, да:
или так
не осилил всю тему, может уже появилась такая настройка в этой библе. Но меня всё ещё волнует этот воспрос
такую конструкцию ты не создашь практически - такую, да:
Button test1; Button test2;
test1.button(1, 2,3 ... 50); test2.button(51, 52, 53, ... 100);
а такую создам? И потом, опросы отдельно по группам. И идея моего примера выше, спросил кнопки, были нажаты - если нет, то и 100 if-ов нет смысла опрашивать, если да, то проверяем.
а такую создам?
т.е. для того, что бы тебе начать работать с n-количеством списков(массивов) кнопок - тебе нужно объявить n экземпляров класса Button.
объявлять экземпляры класса можно явно:
не осилил всю тему, может уже появилась такая настройка в этой библе. Но меня всё ещё волнует этот воспрос
отсюда можно почитать #451 , почему не существует длинных и коротких кликов - существуют исключительно событие нажатия/отпускания и событие неактивности нажатой/отпущенной кнопки. народ упоминаемыми там библиотеками делает нажатие служебным флагом и заменяет его производной по времени удержания кнопки и отпускания. здесь #468 я написал пример для велосипеда, как они это делают - нажатие и отпускание менее 1 секунды управляет одним светодиодом, нажатие и отпускание более 1 секунды управляет вторым светодиодом.
хотел написать ещё шуточный пример, что бы и после дабл-клика, а не удержания кнопки такой фокус делать, но ты подтвердил, что дела тут совсем не шуточные, а в всё очень даже всерьёз - осталось определиться: нужно нам событие нажатия кнопки или заменим событие нажатия например: нужно кнопку подержать 1 секунду, затем сделать четыре даблклика, затем отпустить кнопку на 1 секунду
, затем совершить танец с бубном вокруг сосны против часовой стрелки при полнолунии в одном красном носкеи после всё произойдёт.click_down - это какую ты версию велосипеда юзаешь? переползай на последнюю версию велосипеда
затупленный click_down(теперь event_click_Dn()) событие "нажатие кнопки" - это и есть "событие удержания кнопки" event_inactivity_Dn()
т.е. даблкликами переключаешь какой лампой ты управляешь, а удержанием кнопки, допустим в 1 секунду - включаешь/выключаешь выбранную лампу... или "количество" ламп.
ну, или я тебе дал пример #468 бубна, как флагами фильтровать ненужные тебе события.
я не понимаю, что ты хочешь - переформулируй мисль и пиши примеры или нормальным текстом или в теге код. выделение жирным вырывает мне глаза.
Наверно шрифт неправильно подобран, вот и вырывает глаза :)
пытаюсь сокротить время общего цикла, на времени опроса кнопок. Получится, нет ?
нет даблкликами - просто меняется переменная int , в зависимости от которой меняется количество ламп в люстре, когда состояние света - вкл. Коротким нажатием, меняется как раз это состояние на противоположное, т.е. вкл или выключаем свет. А на длительном нажатии у меня вкл/выкл функции "автосвет" - от датчиков движения.
Спасибо за развернутый ответ! Вел да, старый ещё там, давно делал. Перейду на новую версию.
видяху потом засниму как все эти функции на выключателе работают. Посмотришь как вел в реальной работе. За год ниразу косяков не было, даже в грозу. Хотя аппаратную часть тоже долго мучал, всё в экране и т.д.
пытаюсь сокротить время общего цикла, на времени опроса кнопок. Получится, нет ?
вместо хернёй заниматься, посмотрел бы содержимое файлов библиотеки.
откуда ты думаешь берётся значение test1.event_click_Dn() ?
внезапно:
продолжение эпопеи с длинными и короткими нажатиями...
после внимательного анализа сути хотелок свидетелей длинного и короткого нажатия(на самом деле "удержания кнопки в нажатом состоянии более или менее определённого времени") пришёл к выводу, что всё, чего не хватает еретикам - это настраиваемый таймер, запускаемый по нажатию или отпусканию кнопки.
теперь можно разделить удержания кнопки в нажатом состоянии(или в отпущенном) на длинные и короткие - до обнуления таймера и после.
титановый велосипед для кнопки v7.3
...и, пофиксил state_inactivity_Up()/state_inactivity_Dn() - теперь значение state_inactivity_Up нажатой кнопки равно 0, значение state_inactivity_Dn() отпущенной кнопки равно 0.
прописал в классы-оболочки Button, Matrix деструкторы, утилизирующие массивы класса Click из памяти.
теперь можно на лету генерить или удалять матрицу или массив кнопок из памяти вместе с классом-оболочкой, когда это нужно... ну, например: горячее подключение или отключение расширенного пульта кнопок для комфортной настройки устройства.
тоись, на лету можно клавиатуру отрывать? :)
тоись, на лету можно клавиатуру отрывать? :)
всегда можно было аппаратно отключать, но память использовалась, ресурсы контроллера тратились на опрос пинов кнопок - сейчас это всё можно деактивировать программно и освободить память от неиспользуемых переменных. а, в случае необходимости - вернуть всё взад.
маленький сайтик титанового велосипеда https://klapautsiy.github.io/titanium-bicycle-for-button/
Клапуций, вот вам не понять имея титановый велосипед за ценой подержаного жигуля тех кто ездит на дачу в забитой электричке и просит старую лошадку