Coder Social home page Coder Social logo

ai-esp32-rotary-encoder's Introduction

Intro

Use this library to connect and use a rotary encoder with ESP32 or ESP8266.

But it is a bit more than just that.

Strongly recomended is to try a few included examples to see how it works.

The main fatures are:

  • select a number in a predifined range. For example select a termostat value between 18 and 29 Celsius degrees.
  • you can also set step size. Meaning in previous example you can select temperature in steps of 0.5 degrees (18.0, 18.5 .....). Of course step can be also greater than 1 like select a motr speed 500-3000 in steps of 100 (500,600, ....,2900,3000). See examples like FM-radio-tuner
  • when using large range like select a number of repeating operation (1....5000) setting a desired number like 4525 cen be frustrating without using acceleration. Acceleration is a nice option you can use in such cases, meaning that if you rotate fast it will go like (1,2,3,5,10,15,30,50,100...) so use fast movements for getting close to desired number and then start rotating slower for a precise selection.

To disable use

rotaryEncoder.disableAcceleration();
  • additionally there is a helper so see example Number-select which includes a NumberSellector
  • if you want to implement a menu, see example Multi-select
  • in some cases like menus, you would like to go from last item to first. Boolean cycleValues parameter set to true will do exactly that.

Using a button

You can also use a button. Version 1.3 and above has significant changes after I found previous implementation didnt fit my needs. All examples are now updated, so if you used it before and getting crashes or you dont like a button how it is working, check a new examples.

For compatibility older examples still works but will become obsolete soon.

update 2023-05 for button custom iplementation (long click...)

Some people asked how they can handle more complex button events like double click, short press, long press.

There is an example Esp32RotaryEncoderButtonOptions.ino

You will fint there how to implement long press, how to invert button state, but also get ideas how to implement double click. The code is nonblocking so try to rotate a rotary encoder while the button is down.

Support fot ESP8266 added 10/2021

Support added also for ESP8266

Changes in button processing 10/2021

Old button using interrupt is now obsolete. Please look at upadated examples how to handle click, properly initialize encoder and avoid crashing.

New feature added 02/2021 - accelerated movement

In case a range to select is large, for example - select a value between 0 and 1000 and we want 785, without accelerateion you need long time to get to that number. However using new implemented acceleration, faster you turn, faster will the value raise.For fine tuning just slow down. In new example imagine any random naumber between 1 and 1000 and try to select it as fast as you can using example code, and after that disable acceleration and try again.

rotaryEncoder.setAcceleration(250); this will set acceleration; larger number = more accelearation; 0 or 1 means disabled acceleration

rotaryEncoder.disableAcceleration(); This will disable acceleration (now enabled by default) in case you dont need one.

Recomendation - turn off for small ranges; but turn on when you select from more than 50 values in range.

Arduino Esp32 Encoder Library

Rotary encoder main interrupt code is extracted from (https://github.com/marcmerlin/IoTuz) and some additional features are included here.

Description

This library enables easy implementation of rotary encoder functionality in your application for ESP32, ESP8266 (or similar microcontroller).

Installing

Since 2021 you can download using Arduino, which is preffered way:

 Sketch / include Library / Manage Libraries

 in search box type "ai rotary" (without quotes)

Alternative way (to get not yet published version) The downloaded code can be included as a new library into the IDE selecting the menu:

 Sketch / include Library / Add .Zip library

Restart the Arduino IDE and follow the examples located at

 File -> Examples -> Ai Esp32 Rotary Encoder

Connecting Rotary Encoder Module to your microcontroller ESP32, ESP8266 (or similar)

This are instructions for "Rotary Encoder Module" which is actually Rotary Encoder with 2 resistors on board.

CLK (A pin) - connect to any microcontroler input pin with interrupt -> in this example pin 32

DT (B pin) - connect to any microcontroler input pin with interrupt -> in this example pin 21

SW (button pin) - connect to any microcontroler input pin -> in this example pin 25

VCC - for this you can two options:

a) connect to microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1) or

b) connect to any microcontroler output pin - in this example pin 25

GND - connect to microcontroler GND

Connecting Rotary Encoder with Switch (no pcb version. The encoder is like this) to your microcontroller ESP32, ESP8266 (or similar)

There is no need for external resistors, you can use only the encoder.

3 pin side:

Right pin (A pin) - connect to any microcontroler input pin with interrupt -> in the example pin 22

Left pin (B pin) - connect to any microcontroler input pin with interrupt -> in the example pin 23

Middle pin - connect to microcontroller Gnd

2 pin side:

one of the 2 pins: connect to microcontroller Gnd

the other pin: connect to any microcontroller input pin -> in this example pin 25

You have to set INPUT_PULLUP of Right and Left pins with pinMode(ROTARY_ENCODER_A_PIN, INPUT_PULLUP); and pinMode(ROTARY_ENCODER_B_PIN, INPUT_PULLUP); Look for example Esp32RotaryEncoderTheShortestExampleNoResistors.

update 2024-03-10:

There is an optional parameter in the constructor areEncoderPinsPulldownforEsp32. By default it is true, but in case you use ESP32 you can set it to false. Please note that it doesn't make any change for ESP8266, but only for ESP32.

Here in example pay attention to the end of the line - parameter ",false".

To modify other examples just add ", false" as an additional parameter.

AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS,false);

There is a new option isButtonPulldown. By default it is false, but in case you use ESP32 you can set it to true. See Multi-select example. It doesn't make any change for ESP8266, only ESP32.

rotaryEncoder.isButtonPulldown = true;

How to use

I suggest you should start using built in example. After installing library (and reopening Arduino IDE if required) open

File -> Examples -> Ai Esp32 Rotary Encoder

If you didnt use suggested pins, adjust defines

#define ROTARY_ENCODER_A_PIN 32
#define ROTARY_ENCODER_B_PIN 21
#define ROTARY_ENCODER_BUTTON_PIN 25
#define ROTARY_ENCODER_VCC_PIN 27

For ESP8266 you can use Dx as pin names like in example:

#define ROTARY_ENCODER_A_PIN D6
#define ROTARY_ENCODER_B_PIN D5
#define ROTARY_ENCODER_BUTTON_PIN D7

Then upload code to microcontroller.

README_old.md contains more information but some parts are obsolete.

ai-esp32-rotary-encoder's People

Contributors

geo17137 avatar igor-antolic avatar igorantolic avatar imkereiwetzel avatar ligantx avatar per1234 avatar timkoers avatar ttump avatar zhivko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ai-esp32-rotary-encoder's Issues

Compilation errors with examples

Hi, I am trying out this library but a few errors persist during compilation. Everything is left untouched in the examples, including pin assignments.
I am compiling for ESP32 Dev Module.

`Compiling sketch...
In file included from G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.cpp:11:
G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.h:53:32: warning: left shift of negative value [-Wshift-negative-value]
long _minEncoderValue = -1 << 15;
^~

G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.cpp: In member function 'void AiEsp32RotaryEncoder::begin()':
G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.cpp:199:26: warning: comparison is always true due to limited range of data type [-Wtype-limits]
if (this->encoderVccPin >= 0)
~~~~~~~~~~~~~~~~~~~~^~~~

G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.cpp:207:29: warning: comparison is always true due to limited range of data type [-Wtype-limits]
if (this->encoderButtonPin >= 0)
~~~~~~~~~~~~~~~~~~~~~~~^~~~

G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.cpp: In member function 'ButtonState AiEsp32RotaryEncoder::readButtonState()':
G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder\src\AiEsp32RotaryEncoder.cpp:220:14: error: unused variable '_buttonState' [-Werror=unused-variable]
ButtonState _buttonState = buttonState;
^~~~~~~~~~~~

cc1plus.exe: some warnings being treated as errors
Using library Ai_Esp32_Rotary_Encoder at version 1.4 in folder: G:\Dropbox\CODE\libraries\Ai_Esp32_Rotary_Encoder
exit status 1
Error compiling for board ESP32 Dev Module.
`

Are these problems with the library, or some upload setting I have?

Please give better instructions on connecting bare encoders.

Upon connecting bare encoders it is clear that A and B are switched against Vcc (or a pin as pull up).

But it is not obvious that the button is switched against GND in negative logic.
Please explain that: I have lost almost two hours to find out, why the button did not work since I did connect it, like A/B on Vcc.

Acceleration done more simply.

To do an acceleration ways easier with far less code:
Just multiply the encoderChanged result by itself (as an absolute value).
encoderChanged * abs(encoderChanged).

example

21:10:29.398 -> Value: 16
21:10:30.382 -> Value: 9
21:10:31.371 -> Value: 484
21:10:33.389 -> Value: 100
21:10:34.376 -> Value: 729
21:10:35.360 -> Value: 1
21:10:36.393 -> Value: 529
21:10:37.380 -> Value: 7744
21:10:45.390 -> Value: -1
21:10:47.369 -> Value: -1
21:10:48.359 -> Value: -4
21:10:49.395 -> Value: -4
21:10:51.375 -> Value: -484
21:10:53.397 -> Value: -121
21:10:54.384 -> Value: -2209

Precision not working

In the numberSelector.setRange() the last parameter "precision - how many decimal places you want, default is 0" has no effect.

Reverse direction

Hi, thanks for this library, it works quite well.

Is it possible to reverse the direction? Right now I turn the encoder clockwise the value goes down. I would like to have it go up instead when turning clockwise. I am using the Number-select example.

BugReport

encoderVccPin is defined as uint, so setting to -1 will not wrok

AiEsp32RotaryEncoder.h
Line 50 & Line 71

uint8_t encoderVccPin = AIESP32ROTARYENCODER_DEFAULT_VCC_PIN;

Critical line is here:
AiEsp32RotaryEncoder.h
Line 199

if (this->encoderVccPin >= 0)

Same btw for Button pin ...

Thanks for this nice library :-)

currentButtonState has only one value returned--BUT_DOWN

By readme_old.md, it said:
This methor returns value of enum - current button state

	ButtonState current  = rotaryEncoder.currentButtonState();
	// or
	if (rotaryEncoder.currentButtonState() == BUT_RELEASED) {
		Serial.println("Click!");	
	}	

	/*
	Button values are:
	typedef enum {
		BUT_DOWN = 0,
		BUT_PUSHED = 1,
		BUT_UP = 2,
		BUT_RELEASED = 3,
		BUT_DISABLED = 99, //this state is after you call rotaryEncoder.disable(); 
	} ButtonState;
	*/

When I tested it with blow code, I had only got one button state  value--BUT_DOWN every time,why?
    ButtonState current = rotaryEncoder.currentButtonState();
    Serial.printf("button state:%d\n", current);

Guru Meditation Error: when rotating fast

Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)
Core 1 register dump:
PC : 0x400d0b3c PS : 0x00060034 A0 : 0x40087284 A1 : 0x3ffbff50
A2 : 0x0000000d A3 : 0x3ffc1afc A4 : 0x00000000 A5 : 0x00002000
A6 : 0x00042098 A7 : 0x3ffb8b88 A8 : 0x8008111c A9 : 0x00000001
A10 : 0x00000000 A11 : 0x00000000 A12 : 0x8008f099 A13 : 0x3ffb1ad0
A14 : 0x00000000 A15 : 0x3ffb1b0c SAR : 0x00000011 EXCCAUSE: 0x00000007
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
Core 1 was running in ISR context:
EPC1 : 0x4008f1b4 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d0b3c

Question about the basic example

Hi, i am using ESP32 Dev board with your library. Your examples are really good. But i found a small problem.

In ''Esp32RotaryEncoderBasics.ino'' .If i delete //delay(50); //or do whatever you need to do... in the void loop, and flash this programm to my board. My board will stuck in reboot. The following codes are what i got from the serial monitor.

01:08:18.613 -> ELF file SHA256: 0000000000000000
01:08:18.613 ->
01:08:18.613 -> Rebooting...
01:08:18.613 -> ets Jun 8 2016 00:22:57
01:08:18.613 ->
01:08:18.613 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
01:08:18.613 -> configsip: 0, SPIWP:0xee
01:08:18.613 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
01:08:18.613 -> mode:DIO, clock div:1
01:08:18.661 -> load:0x3fff0030,len:1344
01:08:18.661 -> load:0x40078000,len:13864
01:08:18.661 -> load:0x40080400,len:3608
01:08:18.661 -> entry 0x400805f0
01:08:18.753 -> E (132) gpio: gpio_set_level(226): GPIO output gpio_num error

This is a really weird problem. All examples will run flawlessly only with this delay(50). I have also tried other examples... I don't understand why....

Dosnt Compile.

/var/folders/k_/4s4567950jdf7pxbn5hl51m40000gn/T/arduino_modified_sketch_815518/Esp32RotaryEncoderBasics.ino: In function 'void setup()':
Esp32RotaryEncoderBasics:65:58: error: no matching function for call to 'AiEsp32RotaryEncoder::setup(setup()::<lambda()>)'
  rotaryEncoder.setup([]{rotaryEncoder.readEncoder_ISR();});
                                                          ^
In file included from /var/folders/k_/4s4567950jdf7pxbn5hl51m40000gn/T/arduino_modified_sketch_815518/Esp32RotaryEncoderBasics.ino:1:0:
/Users/trackhe/Documents/Arduino/libraries/ai-esp32-rotary-encoder-master/src/AiEsp32RotaryEncoder.h:68:7: note: candidate: void AiEsp32RotaryEncoder::setup(void (*)(), void (*)())
  void setup(void (*ISR_callback)(void), void (*ISR_button)(void));
       ^
/Users/trackhe/Documents/Arduino/libraries/ai-esp32-rotary-encoder-master/src/AiEsp32RotaryEncoder.h:68:7: note:   candidate expects 2 arguments, 1 provided
exit status 1
no matching function for call to 'AiEsp32RotaryEncoder::setup(setup()::<lambda()>)'

Implement "steps" for different types of encoders

Hey first I'd like to thank you for your nice piece of code.

As I have here some cheap encoders from China (bought thru AMAZ*N) I had to patch your library to get them to work. The unpatched library would count always +/-2 at each step, so I had to change the multiplication (or division) by 2 in your code.

I have patched the library and introduced a new parameter to the constructor called encoderSteps, with a default like your current implementation. Maybe you like to integrate it in your release?
ai-esp32-rotaryencoder.zip

gpio: gpio_set_level(226): GPIO output gpio_num error

Hi, i would like to thank you for providing this library.

I'm currently using it for my project. I'm using wokwi first to code as to grasp what i'm working on without needing to reflash my esp32 many times. everytime i ran the code, i would get this error below:

E (167) gpio: gpio_set_level(226): GPIO output gpio_num error

i've asked the wokwi discord, and someone there said (directly quoting them):
OK, it should be harmless. The docs for the library suggest setting the encoder Vcc pin to -1 when the encoder is connected directly to the ESP's Vcc. But this pin number is stored in an unsigned variable, so when https://github.com/igorantolic/ai-esp32-rotary-encoder/blob/master/src/AiEsp32RotaryEncoder.cpp#L199-L203 that code checks to see if it is >=0 the answer is always true. It's just a warning that the library tried to set pin 255, and there isn't a pin 255.

at first it would boot just fine, but it seems like after doing everything in the void setup the web started chugging to only around 20% speed. seems like something is wrong with my code

Wiring

This isn't code related, but I have issues with my wiring probably.
The only values I get are 0 or 1, or -1 or 0. I have a STEC12E08 encoder with the terminals A, C and B.
The wiring to GND and Vcc is done as shown on page 11 of this document.
Are terminals A and B the same in both this library's and the document's case?
What else could be the cause of this?

Button State and Encoder value.

Hi.

I am testing this lib and have some questions.

  1. I only get 2 states (BUT_DOWN) and (BUT_RELEASED) when do I get BUT_PUSHED ?
  2. The value increases with more than 1 value wit the encoder I have. On the Arduino lib I can set the click count. It has to be 4 with this encoder I have. How do I set it with this lib so I get single increments ?

Disable Acceleration | Number Selector

Hi - this is a great library. Thank you for your time developing this.

I am using the example in: https://github.com/igorantolic/ai-esp32-rotary-encoder/blob/master/examples/Number-select/Number-select.ino to build a MIDI Master clock.

The acceleration feature, which is great for many uses, doesn't, however, work very well in changing the tempo - it can make changing tempo go very abrupt at times.

Q: how can I disable the acceleration feature in the sample code?

Cheers, Erik

INPUT_PULLUP not defined

I´m not sure if this is a misunderstanding by myself, but when i connect an incremental encoder with the middle pin as GND and no pushbutton, i need to define the A+B-pins to be INPUT_PULLUP. (Which makes sense, otherwise they are floating)
Is this a bug, or do most of the people use external pullups? Or is the button VCC-pin involved in this?
I´m using a esp32doit board.

When maximum value reached , rotaryEncoder.encoderChanged()) very often give max value, and then , automaticaly max value -1

ESP32 board
`
#define ROTARY_ENCODER_A_PIN 32
#define ROTARY_ENCODER_B_PIN 33
#define ROTARY_ENCODER_BUTTON_PIN 25

AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, 4);

void setup(){
...
rotaryEncoder.begin();
rotaryEncoder.setup(readEncoderISR);
rotaryEncoder.setAcceleration(0);
rotaryEncoder.setBoundaries(0, 8, false);
rotaryEncoder.setEncoderValue(0);
}

void rotary_loop()
{

// dont print anything unless value changed
if (rotaryEncoder.encoderChanged())
{
Serial.println(rotaryEncoder.readEncoder());
}
}

void loop(){
rotary_loop();
}

`
Now , I rotate encoder only in right , I have got in console:
1 2 3 4 5 6 7 8 7 8 7 8 7 8 7 8 7 8 7 8 7 8 7
So, right after 8 I get 7 but I didn't turn the encoder to the left, I only turn it to the right.
And value 7 I have got right after 8, without turn encoder.
For example . If I made rotaryEncoder.setBoundaries(0, 9, false);
I will got
1 2 3 4 5 6 7 8 9 8 9 8 9 etc.
Tell me please , how to fix this bug ?

question: button long press vs short press

Thank you for this great library which works very well.
I'm trying to implement it into a project where I have to differentiate between a long and short button press.
I've tried it with something like this because I thought maybe I could use the maximumWaitMilliseconds for my case

if (rotaryEncoder.isEncoderButtonClicked(400))
      {
        shortPress();
      }
 else if (rotaryEncoder.isEncoderButtonClicked(2000))
      {
        longPress();
      }

which kind of works but causes an exception and crashes the ESP if I hold the button for much longer (like 10 seconds).
I would appreciate any tips on how to implement it in a correct way. I couldn't find anything for it in the examples.

I'm a novice at programming so maybe I miss something obvious(?).

compile error on esp32

Hi,

I am using esp32 dev board. In file AiEsp32RotaryEncoder.cpp the line 255 should read like that:

pinMode(this->encoderButtonPin,isButtonPulldown? INPUT_PULLDOWN:INPUT_PULLUP);

There was a comma instead, which lead to a compile error.

cheers,
Lars

Error compiling for ESP32 - Dev Module

The initial release compiled just fine, but the new edition glitches on compile with:

no matching function for call to 'AiEsp32RotaryEncoder::setup(setup()::<lambda()>)'

when compiling

rotaryEncoder.setup([]{rotaryEncoder.readEncoder_ISR();});

Issue is in evidence in the Esp32RotaryEncoderBasics.ino example .

This is using the Arduino IDE version 1.8.13 on a Windows 10 Pro platform.

For ESP32 - Issue with the "Circling" Option

This library is a great idea (boundaries & acceleration) and thank you! However on ESP32 there are bugs when using the "circleValues" feature (when max go to min and vice versa.) I would like to try and debug and fix, but when looking at the code, my opinion it needs a whole re-write, and I'm not up to that at the moment unfortunately.

I'm switching to something like this, and adding the other features as needed:
https://github.com/buxtronix/arduino/tree/master/libraries/Rotary

Won't work with optical encoder

Hi. Have the function working well with simple mechanical encoder. Want to switch to optical encoder described here: https://smile.amazon.com/dp/B07MX1SYXB?psc=1&ref=ppx_yo2ov_dt_b_product_details. This encoder apparently is looking for high logic on the A and B pins and takes them low when sending pulses and requires a minimum of 5v cc. I consequently pulled up the A & B pins in my ESP32 sketch. I have the vcc connected to my Vin pin which seems to be working. I wrote a test sketch and I can trigger an interrupt if the condition is FALLING but not if it is LOW. Can't get your function to work reliable. Any suggestions? Thanks.

not using encoderButtonPin

If I am not using encoderButtonPin why not initialize it only if pin no is >-1 like it is case for encoderVccPin:

if (encoderVccPin >= 0) {
pinMode(encoderVccPin, OUTPUT); digitalWrite(encoderVccPin, 1);//Vcc for encoder
}

so something like:

if (encoderButtonPin>= 0) {
pinMode(encoderButtonPin, INPUT_PULLUP);
}

does it sound reasonable?

Button is working - encode pin A / pin B not

Hi,

I use your library for my encoder (manufacturer ALPS) but I cannot get it working.
I use an ESP32 WROOM. Pin A of encoder is connected to IO12, pin B is connected to IO13 and the switch is connected to IO5.
If I run your code I only see in serial monitor if button is pressed - but if I turn the encoder nothing happens.

The default RotaryEncoder-Library (Matthias Hertel) is working. But I want to use yours since it uses interrups.

May you can you tell me what I am missing?

Using rotaryEncoder.setup() without a Button ISR: Misunderstanding, or bug?

I am new to arduino / ESP32, and have only basic understanding of C / C++, so it's possible I'm doing something wrong or unnecessary, but looking to the code in AiEsp32RotaryEncoder.h it seems that the rotaryEncoder.setup() function has 2 versions (function override?):

void setup(void (*ISR_callback)(void));	
void setup(void (*ISR_callback)(void), void (*ISR_button)(void));

However, in AiEsp32RotaryEncoder.cpp there is only a single function definition for the setup routine:

void AiEsp32RotaryEncoder::setup(void (*ISR_callback)(void), void (*ISR_button)(void))
{	attachInterrupt(digitalPinToInterrupt(this-&gt;encoderAPin), ISR_callback, CHANGE);	
        attachInterrupt(digitalPinToInterrupt(this-&gt;encoderBPin), ISR_callback, CHANGE);	 
        attachInterrupt(digitalPinToInterrupt(this-&gt;encoderButtonPin), ISR_button, RISING);
}

Without any changes, the supplied examples all worked successfully - but these all call a button ISR. However, in my own program if I tried to call:

rotaryEncoder.setup( [] { Encoder.readEncoder_ISR(); } );

(i.e. no button ISR, just the encoder ISR), the code failed to compile, with the generic error "unable to compile for Adafruit ESP32 Feather"

I then changed the code in AiEsp32RotaryEncoder.cpp to create 2 versions of the setup function, one without the button ISR, and the other as it was originally, like this:

void AiEsp32RotaryEncoder::setup(void (*ISR_callback)(void))
{
	attachInterrupt(digitalPinToInterrupt(this->encoderAPin), ISR_callback, CHANGE);
	attachInterrupt(digitalPinToInterrupt(this->encoderBPin), ISR_callback, CHANGE);
}

void AiEsp32RotaryEncoder::setup(void (*ISR_callback)(void), void (*ISR_button)(void))
{
	attachInterrupt(digitalPinToInterrupt(this->encoderAPin), ISR_callback, CHANGE);
	attachInterrupt(digitalPinToInterrupt(this->encoderBPin), ISR_callback, CHANGE);
	attachInterrupt(digitalPinToInterrupt(this->encoderButtonPin), ISR_button, RISING);
}

The code now compiles successfully, and I can call the setup routine either with or without an ISR for the button.

Is what I have done correct, or have I misunderstood something due to my limited knowledge of C / C++ ?

(I also don't know how to go about submitting this as a code change to this repository, so if these changes are correct, can someone please make the required changes? Thank you)

ESP32-S3: Warning Invalid Pin Selected

Hello,

it seems that there is some trouble when defining the ROTARY_ENCODER_VCC_PIN to -1 on a ESP32-S3 chipset.
In this case the following message is reported back via UART interface.

[ 5475][E][esp32-hal-gpio.c:102] __pinMode(): Invalid pin selected
E (5242) gpio: gpio_set_level(226): GPIO output gpio_num error

As a workaround I can define the VCC Pin to be attached to an unused pin.

lambda function not in IRAM

In the example "Esp32RotaryEncoderBasics.ino" the lambda function for calling the ISR is not put into IRAM.

rotaryEncoder.setup([]{rotaryEncoder.readEncoder_ISR();});

Having the complete ISR call in IRAM is something I have painfully learned. My solution is to wrap the call in a plain function like

void IRAM_ATTR readEncoderWrapper_ISR(){ rotaryEncoder.readEncoder_ISR(); }

and set the library up with

rotaryEncoder.setup(readEncoderWrapper_ISR);

This discussion helped me to understand.

I hope this helps.

p.s. thanks for your ai-esp32-rotary-encoder library!

Wiring an ec11 encoder

How can I use this library with a EC11 encoder that does not have resistors or any other component apart from de encoder itself. In other words I don't have to connect to 5v because it will be A-GND-B for the encoder.

Typo in current code

Hi, the current library isn't working at the moment because the interrupt routine is pointing to array "enc_states" (which it probably used to be) but the header file is using "enc_state". Also the example is not calling the interrupt setup routine.

Slow void loop...

Hi, I have an issue that I can't seem to fix. The main void loop() loops really slow when I use this library. I flashed the Number-select example to my esp-32 dev board and have nothing connected to the board other than my rotary encoder. I also added a serial print to the main loop to check how often it runs, and it prints every ~400ms. However, when I press the Encoder button, the program runs smoothly and loops every 2ms.

This causes problems to my actual program because the main loop is so slow. Is there anything I missed?

Error compiling Esp32RotaryEncoder.ino for ESP8266

Hello everybody,
Example sketch compiles without any problems for ESP32 boards, but gives the following error for ESP8266 boards (pin definitions are modified appropriately) :

Arduino: 1.8.10 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"

In file included from C:\Users\Andre\Documents\Arduino\ESP8266_RotaryEncoder_test\ESP8266_RotaryEncoder_test.ino:1:0:

C:\Users\Andre\Documents\Arduino\libraries\ai-esp32-rotary-encoder-master\src/AiEsp32RotaryEncoder.h:31:2: error: 'portMUX_TYPE' does not name a type

portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;

Multiple libraries were found for "AiEsp32RotaryEncoder.h"
Used: C:\Users\Andre\Documents\Arduino\libraries\ai-esp32-rotary-encoder-master
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

Can somebody help?

Encoder max value is 8192

Hi!,

First of all, thanks for this excellent lib! I try to use it in my project and realized that the max value could be returned by Encoder.readEncoder() is 8192. Is it according to the lib approach or maybe a wrong type of variable is used somewhere?

I try it in Esp32RotaryEncoderBasics example just exclude the string: rotaryEncoder.setBoundaries(0, 1000, circleValues);

Thanks in advance for any prompts!

Debouncing

Hello,

i'm using your library with a Heltec esp32 LoRa and a KY-040 on pins 27,19,25,-1

I'm having trouble that the values go almost always 2 steps instead of one one one encoder turn. How to debounce the encoder correctly? There is also a problem, that often the values are flapping from one to another without turning the knob.

Thank you!

push-button works on release not press

Using the basic sketch,
the push-button does not register as pushed until AFTER it has been released.

I need it to register the push & whilst still pushed, go off and do something....

readButton_ISR

readButton_ISR looks like a work in progress. Are you planning to work on this feature?

Initial value bug

Hi! Nice lib, it helped me with my project. But I've found one bug when I launch my esp32: if I set boundaries like 0-100 and setEncoderValue = 0 it will ignore the first rotation and only after that it will start to change the value. In case I'll set 0-100 and setEncoderValue = 20, for instance, it will very fast switch to 19 and back to 20 in case of CW rotation.
So my suggestion is to change the 137 line from
this->old_AB = 0;
to:
this->old_AB = -1;
It woks fine even with range -1 to 100 with default -1 value. And with -100 to 100 range with 0 as the default.

imported the code to vs code platformio

On compile, i get this error
no declaration matches 'AiEsp32RotaryEncoder::AiEsp32RotaryEncoder(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)'
how to fix it , regards

Square wave read up and down

Hello there:

I have a 12-step encoder but I know that one can read typically it at a 24-step rate by being able to differentiate the up and down step of the square wave.

Is there a way to achieve this with this plugin by any chance?

Thank you for your help :)

Questions about behaviours

Hi, I have some questions about how the library works :

  • rotaryEncoder.encoderChanged(); --> if i reset it, does the DELTA is between the last value and 0 (or reset value ?)

  • rotaryEncoder.setBoundaries(1,4,true);
    What are the maximum boundaries we can use ? (-10 000, 10 000) is working but i can't put a bigger limit. Can we use it without limit ? I tried some changes but i can get it working without seting boundaries.

Thanks,

TD

encoder_VccPin must be int8_t, not unsigned integer

When calling AiEsp32RotaryEncoder(uint8_t encoder_APin, uint8_t encoder_BPin, uint8_t encoder_ButtonPin, uint8_t encoder_VccPin, uint8_t encoderSteps) with encoder_VccPin = -1 (no Vcc pin), the variable gets the value of 255 instead. This means that in the "begin" function it will try to set to HIGH the pin number 255, generating an error in the serial monitor:

[ 32][E][esp32-hal-gpio.c:102] __pinMode(): Invalid pin selected
E (28) gpio: gpio_set_level(226): GPIO output gpio_num error)

The type for this variable should be int8_t (or int16_t) to accommodate the -1.

Support for bare bones rotary encoder

Hi, I see that someone has raised a pull request for an issue I've been having. Might I respectfully request that you add a flag such that the mode of the input pins can be chosen between PULLUP and PULLDOWN. Currently your library assumes a KY-040 style breakout board or external pullup resistors. This new feature would allow those MCUs (e.g. ESP32) with software-enabled pullup/pulldown functions to use bare rotary encoders without the need for physical pullup resistors. Thanks for a great library!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.