You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// обработка в прерывании (только энкодер). Вернёт 0 в покое, 1 или -1 при повороте
421
438
int8_t tickISR(bool e0, bool e1);
422
-
423
-
// обработка в прерывании (только энкодер). Вернёт 0 в покое, 1 или -1 при повороте
424
439
int8_t tickISR(int8_t e01);
425
440
426
441
// обработка энкодера и кнопки
427
442
bool tick(bool e0, bool e1, bool btn);
428
443
bool tick(int8_t e01, bool btn);
429
444
bool tick(bool btn); // энкодер в прерывании
445
+
446
+
// обработка энкодера и кнопки без сброса флагов и вызова коллбэка
447
+
bool tickRaw(bool e0, bool e1, bool btn);
448
+
bool tickRaw(int8_t e01, bool btn);
449
+
bool tickRaw(bool btn); // энкодер в прерывании
430
450
```
431
451
</details>
432
452
<details>
@@ -450,6 +470,9 @@ bool read();
450
470
451
471
// функция обработки, вызывать в loop
452
472
bool tick();
473
+
474
+
// обработка кнопки без сброса событий и вызова коллбэка
475
+
bool tickRaw();
453
476
```
454
477
</details>
455
478
<details>
@@ -631,18 +654,93 @@ void loop() {
631
654
}
632
655
```
633
656
657
+
Если библиотека используется с подключенным обработчиком событий `attach()` (см. ниже), то можно вызывать `tick()` где угодно и сколько угодно раз, события будут обработаны в обработчике:
658
+
```cpp
659
+
voidcb() {
660
+
switch (btn.action()) {
661
+
// ...
662
+
}
663
+
}
664
+
665
+
voidsetup() {
666
+
btn.attach(cb);
667
+
}
668
+
669
+
voidloop() {
670
+
btn.tick();
671
+
// ...
672
+
btn.tick();
673
+
// ...
674
+
btn.tick();
675
+
}
676
+
```
677
+
634
678
#### "Загруженная" программа
635
679
Библиотека EncButton - **асинхронная**: она не ждёт, пока закончится обработка кнопки, а позволяет программе выполняться дальше. Это означает, что для корректной работы библиотеки основной цикл программы должен выполняться как можно быстрее и не содержать задержек и других "глухих" циклов внутри себя. Для обеспечения правильной обработки кнопки не рекомендуется иметь в основном цикле задержки длительностью более 50-100 мс. Несколько советов:
636
-
- Новичкам: изучите цикл уроков [Как написать скетч](https://alexgyver.ru/lessons/how-to-sketch/)
637
-
-Пишите асинхронный код в `loop()`
680
+
- Новичкам: изучить цикл уроков [как написать скетч](https://alexgyver.ru/lessons/how-to-sketch/)
681
+
-Писать асинхронный код в `loop()`
638
682
- Любую синхронную конструкцию на `delay()` можно сделать асинхронной при помощи `millis()`
639
-
- Если в вашей программе *каждая* итерация главного цикла выполняется дольше 50-100мс - в большинстве случаев программа написана неправильно, за исключением каких-то особых случаев
640
-
-Подключите кнопку на аппаратное прерывание (см. ниже)
641
-
-Избегайте выполнения "тяжёлых" участков кода, пока идёт обработка кнопки, например поместив их в условие `if (!button.busy()) { тяжёлый код }`
642
-
- Если оптимизировать основной цикл невозможно - вызывайте обработчик в другом "потоке":
683
+
- Если в программе *каждая* итерация главного цикла выполняется дольше 50-100мс - в большинстве случаев программа написана неправильно, за исключением каких-то особых случаев
684
+
-Подключить кнопку на аппаратное прерывание (см. ниже)
685
+
-Избегать выполнения "тяжёлых" участков кода, пока идёт обработка кнопки, например поместив их в условие `if (!button.busy()) { тяжёлый код }`
686
+
- Если оптимизировать основной цикл невозможно - вызывать тикер в другом "потоке" и использовать функцию-обработчик:
643
687
- В прерывании таймера с периодом ~50мс или чаще
644
688
- На другом ядре (например ESP32)
645
689
- В другом таске FreeRTOS
690
+
- Внутри `yield()` (внутри `delay()`)
691
+
692
+
#### Раздельная обработка
693
+
> Имеет смысл только при ручном опросе событий! При подключенной функции-обработчике достаточно вызывать обычный `tick()` между тяжёлыми участками программы
694
+
695
+
Также в загруженной программе можно разделить обработку и сброс событий: вместо `tick()` использовать `tickRaw()` между тяжёлыми участками кода и ручной сброс `clear()`. Порядок следующий:
696
+
- Опросить действия (click, press, turn...)
697
+
- Вызвать `clear()`
698
+
- Вызывать `tickRaw()` между тяжёлыми участками кода
699
+
700
+
```cpp
701
+
voidloop() {
702
+
if (btn.click()) ...
703
+
if (btn.press()) ...
704
+
if (btn.step()) ...
705
+
706
+
btn.clear();
707
+
708
+
// ...
709
+
btn.tickRaw();
710
+
// ...
711
+
btn.tickRaw();
712
+
// ...
713
+
btn.tickRaw();
714
+
// ...
715
+
}
716
+
```
717
+
Это позволит опрашивать кнопку/энкодер в не очень хорошо написанной программе, где основной цикл завален тяжёлым кодом. Внутри `tickRaw()` накапливаются события, которые раз в цикл разбираются, а затем вручную сбрасываются.
718
+
719
+
> В этом сценарии буферизация энкодера в прерывании не работает и не обрабатываются все события `releaseXxx`
720
+
721
+
#### Обработка внутри delay
722
+
Если сложно избавиться от `delay()` внутри главного цикла программы, то на некоторых платформах можно поместить свой код внутри него. Таким образом можно получить даже обработку энкодера в цикле с дилеями без использования прерываний:
723
+
```cpp
724
+
// вставка кода в delay
725
+
voidyield() {
726
+
eb.tickRaw();
727
+
}
728
+
729
+
voidloop() {
730
+
if (eb.click()) ...
731
+
if (btn.turn()) ...
732
+
733
+
eb.clear();
734
+
735
+
// ...
736
+
delay(10);
737
+
// ...
738
+
delay(50);
739
+
// ...
740
+
}
741
+
```
742
+
743
+
> В этом сценарии буферизация энкодера в прерывании не работает и не обрабатываются все события `releaseXxx`
646
744
647
745
#### Обработка кнопки
648
746
Библиотека обрабатывает кнопку следующим образом:
@@ -1411,6 +1509,9 @@ void loop() {
1411
1509
- Сильно оптимизирована скорость работы action() (общий обработчик)
1412
1510
- Добавлено подключение внешней функции-обработчика событий
1413
1511
- Добавлена обработка кнопки в прерывании - pressISR()
1512
+
- v3.2
1513
+
- Добавлены функции tickRaw() и clear() для всех классов. Позволяет проводить раздельную обработку (см. доку)
1514
+
- Улучшена обработка кнопки с использованием прерываний
0 commit comments