4040 v1.18 - не считаем клики после активации step. held() и hold() тоже могут принимать предварительные клики. Переделан и улучшен дебаунс
4141 v1.18.1 - исправлена ошибка в releaseStep() (не возвращала результат)
4242 v1.18.2 - fix compiler warnings
43+ v1.19 - оптимизация скорости, уменьшен вес в sram
4344*/
4445
4546#ifndef _EncButton_h
@@ -173,7 +174,6 @@ class EncButton {
173174 uint8_t tickISR (uint8_t s1 = 0 , uint8_t s2 = 0 , uint8_t key = 0 ) {
174175 if (!_isrFlag) {
175176 _isrFlag = 1 ;
176-
177177 // обработка энка (компилятор вырежет блок если не используется)
178178 // если объявлены два пина или выбран вирт. энкодер или энкодер с кнопкой
179179 if ((_S1 < 252 && _S2 < 252 ) || _S1 == VIRT_ENC || _S1 == VIRT_ENCBTN) {
@@ -191,7 +191,7 @@ class EncButton {
191191 if (_S1 == VIRT_BTN) _btnState = s1; // вирт кнопка
192192 if (_S1 == VIRT_ENCBTN) _btnState = key; // вирт энк с кнопкой
193193 _btnState ^= _EB_readFlag (11 ); // инверсия кнопки
194- poolBtn ();
194+ if (_btnState || _EB_readFlag ( 15 )) poolBtn (); // опрос если кнопка нажата или не вышли таймауты
195195 }
196196 }
197197 _isrFlag = 0 ;
@@ -254,6 +254,7 @@ class EncButton {
254254 int16_t counter = 0 ; // счётчик энкодера
255255
256256 // ======================================= BTN =======================================
257+ bool busy () { return _EB_readFlag (15 ); } // вернёт true, если всё ещё нужно вызывать tick для опроса таймаутов
257258 bool state () { return _btnState; } // статус кнопки
258259 bool press () { return checkState (8 ); } // кнопка нажата
259260 bool release () { return checkFlag (10 ); } // кнопка отпущена
@@ -317,6 +318,7 @@ class EncButton {
317318 #else // полношаговый
318319 if (state == 0x3 && _ecount != 0 ) { // защёлкнули позицию
319320 #endif
321+ uint16_t ms = millis () & 0xFFFF ;
320322 EBState = (_ecount < 0 ) ? 1 : 2 ;
321323 _ecount = 0 ;
322324 if (_S2 == EB_NO_PIN || _KEY != EB_NO_PIN) { // энкодер с кнопкой
@@ -326,13 +328,14 @@ class EncButton {
326328 counter += _dir; // счётчик
327329 if (EBState <= 2 ) _EB_setFlag (0 ); // флаг поворота для юзера
328330 else if (EBState <= 4 ) _EB_setFlag (9 ); // флаг нажатого поворота для юзера
329- if (millis () - _debTimer < EB_FAST) _EB_setFlag (1 ); // быстрый поворот
331+ if (ms - _debTmr < EB_FAST) _EB_setFlag (1 ); // быстрый поворот
330332 else _EB_clrFlag (1 ); // обычный поворот
331- _debTimer = millis () ;
333+ _debTmr = ms ;
332334 }
333335 }
334336 #else
335337 if (_encRST && state == 0b11 ) { // ресет и энк защёлкнул позицию
338+ uint16_t ms = millis () & 0xFFFF ;
336339 if (_S2 == EB_NO_PIN || _KEY != EB_NO_PIN) { // энкодер с кнопкой
337340 if ((_prev == 1 || _prev == 2 ) && !_EB_readFlag (4 )) { // если кнопка не "удерживается" и энкодер в позиции 1 или 2
338341 EBState = _prev;
@@ -347,12 +350,12 @@ class EncButton {
347350 counter += _dir; // счётчик
348351 if (EBState <= 2 ) _EB_setFlag (0 ); // флаг поворота для юзера
349352 else if (EBState <= 4 ) _EB_setFlag (9 ); // флаг нажатого поворота для юзера
350- if (millis () - _debTimer < EB_FAST) _EB_setFlag (1 ); // быстрый поворот
353+ if (ms - _debTmr < EB_FAST) _EB_setFlag (1 ); // быстрый поворот
351354 else _EB_clrFlag (1 ); // обычный поворот
352355 }
353356
354357 _encRST = 0 ;
355- _debTimer = millis () ;
358+ _debTmr = ms ;
356359 }
357360 if (state == 0b00 ) _encRST = 1 ;
358361 _prev = state;
@@ -361,15 +364,16 @@ class EncButton {
361364
362365 // ===================================== POOL BTN =====================================
363366 void poolBtn () {
364- uint32_t thisMls = millis ();
365- uint32_t debounce = thisMls - _debTimer ;
367+ uint16_t ms = millis () & 0xFFFF ;
368+ uint16_t debounce = ms - _debTmr ;
366369 if (_btnState) { // кнопка нажата
370+ _EB_setFlag (15 ); // busy флаг
367371 if (!_EB_readFlag (3 )) { // и не была нажата ранее
368372 if (_EB_readFlag (14 )) { // ждём дебаунс
369373 if (debounce > EB_DEB) { // прошел дебаунс
370374 _EB_setFlag (3 ); // флаг кнопка была нажата
371375 EBState = 8 ; // кнопка нажата
372- _debTimer = thisMls; // сброс таймаутов
376+ _debTmr = ms; // сброс таймаутов
373377 }
374378 } else { // первое нажатие
375379 EBState = 0 ;
@@ -378,7 +382,7 @@ class EncButton {
378382 clicks = 0 ; // сбросить счётчик и флаг кликов
379383 flags &= ~0b0011000011100000 ; // clear 5 6 7 12 13 (клики)
380384 }
381- _debTimer = thisMls ;
385+ _debTmr = ms ;
382386 }
383387 } else { // кнопка уже была нажата
384388 if (!_EB_readFlag (4 )) { // и удержание ещё не зафиксировано
@@ -388,14 +392,14 @@ class EncButton {
388392 if (!_EB_readFlag (2 )) { // и энкодер не повёрнут
389393 EBState = 6 ; // значит это удержание (сигнал)
390394 flags |= 0b00110000 ; // set 4 5 запомнили что удерживается и отключаем сигнал о кликах
391- _debTimer = thisMls; // сброс таймаута
395+ _debTmr = ms; // сброс таймаута
392396 }
393397 }
394398 } else { // удержание зафиксировано
395399 if (debounce > EB_STEP) { // таймер степа
396400 EBState = 7 ; // сигналим
397401 _EB_setFlag (13 ); // зафиксирован режим step
398- _debTimer = thisMls; // сброс таймаута
402+ _debTmr = ms; // сброс таймаута
399403 }
400404 }
401405 }
@@ -407,11 +411,13 @@ class EncButton {
407411 clicks++;
408412 }
409413 flags &= ~0b00011100 ; // clear 2 3 4
410- _debTimer = thisMls; // сброс таймаута
414+ _debTmr = ms; // сброс таймаута
411415 _EB_setFlag (10 ); // кнопка отпущена
412416 if (checkFlag (13 )) _EB_setFlag (12 ); // кнопка отпущена после step
413417 }
414- } else if (clicks > 0 && debounce > EB_CLICK && !_EB_readFlag (5 )) flags |= 0b11100000 ; // set 5 6 7 (клики)
418+ } else if (clicks && !_EB_readFlag (5 )) { // есть клики
419+ if (debounce > EB_CLICK) flags |= 0b11100000 ; // set 5 6 7 (клики)
420+ } else _EB_clrFlag (15 ); // снимаем busy флаг
415421 checkFlag (14 ); // сброс ожидания нажатия
416422 }
417423 }
@@ -444,7 +450,7 @@ class EncButton {
444450 int8_t _ecount = 0 ;
445451 #endif
446452
447- uint32_t _debTimer = 0 ;
453+ uint16_t _debTmr = 0 ;
448454 uint8_t _holdT = (EB_HOLD >> 7 );
449455 int8_t _dir = 0 ;
450456 void (*_callback[_EB_MODE ? 14 : 0 ])() = {};
@@ -466,6 +472,7 @@ class EncButton {
466472 // 12 - btn released after step
467473 // 13 - step flag
468474 // 14 - deb flag
475+ // 15 - busy flag
469476
470477 // EBState
471478 // 0 - idle
0 commit comments