diff --git a/README.md b/README.md index d693cb4..e84b391 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,6 @@ Объявлять до подключения библиотеки ```cpp -// отключить привязку к библиотеке GyverIO и использовать стандартный digitalRead -#define EB_NO_GYVER_IO // отключить поддержку pressFor/holdFor/stepFor и счётчик степов (экономит 2 байта оперативки) #define EB_NO_FOR @@ -143,10 +141,6 @@ // отключить буферизацию энкодера (экономит 2 байта оперативки) #define EB_NO_BUFFER -// кастомные функции -#define EB_CUSTOM_READ // использовать своё чтение пина -#define EB_CUSTOM_UPTIME // использовать свой таймер - /* Настройка таймаутов для всех классов - Заменяет таймауты константами, изменить их из программы (SetXxxTimeout()) будет нельзя @@ -1214,23 +1208,14 @@ void loop() { ### Кастомные функции -Библиотека поддерживает задание своих функций для чтения пина и получения времени без редактирования файлов библиотеки. Для этого нужно: -- Объявить соответствующий дефайн перед подключением библиотеки - - `EB_CUSTOM_READ` - для своей функции чтения пина - - `EB_CUSTOM_UPTIME` - для своего аналога millis() - - `EB_CUSTOM_MODE` - для своего аналога pinMode() -- Реализовать соответствующую функцию в .cpp или .ino файле - - `EB_read` - для своей функции чтения пина - - `EB_uptime` - для своего аналога millis() - - `EB_mode` - для своего аналога pinMode +Библиотека поддерживает задание своих функций для чтения пина и получения времени без редактирования файлов библиотеки. Для этого нужно реализовать соответствующую функцию в своём .cpp или .ino файле: +- `bool EB_read(uint8_t pin)` - для своей функции чтения пина +- `void EB_mode(uint8_t pin, uint8_t mode)` - для своего аналога pinMode +- `uint32_t EB_uptime()` - для своего аналога millis() Пример: ```cpp -#define EB_CUSTOM_READ -#define EB_CUSTOM_MODE -#define EB_CUSTOM_UPTIME - #include bool EB_read(uint8_t pin) { @@ -1780,6 +1765,10 @@ void loop() { - v3.5 - Добавлена зависимость GyverIO (ускорен опрос пинов) - Добавлена возможность задать свои функции аптайма и чтения пина +- v3.5.2 + - Оптимизация + - Упрощена замена кастомных функций + - Исправлена ошибка компиляции при использовании библиотеки в нескольких .cpp файлах ## Баги и обратная связь diff --git a/keywords.txt b/keywords.txt index a87fb08..d308134 100644 --- a/keywords.txt +++ b/keywords.txt @@ -24,11 +24,6 @@ EB_HOLD_TIME KEYWORD1 EB_STEP_TIME KEYWORD1 EB_FAST_TIME KEYWORD1 -EB_NO_GYVER_IO KEYWORD1 -EB_CUSTOM_READ KEYWORD1 -EB_CUSTOM_MODE KEYWORD1 -EB_CUSTOM_UPTIME KEYWORD1 - ####################################### # Methods and Functions (KEYWORD2) ####################################### diff --git a/library.properties b/library.properties index 410de21..d923057 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=EncButton -version=3.5.1 +version=3.5.2 author=AlexGyver maintainer=AlexGyver sentence=Light and powerful library for button and encoder operation for Arduino diff --git a/src/core/Button.h b/src/core/Button.h index f0689c0..ca53345 100644 --- a/src/core/Button.h +++ b/src/core/Button.h @@ -2,7 +2,7 @@ #include #include "VirtButton.h" -#include "utils.h" +#include "io.h" // ============= VAR PIN ============= class Button : public VirtButton { diff --git a/src/core/EncButton.h b/src/core/EncButton.h index d4d3b2c..44d7cfa 100644 --- a/src/core/EncButton.h +++ b/src/core/EncButton.h @@ -2,7 +2,7 @@ #include #include "VirtEncButton.h" -#include "utils.h" +#include "io.h" // ===================== CLASS ===================== class EncButton : public VirtEncButton { diff --git a/src/core/Encoder.h b/src/core/Encoder.h index 3509422..584b6b7 100644 --- a/src/core/Encoder.h +++ b/src/core/Encoder.h @@ -2,7 +2,7 @@ #include #include "VirtEncoder.h" -#include "utils.h" +#include "io.h" // ============= VAR PIN ============= class Encoder : public VirtEncoder { diff --git a/src/core/VirtButton.h b/src/core/VirtButton.h index 318454e..9c389dc 100644 --- a/src/core/VirtButton.h +++ b/src/core/VirtButton.h @@ -1,7 +1,7 @@ #pragma once #include -#include "utils.h" +#include "io.h" // ===================== FLAGS ====================== #define EB_PRESS (1 << 0) // нажатие на кнопку @@ -67,35 +67,35 @@ class VirtButton { public: // ====================== SET ====================== // установить таймаут удержания, умолч. 600 (макс. 4000 мс) - void setHoldTimeout(uint16_t tout) { + void setHoldTimeout(const uint16_t& tout) { #ifndef EB_HOLD_TIME EB_HOLD_T = tout >> EB_SHIFT; #endif } // установить таймаут импульсного удержания, умолч. 200 (макс. 4000 мс) - void setStepTimeout(uint16_t tout) { + void setStepTimeout(const uint16_t& tout) { #ifndef EB_STEP_TIME EB_STEP_T = tout >> EB_SHIFT; #endif } // установить таймаут ожидания кликов, умолч. 500 (макс. 4000 мс) - void setClickTimeout(uint16_t tout) { + void setClickTimeout(const uint16_t& tout) { #ifndef EB_CLICK_TIME EB_CLICK_T = tout >> EB_SHIFT; #endif } // установить таймаут антидребезга, умолч. 50 (макс. 255 мс) - void setDebTimeout(uint8_t tout) { + void setDebTimeout(const uint8_t& tout) { #ifndef EB_DEB_TIME EB_DEB_T = tout; #endif } // установить уровень кнопки (HIGH - кнопка замыкает VCC, LOW - замыкает GND) - void setBtnLevel(bool level) { + void setBtnLevel(const bool& level) { write_bf(EB_INV, !level); } @@ -160,7 +160,7 @@ class VirtButton { } // кнопка была удержана (больше таймаута) с предварительными кликами [событие] - bool hold(uint8_t num) { + bool hold(const uint8_t& num) { return clicks == num && hold(); } @@ -170,7 +170,7 @@ class VirtButton { } // кнопка удерживается (больше таймаута) с предварительными кликами [состояние] - bool holding(uint8_t num) { + bool holding(const uint8_t& num) { return clicks == num && holding(); } @@ -180,7 +180,7 @@ class VirtButton { } // импульсное удержание с предварительными кликами [событие] - bool step(uint8_t num) { + bool step(const uint8_t& num) { return clicks == num && step(); } @@ -190,7 +190,7 @@ class VirtButton { } // зафиксировано указанное количество кликов [событие] - bool hasClicks(uint8_t num) { + bool hasClicks(const uint8_t& num) { return clicks == num && hasClicks(); } @@ -217,7 +217,7 @@ class VirtButton { } // кнопка отпущена после удержания с предварительными кликами [событие] - bool releaseHold(uint8_t num) { + bool releaseHold(const uint8_t& num) { return clicks == num && eq_bf(EB_CLKS_R | EB_HLD | EB_STP, EB_CLKS_R | EB_HLD); } @@ -227,7 +227,7 @@ class VirtButton { } // кнопка отпущена после импульсного удержания с предварительными кликами [событие] - bool releaseStep(uint8_t num) { + bool releaseStep(const uint8_t& num) { return clicks == num && eq_bf(EB_CLKS_R | EB_STP, EB_CLKS_R | EB_STP); } @@ -272,7 +272,7 @@ class VirtButton { // ====================== TIME ====================== // после взаимодействия с кнопкой (или энкодером EncButton) прошло указанное время, мс [событие] - bool timeout(uint16_t tout) { + bool timeout(const uint16_t& tout) { if (read_bf(EB_TOUT) && (uint16_t)((uint16_t)EB_uptime() - tmr) > tout) { clr_bf(EB_TOUT); return 1; @@ -289,7 +289,7 @@ class VirtButton { } // кнопка удерживается дольше чем (с начала нажатия), мс [состояние] - bool pressFor(uint16_t ms) { + bool pressFor(const uint16_t& ms) { return pressFor() > ms; } @@ -308,7 +308,7 @@ class VirtButton { } // кнопка удерживается дольше чем (с начала удержания), мс [состояние] - bool holdFor(uint16_t ms) { + bool holdFor(const uint16_t& ms) { return holdFor() > ms; } @@ -358,7 +358,7 @@ class VirtButton { } // обработка кнопки без сброса событий и вызова коллбэка - bool tickRaw(bool s) { + bool tickRaw(const bool& s) { return pollBtn(s); } @@ -480,20 +480,20 @@ class VirtButton { uint8_t EB_STEP_T = (200 >> EB_SHIFT); #endif - inline void set_bf(const uint16_t x) __attribute__((always_inline)) { + inline void set_bf(const uint16_t& x) __attribute__((always_inline)) { flags |= x; } - inline void clr_bf(const uint16_t x) __attribute__((always_inline)) { + inline void clr_bf(const uint16_t& x) __attribute__((always_inline)) { flags &= ~x; } - inline bool read_bf(const uint16_t x) __attribute__((always_inline)) { + inline bool read_bf(const uint16_t& x) __attribute__((always_inline)) { return flags & x; } - inline void write_bf(const uint16_t x, bool v) __attribute__((always_inline)) { + inline void write_bf(const uint16_t& x, const bool& v) __attribute__((always_inline)) { if (v) set_bf(x); else clr_bf(x); } - inline bool eq_bf(const uint16_t x, const uint16_t y) __attribute__((always_inline)) { + inline bool eq_bf(const uint16_t& x, const uint16_t& y) __attribute__((always_inline)) { return (flags & x) == y; } diff --git a/src/core/VirtEncButton.h b/src/core/VirtEncButton.h index 6d7e0d8..bc0c143 100644 --- a/src/core/VirtEncButton.h +++ b/src/core/VirtEncButton.h @@ -3,7 +3,7 @@ #include "VirtButton.h" #include "VirtEncoder.h" -#include "utils.h" +#include "io.h" #ifdef EB_FAST_TIME #define EB_FAST_T (EB_FAST_TIME) @@ -14,7 +14,7 @@ class VirtEncButton : public VirtButton, public VirtEncoder { public: // ====================== SET ====================== // установить таймаут быстрого поворота, мс - void setFastTimeout(uint8_t tout) { + void setFastTimeout(const uint8_t& tout) { #ifndef EB_FAST_TIME EB_FAST_T = tout; #endif @@ -71,7 +71,7 @@ class VirtEncButton : public VirtButton, public VirtEncoder { // ====================== POLL ====================== // ISR // обработка в прерывании (только энкодер). Вернёт 0 в покое, 1 или -1 при повороте - int8_t tickISR(bool e0, bool e1) { + int8_t tickISR(const bool& e0, const bool& e1) { return tickISR(e0 | (e1 << 1)); } @@ -99,12 +99,12 @@ class VirtEncButton : public VirtButton, public VirtEncoder { // TICK // обработка энкодера и кнопки - bool tick(bool e0, bool e1, bool btn) { + bool tick(const bool& e0, const bool& e1, const bool& btn) { return tick(e0 | (e1 << 1), btn); } // обработка энкодера и кнопки. state = -1 для пропуска обработки энкодера - bool tick(int8_t state, bool btn) { + bool tick(const int8_t& state, const bool& btn) { clear(); bool f = tickRaw(state, btn); @@ -115,13 +115,13 @@ class VirtEncButton : public VirtButton, public VirtEncoder { } // обработка энкодера (в прерывании) и кнопки - bool tick(bool btn) { + bool tick(const bool& btn) { return tick(-1, btn); } // RAW // обработка без сброса событий и вызова коллбэка - bool tickRaw(bool e0, bool e1, bool btn) { + bool tickRaw(const bool& e0, const bool& e1, const bool& btn) { return tickRaw(e0 | (e1 << 1), btn); } @@ -158,7 +158,7 @@ class VirtEncButton : public VirtButton, public VirtEncoder { } // обработка без сброса событий и вызова коллбэка (кнопка) - bool tickRaw(bool btn) { + bool tickRaw(const bool& btn) { return tickRaw(-1, btn); } diff --git a/src/core/VirtEncoder.h b/src/core/VirtEncoder.h index 20c2027..636118b 100644 --- a/src/core/VirtEncoder.h +++ b/src/core/VirtEncoder.h @@ -1,7 +1,7 @@ #pragma once #include -#include "utils.h" +#include "io.h" // ===================== CONST ====================== #define EB_STEP4_LOW 0 @@ -26,28 +26,28 @@ class VirtEncoder { } // ====================== SET ====================== // инвертировать направление энкодера - void setEncReverse(bool rev) { + void setEncReverse(const bool& rev) { if (rev) set_ef(EB_REV); else clr_ef(EB_REV); } // установить тип энкодера (EB_STEP4_LOW, EB_STEP4_HIGH, EB_STEP2, EB_STEP1) - void setEncType(uint8_t type) { + void setEncType(const uint8_t& type) { flags = (flags & 0b11111100) | type; } // использовать обработку энкодера в прерывании - void setEncISR(bool use) { + void setEncISR(const bool& use) { write_ef(EB_EISR, use); } // инициализация энкодера - void initEnc(bool e0, bool e1) { + void initEnc(const bool& e0, const bool& e1) { initEnc(e0 | (e1 << 1)); } // инициализация энкодера совмещённым значением - void initEnc(int8_t v) { + void initEnc(const int8_t& v) { prev = v; } @@ -70,7 +70,7 @@ class VirtEncoder { // ====================== POLL ====================== // ISR // опросить энкодер в прерывании. Вернёт 1 или -1 при вращении, 0 при остановке - int8_t tickISR(bool e0, bool e1) { + int8_t tickISR(const bool& e0, const bool& e1) { return tickISR(e0 | (e1 << 1)); } @@ -86,7 +86,7 @@ class VirtEncoder { // TICK // опросить энкодер. Вернёт 1 или -1 при вращении, 0 при остановке - int8_t tick(bool e0, bool e1) { + int8_t tick(const bool& e0, const bool& e1) { return tick(e0 | (e1 << 1)); } @@ -105,7 +105,7 @@ class VirtEncoder { // RAW // опросить энкодер без сброса события поворота - int8_t tickRaw(bool e0, bool e1) { + int8_t tickRaw(const bool& e0, const bool& e1) { return tickRaw(e0 | (e1 << 1)); } @@ -131,7 +131,7 @@ class VirtEncoder { // POLL // опросить энкодер без установки события поворота (быстрее). Вернёт 1 или -1 при вращении, 0 при остановке - int8_t pollEnc(bool e0, bool e1) { + int8_t pollEnc(const bool& e0, const bool& e1) { return pollEnc(e0 | (e1 << 1)); } @@ -168,17 +168,17 @@ class VirtEncoder { // ===================== PRIVATE ===================== protected: - inline void set_ef(const uint16_t x) __attribute__((always_inline)) { + inline void set_ef(const uint16_t& x) __attribute__((always_inline)) { flags |= x; } - inline void clr_ef(const uint16_t x) __attribute__((always_inline)) { + inline void clr_ef(const uint16_t& x) __attribute__((always_inline)) { flags &= ~x; } - inline void write_ef(const uint16_t x, bool v) __attribute__((always_inline)) { + inline void write_ef(const uint16_t& x, const bool& v) __attribute__((always_inline)) { if (v) set_ef(x); else clr_ef(x); } - inline bool read_ef(const uint16_t x) __attribute__((always_inline)) { + inline bool read_ef(const uint16_t& x) __attribute__((always_inline)) { return flags & x; } diff --git a/src/core/io.cpp b/src/core/io.cpp new file mode 100644 index 0000000..1952b23 --- /dev/null +++ b/src/core/io.cpp @@ -0,0 +1,13 @@ +#include "io.h" + +bool __attribute__((weak)) EB_read(uint8_t pin) { + return gio::read(pin); +} + +void __attribute__((weak)) EB_mode(uint8_t pin, uint8_t mode) { + gio::mode(pin, mode); +} + +uint32_t __attribute__((weak)) EB_uptime() { + return millis(); +} \ No newline at end of file diff --git a/src/core/io.h b/src/core/io.h new file mode 100644 index 0000000..c761bae --- /dev/null +++ b/src/core/io.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +bool EB_read(uint8_t pin); +void EB_mode(uint8_t pin, uint8_t mode); +uint32_t EB_uptime(); \ No newline at end of file diff --git a/src/core/utils.h b/src/core/utils.h deleted file mode 100644 index 9a5b91a..0000000 --- a/src/core/utils.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include - -#if !defined(EB_NO_GYVER_IO) && !defined(EB_CUSTOM_READ) -#include -#endif - -bool EB_read(uint8_t pin); -void EB_mode(uint8_t pin, uint8_t mode); -uint32_t EB_uptime(); - -// ==================== - -#ifndef EB_CUSTOM_READ -bool EB_read(uint8_t pin) { -#ifndef EB_NO_GYVER_IO - return gio::read(pin); -#else - return digitalRead(pin); -#endif -} -#endif - -#ifndef EB_CUSTOM_MODE -void EB_mode(uint8_t pin, uint8_t mode) { - pinMode(pin, mode); -} -#endif - -#ifndef EB_CUSTOM_UPTIME -uint32_t EB_uptime() { - return millis(); -} -#endif \ No newline at end of file