Skip to content

Commit e48083e

Browse files
committed
Examples Update
1 parent 029aa31 commit e48083e

File tree

4 files changed

+227
-80
lines changed

4 files changed

+227
-80
lines changed

examples/AcceleratedRotator/AcceleratedRotator.ino

+79-72
Original file line numberDiff line numberDiff line change
@@ -7,107 +7,114 @@
77
// -----
88
// 18.01.2014 created by Matthias Hertel
99
// 13.11.2019 converted to AcceleratedRotator by Damian Philipp
10+
// 06.02.2021 conditions and settings added for ESP8266
1011
// -----
1112

1213
// This example checks the state of the rotary encoder in the loop() function.
1314
// It then computes an acceleration value and prints the current position when changed.
15+
// There is detailed output given to the Serial.
16+
// You may play around with the constants to fit to your needs.
1417

1518
// Hardware setup:
16-
// Attach a rotary encoder with output pins to A2 and A3.
19+
// Attach a rotary encoder with output pins to
20+
// * 2 and 3 on Arduino UNO.
21+
// * A2 and A3 can be used when directly using the ISR interrupts, see comments below.
22+
// * D5 and D6 on ESP8266 board (e.g. NodeMCU).
23+
// Swap the pins when direction is detected wrong.
1724
// The common contact should be attached to ground.
1825

26+
#include <Arduino.h>
1927
#include <RotaryEncoder.h>
2028

21-
// Setup a RoraryEncoder for pins A2 and A3:
22-
RotaryEncoder encoder(A2, A3);
29+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
30+
// Example for Arduino UNO with input signals on pin 2 and 3
31+
#define PIN_IN1 2
32+
#define PIN_IN2 3
33+
34+
#elif defined(ESP8266)
35+
// Example for ESP8266 NodeMCU with input signals on pin D5 and D6
36+
#define PIN_IN1 D5
37+
#define PIN_IN2 D6
38+
39+
#endif
40+
41+
// Setup a RotaryEncoder with 4 steps per latch for the 2 signal input pins:
42+
// RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3);
43+
44+
// Setup a RotaryEncoder with 2 steps per latch for the 2 signal input pins:
45+
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
2346

2447
// Define some constants.
25-
// at 500ms, there should be no acceleration.
26-
constexpr const unsigned long kAccelerationLongCutoffMillis = 500;
27-
// at 4ms, we want to have maximum acceleration
28-
constexpr const unsigned long kAccelerationShortCutffMillis = 4;
29-
// linear acceleration: incline
30-
constexpr static const float m = -0.16;
31-
// linear acceleration: y offset
32-
constexpr static const float c = 84.03;
33-
34-
/* To derive these constants, compute as follows:
35-
* * On an x-y-plane, let x be the time between rotations.
36-
* * On an x-y-plane, let y be the accelerated number of rotations.
37-
* * Select a long cuttoff. If two encoder rotations happen longer apart than the cutoff,
38-
* they are not accelerated anymore. Without the long cutoff, not moving the encoder for a while
39-
* will make the value jump by extreme amounts (possibly in the wrong direction) on the next rotation.
40-
* * Select a short cutoff. This limits the maximum acceleration. While an infinite acceleration is
41-
* not really a problem, it is unrealistic to achieve (how quickly can you tick the encoder?) and
42-
* not having it causes headaches when computing the actual acceleration ;)
43-
* Pick two points defining your acceleration. At x2=(long cutoff), you want y2=1 (No acceleration happened).
44-
* At x1=(short cutoff) you want y1=(maximum accelerated number of ticks).
45-
* Then, compute m and c using high school math (or google for "straight line through two points").
46-
*
47-
* The numbers given in this example are tailored for the following conditions:
48-
* * An encoder with 24 increments per 360 degrees
49-
* * A useful range of 0..1000 rotations
50-
* * Making a 180 degree rotation (12 increments) on the encoder within 50ms will hit
51-
* the opposite end of the range.
52-
*
53-
* Please do not rely on these exact numbers. Recompute them for your usecase and verify
54-
* them with a physical test. A 4ms timing is fairly tight for many controllers. Depending on your
55-
* controller and application, you might not be able to sample the encoder quickly enough to achieve this.
56-
*/
48+
49+
// the maximum acceleration is 10 times.
50+
constexpr float m = 10;
51+
52+
// at 200ms or slower, there should be no acceleration. (factor 1)
53+
constexpr float longCutoff = 50;
54+
55+
// at 5 ms, we want to have maximum acceleration (factor m)
56+
constexpr float shortCutoff = 5;
57+
58+
// To derive the calc. constants, compute as follows:
59+
// On an x(ms) - y(factor) plane resolve a linear formular factor(ms) = a * ms + b;
60+
// where f(4)=10 and f(200)=1
61+
62+
constexpr float a = (m - 1) / (shortCutoff - longCutoff);
63+
constexpr float b = 1 - longCutoff * a;
64+
65+
// a global variables to hold the last position
66+
static int lastPos = 0;
5767

5868
void setup()
5969
{
60-
Serial.begin(57600);
70+
Serial.begin(115200);
71+
while (!Serial)
72+
;
73+
6174
Serial.println("AcceleratedRotator example for the RotaryEncoder library.");
75+
Serial.print("a=");
76+
Serial.println(a);
77+
Serial.print("b=");
78+
Serial.println(b);
6279
} // setup()
6380

6481

6582
// Read the current position of the encoder and print out when changed.
6683
void loop()
6784
{
68-
static int pos = 0;
69-
static RotaryEncoder::Direction lastMovementDirection = RotaryEncoder::Direction::NOROTATION;
7085
encoder.tick();
7186

7287
int newPos = encoder.getPosition();
73-
if (pos != newPos) {
74-
75-
// compute linear acceleration
76-
RotaryEncoder::Direction currentDirection = encoder.getDirection();
77-
if (currentDirection == lastMovementDirection &&
78-
currentDirection != RotaryEncoder::Direction::NOROTATION &&
79-
lastMovementDirection != RotaryEncoder::Direction::NOROTATION) {
80-
// ... but only of the direction of rotation matched and there
81-
// actually was a previous rotation.
82-
unsigned long deltat = encoder.getMillisBetweenRotations();
83-
84-
if (deltat < kAccelerationLongCutoffMillis) {
85-
if (deltat < kAccelerationShortCutffMillis) {
86-
// limit to maximum acceleration
87-
deltat = kAccelerationShortCutffMillis;
88-
}
89-
90-
float ticksActual_float = m * deltat + c;
91-
// Round by adding 1
92-
// Then again remove 1 to determine the actual delta to the encoder
93-
// value, as the encoder already ticked by 1 tick in the correct
94-
// direction. Thus, just cast to an integer type.
95-
long deltaTicks = (long)ticksActual_float;
96-
97-
// Adjust sign: Needs to be inverted for counterclockwise operation
98-
if (currentDirection == RotaryEncoder::Direction::COUNTERCLOCKWISE) {
99-
deltaTicks = -(deltaTicks);
100-
}
101-
102-
newPos = newPos + deltaTicks;
103-
encoder.setPosition(newPos);
104-
lastMovementDirection = currentDirection;
88+
if (lastPos != newPos) {
89+
90+
// accelerate when there was a previous rotation in the same direction.
91+
92+
unsigned long ms = encoder.getMillisBetweenRotations();
93+
94+
if (ms < longCutoff) {
95+
// do some acceleration using factors a and b
96+
97+
// limit to maximum acceleration
98+
if (ms < shortCutoff) {
99+
ms = shortCutoff;
105100
}
101+
102+
float ticksActual_float = a * ms + b;
103+
Serial.print(" f= ");
104+
Serial.println(ticksActual_float);
105+
106+
long deltaTicks = (long)ticksActual_float * (newPos - lastPos);
107+
Serial.print(" d= ");
108+
Serial.println(deltaTicks);
109+
110+
newPos = newPos + deltaTicks;
111+
encoder.setPosition(newPos);
106112
}
107113

108114
Serial.print(newPos);
109-
Serial.println();
110-
pos = newPos;
115+
Serial.print(" ms: ");
116+
Serial.println(ms);
117+
lastPos = newPos;
111118
} // if
112119
} // loop ()
113120

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// -----
2+
// AcceleratedRotator.ino - Example for the RotaryEncoder library.
3+
// This class is implemented for use with the Arduino environment.
4+
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
5+
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
6+
// More information on: http://www.mathertel.de/Arduino
7+
// -----
8+
// 18.01.2014 created by Matthias Hertel
9+
// 13.11.2019 converted to AcceleratedRotator by Damian Philipp
10+
// 06.02.2021 conditions and settings added for ESP8266
11+
// -----
12+
13+
// This example checks the state of the rotary encoder in the loop() function.
14+
// It then computes an acceleration value and prints the current position when changed.
15+
// There is detailed output given to the Serial.
16+
// You may play around with the constants to fit to your needs.
17+
18+
// Hardware setup:
19+
// Attach a rotary encoder with output pins to
20+
// * 2 and 3 on Arduino UNO.
21+
// * A2 and A3 can be used when directly using the ISR interrupts, see comments below.
22+
// * D5 and D6 on ESP8266 board (e.g. NodeMCU).
23+
// Swap the pins when direction is detected wrong.
24+
// The common contact should be attached to ground.
25+
26+
#include <Arduino.h>
27+
#include <RotaryEncoder.h>
28+
29+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
30+
// Example for Arduino UNO with input signals on pin 2 and 3
31+
#define PIN_IN1 2
32+
#define PIN_IN2 3
33+
34+
#elif defined(ESP8266)
35+
// Example for ESP8266 NodeMCU with input signals on pin D5 and D6
36+
#define PIN_IN1 D5
37+
#define PIN_IN2 D6
38+
39+
#endif
40+
41+
// Setup a RotaryEncoder with 4 steps per latch for the 2 signal input pins:
42+
// RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3);
43+
44+
// Setup a RotaryEncoder with 2 steps per latch for the 2 signal input pins:
45+
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
46+
47+
// Define some constants.
48+
49+
// the maximum acceleration is 10 times.
50+
constexpr float m = 10;
51+
52+
// at 200ms or slower, there should be no acceleration. (factor 1)
53+
constexpr float longCutoff = 50;
54+
55+
// at 5 ms, we want to have maximum acceleration (factor m)
56+
constexpr float shortCutoff = 5;
57+
58+
// To derive the calc. constants, compute as follows:
59+
// On an x(ms) - y(factor) plane resolve a linear formular factor(ms) = a * ms + b;
60+
// where f(4)=10 and f(200)=1
61+
62+
constexpr float a = (m - 1) / (shortCutoff - longCutoff);
63+
constexpr float b = 1 - longCutoff * a;
64+
65+
// a global variables to hold the last position
66+
static int lastPos = 0;
67+
68+
void setup()
69+
{
70+
Serial.begin(115200);
71+
while (!Serial)
72+
;
73+
74+
Serial.println("AcceleratedRotator example for the RotaryEncoder library.");
75+
Serial.print("a=");
76+
Serial.println(a);
77+
Serial.print("b=");
78+
Serial.println(b);
79+
} // setup()
80+
81+
82+
// Read the current position of the encoder and print out when changed.
83+
void loop()
84+
{
85+
encoder.tick();
86+
87+
int newPos = encoder.getPosition();
88+
if (lastPos != newPos) {
89+
90+
// accelerate when there was a previous rotation in the same direction.
91+
92+
unsigned long ms = encoder.getMillisBetweenRotations();
93+
94+
if (ms < longCutoff) {
95+
// do some acceleration using factors a and b
96+
97+
// limit to maximum acceleration
98+
if (ms < shortCutoff) {
99+
ms = shortCutoff;
100+
}
101+
102+
float ticksActual_float = a * ms + b;
103+
Serial.print(" f= ");
104+
Serial.println(ticksActual_float);
105+
106+
long deltaTicks = (long)ticksActual_float * (newPos - lastPos);
107+
Serial.print(" d= ");
108+
Serial.println(deltaTicks);
109+
110+
newPos = newPos + deltaTicks;
111+
encoder.setPosition(newPos);
112+
}
113+
114+
Serial.print(newPos);
115+
Serial.print(" ms: ");
116+
Serial.println(ms);
117+
lastPos = newPos;
118+
} // if
119+
} // loop ()
120+
121+
// The End

examples/LimitedRotator/LimitedRotator.ino

+24-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// -----
22
// LimitedRotator.ino - Example for the RotaryEncoder library.
33
// This class is implemented for use with the Arduino environment.
4+
//
45
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
5-
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
6+
// This work is licensed under a BSD 3-Clause License. See http://www.mathertel.de/License.aspx
67
// More information on: http://www.mathertel.de/Arduino
78
// -----
89
// 26.03.2017 created by Matthias Hertel
10+
// 06.02.2021 conditions and settings added for ESP8266
911
// -----
1012

1113
// This example checks the state of the rotary encoder in the loop() function.
@@ -19,21 +21,38 @@
1921
// Attach a rotary encoder with output pins to A2 and A3.
2022
// The common contact should be attached to ground.
2123

24+
#include <Arduino.h>
2225
#include <RotaryEncoder.h>
2326

27+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
28+
// Example for Arduino UNO with input signals on pin 2 and 3
29+
#define PIN_IN1 2
30+
#define PIN_IN2 3
31+
32+
#elif defined(ESP8266)
33+
// Example for ESP8266 NodeMCU with input signals on pin D5 and D6
34+
#define PIN_IN1 D5
35+
#define PIN_IN2 D6
36+
37+
#endif
38+
2439
#define ROTARYSTEPS 2
2540
#define ROTARYMIN 0
2641
#define ROTARYMAX 16
2742

28-
// Setup a RoraryEncoder for pins A2 and A3:
29-
RotaryEncoder encoder(A2, A3);
43+
// Setup a RotaryEncoder with 4 steps per latch for the 2 signal input pins:
44+
// RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3);
45+
46+
// Setup a RotaryEncoder with 2 steps per latch for the 2 signal input pins:
47+
RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03);
3048

3149
// Last known rotary position.
3250
int lastPos = -1;
3351

3452
void setup()
3553
{
36-
Serial.begin(57600);
54+
Serial.begin(115200);
55+
while (! Serial);
3756
Serial.println("LimitedRotator example for the RotaryEncoder library.");
3857
encoder.setPosition(10 / ROTARYSTEPS); // start with the value of 10.
3958
} // setup()
@@ -64,4 +83,4 @@ void loop()
6483
} // loop ()
6584

6685
// The End
67-
86+

examples/SimplePollRotator/SimplePollRotator.ino

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
#include <RotaryEncoder.h>
2525

2626
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY)
27-
// Example for Arduino UNO with input signals on pin A2 and A3
28-
#define PIN_IN1 A2
29-
#define PIN_IN2 A3
27+
// Example for Arduino UNO with input signals on pin 2 and 3
28+
#define PIN_IN1 2
29+
#define PIN_IN2 3
3030

3131
#elif defined(ESP8266)
3232
// Example for ESP8266 NodeMCU with input signals on pin D5 and D6

0 commit comments

Comments
 (0)