Skip to content

Commit fdfc185

Browse files
committed
upd
1 parent 9e7c788 commit fdfc185

File tree

7 files changed

+117
-52
lines changed

7 files changed

+117
-52
lines changed

README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,19 +260,22 @@ void setPins(uint8_t mode, uint8_t P1, uint8_t P2, uint8_t P3); // наст
260260
- Основная идея работы: "тикнули", а затем вручную через условия опрашиваем нужные действия кнопки/энкодера. Почти все функции опроса имеют механизм "однократного срабатывания", то есть возвращают `true` и автоматически сбрасываются в `false` до наступления следующего события. Таким образом конструкция `if (btn.click())` позволяет выполнить какой-то блок кода однократно по клику. Подробнее разберём ниже.
261261

262262
#### Кнопка
263-
- `press()` - кнопка была нажата (с антидребезгом). *[однократно вернёт true]*
263+
- `press()` - кнопка была нажата. *[однократно вернёт true]*
264264
- `release()` - кнопка была отпущена. *[однократно вернёт true]*
265-
- `click()` - кнопка была кликнута, т.е. коротко нажата и отпущена (удерживалась больше времени антидребезга, но меньше таймаута удержания). *[однократно вернёт true]*
266-
- `held()` - кнопка была удержана дольше `setHoldTimeout()` таймаута. *[однократно вернёт true]*
267-
- `hold()` - кнопка была удержана дольше `setHoldTimeout()` таймаута. *[возвращает true, пока удерживается]*
268-
- `step()` - режим "импульсного удержания": после удержания кнопки дольше таймаута данная функция *[возвращает true с периодом EB_STEP]*. Удобно использовать для пошагового изменения какой-то величины в программе: `if (btn.step()) val++;`.
269-
- `step(clicks)` - всё то же самое, но функция принимает количество кликов, сделанных до удержания. Это позволяет очень просто контролировать несколько величин одной кнопкой. См. пример *StepMode*.
270-
- `releaseStep()` - кнопка была отпущена после импульсного удержания. Может использоваться для изменения знака инкремента переменной: удерживаем - переменная увеличивается, отпустили, удерживаем ещё раз - уменьшается. См. пример *StepMode*. *[однократно вернёт true]*
271-
- `releaseStep(clicks)` - всё то же самое, но функция принимает количество кликов, сделанных до удержания. См. пример *StepMode*. *[однократно вернёт true]*
265+
- `click()` - кнопка была кликнута, т.е. нажата и отпущена до таймаута удержания. *[однократно вернёт true]*
266+
- `held()` - кнопка была удержана дольше таймаута удержания. *[однократно вернёт true]*
267+
- `held(clicks)` - то же самое, но функция принимает количество кликов, сделанных до удержания. Примечание: held() без аргумента перехватит вызов! См. пример *preClicks*. *[однократно вернёт true]*
268+
- `hold()` - кнопка была удержана дольше таймаута удержания. *[возвращает true, пока удерживается]*
269+
- `hold(clicks)` - то же самое, но функция принимает количество кликов, сделанных до удержания. Примечание: hold() без аргумента перехватит вызов! См. пример *preClicks*. *[возвращает true, пока удерживается]*
270+
- `step()` - режим "импульсного удержания": после удержания кнопки дольше таймаута данная функция *[возвращает true с периодом EB_STEP]*. Удобно использовать для пошагового изменения переменных: `if (btn.step()) val++;`.
271+
- `step(clicks)` - то же самое, но функция принимает количество кликов, сделанных до удержания. Примечание: step() без аргумента перехватит вызов! См. пример *StepMode* и *preClicks*.
272+
- `releaseStep()` - кнопка была отпущена после импульсного удержания. Может использоваться для изменения знака инкремента переменной. См. пример *StepMode*. *[однократно вернёт true]*
273+
- `releaseStep(clicks)` - то же самое, но функция принимает количество кликов, сделанных до удержания. Примечание: releaseStep() без аргумента перехватит вызов! См. пример *StepMode* и *preClicks*. *[однократно вернёт true]*
272274
- `hasClicks(clicks)` - было сделано указанное количество кликов с периодом менее *EB_CLICK*. *[однократно вернёт true]*
273275
- `state()` - возвращает теукщее состояние кнопки (сигнал с пина, без антидребезга): `true` - нажата, `false` - не нажата.
274276
- `hasClicks()` - вернёт количество кликов, сделанных с периодом менее *EB_CLICK*. В противном случае вернёт 0.
275277
- `uint8_t clicks` - публичная переменная (член класса), хранит количество сделанных кликов с периодом менее *EB_CLICK*. Сбрасывается в 0 после нового клика.
278+
![diagram](/doc/diagram.png)
276279

277280
#### Энкодер
278281
- `turn()` - поворот на один щелчок в любую сторону. *[однократно вернёт true]*
@@ -500,6 +503,7 @@ void loop() {
500503
- v1.15 - добавлен setPins() для EncButton2
501504
- v1.16 - добавлен режим EB_HALFSTEP_ENC для полушаговых энкодеров
502505
- v1.17 - добавлен step с предварительными кликами
506+
- v1.18 - не считаем клики после активации step. held() и hold() тоже могут принимать предварительные клики. Переделан и улучшен дебаунс
503507

504508
<a id="feedback"></a>
505509
## Баги и обратная связь

doc/diagram.png

44.2 KB
Loading

examples/preClicks/preClicks.ino

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// срабатывание функций held/hold/step после предварительных кликов
2+
3+
#include <EncButton.h>
4+
EncButton<EB_TICK, 3> btn;
5+
6+
void setup() {
7+
Serial.begin(9600);
8+
}
9+
10+
void loop() {
11+
btn.tick();
12+
if (btn.click()) Serial.println("click");
13+
14+
// вызов без количества кликов перехватит все остальные вызовы!
15+
//if (btn.held()) Serial.println("held any clicks");
16+
if (btn.held(0)) Serial.println("held after 0 clicks");
17+
if (btn.held(2)) Serial.println("held after 2 clicks");
18+
19+
// вызов без количества кликов перехватит все остальные вызовы!
20+
//if (btn.hold()) Serial.println("hold any clicks");
21+
//if (btn.hold(0)) Serial.println("hold after 0 clicks");
22+
//if (btn.hold(2)) Serial.println("hold after 2 clicks");
23+
24+
// вызов без количества кликов перехватит все остальные вызовы!
25+
//if (btn.step()) Serial.println("step after any clicks");
26+
if (btn.step(0)) Serial.println("step after 0 clicks");
27+
if (btn.step(2)) Serial.println("step after 2 clicks");
28+
29+
// вызов без количества кликов перехватит все остальные вызовы!
30+
//if (btn.releaseStep()) Serial.println("release step after any clicks");
31+
if (btn.releaseStep(0)) Serial.println("release step after 0 clicks");
32+
if (btn.releaseStep(2)) Serial.println("release step after 2 clicks");
33+
}

examples/tickMode/tickMode.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
//#define EB_CLICK 400 // таймаут накликивания, мс
1010

1111
#include <EncButton.h>
12-
EncButton<EB_TICK, 2, 3, 4> enc; // энкодер с кнопкой <A, B, KEY>
12+
//EncButton<EB_TICK, 2, 3, 4> enc; // энкодер с кнопкой <A, B, KEY>
1313
//EncButton<EB_TICK, 2, 3> enc; // просто энкодер <A, B>
14-
//EncButton<EB_TICK, 4> enc; // просто кнопка <KEY>
14+
EncButton<EB_TICK, 3> enc; // просто кнопка <KEY>
1515
// для изменения направления энкодера поменяй A и B при инициализации
1616

1717
// по умолчанию пины настроены в INPUT_PULLUP

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=EncButton
2-
version=1.17
2+
version=1.18
33
author=AlexGyver <[email protected]>
44
maintainer=AlexGyver <[email protected]>
55
sentence=Light and fast library for button and encoder operation for Arduino

src/EncButton.h

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
v1.15 - добавлен setPins() для EncButton2
3838
v1.16 - добавлен режим EB_HALFSTEP_ENC для полушаговых энкодеров
3939
v1.17 - добавлен step с предварительными кликами
40+
v1.18 - не считаем клики после активации step. held() и hold() тоже могут принимать предварительные клики. Переделан и улучшен дебаунс
4041
*/
4142

4243
#ifndef _EncButton_h
@@ -246,6 +247,7 @@ class EncButton {
246247
bool fast() { return _EB_readFlag(1); } // быстрый поворот
247248
bool turn() { return checkFlag(0); } // энкодер повёрнут
248249
bool turnH() { return checkFlag(9); } // энкодер повёрнут нажато
250+
249251
int8_t getDir() { return _dir; } // направление последнего поворота, 1 или -1
250252
int16_t counter = 0; // счётчик энкодера
251253

@@ -254,19 +256,23 @@ class EncButton {
254256
bool press() { return checkState(8); } // кнопка нажата
255257
bool release() { return checkFlag(10); } // кнопка отпущена
256258
bool click() { return checkState(5); } // клик по кнопке
259+
257260
bool held() { return checkState(6); } // кнопка удержана
258261
bool hold() { return _EB_readFlag(4); } // кнопка удерживается
259-
bool step(uint8_t clk = 0) { return (clicks == clk) ? checkState(7) : 0; } // режим импульсного удержания с предварительным накликиванием
260-
bool releaseStep(uint8_t clk = 0) { return (clicks == clk) ? checkFlag(12) : 0; } // кнопка отпущена после импульсного удержания с предварительным накликиванием
262+
bool step() { return checkState(7); } // режим импульсного удержания
263+
bool releaseStep() { checkFlag(12); } // кнопка отпущена после импульсного удержания
264+
265+
bool held(uint8_t clk) { return (clicks == clk) ? checkState(6) : 0; } // кнопка удержана с предварительным накликиванием
266+
bool hold(uint8_t clk) { return (clicks == clk) ? _EB_readFlag(4) : 0; } // кнопка удерживается с предварительным накликиванием
267+
bool step(uint8_t clk) { return (clicks == clk) ? checkState(7) : 0; } // режим импульсного удержания с предварительным накликиванием
268+
bool releaseStep(uint8_t clk) { return (clicks == clk) ? checkFlag(12) : 0; } // кнопка отпущена после импульсного удержания с предварительным накликиванием
261269

262270
uint8_t clicks = 0; // счётчик кликов
263-
bool hasClicks(uint8_t num) { return (clicks == num && checkFlag(7)) ? 1 : 0; } // имеются клики
264-
uint8_t hasClicks() { return checkFlag(6) ? clicks : 0; } // имеются клики
271+
bool hasClicks(uint8_t num) { return (clicks == num && checkFlag(7)) ? 1 : 0; } // имеются клики
272+
uint8_t hasClicks() { return checkFlag(6) ? clicks : 0; } // имеются клики
265273

266274
// ===================================================================================
267275
// =================================== DEPRECATED ====================================
268-
//bool step() { return checkState(7); } // режим импульсного удержания
269-
//bool releaseStep() { return checkFlag(12); } // кнопка отпущена после импульсного удержания
270276
bool isStep() { return step(); }
271277
bool isHold() { return hold(); }
272278
bool isHolded() { return held(); }
@@ -357,14 +363,20 @@ class EncButton {
357363
uint32_t debounce = thisMls - _debTimer;
358364
if (_btnState) { // кнопка нажата
359365
if (!_EB_readFlag(3)) { // и не была нажата ранее
360-
if (debounce > EB_DEB) { // и прошел дебаунс
361-
_EB_setFlag(3); // флаг кнопка была нажата
362-
_debTimer = thisMls; // сброс таймаутов
363-
EBState = 8; // кнопка нажата
364-
}
365-
if (debounce > EB_CLICK) { // кнопка нажата после EB_CLICK
366-
clicks = 0; // сбросить счётчик и флаг кликов
367-
flags &= ~0b0011000011100000; // clear 5 6 7 12 13 (клики)
366+
if (_EB_readFlag(14)) { // ждём дебаунс
367+
if (debounce > EB_DEB) { // прошел дебаунс
368+
_EB_setFlag(3); // флаг кнопка была нажата
369+
EBState = 8; // кнопка нажата
370+
_debTimer = thisMls; // сброс таймаутов
371+
}
372+
} else { // первое нажатие
373+
EBState = 0;
374+
_EB_setFlag(14); // запомнили что хотим нажать
375+
if (debounce > EB_CLICK || _EB_readFlag(5)) { // кнопка нажата после EB_CLICK
376+
clicks = 0; // сбросить счётчик и флаг кликов
377+
flags &= ~0b0011000011100000; // clear 5 6 7 12 13 (клики)
378+
}
379+
_debTimer = thisMls;
368380
}
369381
} else { // кнопка уже была нажата
370382
if (!_EB_readFlag(4)) { // и удержание ещё не зафиксировано
@@ -373,7 +385,7 @@ class EncButton {
373385
} else { // прошло больше времени удержания
374386
if (!_EB_readFlag(2)) { // и энкодер не повёрнут
375387
EBState = 6; // значит это удержание (сигнал)
376-
_EB_setFlag(4); // запомнили что удерживается
388+
flags |= 0b00110000; // set 4 5 запомнили что удерживается и отключаем сигнал о кликах
377389
_debTimer = thisMls; // сброс таймаута
378390
}
379391
}
@@ -389,15 +401,16 @@ class EncButton {
389401
if (_EB_readFlag(3)) { // но была нажата
390402
if (debounce > EB_DEB) {
391403
if (!_EB_readFlag(4) && !_EB_readFlag(2)) { // энкодер не трогали и не удерживали - это клик
392-
EBState = 5;
404+
EBState = 5; // click
393405
clicks++;
394406
}
395-
flags &= ~0b00011100; // clear 2 3 4
396-
_debTimer = thisMls; // сброс таймаута
397-
_EB_setFlag(10); // кнопка отпущена
398-
if (checkFlag(13)) _EB_setFlag(12); // кнопка отпущена после step
407+
flags &= ~0b00011100; // clear 2 3 4
408+
_debTimer = thisMls; // сброс таймаута
409+
_EB_setFlag(10); // кнопка отпущена
410+
if (checkFlag(13)) _EB_setFlag(12); // кнопка отпущена после step
399411
}
400412
} else if (clicks > 0 && debounce > EB_CLICK && !_EB_readFlag(5)) flags |= 0b11100000; // set 5 6 7 (клики)
413+
checkFlag(14); // сброс ожидания нажатия
401414
}
402415
}
403416

@@ -450,6 +463,7 @@ class EncButton {
450463
// 11 - btn level
451464
// 12 - btn released after step
452465
// 13 - step flag
466+
// 14 - deb flag
453467

454468
// EBState
455469
// 0 - idle

0 commit comments

Comments
 (0)