Skip to content

Commit 6993a63

Browse files
committed
version 1.2: AiEsp32RotaryEncoderNumberSelector
1 parent 68e0deb commit 6993a63

File tree

6 files changed

+176
-21
lines changed

6 files changed

+176
-21
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "AiEsp32RotaryEncoder.h"
2+
#include "AiEsp32RotaryEncoderNumberSelector.h"
3+
#define ROTARY_ENCODER_A_PIN 32
4+
#define ROTARY_ENCODER_B_PIN 21
5+
#define ROTARY_ENCODER_BUTTON_PIN 25
6+
#define ROTARY_ENCODER_STEPS 4
7+
AiEsp32RotaryEncoder *rotaryEncoder = new AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
8+
AiEsp32RotaryEncoderNumberSelector numberSelector = AiEsp32RotaryEncoderNumberSelector();
9+
/*
10+
In this example an additional functionality is used.
11+
12+
AiEsp32RotaryEncoderNumberSelector is that additional helper which will hide calculation for a rotary encoder.
13+
14+
In example 1 - you can select some temperature between -12 and +31.5 degrees in steps by 0.5 degrees; using precision of 1 decimal
15+
In example 2 - you can select some frequency between 6999000 and 7000000 Hz in steps by 10 Hz; using precision of 0 decimal (integer)
16+
17+
Internally AiEsp32RotaryEncoderNumberSelector will do the math and set the most apropriate acceleration, min and max values for you
18+
19+
use setRange to set parameters
20+
use setValue for a default/initial value
21+
and finally read the value with getValue
22+
23+
So, this value is actually value you need
24+
25+
In code bellow comment / uncomment example 1 or 2
26+
*/
27+
28+
void rotary_onButtonClick()
29+
{
30+
static unsigned long lastTimePressed = 0;
31+
if (millis() - lastTimePressed < 200)
32+
return;
33+
lastTimePressed = millis();
34+
35+
Serial.print("Selected value is ");
36+
Serial.print(numberSelector.getValue(), 1);
37+
Serial.println(" ***********************");
38+
}
39+
40+
void setup()
41+
{
42+
Serial.begin(115200);
43+
rotaryEncoder->begin();
44+
rotaryEncoder->setup(
45+
[] { rotaryEncoder->readEncoder_ISR(); },
46+
[] { rotary_onButtonClick(); });
47+
48+
numberSelector.attachEncoder(rotaryEncoder);
49+
//example 1
50+
//numberSelector.setRange(-12.0, 31.5, 0.5, false, 1);
51+
//numberSelector.setValue(24.3);
52+
//example 2
53+
numberSelector.setRange(6999000.0, 7000000.0, 10, false, 0);
54+
numberSelector.setValue(6999500.0);
55+
}
56+
57+
void loop()
58+
{
59+
if (rotaryEncoder->encoderChanged())
60+
{
61+
Serial.print(numberSelector.getValue());
62+
Serial.println(" ");
63+
}
64+
}

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=Ai Esp32 Rotary Encoder
2-
version=1.1
2+
version=1.2
33
author=Igor Antolic (adapted code from github.com/marcmerlin/IoTuz)
44
maintainer=Igor Antolic <[email protected]>
55
sentence=Easy implement rotary encoder to your application
6-
paragraph=Supports acceleration, setting boundaries. Works with ESP32.
6+
paragraph=Supports acceleration, setting boundaries. Works with ESP32. New in version 1.2: AiEsp32RotaryEncoderNumberSelector introduced to help selecting for example range -12 do 31.5 in steps of 0.5.
77
category=Device Control
88
url=https://github.com/iantolic/ai-esp32-rotary-encoder.git
99
architectures=esp32

src/AiEsp32RotaryEncoder.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ void IRAM_ATTR AiEsp32RotaryEncoder::readEncoder_ISR()
2727

2828
if (currentDirection != 0)
2929
{
30-
int16_t prevRotaryPosition = this->encoder0Pos / this->encoderSteps;
30+
long prevRotaryPosition = this->encoder0Pos / this->encoderSteps;
3131
this->encoder0Pos += currentDirection;
32-
int16_t newRotaryPosition = this->encoder0Pos / this->encoderSteps;
32+
long newRotaryPosition = this->encoder0Pos / this->encoderSteps;
3333

3434
if (newRotaryPosition != prevRotaryPosition && rotaryAccelerationCoef > 1)
3535
{
@@ -122,28 +122,28 @@ AiEsp32RotaryEncoder::AiEsp32RotaryEncoder(uint8_t encoder_APin, uint8_t encoder
122122
pinMode(this->encoderBPin, INPUT_PULLDOWN);
123123
}
124124

125-
void AiEsp32RotaryEncoder::setBoundaries(int16_t minEncoderValue, int16_t maxEncoderValue, bool circleValues)
125+
void AiEsp32RotaryEncoder::setBoundaries(long minEncoderValue, long maxEncoderValue, bool circleValues)
126126
{
127127
this->_minEncoderValue = minEncoderValue * this->encoderSteps;
128128
this->_maxEncoderValue = maxEncoderValue * this->encoderSteps;
129129

130130
this->_circleValues = circleValues;
131131
}
132132

133-
int16_t AiEsp32RotaryEncoder::readEncoder()
133+
long AiEsp32RotaryEncoder::readEncoder()
134134
{
135135
return (this->encoder0Pos / this->encoderSteps);
136136
}
137137

138-
void AiEsp32RotaryEncoder::setEncoderValue(int16_t newValue)
138+
void AiEsp32RotaryEncoder::setEncoderValue(long newValue)
139139
{
140140
reset(newValue);
141141
}
142142

143-
int16_t AiEsp32RotaryEncoder::encoderChanged()
143+
long AiEsp32RotaryEncoder::encoderChanged()
144144
{
145-
int16_t _encoder0Pos = readEncoder();
146-
int16_t encoder0Diff = _encoder0Pos - this->lastReadEncoder0Pos;
145+
long _encoder0Pos = readEncoder();
146+
long encoder0Diff = _encoder0Pos - this->lastReadEncoder0Pos;
147147

148148
this->lastReadEncoder0Pos = _encoder0Pos;
149149

@@ -179,7 +179,7 @@ ButtonState AiEsp32RotaryEncoder::currentButtonState()
179179
return buttonState;
180180
}
181181

182-
void AiEsp32RotaryEncoder::reset(int16_t newValue_)
182+
void AiEsp32RotaryEncoder::reset(long newValue_)
183183
{
184184
newValue_ = newValue_ * this->encoderSteps;
185185
this->encoder0Pos = newValue_;

src/AiEsp32RotaryEncoder.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class AiEsp32RotaryEncoder
3232
private:
3333
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
3434
portMUX_TYPE buttonMux = portMUX_INITIALIZER_UNLOCKED;
35-
volatile int16_t encoder0Pos = 0;
35+
volatile long encoder0Pos = 0;
3636

3737
volatile int8_t lastMovementDirection = 0; //1 right; -1 left
3838
volatile unsigned long lastMovementAt = 0;
@@ -45,13 +45,13 @@ class AiEsp32RotaryEncoder
4545
uint8_t encoderBPin = AIESP32ROTARYENCODER_DEFAULT_B_PIN;
4646
uint8_t encoderButtonPin = AIESP32ROTARYENCODER_DEFAULT_BUT_PIN;
4747
uint8_t encoderVccPin = AIESP32ROTARYENCODER_DEFAULT_VCC_PIN;
48-
int16_t encoderSteps = AIESP32ROTARYENCODER_DEFAULT_STEPS;
48+
long encoderSteps = AIESP32ROTARYENCODER_DEFAULT_STEPS;
4949

50-
int16_t _minEncoderValue = -1 << 15;
51-
int16_t _maxEncoderValue = 1 << 15;
50+
long _minEncoderValue = -1 << 15;
51+
long _maxEncoderValue = 1 << 15;
5252

5353
uint8_t old_AB;
54-
int16_t lastReadEncoder0Pos;
54+
long lastReadEncoder0Pos;
5555
bool previous_butt_state;
5656

5757
ButtonState buttonState;
@@ -67,19 +67,19 @@ class AiEsp32RotaryEncoder
6767
uint8_t encoderButtonPin = AIESP32ROTARYENCODER_DEFAULT_BUT_PIN,
6868
uint8_t encoderVccPin = AIESP32ROTARYENCODER_DEFAULT_VCC_PIN,
6969
uint8_t encoderSteps = AIESP32ROTARYENCODER_DEFAULT_STEPS);
70-
void setBoundaries(int16_t minValue = -100, int16_t maxValue = 100, bool circleValues = false);
70+
void setBoundaries(long minValue = -100, long maxValue = 100, bool circleValues = false);
7171
void IRAM_ATTR readEncoder_ISR();
7272
void IRAM_ATTR readButton_ISR();
7373

7474
void setup(void (*ISR_callback)(void));
7575
void setup(void (*ISR_callback)(void), void (*ISR_button)(void));
7676
void begin();
77-
void reset(int16_t newValue = 0);
77+
void reset(long newValue = 0);
7878
void enable();
7979
void disable();
80-
int16_t readEncoder();
81-
void setEncoderValue(int16_t newValue);
82-
int16_t encoderChanged();
80+
long readEncoder();
81+
void setEncoderValue(long newValue);
82+
long encoderChanged();
8383
ButtonState currentButtonState();
8484
unsigned long getAcceleration() { return this->rotaryAccelerationCoef; }
8585
void setAcceleration(unsigned long acceleration) { this->rotaryAccelerationCoef = acceleration; }

src/AiEsp32RotaryEncoderNumberSelector.cpp

Whitespace-only changes.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#pragma once
2+
3+
#include <Arduino.h>
4+
#include "AiEsp32RotaryEncoder.h"
5+
/*
6+
setRange (float min, max, step)
7+
100,500,25
8+
88 , 104 , 0.05
9+
10+
coef = 1/step
11+
range min/step, max/step -> 4 - 20
12+
realValue = value*step -> 6*25 =150
13+
14+
*/
15+
//#define DEBUG_NUM_SEL
16+
17+
class AiEsp32RotaryEncoderNumberSelector
18+
{
19+
private:
20+
float minValue = 0;
21+
float maxValue = 100;
22+
float step = 2;
23+
float coeficient = 1;
24+
AiEsp32RotaryEncoder *encoder;
25+
26+
public:
27+
AiEsp32RotaryEncoderNumberSelector(AiEsp32RotaryEncoder *encoderInstance = NULL)
28+
{
29+
encoder = encoderInstance;
30+
}
31+
32+
void attachEncoder(AiEsp32RotaryEncoder *encoderInstance = NULL)
33+
{
34+
encoder = encoderInstance;
35+
}
36+
37+
void setRange(float minValue, float maxValue, float step, bool cycleValues, unsigned int decimals = 0)
38+
{
39+
this->minValue = minValue;
40+
this->maxValue = maxValue;
41+
this->coeficient = pow(10.0, decimals);
42+
if (maxValue < minValue)
43+
coeficient *= -1.0;
44+
this->step = step * this->coeficient;
45+
46+
long minEncoderValue = (long)((this->coeficient * this->minValue) / this->step);
47+
long maxEncoderValue = (long)((this->coeficient * this->maxValue) / this->step);
48+
long range = maxEncoderValue - minEncoderValue;
49+
50+
encoder->setBoundaries(minEncoderValue, maxEncoderValue, cycleValues);
51+
52+
if (range < 20)
53+
encoder->setAcceleration(0);
54+
else if (range < 60)
55+
encoder->setAcceleration(20);
56+
else if (range < 200)
57+
encoder->setAcceleration(100);
58+
else if (range < 1000)
59+
encoder->setAcceleration(300);
60+
else
61+
encoder->setAcceleration(500);
62+
63+
#ifdef DEBUG_NUM_SEL
64+
Serial.println(minEncoderValue);
65+
Serial.println(maxEncoderValue);
66+
Serial.println(range);
67+
Serial.println(step);
68+
Serial.println(coeficient);
69+
70+
#endif
71+
}
72+
73+
void setValue(float value)
74+
{
75+
long encoderValue = (long)((coeficient * value) / step);
76+
encoder->setEncoderValue(encoderValue);
77+
}
78+
79+
float getValue()
80+
{
81+
float encoderValue = 1.0 * encoder->readEncoder();
82+
float value = encoderValue * step / coeficient;
83+
84+
#ifdef DEBUG_NUM_SEL
85+
Serial.print(encoderValue);
86+
Serial.print(" -> ");
87+
Serial.println(value);
88+
#endif
89+
return value;
90+
}
91+
};

0 commit comments

Comments
 (0)