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

Клапауций 999
Offline
Зарегистрирован: 06.06.2015
класс титановый велосипед для тактовой кнопки.
фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.
Клапауций 999
Offline
Зарегистрирован: 06.06.2015
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для тактовой кнопки.
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.

class BUTTON {
public:
//================================================================
static const byte bounce_              =   50; // длительность отслеживания дребезга.
static const byte doubleclick_         =  200; // длительность отслеживания двойного клика.
static const unsigned long timer_      = 5000; // длительность отслеживания неактивности.
static const unsigned int retention_   = 2000; // длительность отслеживания нажатия и удержания.
//================================================================
boolean click_down;
boolean click_up;
boolean doubleclick;
boolean timer;
boolean retention;
//=================================
unsigned long m;
boolean  p;
boolean  b;
boolean dc;
byte     c;
boolean  t;
boolean  r;
//=================================
byte _pb;
//=================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//====
click_down      = 0;
click_up        = 0;
doubleclick     = 0;
timer           = 0;
retention       = 0;
//====
m  =      millis();
p  = digitalRead(_pb);
b  =                0;
dc =                0;
c  =                0;
t  =                0;
r  =                0;
//====
}

void read() {
//=======================================================
unsigned long nm =      millis();
boolean       np = digitalRead(_pb);
//=================
boolean nb  = 0;
boolean ndc = 0;
boolean nt  = 0;
boolean nr  = 0;
//================
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//=================
if (np != p) {p = np; m = nm; }
//=======================================================
if (nm - m > bounce_) {nb = 1;}
if (nm - m > doubleclick_) {ndc = 1;}
if (ndc != dc) {dc = ndc; if (dc == 1) {c = 0;}}
if (nb != b) {b = nb;
if (p == 0 && b == 0) {click_down = 1;
++c;      if (c == 2) {c = 0; doubleclick = 1;}
}
if (p == 1 && b == 1) {click_up = 1;}
}
//=======================================================
if (nm - m > timer_) {nt = 1;}
if (nt != t) {t = nt;
if (p == 1 && t == 1) {timer = 1;}
}
//=======================================================
if (nm - m > retention_) {nr = 1;}
if (nr != r) {r = nr;
if (p == 0 && r == 1) {retention = 1;}
}
//=======================================================
}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015
класс генерит события TRUE состояния переменных кнопки в течении одного цикла программы.
т.е. сохраняется дизайн поведения визуального восприятия обращения с кнопкой: что-то сделал один раз реальной кнопкой - что-то произошло один раз программно.
 
каждый объявленный объект класса работает со своим уникальным набором переменных:
click_down - приобретает значение TRUE при нажатии.
click_up - приобретает значение TRUE при отпускании.
doubleclick - приобретает значение TRUE при двойном нажатии(doubleclick).
timer - приобретает значение TRUE, если отпущено и нективно в течении определённого времени.
retention - приобретает значение TRUE, если нажато и удерживается в течении определённого времени.
Клапауций 999
Offline
Зарегистрирован: 06.06.2015

пример, объясняющий отличия работы с кнопкой классическим способом и с использованием предложенного класса:


void loop() {

// классический способ использования кнопки.
if (считываем логическое состояние пина кнопки ==  LOW) {что-то делаем при нажатой кнопке} // стоп! а, зачем что-то делается во время каждого цикла loop многократно, если мы нажали на кнопку только один раз?
if (считываем логическое состояние пина кнопки == HIGH) {что-то делаем при отпущенной кнопке} // так же непорядок - что-то делается многократно, не смотря на то, что событие отпускания кнопки произошло ровно один раз.

// использование кнопки с классом - всё корректно: одно физическое событие генерит одно программное событие.
if (нажатие == TRUE) {что-то делаем при нажатой кнопке}
if (отпускание == TRUE) {что-то делаем при отпущенной кнопке}
if (двойное нажатие == TRUE) {что-то делаем при двойном нажатии}
if (удержание == TRUE) {что-то делаем, если нажато и удерживается в течении определённого времени}
if (неактивность == TRUE) {что-то делаем, если отпущено и неактивно в течении определённого времени}

}

 

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

пример скетча с использованием класса:

//~~~~~~~~~~~~~~~~~~~~
// здесь код приведённого выше класса class BUTTON {}; 
//~~~~~~~~~~~~~~~~~~~~

BUTTON BUTTON_01(3); // объявляем объект класса BUTTON кнопку с именем BUTTON_01, подключенную к пину 3.
BUTTON BUTTON_02(4); // объявляем объект класса BUTTON кнопку с именем BUTTON_02, подключенную к пину 4.

void setup () {}

void loop() {

BUTTON_01.read(); // обновляем состояние переменных кнопки BUTTON_01.
BUTTON_02.read(); // обновляем состояние переменных кнопки BUTTON_02.

// работаем с переменными кнопки BUTTON_01.
if (BUTTON_01.click_down) {что-то делаем при нажатии}
if (BUTTON_01.click_up) {что-то делаем при отпускании}
if (BUTTON_01.doubleclick) {что-то делаем при двойном нажатии(doubleclick)}
if (BUTTON_01.timer) {что-то делаем, если кнопка отпущена и неактивна в течении определённого времени}
if (BUTTON_01.retention) {что-то делаем при нажатии и удержании в течении определённого времени}

// работаем с переменными кнопки BUTTON_02.
if (BUTTON_02.click_down) {}
if (BUTTON_02.click_up) {}
if (BUTTON_02.doubleclick) {}
if (BUTTON_02.timer) {}
if (BUTTON_02.retention) {}

}

UPD: упустил из вида очевидное - надеюсь, ползателям ясно, что эти переменные можно настраивать по своему хотению:

07 //================================================================
08 static const byte bounce_              =   50; // длительность отслеживания дребезга.
09 static const byte doubleclick_         =  200; // длительность отслеживания двойного клика.
10 static const unsigned long timer_      = 5000; // длительность отслеживания неактивности.
11 static const unsigned int retention_   = 2000; // длительность отслеживания нажатия и удержания.
12 //================================================================

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

а если приделать вместо иф-ов свитч?

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

JollyBiber пишет:

а если приделать вместо иф-ов свитч?

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

накидай пример, как-то я не понимаю, где там свитчи можно приделать.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Классический switch - это только константы или типа того. Здесь разве что callbackи можно прикрутить, другое дело нужно ли, не знаю.

 

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

kisoft пишет:

Классический switch - это только константы или типа того. Здесь разве что callbackи можно прикрутить, другое дело нужно ли, не знаю.

оба-два, признавайтесь, что вы имеете ввиду.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012
switch(BUTTON_02.acton) {
    case 'click_down': action....;
                                      break;
     case 'click_up': action....;
                                      break;
     default: action....;
                                      break;
     }

как то так

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

JollyBiber пишет:

switch(BUTTON_02.acton) {
    case 'click_down': action....;
                                      break;
     case 'click_up': action....;
                                      break;
     default: action....;
                                      break;
     }

как то так

BUTTON_02.acton - это что такое у нас?

*кароче, делайте с переменными:

click_down
click_up
doubleclick
timer
retention

шо хотите, учитывая, что полезное нам значение они приобретают, когда равны TRUE,

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

BUTTON_01.read()

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

JollyBiber пишет:

BUTTON_01.read()

дык, эта халабуда ничего не возвращает - её нужно просто дёргать, для обновления 

click_down
click_up
doubleclick
timer
retention
 
до актуальных.
 
*или возвращает? - я не программист, поэтому проверю.
JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Я не смотрел :) сделай чобды возвращала, я отчасти поэтому и написал .action

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

JollyBiber пишет:

Я не смотрел :) сделай чобды возвращала, я отчасти поэтому и написал .action

сделать, что бы было что?

пока у нас есть пять переменных, у которых мы отслеживаем состояние TRUE

а, тогда у нас будет переменная с пятью состояниями... или шестью? - не знаю, подумаю над необходимостью.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Щас 10-ка ставится, потому много не напишу с телефона, но
Имена локальных переменных - мама роди меня обратно. Автор через неделю забудет что это и для чего. Для либы - это смерть. Утрирую, но так и есть, имена переменных должны пониматься без переводчика. Далее, все, что есть в классе имеет доступ public. Блджад, так нельзя. Нужно исходить из мысли, что члены класса не должны меняться снаружи никогда, только методами set и т.п. А щас, что хочу, то и ворочу. Это неправильно.
private - все, что никто не увидит. protected - это увидят только здесь и в порождённое классе. public - увидят все. Типа так

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

kisoft пишет:
Автор через неделю забудет что это и для чего. Для либы - это смерть. Утрирую, но так и есть, имена переменных должны пониматься без переводчика. Далее, все, что есть в классе имеет доступ public. Блджад, так нельзя. Нужно исходить из мысли, что члены класса не должны меняться снаружи никогда, только методами set и т.п. А щас, что хочу, то и ворочу. Это неправильно. private - все, что никто не увидит. protected - это увидят только здесь и в порождённое классе. public - увидят все. Типа так

автор помнит имена переменных, т.к. они именованы не просто так, а являются производными переменных, имена которых полные и закоментированы - например:

ndc - новое состояние булевой производной переменной doubleclick_ dc.

всё имеет доступ public, т.к. не понимаю в чём риск полного доступа, кроме того, что скетч ломанут хакеры и начнут рулить классом во вред... кому во вред? что может сподвигнуть ползателя класса сознательно рулить служебными переменными из void loop() {} во вред себе?

возможно, я не понимаю рисков или, таки, применение private и protected актуально для использования C++ в операционных системах компьютеров, дабы народ не хакнул сам себя?

спасибо.

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

JollyBiber пишет:

Я не смотрел :) сделай чобды возвращала, я отчасти поэтому и написал .action

проверил твою хотелку свичей - не выходит твой каменный цветок:

if (BUTTON_01.click_down && BUTTON_01.doubleclick) {lcd.setCursor(8, 0); lcd.print("**");}

BUTTON_01.click_down и BUTTON_01.doubleclick могут быть TRUE одновременно - для тебя критично, а по мне - не противоречит логике реакции балалайки на события нажатия.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Скрытие доступа нужно для исключения случайных ошибок, когда, например, признак нажатия сформируется не внутри, а снаружи, по ошибке. Т.е. данный признак с точки зрения скетча пользователя является readonly. На такой случай, для члена класса реализуется геттер, а сеттер не формируется.
Если хочешь, могу твой исходник переработать, для примера, а там решай сам. Если нет, то нет.

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

kisoft пишет:
Скрытие доступа нужно для исключения случайных ошибок, когда, например, признак нажатия сформируется не внутри, а снаружи, по ошибке. Т.е. данный признак с точки зрения скетча пользователя является readonly. На такой случай, для члена класса реализуется геттер, а сеттер не формируется. Если хочешь, могу твой исходник переработать, для примера, а там решай сам. Если нет, то нет.

спасибо, пока я не пойму, зачем мне и ползателям нужно запрещать рулить классом из loop()

*я могу понять, когда кот, набрав случайных символов в блокноте, валит систему, но как это катастрофически применимо к программе в контроллере - не доходит до меня.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Согласно общепринятым правилам обращение к членам класса напрямую должно быть исключено. Но дело хозяйское. К примеру я такой класс использовать не буду. Мне проще будет написать свой, хотя по функциональности он будет точно такой же. Если не веришь, посмотри исходники любой библиотеки, которая идет с ArduinoIDE.

PS IMHO, не важно, для МК пишется что то или нет, есть понятие стиля, принципов написания классов. К примеру я всегда стараюсь писать одинаково, независимо от того, на 5 минут нужен класс или на всё время жизни приложения. И это себя оправдывает (у меня более 30 лет опыта, знаю не понаслышке). Разумеется для МК есть свои особенности, тонкости. Это всё я не сам придумал, а вычитал, выстрадал на своей жопе шее. Имена членов класса или локальных переменных. Это тоже особая статья, за переменные с именами типа kk, я бы своих бойцов отымел поставил в угол. Длина имени переменной не влияет на объем кода, а размеры исходников - это второстепенное. Если же имя переменной длинное и читается, то и весь исходник читается на раз и не требует ковыряний. К том же при поиске ошибок это может сильно помочь.

Ок, лечение OFF ;) а то уже повторяюсь. Всё, не буду больше уговаривать.

 

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

kisoft пишет:

Согласно общепринятым правилам обращение к членам класса напрямую должно быть исключено. Но дело хозяйское. К примеру я такой класс использовать не буду. Мне проще будет написать свой, хотя по функциональности он будет точно такой же. Если не веришь, посмотри исходники любой библиотеки, которая идет с ArduinoIDE.

PS IMHO, не важно, для МК пишется что то или нет, есть понятие стиля, принципов написания классов. К примеру я всегда стараюсь писать одинаково, независимо от того, на 5 минут нужен класс или на всё время жизни приложения. И это себя оправдывает (у меня более 30 лет опыта, знаю не понаслышке). Разумеется для МК есть свои особенности, тонкости. Это всё я не сам придумал, а вычитал, выстрадал на своей жопе шее. Имена членов класса или локальных переменных. Это тоже особая статья, за переменные с именами типа kk, я бы своих бойцов отымел поставил в угол. Длина имени переменной не влияет на объем кода, а размеры исходников - это второстепенное. Если же имя переменной длинное и читается, то и весь исходник читается на раз и не требует ковыряний. К том же при поиске ошибок это может сильно помочь.

Ок, лечение OFF ;) а то уже повторяюсь. Всё, не буду больше уговаривать.

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

поэтому, сняты все ограничения и тормоза.

не нравятся имена переменных - Ctrl+H !

*вот на этом хотел отсановиться более подробно - спрашивал, но чёткого ответа не получил:

kisoft пишет:

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

ты в коде путаешь "=" и "=="? или где?

где почитать книгу "общепринятые правила"? - кем они общеприняты?

*а, в контексте сабжа - переменные класса практически невозможно изменить случайно.

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Плюсанул. Дело нужное.

Но вы уж извините, но за такую структуру кода, за такое именование переменных можно и канделябром...

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

Gippopotam пишет:

Плюсанул. Дело нужное.

Но вы уж извините, но за такую структуру кода, за такое именование переменных можно и канделябром...

ок - просто попробуйте. оно вылизано, выверено и протестировано в меру способностей и не в меру настойчивости.

структура кода - читабельная для меня, можно развернуть - функция есть в любом редакторе.

я, лично не воспринимаю смысла кода вида по одному оператору в одну строку.

имена переменных... ну, поймите пожалуйста, что челу, не владеющему ни одним языком на латинице, проще свести имена переменных к логическому виду письма майя, чем пялиться на незнакомые слова.

пример: переменная nt по русски звучит "новое состояние булевой производной константы timer_" - как это сформулировать и написать на латинице, что бы не сломать себе мосг? 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Клапауций 999 пишет:

пример: переменная nt по русски звучит "новое состояние булевой производной константы timer_" - как это сформулировать и написать на латинице, что бы не сломать себе мосг? 

неубедительно.

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

Gippopotam пишет:

неубедительно.

а, и не убеждаю - я вежливо констатирую факт, с которомым вам придётся смириться, т.к. на работу балалайки имена переменных не влияют. kisoft подтвердит. :D 

Andrey-S
Offline
Зарегистрирован: 02.01.2015

А мне, как новичку, понравился код... Отлично работает, а больше и не нужно... В его смысл не лезу вникать (не с моими знаниями пока). А вот "гурманы" вижу критикуют))). Клапауций старался писал для таких как я, а тут накинулись... Что ж вы просто не выложите сюда же "идеально подправленный код", а только указываете на мелкие недостатки?

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Andrey-S пишет:

А мне, как новичку, понравился код... Отлично работает, а больше и не нужно... В его смысл не лезу вникать (не с моими знаниями пока). А вот "гурманы" вижу критикуют))). Клапауций старался писал для таких как я, а тут накинулись... Что ж вы просто не выложите сюда же "идеально подправленный код", а только указываете на мелкие недостатки?

 

Мне есть, что ответить, но я не стану. Тем более я не накидывался и не критиковал.

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

Andrey-S пишет:

А мне, как новичку, понравился код... Отлично работает, а больше и не нужно...

ок.

Andrey-S присвоено почётное звание "Бета-тестер класса титановый велосипед для тактовой кнопки № 1".

*юзай - будут вопросы, спрашивай.

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

как ты сам и написал новички часто путают "=" и "==". Вот как раз для них приват и нужен.

"BUTTON_01.click_down и BUTTON_01.doubleclick могут быть TRUE"

вот это, по мне как, не камильфо. Оно не толко не противоречит конечно, но в каком случае может быть false и true???. Может расширить функционал и добавить возможность самому настраивать есть двойной клик или нету? Если есть ставится стандартная задержка + возможность ее поменять?

 

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

JollyBiber пишет:

как ты сам и написал новички часто путают "=" и "==". Вот как раз для них приват и нужен.

я строю фонтастические догадки, как самый неопытный ползатель может написать "="

в строке if (TRUE) {} ?

JollyBiber пишет:

но в каком случае может быть false и true???.

в сабже FALSE считается ничем и никого не интересует в принципе - т.к. FALSE у нас будет всегда, когда ничего не произошло - нас интересуют события, а не их отсутсвие.

пример - перечисли всё, чего у тебя нет. бессмысленная и невозможная задача, не правда ли?

JollyBiber пишет:

Может расширить функционал и добавить возможность самому настраивать есть двойной клик или нету? Если есть ставится стандартная задержка + возможность ее поменять?

расширяю тебе функционал на лету - следи за руками:

делаешь if (имя кнопки.doubleclick) {} - есть даблклик

не делаешь // if (имя кнопки.doubleclick) {} - нет даблклика!

переменные можно менять по своему хотению - добавил в #4 , думал - что очевидно самодостаточно.

 

07 //================================================================
08 static const byte bounce_              =   50; // длительность отслеживания дребезга.
09 static const byte doubleclick_         =  200; // длительность отслеживания двойного клика.
10 static const unsigned long timer_      = 5000; // длительность отслеживания неактивности.
11 static const unsigned int retention_   = 2000; // длительность отслеживания нажатия и удержания.
12 //================================================================

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

if(Button_02.doubleclick = Button_02.click)

if(Button_02.doubleclick = true)

 

"пример - перечисли всё, чего у тебя нет. бессмысленная и невозможная задача, не правда ли?"

не понял довода. Чем отлчаются условия и когда может возникнуть разница при даблклике?

if (BUTTON_01.click_down && BUTTON_01.doubleclick)

if (BUTTON_01.doubleclick)

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

JollyBiber пишет:

if(Button_02.doubleclick = Button_02.click)

if(Button_02.doubleclick = true)

извращенец. ок - убедил, класс абсолютно уязвим перед топчущим клаву котом.

JollyBiber пишет:

не понял довода.

ты меня спросил, когда у нас случается FALSE - я тебе ответил, что список может быть бесконечным.

например: я могу не сделать даблклик, затем не сделать клик, затем не отпустить кнопку тясячу раз, затем... продолжать?

JollyBiber пишет:

Чем отлчаются условия и когда может возникнуть разница при даблклике?

if (BUTTON_01.click_down && BUTTON_01.doubleclick)

if (BUTTON_01.doubleclick)

концептуально неправильный вопрос - что бы породить doubleclick, нужно сделать два click_down

стработает if (BUTTON_01.click_down && BUTTON_01.doubleclick)

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Я тебя спрашивал про твой конкретный приер, который ты сам и привел )))))

if (BUTTON_01.doubleclick)

а этот чем не сработает на даблклик?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Клапауций 999 пишет:

kisoft пишет:

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

ты в коде путаешь "=" и "=="? или где?

где почитать книгу "общепринятые правила"? - кем они общеприняты?

*а, в контексте сабжа - переменные класса практически невозможно изменить случайно.

Я не путаю, я пишу сначала константу, потом ==. Но юзать класс буду не я.

Почитать, ну например, здесь п.49 в частности. Это первое что нашлось. Нет источника, есть годами накопленный опыт.

Слово "практически" в фразе "переменные класса практически невозможно" меня не устраивает. Но это мои проблемы.

PS Нас тут "гурманами" назвали, ню-ню. Я не критикую, скорее оказываю братскую помощь. Точнее я пытаюсь её оказать, но пациент неприклонен. "В сад!" :)

break;

 

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

JollyBiber пишет:

Я тебя спрашивал про твой конкретный приер, который ты сам и привел )))))

if (BUTTON_01.doubleclick)

а этот чем не сработает на даблклик?

ты не понял - это был не пример, а подтверждение того что click_down и doubleclick могут принимать значение TRUE в одном цикле программы и, значит, твои мечты о свитче маловероятно реализуемы.

ещё раз - твой

switch(BUTTON_02.acton) {

должен вернуть более одного актуального значения за один проход

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

kisoft пишет:

Но юзать класс буду не я.

вот на этом и отсановимся - класс буду юзать я.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

даже если Вас съели у Вас есть 2 выхода.

1. можно при даблклике ставить клик в false.

2. можно в свитче сначала проверять на даблклик.

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

JollyBiber пишет:

даже если Вас съели у Вас есть 2 выхода.

1. можно при даблклике ставить клик в false.

2. можно в свитче сначала проверять на даблклик.

1. нельзя знать заранее, будет ли произведён второй клик.

2. если желаешь затупить кнопку на время отслеживания даблклика, то - да. но реализовывать ересь не буду.

выше один вызывал милицию по одиночному клику, а пожарных по даблклику... знаешь, шо было? - всегда приезжала милиция, Карл!

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

а зачем заранее? когда наступил даблклик тогда клик в фальш и ставь

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

JollyBiber пишет:

а зачем заранее? когда наступил даблклик тогда клик в фальш и ставь

Это не нужно и бессмысленно, да и неправильно это, клик то есть. В больших системах точно так же.

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

В чем неправильность? Разве может наступить даблклик без "одиночного" клика? А вот логику можно в дабле уже и ветвить как хочется. Хоть по времени между первым и вторым

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

JollyBiber пишет:

а зачем заранее? когда наступил даблклик тогда клик в фальш и ставь

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

юзай свою хотелку и не приставай со странным

++c;      if (c == 2) {c = 0; click_down = 0; doubleclick = 1;}

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Клапауций 999 пишет:

выше один вызывал милицию по одиночному клику, а пожарных по даблклику... знаешь, шо было? - всегда приезжала милиция, Карл!

И сейчас тоже приезжают и даже две бригады милиции, одна до пожарных, а вторая после:

Timer
Click UP
Double Click
Click UP
Timer

З.Ы. Помню и как младший брат слежу за дискуссией.
 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

* А я принципиально буду 3,14здеть!

Даешь функцию возврата действия в народ! Все хотят кружевной свитч и в африку! IF - go home!

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

trembo пишет:

И сейчас тоже приезжают и даже две бригады милиции, одна до пожарных, а вторая после:

Timer
Click UP
Double Click
Click UP
Timer

З.Ы. Помню и как младший брат слежу за дискуссией.

и, что тебе неправильного работает?

ты же искал "длиных нажатий", не видя очевидного? - настрой:

static const unsigned int retention_   = 2000; // длительность отслеживания нажатия и удержания.

но... если у нас есть "длинные нажатия", то у нас, очевидно, обязаны быть "длинные отпускания" - настрой:

static const unsigned long timer_      = 5000; // длительность отслеживания неактивности.

*если ты не понимаешь, почему оно происходит - да, потому, что ега не может не быть. :D

**на практике "длинные отпускания" можно юзать, как событие неактивности кнопки.

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

JollyBiber пишет:

Даешь функцию возврата действия в народ! Все хотят кружевной свитч и в африку! IF - go home!

не морочь голову - дописывай ифы преобразования комбинаций переменных состояния кнопки в loop(), что бы доставать их из свитч.

*я думал, тебе один конфликт значений переменных отобъёт охоту фигнёй заниматься.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

JollyBiber пишет:

В чем неправильность? Разве может наступить даблклик без "одиночного" клика? А вот логику можно в дабле уже и ветвить как хочется. Хоть по времени между первым и вторым

Самый тупой вариант, если чел не использует дабл, а только нажатия, то он будет удивлен, что не получает второй клик. И пока он поймет, как это исправить, может и застрелиться.

Док, чего ты паришься, проверяй сначала дабл, а потом просто клик. Всё равно switch в такой реализации нельзя использовать.

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

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

Может так?

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

trembo пишет:

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

Может так?

я уже говорил, что будет, если так сделать - мы затупим базовый функционал click_down кнопки на время отслеживания даблклика.

static const byte doubleclick_         =  200; // длительность отслеживания двойного клика.

т.е. каждое следующее за первым одиночным нажатием одиночное нажатие у тебя будет тупить 200 миллисекунд, что концептуально не правильно, т.к. здесь ещё раз внимательно!:

click_down - срабатывает не раньше времени прошедшего с момента нажатия кнопки:

static const byte bounce_              =   50; // длительность отслеживания дребезга.

click_up - срабатывает не раньше времени прошедшего с момента отпускания кнопки:

static const byte bounce_              =   50; // длительность отслеживания дребезга.

и, естественно, возникает вопрос: а, click_up когда возвращать? - через 50 или 200 миллисекунд?

 

поэтому, придерживаюсь следующей концепции - дабы не наступать на грабли логических конфликтов:

нажатие и отпускание кнопки (переменные click_down и click_up) являются базовым функционалом, все отсальные плюшки являются производными этого функционала от времени, производные функционала не могут убивать базовый функционал, производные функционала + что-то ещё могут рождать дополнительный функционал.

*если тебе желается и ты меня убедишь, что в классе необходимо добавить нечто вроде click_down-doubleclick - так и случится. но, пока, кроме разглагольствований, что можно сделать так или эдак - я ничего не наблюдаю.

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

JollyBiber пишет:

как ты сам и написал новички часто путают "=" и "==". Вот как раз для них приват и нужен.

ну, и чем тут http://arduino.ru/forum/programmirovanie/pomogite-po-analogovomu-pinu челу приват поможет?

смотри - во всю среду Дуино ИДЕ приват прописан, а нихрена не помогает.