From e2ed653e9aa54c99bea57b5bdaeedb8e6ce10300 Mon Sep 17 00:00:00 2001 From: 0xPIT Date: Tue, 27 May 2014 20:44:59 +0200 Subject: [PATCH 1/4] remove link to branches --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index d954b8a..30dbc66 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,8 @@ ClickEncoder ============= > Arduino library to handle rotary encoders **with** buttons as a user input device. -Atmel AVR C++ RotaryEncoder with Button Implementation. +Arduino RotaryEncoder with Button Implementation. -**See Arduino Library in the [Branch arduino]** - Timer-Based: Works on any IO-Pin. - Supports rotary acceleration, so when the encoder is rotated faster, the encoders value will increment faster From 65166bced855e801916f4afd2eb48dde774694ae Mon Sep 17 00:00:00 2001 From: Andy Huntington Date: Mon, 9 Nov 2015 19:06:04 +0000 Subject: [PATCH 2/4] move accelerationEnabled Moved the accelerationEnabled declaration outside of the WITHOUT_BUTTON #ifndef as it wouldn't compile when setting WITHOUT_BUTTON. --- ClickEncoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClickEncoder.h b/ClickEncoder.h index 73f9f41..8148579 100644 --- a/ClickEncoder.h +++ b/ClickEncoder.h @@ -103,13 +103,13 @@ class ClickEncoder volatile int16_t last; uint8_t steps; volatile uint16_t acceleration; + bool accelerationEnabled; #if ENC_DECODER != ENC_NORMAL static const int8_t table[16]; #endif #ifndef WITHOUT_BUTTON volatile Button button; bool doubleClickEnabled; - bool accelerationEnabled; #endif }; From 253b26c4cb1486fe9648a78c189effc4d221a51e Mon Sep 17 00:00:00 2001 From: Valerii Koval Date: Mon, 25 Apr 2016 09:04:29 +0300 Subject: [PATCH 3/4] @PlatformIO Library Registry manifest file --- library.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 library.json diff --git a/library.json b/library.json new file mode 100644 index 0000000..ce6c3b8 --- /dev/null +++ b/library.json @@ -0,0 +1,12 @@ +{ + "name": "ClickEncoder", + "keywords": "encoder, button, input", + "description": "Arduino library to handle rotary encoders with buttons as a user input device", + "repository": + { + "type": "git", + "url": "https://github.com/0xPIT/encoder.git" + }, + "frameworks": "arduino", + "platforms": "atmelavr" +} From fa0139d5e0841054eae4257cdd48ee27bb6195c1 Mon Sep 17 00:00:00 2001 From: Anthony Batchelor Date: Mon, 6 Feb 2017 21:39:22 +0000 Subject: [PATCH 4/4] Fix #2 - Using buttons with multiple encoders Move static variable into header file to fix handling of multiple rotary encoders with buttons. --- ClickEncoder.cpp | 36 ++++--- ClickEncoder.h | 239 ++++++++++++++++++++++++----------------------- 2 files changed, 137 insertions(+), 138 deletions(-) diff --git a/ClickEncoder.cpp b/ClickEncoder.cpp index 4ca135b..af43f6d 100644 --- a/ClickEncoder.cpp +++ b/ClickEncoder.cpp @@ -4,7 +4,7 @@ // // (c) 2010 karl@pitrich.com // (c) 2014 karl@pitrich.com -// +// // Timer-based rotary encoder logic by Peter Dannegger // http://www.mikrocontroller.net/articles/Drehgeber // ---------------------------------------------------------------------------- @@ -30,14 +30,14 @@ #if ENC_DECODER != ENC_NORMAL # ifdef ENC_HALFSTEP // decoding table for hardware with flaky notch (half resolution) - const int8_t ClickEncoder::table[16] __attribute__((__progmem__)) = { - 0, 0, -1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 0 - }; + const int8_t ClickEncoder::table[16] __attribute__((__progmem__)) = { + 0, 0, -1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 0 + }; # else // decoding table for normal hardware - const int8_t ClickEncoder::table[16] __attribute__((__progmem__)) = { - 0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0 - }; + const int8_t ClickEncoder::table[16] __attribute__((__progmem__)) = { + 0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0 + }; # endif #endif @@ -53,7 +53,7 @@ ClickEncoder::ClickEncoder(uint8_t A, uint8_t B, uint8_t BTN, uint8_t stepsPerNo pinMode(pinA, configType); pinMode(pinB, configType); pinMode(pinBTN, configType); - + if (digitalRead(pinA) == pinsActive) { last = 3; } @@ -89,7 +89,7 @@ void ClickEncoder::service(void) last |= 1; } - uint8_t tbl = pgm_read_byte(&table[last]); + uint8_t tbl = pgm_read_byte(&table[last]); if (tbl) { delta += tbl; moved = true; @@ -104,13 +104,13 @@ void ClickEncoder::service(void) if (digitalRead(pinB) == pinsActive) { curr ^= 1; } - + int8_t diff = last - curr; if (diff & 1) { // bit 0 = step last = curr; delta += (diff & 2) - 1; // bit 1 = direction (+/-) - moved = true; + moved = true; } #else # error "Error: define ENC_DECODER to ENC_NORMAL or ENC_FLAKY" @@ -126,15 +126,11 @@ void ClickEncoder::service(void) // handle button // #ifndef WITHOUT_BUTTON - static uint16_t keyDownTicks = 0; - static uint8_t doubleClickTicks = 0; - static unsigned long lastButtonCheck = 0; - if (pinBTN > 0 // check button only, if a pin has been provided && (now - lastButtonCheck) >= ENC_BUTTONINTERVAL) // checking button is sufficient every 10-30ms - { + { lastButtonCheck = now; - + if (digitalRead(pinBTN) == pinsActive) { // key is down keyDownTicks++; if (keyDownTicks > (ENC_HOLDTIME / ENC_BUTTONINTERVAL)) { @@ -164,7 +160,7 @@ void ClickEncoder::service(void) keyDownTicks = 0; } - + if (doubleClickTicks > 0) { doubleClickTicks--; if (--doubleClickTicks == 0) { @@ -181,7 +177,7 @@ void ClickEncoder::service(void) int16_t ClickEncoder::getValue(void) { int16_t val; - + cli(); val = delta; @@ -190,7 +186,7 @@ int16_t ClickEncoder::getValue(void) else delta = 0; // default to 1 step per notch sei(); - + if (steps == 4) val >>= 2; if (steps == 2) val >>= 1; diff --git a/ClickEncoder.h b/ClickEncoder.h index 8148579..a677ec8 100644 --- a/ClickEncoder.h +++ b/ClickEncoder.h @@ -1,118 +1,121 @@ -// ---------------------------------------------------------------------------- -// Rotary Encoder Driver with Acceleration -// Supports Click, DoubleClick, Long Click -// -// (c) 2010 karl@pitrich.com -// (c) 2014 karl@pitrich.com -// -// Timer-based rotary encoder logic by Peter Dannegger -// http://www.mikrocontroller.net/articles/Drehgeber -// ---------------------------------------------------------------------------- - -#ifndef __have__ClickEncoder_h__ -#define __have__ClickEncoder_h__ - -// ---------------------------------------------------------------------------- - -#include -#include -#include -#include -#include "Arduino.h" - -// ---------------------------------------------------------------------------- - -#define ENC_NORMAL (1 << 1) // use Peter Danneger's decoder -#define ENC_FLAKY (1 << 2) // use Table-based decoder - -// ---------------------------------------------------------------------------- - -#ifndef ENC_DECODER -# define ENC_DECODER ENC_NORMAL -#endif - -#if ENC_DECODER == ENC_FLAKY -# ifndef ENC_HALFSTEP -# define ENC_HALFSTEP 1 // use table for half step per default -# endif -#endif - -// ---------------------------------------------------------------------------- - -class ClickEncoder -{ -public: - typedef enum Button_e { - Open = 0, - Closed, - - Pressed, - Held, - Released, - - Clicked, - DoubleClicked - - } Button; - -public: - ClickEncoder(uint8_t A, uint8_t B, uint8_t BTN = -1, - uint8_t stepsPerNotch = 1, bool active = LOW); - - void service(void); - int16_t getValue(void); - -#ifndef WITHOUT_BUTTON -public: - Button getButton(void); -#endif - -#ifndef WITHOUT_BUTTON -public: - void setDoubleClickEnabled(const bool &d) - { - doubleClickEnabled = d; - } - - const bool getDoubleClickEnabled() - { - return doubleClickEnabled; - } -#endif - -public: - void setAccelerationEnabled(const bool &a) - { - accelerationEnabled = a; - if (accelerationEnabled == false) { - acceleration = 0; - } - } - - const bool getAccelerationEnabled() - { - return accelerationEnabled; - } - -private: - const uint8_t pinA; - const uint8_t pinB; - const uint8_t pinBTN; - const bool pinsActive; - volatile int16_t delta; - volatile int16_t last; - uint8_t steps; - volatile uint16_t acceleration; - bool accelerationEnabled; -#if ENC_DECODER != ENC_NORMAL - static const int8_t table[16]; -#endif -#ifndef WITHOUT_BUTTON - volatile Button button; - bool doubleClickEnabled; -#endif -}; - -// ---------------------------------------------------------------------------- - -#endif // __have__ClickEncoder_h__ +// ---------------------------------------------------------------------------- +// Rotary Encoder Driver with Acceleration +// Supports Click, DoubleClick, Long Click +// +// (c) 2010 karl@pitrich.com +// (c) 2014 karl@pitrich.com +// +// Timer-based rotary encoder logic by Peter Dannegger +// http://www.mikrocontroller.net/articles/Drehgeber +// ---------------------------------------------------------------------------- + +#ifndef __have__ClickEncoder_h__ +#define __have__ClickEncoder_h__ + +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include "Arduino.h" + +// ---------------------------------------------------------------------------- + +#define ENC_NORMAL (1 << 1) // use Peter Danneger's decoder +#define ENC_FLAKY (1 << 2) // use Table-based decoder + +// ---------------------------------------------------------------------------- + +#ifndef ENC_DECODER +# define ENC_DECODER ENC_NORMAL +#endif + +#if ENC_DECODER == ENC_FLAKY +# ifndef ENC_HALFSTEP +# define ENC_HALFSTEP 1 // use table for half step per default +# endif +#endif + +// ---------------------------------------------------------------------------- + +class ClickEncoder +{ +public: + typedef enum Button_e { + Open = 0, + Closed, + + Pressed, + Held, + Released, + + Clicked, + DoubleClicked + + } Button; + +public: + ClickEncoder(uint8_t A, uint8_t B, uint8_t BTN = -1, + uint8_t stepsPerNotch = 1, bool active = LOW); + + void service(void); + int16_t getValue(void); + +#ifndef WITHOUT_BUTTON +public: + Button getButton(void); +#endif + +#ifndef WITHOUT_BUTTON +public: + void setDoubleClickEnabled(const bool &d) + { + doubleClickEnabled = d; + } + + const bool getDoubleClickEnabled() + { + return doubleClickEnabled; + } +#endif + +public: + void setAccelerationEnabled(const bool &a) + { + accelerationEnabled = a; + if (accelerationEnabled == false) { + acceleration = 0; + } + } + + const bool getAccelerationEnabled() + { + return accelerationEnabled; + } + +private: + const uint8_t pinA; + const uint8_t pinB; + const uint8_t pinBTN; + const bool pinsActive; + volatile int16_t delta; + volatile int16_t last; + uint8_t steps; + volatile uint16_t acceleration; + bool accelerationEnabled; +#if ENC_DECODER != ENC_NORMAL + static const int8_t table[16]; +#endif +#ifndef WITHOUT_BUTTON + volatile Button button; + bool doubleClickEnabled; + uint16_t keyDownTicks = 0; + uint8_t doubleClickTicks = 0; + unsigned long lastButtonCheck = 0; +#endif +}; + +// ---------------------------------------------------------------------------- + +#endif // __have__ClickEncoder_h__