Как обеспечить считывание двойного клика кнопки в теле прерывания?

После прочтения комментов, в голове возникла реализация, но такое себе:

По любому входу в прерывание:

clickCounter++;
lastClickTime=millis();

В цикле смотрим:

if(millis()-lastClickTime>=maxInterval){
nClick=clickCounter;
clickCounter=0;
}

Соответственно переменные lastClickTime и clickCounter должны быть volatile

Только так и не понял, зачем оно надо…

3 лайка

До истечения таймаута после последнего клика. Если таймаут истёк - фиксируем результат и обнуляем счётчик. И пофигу - один клик был или пять ))

тулуп )))
Правильно для себя я клик и лонг сделал

Дима написал правильно, Что событие Клик всегда предшествует ДаблКлику.
Далее вопрос только в логике обработки. Драйвер тебе честно отдал и первое и второе. И отсутствие коллизий в обработке - уже вопрос не к драйверу, а к автору кода.

Например в ГУИ клик можно трактовать как СелектАйтем, а ДаблКлик как ЭкзекьютАйтем. Собственно как обычно. Тогда ты нормально обрабатываешь Селект по Клику, если элемент еще не выбран и если пришел Дабл - то выполняешь его.

Допишу:
Есть дурацкая школа, я видел её приверженцев среди заказчиков: отдавать событие Клик не сразу, а после истечения таймера между ДаблКликом.
Мне кажется, что эргономика такого ГУИ странная, человек нажал кнопку, а ничего не происходит заметное время… Но, повторю, есть адепты этой религии. В таком драйвере можно различить эти действия.
Еще допишу - это та же религия в которой событие Клик отдают по отпусканию… я не люблю такое. Помню знатный срач с Клапауцием на старом форуме. Он тоже считал, что Клик нужно отдать по нажатию, а коллизии пусть обрабатывает программист в своем коде.

1 лайк

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

ага, и я ее адепт

1 лайк

Кликают не только на кнопки. Как раз кнопки в ГУИ даблкликать еще додуматься нужно. А есть же еще всякие иконки в трее и все тому подобное ))

я про мышь, еслишто

А что там не мышью кликается? ))

Баттоны

Они мышью и кликаются. И события так и идут - клик, клик, даблклик

а пробелом не?

Чойта не? А даблклик пробелом никак? ))

у меня не получалось

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

Вот интересно, а как с дребезгом работать в прерывании?
…просто и не думал кнопку сажать на прерывание…никогда.

по фронту если, флаг дебонса не поднят, фиксируешь нажатие, время и поднимаешь флаг дебонса. При поднятом флаге дебонса не делаешь ничего. При спаде - аналогично, только фиксируешь отпускание. Флаг дебонса опускаешь в loop() или в отдельном тикере/потоке - на свой вкус. Помним, что в АВР нет контроллера прерываний, и прерывание может просто потеряться, если контроллер выполнял прерывание с меньшим номером вектора. (там приоритет такой). Вообще АВР Ардуинщики применяют для тех целей, для которых его Атмел никогда не имел ввиду :wink: :wink: :wink: То есть мы гораздо круче профессионалов, если честно!

1 лайк

антидребезг вне прерывания

	static bool ReadDigitalPin(const uint8_t APin, const bool AActiveLevel) {
		for (uint8_t i = 0; i < 16; ++i) {
			if (digitalRead(APin) != AActiveLevel) 
				return false;
          delay(1);
		}
		return true;
	}

16 раз читаем порт. Если ХОТЬ РАЗ из 16 кнопка не нажата, вернем false. Если ВСЕ 16 раз нажата - вернем true.
Чуть больше 16 мс на чтение.

Ты научишь шалопаев писать блокирующий код, а потом они будут спрашивать, почему у них серва дергается, IR не принимает и гирлянда моргает, как при эпилепсии.

Друзья, всем спасибо за комментарии! Кое-что из них для себя уяснил. Но такое развитое обсуждение свидетельствует только об одном: задачку я себе поставил стрёмную :slight_smile: Буду бодаться, что получится - выложу.