├── .gitattributes
├── .gitignore
├── .vscode
├── arduino.json
├── c_cpp_properties.json
└── settings.json
├── LICENSE.md
├── README.md
├── README_old.md
├── examples
├── Esp32RotaryEncoderBasics
│ ├── .vscode
│ │ ├── arduino.json
│ │ ├── c_cpp_properties.json
│ │ └── settings.json
│ └── Esp32RotaryEncoderBasics.ino
├── Esp32RotaryEncoderButtonOptions
│ └── Esp32RotaryEncoderButtonOptions.ino
├── Esp32RotaryEncoderTestAcceleration
│ ├── .vscode
│ │ ├── arduino.json
│ │ ├── c_cpp_properties.json
│ │ └── settings.json
│ └── Esp32RotaryEncoderTestAcceleration.ino
├── Esp32RotaryEncoderTestBoundaries
│ ├── .vscode
│ │ ├── arduino.json
│ │ ├── c_cpp_properties.json
│ │ └── settings.json
│ └── Esp32RotaryEncoderTestBoundaries.ino
├── Esp32RotaryEncoderTheShortestExample
│ ├── .vscode
│ │ ├── arduino.json
│ │ ├── c_cpp_properties.json
│ │ └── settings.json
│ └── Esp32RotaryEncoderTheShortestExample.ino
├── Esp32RotaryEncoderTheShortestExampleNoResistors
│ └── Esp32RotaryEncoderTheShortestExampleNoResistors.ino
├── FM-radio-tuner
│ ├── .vscode
│ │ ├── arduino.json
│ │ ├── c_cpp_properties.json
│ │ └── settings.json
│ └── FM-radio-tuner.ino
├── Multi-select
│ ├── .vscode
│ │ ├── arduino.json
│ │ ├── c_cpp_properties.json
│ │ └── settings.json
│ └── Multi-select.ino
└── Number-select
│ ├── .vscode
│ ├── arduino.json
│ ├── c_cpp_properties.json
│ └── settings.json
│ └── Number-select.ino
├── library.properties
└── src
├── AiEsp32RotaryEncoder.cpp
├── AiEsp32RotaryEncoder.h
├── AiEsp32RotaryEncoderNumberSelector.cpp
└── AiEsp32RotaryEncoderNumberSelector.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
--------------------------------------------------------------------------------
/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "port": "COM6",
4 | "configuration": "xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600",
5 | "sketch": "examples\\Number-select\\Number-select.ino"
6 | }
--------------------------------------------------------------------------------
/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\hraani\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-free",
32 | "-fipa-pta",
33 | "-Werror=return-type",
34 | "-mlongcalls",
35 | "-mtext-section-literals",
36 | "-fno-rtti",
37 | "-falign-functions=4",
38 | "-std=gnu++17"
39 | ],
40 | "intelliSenseMode": "gcc-x64",
41 | "includePath": [
42 | "C:\\Users\\hraani\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.1.2\\tools\\sdk\\include",
43 | "C:\\Users\\hraani\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.1.2\\tools\\sdk\\lwip2\\include",
44 | "C:\\Users\\hraani\\AppData\\Local\\Temp\\arduino\\sketches\\E48FE079AAF10B4D015D81F1F199AA68\\core",
45 | "C:\\Users\\hraani\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.1.2\\cores\\esp8266",
46 | "C:\\Users\\hraani\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.1.2\\variants\\d1_mini",
47 | "C:\\Users\\hraani\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
48 | "c:\\users\\hraani\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\xtensa-lx106-elf\\include\\c++\\10.3.0",
49 | "c:\\users\\hraani\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\xtensa-lx106-elf\\include\\c++\\10.3.0\\xtensa-lx106-elf",
50 | "c:\\users\\hraani\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\xtensa-lx106-elf\\include\\c++\\10.3.0\\backward",
51 | "c:\\users\\hraani\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\lib\\gcc\\xtensa-lx106-elf\\10.3.0\\include",
52 | "c:\\users\\hraani\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\lib\\gcc\\xtensa-lx106-elf\\10.3.0\\include-fixed",
53 | "c:\\users\\hraani\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.1.0-gcc10.3-e5f9fec\\xtensa-lx106-elf\\include"
54 | ],
55 | "forcedInclude": [
56 | "C:\\Users\\hraani\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.1.2\\cores\\esp8266\\Arduino.h"
57 | ],
58 | "cStandard": "c11",
59 | "cppStandard": "c++17",
60 | "defines": [
61 | "__ets__",
62 | "ICACHE_FLASH",
63 | "_GNU_SOURCE",
64 | "ESP8266",
65 | "MMU_IRAM_SIZE=0x8000",
66 | "MMU_ICACHE_SIZE=0x8000",
67 | "NONOSDK22x_190703=1",
68 | "F_CPU=80000000L",
69 | "LWIP_OPEN_SRC",
70 | "TCP_MSS=536",
71 | "LWIP_FEATURES=1",
72 | "LWIP_IPV6=0",
73 | "ARDUINO=10607",
74 | "ARDUINO_ESP8266_WEMOS_D1MINI",
75 | "ARDUINO_ARCH_ESP8266",
76 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
77 | "ARDUINO_BOARD_ID=\"d1_mini\"",
78 | "FLASHMODE_DIO",
79 | "__DBL_MIN_EXP__=(-1021)",
80 | "__cpp_attributes=200809L",
81 | "__UINT_LEAST16_MAX__=0xffff",
82 | "__ATOMIC_ACQUIRE=2",
83 | "__FLT_MIN__=1.1754943508222875e-38F",
84 | "__GCC_IEC_559_COMPLEX=0",
85 | "__cpp_aggregate_nsdmi=201304L",
86 | "__UINT_LEAST8_TYPE__=unsigned char",
87 | "__INTMAX_C(c)=c ## LL",
88 | "__CHAR_BIT__=8",
89 | "__UINT8_MAX__=0xff",
90 | "__WINT_MAX__=0xffffffffU",
91 | "__FLT32_MIN_EXP__=(-125)",
92 | "__cpp_static_assert=200410L",
93 | "__ORDER_LITTLE_ENDIAN__=1234",
94 | "__SIZE_MAX__=0xffffffffU",
95 | "__WCHAR_MAX__=0xffff",
96 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
97 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
98 | "__GCC_IEC_559=0",
99 | "__FLT32X_DECIMAL_DIG__=17",
100 | "__FLT_EVAL_METHOD__=0",
101 | "__cpp_binary_literals=201304L",
102 | "__FLT64_DECIMAL_DIG__=17",
103 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
104 | "__cpp_variadic_templates=200704L",
105 | "__UINT_FAST64_MAX__=0xffffffffffffffffULL",
106 | "__SIG_ATOMIC_TYPE__=int",
107 | "__DBL_MIN_10_EXP__=(-307)",
108 | "__FINITE_MATH_ONLY__=0",
109 | "__cpp_variable_templates=201304L",
110 | "__FLT32X_MAX_EXP__=1024",
111 | "__GNUC_PATCHLEVEL__=0",
112 | "__FLT32_HAS_DENORM__=1",
113 | "__UINT_FAST8_MAX__=0xffffffffU",
114 | "__cpp_rvalue_reference=200610L",
115 | "__FLT32_MAX_10_EXP__=38",
116 | "__INT8_C(c)=c",
117 | "__INT_LEAST8_WIDTH__=8",
118 | "__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
119 | "__SHRT_MAX__=0x7fff",
120 | "__LDBL_MAX__=1.7976931348623157e+308L",
121 | "__UINT_LEAST8_MAX__=0xff",
122 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
123 | "__UINTMAX_TYPE__=long long unsigned int",
124 | "__FLT_EVAL_METHOD_TS_18661_3__=0",
125 | "__CHAR_UNSIGNED__=1",
126 | "__UINT32_MAX__=0xffffffffU",
127 | "__GXX_EXPERIMENTAL_CXX0X__=1",
128 | "__LDBL_MAX_EXP__=1024",
129 | "__WINT_MIN__=0U",
130 | "__INT_LEAST16_WIDTH__=16",
131 | "__SCHAR_MAX__=0x7f",
132 | "__WCHAR_MIN__=0",
133 | "__INT64_C(c)=c ## LL",
134 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
135 | "__XTENSA_CALL0_ABI__=1",
136 | "__SIZEOF_INT__=4",
137 | "__FLT32X_MANT_DIG__=53",
138 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
139 | "__USER_LABEL_PREFIX__",
140 | "__STDC_HOSTED__=1",
141 | "__XTENSA_EL__=1",
142 | "__cpp_decltype_auto=201304L",
143 | "__DBL_DIG__=15",
144 | "__FLT32_DIG__=6",
145 | "__FLT_EPSILON__=1.1920928955078125e-7F",
146 | "__GXX_WEAK__=1",
147 | "__SHRT_WIDTH__=16",
148 | "__LDBL_MIN__=2.2250738585072014e-308L",
149 | "__cpp_threadsafe_static_init=200806L",
150 | "__FLT32X_HAS_INFINITY__=1",
151 | "__INT32_MAX__=0x7fffffff",
152 | "__INT_WIDTH__=32",
153 | "__SIZEOF_LONG__=4",
154 | "__UINT16_C(c)=c",
155 | "__DECIMAL_DIG__=17",
156 | "__FLT64_EPSILON__=2.2204460492503131e-16F64",
157 | "__INT16_MAX__=0x7fff",
158 | "__FLT64_MIN_EXP__=(-1021)",
159 | "__LDBL_HAS_QUIET_NAN__=1",
160 | "__FLT64_MANT_DIG__=53",
161 | "__GNUC__=10",
162 | "__GXX_RTTI=1",
163 | "__FLT_HAS_DENORM__=1",
164 | "__SIZEOF_LONG_DOUBLE__=8",
165 | "__BIGGEST_ALIGNMENT__=16",
166 | "__STDC_UTF_16__=1",
167 | "__FLT64_MAX_10_EXP__=308",
168 | "__cpp_delegating_constructors=200604L",
169 | "__FLT32_HAS_INFINITY__=1",
170 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
171 | "__cpp_raw_strings=200710L",
172 | "__INT_FAST32_MAX__=0x7fffffff",
173 | "__DBL_HAS_INFINITY__=1",
174 | "__HAVE_SPECULATION_SAFE_VALUE=1",
175 | "__INTPTR_WIDTH__=32",
176 | "__UINT_LEAST32_MAX__=0xffffffffU",
177 | "__FLT32X_HAS_DENORM__=1",
178 | "__INT_FAST16_TYPE__=int",
179 | "__LDBL_HAS_DENORM__=1",
180 | "__cplusplus=201402L",
181 | "__cpp_ref_qualifiers=200710L",
182 | "__INT_LEAST32_MAX__=0x7fffffff",
183 | "__DEPRECATED=1",
184 | "__cpp_rvalue_references=200610L",
185 | "__DBL_MAX_EXP__=1024",
186 | "__WCHAR_WIDTH__=16",
187 | "__FLT32_MAX__=3.4028234663852886e+38F32",
188 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
189 | "__PTRDIFF_MAX__=0x7fffffff",
190 | "__FLT32_HAS_QUIET_NAN__=1",
191 | "__GNUG__=10",
192 | "__LONG_LONG_MAX__=0x7fffffffffffffffLL",
193 | "__SIZEOF_SIZE_T__=4",
194 | "__cpp_nsdmi=200809L",
195 | "__SIZEOF_WINT_T__=4",
196 | "__LONG_LONG_WIDTH__=64",
197 | "__cpp_initializer_lists=200806L",
198 | "__FLT32_MAX_EXP__=128",
199 | "__cpp_hex_float=201603L",
200 | "__GXX_ABI_VERSION=1014",
201 | "__FLT_MIN_EXP__=(-125)",
202 | "__cpp_lambdas=200907L",
203 | "__INT_FAST64_TYPE__=long long int",
204 | "__FLT64_DENORM_MIN__=4.9406564584124654e-324F64",
205 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
206 | "__SIZEOF_POINTER__=4",
207 | "__SIZE_TYPE__=unsigned int",
208 | "__DBL_HAS_QUIET_NAN__=1",
209 | "__FLT32X_EPSILON__=2.2204460492503131e-16F32x",
210 | "__FLT64_MIN_10_EXP__=(-307)",
211 | "__REGISTER_PREFIX__",
212 | "__UINT16_MAX__=0xffff",
213 | "__FLT32_MIN__=1.1754943508222875e-38F32",
214 | "__UINT8_TYPE__=unsigned char",
215 | "__FLT_DIG__=6",
216 | "__NO_INLINE__=1",
217 | "__DEC_EVAL_METHOD__=2",
218 | "__FLT_MANT_DIG__=24",
219 | "__LDBL_DECIMAL_DIG__=17",
220 | "__VERSION__=\"10.3.0\"",
221 | "__UINT64_C(c)=c ## ULL",
222 | "__cpp_unicode_characters=200704L",
223 | "__XTENSA_SOFT_FLOAT__=1",
224 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
225 | "__FLT32_MANT_DIG__=24",
226 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
227 | "__SCHAR_WIDTH__=8",
228 | "__INT32_C(c)=c",
229 | "__ORDER_PDP_ENDIAN__=3412",
230 | "__INT_FAST32_TYPE__=int",
231 | "__UINT_LEAST16_TYPE__=short unsigned int",
232 | "__DBL_HAS_DENORM__=1",
233 | "__cpp_rtti=199711L",
234 | "__UINT64_MAX__=0xffffffffffffffffULL",
235 | "__INT8_TYPE__=signed char",
236 | "__cpp_digit_separators=201309L",
237 | "__ELF__=1",
238 | "__xtensa__=1",
239 | "__FLT_RADIX__=2",
240 | "__INT_LEAST16_TYPE__=short int",
241 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
242 | "__UINTMAX_C(c)=c ## ULL",
243 | "__FLT32X_MIN__=2.2250738585072014e-308F32x",
244 | "__SIG_ATOMIC_MAX__=0x7fffffff",
245 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
246 | "__SIZEOF_PTRDIFF_T__=4",
247 | "__LDBL_DIG__=15",
248 | "__FLT32X_MIN_EXP__=(-1021)",
249 | "__INT_FAST16_MAX__=0x7fffffff",
250 | "__FLT64_DIG__=15",
251 | "__UINT_FAST32_MAX__=0xffffffffU",
252 | "__UINT_LEAST64_TYPE__=long long unsigned int",
253 | "__FLT_HAS_QUIET_NAN__=1",
254 | "__FLT_MAX_10_EXP__=38",
255 | "__LONG_MAX__=0x7fffffffL",
256 | "__FLT_HAS_INFINITY__=1",
257 | "__cpp_unicode_literals=200710L",
258 | "__UINT_FAST16_TYPE__=unsigned int",
259 | "__INT_FAST32_WIDTH__=32",
260 | "__CHAR16_TYPE__=short unsigned int",
261 | "__PRAGMA_REDEFINE_EXTNAME=1",
262 | "__SIZE_WIDTH__=32",
263 | "__INT_LEAST16_MAX__=0x7fff",
264 | "__INT64_MAX__=0x7fffffffffffffffLL",
265 | "__FLT32_DENORM_MIN__=1.4012984643248171e-45F32",
266 | "__SIG_ATOMIC_WIDTH__=32",
267 | "__INT_LEAST64_TYPE__=long long int",
268 | "__INT16_TYPE__=short int",
269 | "__INT_LEAST8_TYPE__=signed char",
270 | "__INT_FAST8_MAX__=0x7fffffff",
271 | "__INTPTR_MAX__=0x7fffffff",
272 | "__cpp_sized_deallocation=201309L",
273 | "__FLT64_HAS_QUIET_NAN__=1",
274 | "__FLT32_MIN_10_EXP__=(-37)",
275 | "__EXCEPTIONS=1",
276 | "__PTRDIFF_WIDTH__=32",
277 | "__LDBL_MANT_DIG__=53",
278 | "__cpp_range_based_for=200907L",
279 | "__FLT64_HAS_INFINITY__=1",
280 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
281 | "__cpp_return_type_deduction=201304L",
282 | "__INTPTR_TYPE__=int",
283 | "__UINT16_TYPE__=short unsigned int",
284 | "__WCHAR_TYPE__=short unsigned int",
285 | "__SIZEOF_FLOAT__=4",
286 | "__UINTPTR_MAX__=0xffffffffU",
287 | "__INT_FAST64_WIDTH__=64",
288 | "__cpp_decltype=200707L",
289 | "__FLT32_DECIMAL_DIG__=9",
290 | "__INT_FAST64_MAX__=0x7fffffffffffffffLL",
291 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
292 | "__FLT_NORM_MAX__=3.4028234663852886e+38F",
293 | "__UINT_FAST64_TYPE__=long long unsigned int",
294 | "__INT_MAX__=0x7fffffff",
295 | "__INT64_TYPE__=long long int",
296 | "__FLT_MAX_EXP__=128",
297 | "__DBL_MANT_DIG__=53",
298 | "__cpp_inheriting_constructors=201511L",
299 | "__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
300 | "__WINT_TYPE__=unsigned int",
301 | "__UINT_LEAST32_TYPE__=unsigned int",
302 | "__SIZEOF_SHORT__=2",
303 | "__FLT32_NORM_MAX__=3.4028234663852886e+38F32",
304 | "__LDBL_MIN_EXP__=(-1021)",
305 | "__FLT64_MAX__=1.7976931348623157e+308F64",
306 | "__WINT_WIDTH__=32",
307 | "__INT_LEAST8_MAX__=0x7f",
308 | "__INT_LEAST64_WIDTH__=64",
309 | "__FLT32X_MAX_10_EXP__=308",
310 | "__WCHAR_UNSIGNED__=1",
311 | "__LDBL_MAX_10_EXP__=308",
312 | "__ATOMIC_RELAXED=0",
313 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
314 | "__UINT8_C(c)=c",
315 | "__FLT64_MAX_EXP__=1024",
316 | "__INT_LEAST32_TYPE__=int",
317 | "__SIZEOF_WCHAR_T__=2",
318 | "__FLT64_NORM_MAX__=1.7976931348623157e+308F64",
319 | "__INTMAX_MAX__=0x7fffffffffffffffLL",
320 | "__INT_FAST8_TYPE__=int",
321 | "__LDBL_HAS_INFINITY__=1",
322 | "__GNUC_STDC_INLINE__=1",
323 | "__FLT64_HAS_DENORM__=1",
324 | "__FLT32_EPSILON__=1.1920928955078125e-7F32",
325 | "__DBL_DECIMAL_DIG__=17",
326 | "__STDC_UTF_32__=1",
327 | "__INT_FAST8_WIDTH__=32",
328 | "__FLT32X_MAX__=1.7976931348623157e+308F32x",
329 | "__DBL_NORM_MAX__=double(1.7976931348623157e+308L)",
330 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
331 | "__XTENSA__=1",
332 | "__INTMAX_WIDTH__=64",
333 | "__ORDER_BIG_ENDIAN__=4321",
334 | "__cpp_runtime_arrays=198712L",
335 | "__UINT64_TYPE__=long long unsigned int",
336 | "__UINT32_C(c)=c ## U",
337 | "__cpp_alias_templates=200704L",
338 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
339 | "__INT8_MAX__=0x7f",
340 | "__LONG_WIDTH__=32",
341 | "__UINT_FAST32_TYPE__=unsigned int",
342 | "__FLT32X_NORM_MAX__=1.7976931348623157e+308F32x",
343 | "__CHAR32_TYPE__=unsigned int",
344 | "__FLT_MAX__=3.4028234663852886e+38F",
345 | "__cpp_constexpr=201304L",
346 | "__INT32_TYPE__=int",
347 | "__SIZEOF_DOUBLE__=8",
348 | "__cpp_exceptions=199711L",
349 | "__FLT_MIN_10_EXP__=(-37)",
350 | "__FLT64_MIN__=2.2250738585072014e-308F64",
351 | "__INT_LEAST32_WIDTH__=32",
352 | "__INTMAX_TYPE__=long long int",
353 | "__FLT32X_HAS_QUIET_NAN__=1",
354 | "__ATOMIC_CONSUME=1",
355 | "__GNUC_MINOR__=3",
356 | "__INT_FAST16_WIDTH__=32",
357 | "__UINTMAX_MAX__=0xffffffffffffffffULL",
358 | "__FLT32X_DENORM_MIN__=4.9406564584124654e-324F32x",
359 | "__DBL_MAX_10_EXP__=308",
360 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
361 | "__INT16_C(c)=c",
362 | "__STDC__=1",
363 | "__FLT32X_DIG__=15",
364 | "__PTRDIFF_TYPE__=int",
365 | "__ATOMIC_SEQ_CST=5",
366 | "__UINT32_TYPE__=unsigned int",
367 | "__FLT32X_MIN_10_EXP__=(-307)",
368 | "__UINTPTR_TYPE__=unsigned int",
369 | "__LDBL_MIN_10_EXP__=(-307)",
370 | "__cpp_generic_lambdas=201304L",
371 | "__SIZEOF_LONG_LONG__=8",
372 | "__cpp_user_defined_literals=200809L",
373 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
374 | "__FLT_DECIMAL_DIG__=9",
375 | "__UINT_FAST16_MAX__=0xffffffffU",
376 | "__LDBL_NORM_MAX__=1.7976931348623157e+308L",
377 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
378 | "__UINT_FAST8_TYPE__=unsigned int",
379 | "__cpp_init_captures=201304L",
380 | "__ATOMIC_ACQ_REL=4",
381 | "__ATOMIC_RELEASE=3",
382 | "USBCON"
383 | ]
384 | }
385 | ]
386 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Intro
2 |
3 | Use this library to connect and use a **rotary encoder** with **ESP32** or **ESP8266**.
4 |
5 | But it is a bit more than just that.
6 |
7 | **Strongly recomended is to try a few included examples to see how it works.**
8 |
9 | **The main fatures are:**
10 | - select a number in a predifined range. For example select a termostat value between 18 and 29 Celsius degrees.
11 | - 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**
12 | - 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.
13 |
14 | To disable use
15 |
16 | ```
17 | rotaryEncoder.disableAcceleration();
18 | ```
19 |
20 | - additionally there is a helper so see example Number-select which includes a NumberSellector
21 | - if you want to implement a menu, see example Multi-select
22 | - 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.
23 |
24 | **Using a button**
25 |
26 | 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.
27 |
28 | For compatibility older examples still works but will become obsolete soon.
29 |
30 | **update 2023-05 for button custom iplementation (long click...)**
31 |
32 | Some people asked how they can handle more complex button events like double click, short press, long press.
33 |
34 | There is an example Esp32RotaryEncoderButtonOptions.ino
35 |
36 | You will fint there how to implement long press, how to invert button state, but also get ideas how to implement double click.
37 | The code is nonblocking so try to rotate a rotary encoder while the button is down.
38 |
39 |
40 | # Support fot ESP8266 added 10/2021
41 |
42 | Support added also for ESP8266
43 |
44 | # Changes in button processing 10/2021
45 |
46 | Old button using interrupt is now obsolete.
47 | Please look at upadated examples how to handle click, properly initialize encoder and avoid crashing.
48 |
49 | # New feature added 02/2021 - accelerated movement
50 |
51 | 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.
52 | However using new implemented acceleration, faster you turn, faster will the value raise.For fine tuning just slow down.
53 | 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.
54 |
55 | rotaryEncoder.setAcceleration(250);
56 | this will set acceleration; larger number = more accelearation; 0 or 1 means disabled acceleration
57 |
58 |
59 | rotaryEncoder.disableAcceleration();
60 | This will disable acceleration (now enabled by default) in case you dont need one.
61 |
62 | Recomendation - turn off for small ranges; but turn on when you select from more than 50 values in range.
63 |
64 |
65 | # Arduino Esp32 Encoder Library
66 |
67 | Rotary encoder main interrupt code is extracted from (https://github.com/marcmerlin/IoTuz) and some additional features are included here.
68 |
69 | ## Description
70 |
71 | This library enables easy implementation of rotary encoder functionality in your application for ESP32, ESP8266 (or similar microcontroller).
72 | -
73 | ## Installing
74 |
75 | Since 2021 you can download using Arduino, which is preffered way:
76 |
77 | Sketch / include Library / Manage Libraries
78 |
79 | in search box type "ai rotary" (without quotes)
80 |
81 |
82 | Alternative way (to get not yet published version)
83 | The downloaded code can be included as a new library into the IDE selecting the menu:
84 |
85 | Sketch / include Library / Add .Zip library
86 |
87 | Restart the Arduino IDE and follow the examples located at
88 |
89 | File -> Examples -> Ai Esp32 Rotary Encoder
90 |
91 | ## Connecting Rotary Encoder Module to your microcontroller ESP32, ESP8266 (or similar)
92 |
93 | This are instructions for "Rotary Encoder Module" which is actually Rotary Encoder with 2 resistors on board.
94 |
95 | CLK (A pin) - connect to any microcontroler input pin with interrupt -> in this example pin 32
96 |
97 | DT (B pin) - connect to any microcontroler input pin with interrupt -> in this example pin 21
98 |
99 | SW (button pin) - connect to any microcontroler input pin -> in this example pin 25
100 |
101 | VCC - for this you can two options:
102 |
103 | a) connect to microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1) or
104 |
105 | b) connect to any microcontroler output pin - in this example pin 25
106 |
107 | GND - connect to microcontroler GND
108 |
109 | ## Connecting Rotary Encoder with Switch (no pcb version. The encoder is like [this](https://www.seeedstudio.com/Rotary-Encoder-with-Switch-p-667.html)) to your microcontroller ESP32, ESP8266 (or similar)
110 |
111 | There is no need for external resistors, you can use only the encoder.
112 |
113 | 3 pin side:
114 |
115 | Right pin (A pin) - connect to any microcontroler input pin with interrupt -> in the example pin 22
116 |
117 | Left pin (B pin) - connect to any microcontroler input pin with interrupt -> in the example pin 23
118 |
119 | Middle pin - connect to microcontroller Gnd
120 |
121 | 2 pin side:
122 |
123 | one of the 2 pins: connect to microcontroller Gnd
124 |
125 | the other pin: connect to any microcontroller input pin -> in this example pin 25
126 |
127 | **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);`**
128 | Look for example Esp32RotaryEncoderTheShortestExampleNoResistors.
129 |
130 |
131 | update 2024-03-10:
132 |
133 | 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.
134 | Please note that it doesn't make any change for ESP8266, but only for ESP32.
135 |
136 | Here in example pay attention to the end of the line - parameter ",false".
137 |
138 | To modify other examples just add ", false" as an additional parameter.
139 |
140 | ```
141 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS,false);
142 | ```
143 |
144 | 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.
145 | It doesn't make any change for ESP8266, only ESP32.
146 |
147 | ```
148 | rotaryEncoder.isButtonPulldown = true;
149 | ```
150 |
151 |
152 | ## How to use
153 |
154 | I suggest you should start using built in example. After installing library (and reopening Arduino IDE if required) open
155 |
156 | File -> Examples -> Ai Esp32 Rotary Encoder
157 |
158 | If you didnt use suggested pins, adjust defines
159 |
160 | ```c
161 | #define ROTARY_ENCODER_A_PIN 32
162 | #define ROTARY_ENCODER_B_PIN 21
163 | #define ROTARY_ENCODER_BUTTON_PIN 25
164 | #define ROTARY_ENCODER_VCC_PIN 27
165 | ```
166 |
167 | For ESP8266 you can use Dx as pin names like in example:
168 | ```c
169 | #define ROTARY_ENCODER_A_PIN D6
170 | #define ROTARY_ENCODER_B_PIN D5
171 | #define ROTARY_ENCODER_BUTTON_PIN D7
172 | ```
173 | Then upload code to microcontroller.
174 |
175 | README_old.md contains more information but some parts are obsolete.
176 |
177 |
--------------------------------------------------------------------------------
/README_old.md:
--------------------------------------------------------------------------------
1 | # Arduino Esp32 / ESP8266 MULTIPLE Encoder Library
2 |
3 | This project is based on the (https://github.com/igorantolic/ai-esp32-rotary-encoder) with only main difference that it supports
4 | multiple instances on encoders. Original library supported only one instance, but this project allows you to create more instance of encoders like this:
5 |
6 | ```c
7 | #include "AiEsp32RotaryEncoder.h"
8 | #define ROTARY_ENCODER2_A_PIN GPIO_NUM_16
9 | #define ROTARY_ENCODER2_B_PIN GPIO_NUM_4
10 | #define ROTARY_ENCODER1_A_PIN GPIO_NUM_17
11 | #define ROTARY_ENCODER1_B_PIN GPIO_NUM_5
12 |
13 | AiEsp32RotaryEncoder rotaryEncoder1 = AiEsp32RotaryEncoder(ROTARY_ENCODER1_A_PIN, ROTARY_ENCODER1_B_PIN, -1, -1);
14 | AiEsp32RotaryEncoder rotaryEncoder2 = AiEsp32RotaryEncoder(ROTARY_ENCODER2_A_PIN, ROTARY_ENCODER2_B_PIN, -1, -1);
15 | ```
16 |
17 | in setup() of arduino:
18 | ```c
19 | rotaryEncoder1.begin();
20 | rotaryEncoder1.setup([]{rotaryEncoder1.readEncoder_ISR();});
21 |
22 | rotaryEncoder2.begin();
23 | rotaryEncoder2.setup([]{rotaryEncoder2.readEncoder_ISR();});
24 | ```
25 |
26 | Rotary encoder main interrupt code is extracted from (https://github.com/marcmerlin/IoTuz) and some additional features are included here.
27 |
28 | ## Description
29 |
30 | This library enables easy implementation of rotary encoder functionality in your application for ESP32, ESP8266 (or similar microcontroller).
31 |
32 | ## Installing
33 |
34 | The downloaded code can be included as a new library into the IDE selecting the menu:
35 |
36 | Sketch / include Library / Add .Zip library
37 |
38 | Restart the Arduino IDE and follow the examples located at
39 |
40 | File -> Examples -> Ai Esp32 Rotary Encoder
41 |
42 | ## Connecting Rotary Encoder Module to your microcontroller ESP32, ESP8266 (or similar)
43 |
44 | This are instructions for "Rotary Encoder Module" which is actually Rotary Encoder with 2 resistors on board.
45 |
46 | CLK (A pin) - connect to any microcontroler intput pin with interrupt -> in this example pin 32
47 |
48 | DT (B pin) - connect to any microcontroler intput pin with interrupt -> in this example pin 21
49 |
50 | SW (button pin) - connect to any microcontroler intput pin -> in this example pin 25
51 |
52 | VCC - for this you can two options:
53 |
54 | a) connect to microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1) or
55 |
56 | b) connect to any microcontroler output pin - in this example pin 25
57 |
58 | GND - connect to microcontroler GND
59 |
60 | ## How to use
61 |
62 | I suggest you should start using built in example. After installing library (and reopening Arduino IDE if required) open
63 |
64 | File -> Examples -> Ai Esp32 Rotary Encoder
65 |
66 | If you didnt use suggested pins, adjust defines
67 |
68 | ```c
69 | #define ROTARY_ENCODER_A_PIN 32
70 | #define ROTARY_ENCODER_B_PIN 21
71 | #define ROTARY_ENCODER_BUTTON_PIN 25
72 | #define ROTARY_ENCODER_VCC_PIN 27
73 | ```
74 |
75 | For ESP8266 you can use Dx as pin names like in example:
76 | ```c
77 | #define ROTARY_ENCODER_A_PIN D3
78 | #define ROTARY_ENCODER_B_PIN D2
79 | #define ROTARY_ENCODER_BUTTON_PIN D4
80 | ```
81 | Then upload code to microcontroller.
82 |
83 | This example is initally set that you can adjust values 0 to 10. If you try to go beyond upper limit 10, since cycle option is set to true, it will restart from 0. Also tryinf to adjust lower than 0 will go back to 10.
84 |
85 | If you press button first time, new limits -2 ... 2 are set. But this time cycle is set to false, so you have real minimum and maximum values.
86 |
87 | Further pressing button will double the same limit to -4 ... 4. Then -8...8 and so on. I wonder how far will you go. Real limt is int16 limit (signed int16) which should be sufficient for most applications.
88 |
89 | ## Details
90 |
91 | ### step 1) include library using
92 |
93 | ```c
94 | #include "AiEsp32RotaryEncoder.h"
95 | ```
96 |
97 | ### step 2) set pins used. Important: A and B pins must support interrupts.
98 |
99 | ```c
100 | #define ROTARY_ENCODER_A_PIN 32
101 | #define ROTARY_ENCODER_B_PIN 21
102 | #define ROTARY_ENCODER_BUTTON_PIN 25
103 | #define ROTARY_ENCODER_VCC_PIN 27 /*put -1 of Rotary encoder Vcc is
104 | connected directly to 3,3V;
105 | else you can use declared output pin
106 | for powering rotary encoder */
107 | ```
108 |
109 | ### step 3) declare your variable like rotaryEncoder
110 |
111 | ```c
112 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(
113 | ROTARY_ENCODER_A_PIN,
114 | ROTARY_ENCODER_B_PIN,
115 | ROTARY_ENCODER_BUTTON_PIN,
116 | ROTARY_ENCODER_VCC_PIN
117 | );
118 | ```
119 |
120 | ### step 4) in setup() function you should call begin method to initialize encoder.
121 |
122 | ```c
123 | rotaryEncoder.begin();
124 | ```
125 |
126 | ### step 4a) in setup() function you should call begin method to initialize encoder.
127 |
128 | ```c
129 | rotaryEncoder.setup([]{rotaryEncoder.readEncoder_ISR();});
130 | ```
131 |
132 | ### step 5) in loop() call some function like rotary_loop();
133 |
134 | ```c
135 | rotary_loop();
136 | ```
137 |
138 | ### step 6) define function rotary_loop()
139 |
140 | Example:
141 |
142 | ```c
143 |
144 | void rotary_loop() {
145 | //first lets handle rotary encoder button click
146 | if (rotaryEncoder.currentButtonState() == BUT_RELEASED) {
147 | //we can process it here or call separate function like:
148 | rotary_onButtonClick();
149 | }
150 |
151 | //lets see if anything changed
152 | int8_t encoderDelta = rotaryEncoder.encoderChanged();
153 |
154 | //optionally we can ignore whenever there is no change
155 | if (encoderDelta == 0) return;
156 |
157 | //for some cases we only want to know if value is
158 | //increased or decreased (typically for menu items)
159 | if (encoderDelta>0) Serial.print("+");
160 | if (encoderDelta<0) Serial.print("-");
161 |
162 | //for other cases we want to know what is current value.
163 | //Additionally often we only want if something changed
164 | //example: when using rotary encoder to set termostat temperature, or sound volume etc
165 |
166 | //if value is changed compared to our last read
167 | if (encoderDelta!=0) {
168 | //now we need current value
169 | int16_t encoderValue = rotaryEncoder.readEncoder();
170 |
171 | //process new value. Here is simple output.
172 | Serial.print("Value: ");
173 | Serial.println(encoderValue);
174 |
175 | }
176 | }
177 | ```
178 |
179 | ### step 7) if you use separate function for processing rotary encoder button click, implmement it
180 |
181 | In step 6 we call rotary_onButtonClick();
182 |
183 | example:
184 |
185 | ```c
186 | void rotary_onButtonClick() {
187 |
188 | rotaryEncoder.disable();
189 |
190 | }
191 | ```
192 |
193 | In this example we disable encoder on first click on button. Dont expect any further effects before you call
194 |
195 | ```c
196 | rotaryEncoder.enable();
197 | ```
198 |
199 | ...for obvious reasons
200 |
201 | ## List of methods
202 |
203 | ### Constructor
204 |
205 |
206 | Call to define local variable. 4 parameters are pin numbers.
207 | ```c
208 | #define ROTARY_ENCODER_A_PIN 32
209 | #define ROTARY_ENCODER_B_PIN 21
210 | #define ROTARY_ENCODER_BUTTON_PIN 25
211 | #define ROTARY_ENCODER_VCC_PIN 27
212 |
213 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(
214 | ROTARY_ENCODER_A_PIN,
215 | ROTARY_ENCODER_B_PIN,
216 | ROTARY_ENCODER_BUTTON_PIN,
217 | ROTARY_ENCODER_VCC_PIN
218 | );
219 | //or empty constructor
220 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder();
221 | /* Note: in case of empty constructor these are fefault pins:
222 | #define ROTARY_ENCODER_A_PIN 32
223 | #define ROTARY_ENCODER_B_PIN 21
224 | #define ROTARY_ENCODER_BUTTON_PIN 25
225 | #define ROTARY_ENCODER_VCC_PIN 27
226 | */
227 | ```
228 |
229 | ### setBoundaries (optional)
230 |
231 | sets minimum and maximum value.
232 | Additionally set circleValues to false if you want to stop at min or max limits.
233 | If you want to min to continue with max value or vice versa set to true,
234 |
235 | For example when using menu with 4 items you can call
236 | ```c
237 | rotaryEncoder.setBoundaries(1,4,true);
238 | ```
239 | rotating right will select valus 1, 2, 3, 4, 1 ,2, 3, ....
240 |
241 | while rotating left will select valus 1, 4, 3,2,1,4,3, ....
242 |
243 | ### begin - initialization method
244 |
245 | You must call this in setup()
246 | ```c
247 | void setup() {
248 | rotaryEncoder.begin();
249 | //...
250 | }
251 | ```
252 |
253 | ### reset to zero or selected value
254 |
255 | selected value will change to selected value. If value not provided 0 is assumed.
256 | Please note that there is a limit check. If value is lower than low limit low limit will be set. The same is for maximum limit.
257 |
258 | ```c
259 | //reaset to 0
260 | rotaryEncoder.reset();
261 | //reaset to 3
262 | rotaryEncoder.reset(3);
263 | ```
264 |
265 | ### disable and enable
266 |
267 | This will disable rotary movement or button events. You must call enable to contunue getting new values or button clicks.
268 | ```c
269 | rotaryEncoder.disable();
270 | rotaryEncoder.enable();
271 | ```
272 |
273 |
274 | ### readEncoder
275 |
276 | This methot will fetch current value of encoder.
277 | ```c
278 | int16_t currentValue = rotaryEncoder.readEncoder();
279 | ```
280 |
281 | ### encoderChanged
282 |
283 | This methot will return delta (absolute difference) comparing to previous read.
284 | ```c
285 | //you can react only on changes
286 | int16_t encoderDelta = rotaryEncoder.encoderChanged();
287 | if (encoderDelta>0) Serial.print("+");
288 | if (encoderDelta<0) Serial.print("-");
289 | ```
290 |
291 | ### currentButtonState
292 |
293 | This methor returns value of enum - current button state
294 | ```c
295 | ButtonState current = rotaryEncoder.currentButtonState();
296 | // or
297 | if (rotaryEncoder.currentButtonState() == BUT_RELEASED) {
298 | Serial.println("Click!");
299 | }
300 |
301 | /*
302 | Button values are:
303 | typedef enum {
304 | BUT_DOWN = 0,
305 | BUT_PUSHED = 1,
306 | BUT_UP = 2,
307 | BUT_RELEASED = 3,
308 | BUT_DISABLED = 99, //this state is after you call rotaryEncoder.disable();
309 | } ButtonState;
310 | */
311 |
312 | ```
313 |
314 |
315 |
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderBasics/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "port": "COM10",
4 | "output": "b:/dummy/Esp32RotaryEncoderBasics",
5 | "sketch": "Esp32RotaryEncoderBasics.ino",
6 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600"
7 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderBasics/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "b:\\dummy\\Esp32RotaryEncoderBasics\\core",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
44 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
45 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
51 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
52 | ],
53 | "forcedInclude": [
54 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
55 | ],
56 | "cStandard": "c11",
57 | "cppStandard": "c++11",
58 | "defines": [
59 | "__ets__",
60 | "ICACHE_FLASH",
61 | "NONOSDK22x_190703=1",
62 | "F_CPU=80000000L",
63 | "LWIP_OPEN_SRC",
64 | "TCP_MSS=536",
65 | "LWIP_FEATURES=1",
66 | "LWIP_IPV6=0",
67 | "ARDUINO=10815",
68 | "ARDUINO_ESP8266_WEMOS_D1MINI",
69 | "ARDUINO_ARCH_ESP8266",
70 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
71 | "FLASHMODE_DIO",
72 | "ESP8266",
73 | "__DBL_MIN_EXP__=(-1021)",
74 | "__UINT_LEAST16_MAX__=65535",
75 | "__ATOMIC_ACQUIRE=2",
76 | "__FLT_MIN__=1.1754943508222875e-38F",
77 | "__UINT_LEAST8_TYPE__=unsigned char",
78 | "__INTMAX_C(c)=c ## LL",
79 | "__CHAR_BIT__=8",
80 | "__UINT8_MAX__=255",
81 | "__WINT_MAX__=4294967295U",
82 | "__ORDER_LITTLE_ENDIAN__=1234",
83 | "__SIZE_MAX__=4294967295U",
84 | "__WCHAR_MAX__=65535",
85 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
86 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
87 | "__FLT_EVAL_METHOD__=0",
88 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
89 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
90 | "__SIG_ATOMIC_TYPE__=int",
91 | "__DBL_MIN_10_EXP__=(-307)",
92 | "__FINITE_MATH_ONLY__=0",
93 | "__GNUC_PATCHLEVEL__=2",
94 | "__UINT_FAST8_MAX__=4294967295U",
95 | "__DEC64_MAX_EXP__=385",
96 | "__INT8_C(c)=c",
97 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
98 | "__SHRT_MAX__=32767",
99 | "__LDBL_MAX__=1.7976931348623157e+308L",
100 | "__UINT_LEAST8_MAX__=255",
101 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
102 | "__UINTMAX_TYPE__=long long unsigned int",
103 | "__DEC32_EPSILON__=1E-6DF",
104 | "__CHAR_UNSIGNED__=1",
105 | "__UINT32_MAX__=4294967295UL",
106 | "__LDBL_MAX_EXP__=1024",
107 | "__WINT_MIN__=0U",
108 | "__SCHAR_MAX__=127",
109 | "__WCHAR_MIN__=0",
110 | "__INT64_C(c)=c ## LL",
111 | "__DBL_DIG__=15",
112 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
113 | "__XTENSA_CALL0_ABI__=1",
114 | "__SIZEOF_INT__=4",
115 | "__SIZEOF_POINTER__=4",
116 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
117 | "__USER_LABEL_PREFIX__",
118 | "__STDC_HOSTED__=1",
119 | "__LDBL_HAS_INFINITY__=1",
120 | "__XTENSA_EL__=1",
121 | "__FLT_EPSILON__=1.1920928955078125e-7F",
122 | "__GXX_WEAK__=1",
123 | "__LDBL_MIN__=2.2250738585072014e-308L",
124 | "__DEC32_MAX__=9.999999E96DF",
125 | "__INT32_MAX__=2147483647L",
126 | "__SIZEOF_LONG__=4",
127 | "__UINT16_C(c)=c",
128 | "__DECIMAL_DIG__=17",
129 | "__LDBL_HAS_QUIET_NAN__=1",
130 | "__GNUC__=4",
131 | "__GXX_RTTI=1",
132 | "__FLT_HAS_DENORM__=1",
133 | "__SIZEOF_LONG_DOUBLE__=8",
134 | "__BIGGEST_ALIGNMENT__=16",
135 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
136 | "__INT_FAST32_MAX__=2147483647",
137 | "__DBL_HAS_INFINITY__=1",
138 | "__INT64_MAX__=9223372036854775807LL",
139 | "__DEC32_MIN_EXP__=(-94)",
140 | "__INT_FAST16_TYPE__=int",
141 | "__LDBL_HAS_DENORM__=1",
142 | "__cplusplus=199711L",
143 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
144 | "__INT_LEAST32_MAX__=2147483647L",
145 | "__DEC32_MIN__=1E-95DF",
146 | "__DEPRECATED=1",
147 | "__DBL_MAX_EXP__=1024",
148 | "__DEC128_EPSILON__=1E-33DL",
149 | "__PTRDIFF_MAX__=2147483647",
150 | "__GNUG__=4",
151 | "__LONG_LONG_MAX__=9223372036854775807LL",
152 | "__SIZEOF_SIZE_T__=4",
153 | "__SIZEOF_WINT_T__=4",
154 | "__GXX_ABI_VERSION=1002",
155 | "__FLT_MIN_EXP__=(-125)",
156 | "__INT_FAST64_TYPE__=long long int",
157 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
158 | "__FLT_MIN_10_EXP__=(-37)",
159 | "__DEC128_MIN__=1E-6143DL",
160 | "__REGISTER_PREFIX__",
161 | "__UINT16_MAX__=65535",
162 | "__DBL_HAS_DENORM__=1",
163 | "__UINT8_TYPE__=unsigned char",
164 | "__NO_INLINE__=1",
165 | "__FLT_MANT_DIG__=24",
166 | "__VERSION__=\"4.8.2\"",
167 | "__UINT64_C(c)=c ## ULL",
168 | "__XTENSA_SOFT_FLOAT__=1",
169 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
170 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
171 | "__INT32_C(c)=c ## L",
172 | "__DEC64_EPSILON__=1E-15DD",
173 | "__ORDER_PDP_ENDIAN__=3412",
174 | "__DEC128_MIN_EXP__=(-6142)",
175 | "__INT_FAST32_TYPE__=int",
176 | "__UINT_LEAST16_TYPE__=short unsigned int",
177 | "__INT16_MAX__=32767",
178 | "__SIZE_TYPE__=unsigned int",
179 | "__UINT64_MAX__=18446744073709551615ULL",
180 | "__INT8_TYPE__=signed char",
181 | "__ELF__=1",
182 | "__xtensa__=1",
183 | "__FLT_RADIX__=2",
184 | "__INT_LEAST16_TYPE__=short int",
185 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
186 | "__UINTMAX_C(c)=c ## ULL",
187 | "__SIG_ATOMIC_MAX__=2147483647",
188 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
189 | "__SIZEOF_PTRDIFF_T__=4",
190 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
191 | "__INT_FAST16_MAX__=2147483647",
192 | "__UINT_FAST32_MAX__=4294967295U",
193 | "__UINT_LEAST64_TYPE__=long long unsigned int",
194 | "__FLT_HAS_QUIET_NAN__=1",
195 | "__FLT_MAX_10_EXP__=38",
196 | "__LONG_MAX__=2147483647L",
197 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
198 | "__FLT_HAS_INFINITY__=1",
199 | "__UINT_FAST16_TYPE__=unsigned int",
200 | "__DEC64_MAX__=9.999999999999999E384DD",
201 | "__CHAR16_TYPE__=short unsigned int",
202 | "__PRAGMA_REDEFINE_EXTNAME=1",
203 | "__INT_LEAST16_MAX__=32767",
204 | "__DEC64_MANT_DIG__=16",
205 | "__UINT_LEAST32_MAX__=4294967295UL",
206 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
207 | "__INT_LEAST64_TYPE__=long long int",
208 | "__INT16_TYPE__=short int",
209 | "__INT_LEAST8_TYPE__=signed char",
210 | "__DEC32_MAX_EXP__=97",
211 | "__INT_FAST8_MAX__=2147483647",
212 | "__INTPTR_MAX__=2147483647",
213 | "__EXCEPTIONS=1",
214 | "__LDBL_MANT_DIG__=53",
215 | "__DBL_HAS_QUIET_NAN__=1",
216 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
217 | "__INTPTR_TYPE__=int",
218 | "__UINT16_TYPE__=short unsigned int",
219 | "__WCHAR_TYPE__=short unsigned int",
220 | "__SIZEOF_FLOAT__=4",
221 | "__UINTPTR_MAX__=4294967295U",
222 | "__DEC64_MIN_EXP__=(-382)",
223 | "__INT_FAST64_MAX__=9223372036854775807LL",
224 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
225 | "__FLT_DIG__=6",
226 | "__UINT_FAST64_TYPE__=long long unsigned int",
227 | "__INT_MAX__=2147483647",
228 | "__INT64_TYPE__=long long int",
229 | "__FLT_MAX_EXP__=128",
230 | "__DBL_MANT_DIG__=53",
231 | "__INT_LEAST64_MAX__=9223372036854775807LL",
232 | "__DEC64_MIN__=1E-383DD",
233 | "__WINT_TYPE__=unsigned int",
234 | "__UINT_LEAST32_TYPE__=long unsigned int",
235 | "__SIZEOF_SHORT__=2",
236 | "__LDBL_MIN_EXP__=(-1021)",
237 | "__INT_LEAST8_MAX__=127",
238 | "__WCHAR_UNSIGNED__=1",
239 | "__LDBL_MAX_10_EXP__=308",
240 | "__ATOMIC_RELAXED=0",
241 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
242 | "__UINT8_C(c)=c",
243 | "__INT_LEAST32_TYPE__=long int",
244 | "__SIZEOF_WCHAR_T__=2",
245 | "__UINT64_TYPE__=long long unsigned int",
246 | "__INT_FAST8_TYPE__=int",
247 | "__DBL_DECIMAL_DIG__=17",
248 | "__DEC_EVAL_METHOD__=2",
249 | "__XTENSA__=1",
250 | "__ORDER_BIG_ENDIAN__=4321",
251 | "__UINT32_C(c)=c ## UL",
252 | "__INTMAX_MAX__=9223372036854775807LL",
253 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
254 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
255 | "__INT8_MAX__=127",
256 | "__UINT_FAST32_TYPE__=unsigned int",
257 | "__CHAR32_TYPE__=long unsigned int",
258 | "__FLT_MAX__=3.4028234663852886e+38F",
259 | "__INT32_TYPE__=long int",
260 | "__SIZEOF_DOUBLE__=8",
261 | "__INTMAX_TYPE__=long long int",
262 | "__DEC128_MAX_EXP__=6145",
263 | "__ATOMIC_CONSUME=1",
264 | "__GNUC_MINOR__=8",
265 | "__UINTMAX_MAX__=18446744073709551615ULL",
266 | "__DEC32_MANT_DIG__=7",
267 | "__DBL_MAX_10_EXP__=308",
268 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
269 | "__INT16_C(c)=c",
270 | "__STDC__=1",
271 | "__PTRDIFF_TYPE__=int",
272 | "__ATOMIC_SEQ_CST=5",
273 | "__UINT32_TYPE__=long unsigned int",
274 | "__UINTPTR_TYPE__=unsigned int",
275 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
276 | "__DEC128_MANT_DIG__=34",
277 | "__LDBL_MIN_10_EXP__=(-307)",
278 | "__SIZEOF_LONG_LONG__=8",
279 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
280 | "__LDBL_DIG__=15",
281 | "__FLT_DECIMAL_DIG__=9",
282 | "__UINT_FAST16_MAX__=4294967295U",
283 | "__GNUC_GNU_INLINE__=1",
284 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
285 | "__UINT_FAST8_TYPE__=unsigned int",
286 | "__ATOMIC_ACQ_REL=4",
287 | "__ATOMIC_RELEASE=3",
288 | "USBCON"
289 | ]
290 | }
291 | ]
292 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderBasics/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderBasics/Esp32RotaryEncoderBasics.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 | #include "Arduino.h"
3 |
4 | /*
5 | connecting Rotary encoder
6 |
7 | Rotary encoder side MICROCONTROLLER side
8 | ------------------- ---------------------------------------------------------------------
9 | CLK (A pin) any microcontroler intput pin with interrupt -> in this example pin 32
10 | DT (B pin) any microcontroler intput pin with interrupt -> in this example pin 21
11 | SW (button pin) any microcontroler intput pin with interrupt -> in this example pin 25
12 | GND - to microcontroler GND
13 | VCC microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1)
14 |
15 | ***OR in case VCC pin is not free you can cheat and connect:***
16 | VCC any microcontroler output pin - but set also ROTARY_ENCODER_VCC_PIN 25
17 | in this example pin 25
18 |
19 | */
20 | #if defined(ESP8266)
21 | #define ROTARY_ENCODER_A_PIN D6
22 | #define ROTARY_ENCODER_B_PIN D5
23 | #define ROTARY_ENCODER_BUTTON_PIN D7
24 | #else
25 | #define ROTARY_ENCODER_A_PIN 32
26 | #define ROTARY_ENCODER_B_PIN 21
27 | #define ROTARY_ENCODER_BUTTON_PIN 25
28 | #endif
29 | #define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
30 |
31 | //depending on your encoder - try 1,2 or 4 to get expected behaviour
32 | //#define ROTARY_ENCODER_STEPS 1
33 | //#define ROTARY_ENCODER_STEPS 2
34 | #define ROTARY_ENCODER_STEPS 4
35 |
36 | //instead of changing here, rather change numbers above
37 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
38 |
39 | void rotary_onButtonClick()
40 | {
41 | static unsigned long lastTimePressed = 0;
42 | //ignore multiple press in that time milliseconds
43 | if (millis() - lastTimePressed < 500)
44 | {
45 | return;
46 | }
47 | lastTimePressed = millis();
48 | Serial.print("button pressed ");
49 | Serial.print(millis());
50 | Serial.println(" milliseconds after restart");
51 | }
52 |
53 | void rotary_loop()
54 | {
55 | //dont print anything unless value changed
56 | if (rotaryEncoder.encoderChanged())
57 | {
58 | Serial.print("Value: ");
59 | Serial.println(rotaryEncoder.readEncoder());
60 | }
61 | if (rotaryEncoder.isEncoderButtonClicked())
62 | {
63 | rotary_onButtonClick();
64 | }
65 | }
66 |
67 | void IRAM_ATTR readEncoderISR()
68 | {
69 | rotaryEncoder.readEncoder_ISR();
70 | }
71 |
72 | void setup()
73 | {
74 | Serial.begin(115200);
75 |
76 | //we must initialize rotary encoder
77 | rotaryEncoder.begin();
78 | rotaryEncoder.setup(readEncoderISR);
79 | //set boundaries and if values should cycle or not
80 | //in this example we will set possible values between 0 and 1000;
81 | bool circleValues = false;
82 | rotaryEncoder.setBoundaries(0, 1000, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
83 |
84 | /*Rotary acceleration introduced 25.2.2021.
85 | * in case range to select is huge, for example - select a value between 0 and 1000 and we want 785
86 | * without accelerateion you need long time to get to that number
87 | * Using acceleration, faster you turn, faster will the value raise.
88 | * For fine tuning slow down.
89 | */
90 | //rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
91 | rotaryEncoder.setAcceleration(250); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
92 | }
93 |
94 | void loop()
95 | {
96 | //in loop call your custom function which will process rotary encoder values
97 | rotary_loop();
98 | delay(50); //or do whatever you need to do...
99 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderButtonOptions/Esp32RotaryEncoderButtonOptions.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 | #include "Arduino.h"
3 |
4 | /*
5 | connecting Rotary encoder
6 |
7 | Rotary encoder side MICROCONTROLLER side
8 | ------------------- ---------------------------------------------------------------------
9 | CLK (A pin) any microcontroler intput pin with interrupt -> in this example pin 32
10 | DT (B pin) any microcontroler intput pin with interrupt -> in this example pin 21
11 | SW (button pin) any microcontroler intput pin with interrupt -> in this example pin 25
12 | GND - to microcontroler GND
13 | VCC microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1)
14 |
15 | ***OR in case VCC pin is not free you can cheat and connect:***
16 | VCC any microcontroler output pin - but set also ROTARY_ENCODER_VCC_PIN 25
17 | in this example pin 25
18 |
19 | */
20 | #if defined(ESP8266)
21 | #define ROTARY_ENCODER_A_PIN D6
22 | #define ROTARY_ENCODER_B_PIN D5
23 | #define ROTARY_ENCODER_BUTTON_PIN D7
24 | #else
25 | #define ROTARY_ENCODER_A_PIN 32
26 | #define ROTARY_ENCODER_B_PIN 21
27 | #define ROTARY_ENCODER_BUTTON_PIN 25
28 | #endif
29 | #define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
30 |
31 | //depending on your encoder - try 1,2 or 4 to get expected behaviour
32 | //#define ROTARY_ENCODER_STEPS 1
33 | //#define ROTARY_ENCODER_STEPS 2
34 | #define ROTARY_ENCODER_STEPS 4
35 |
36 | //instead of changing here, rather change numbers above
37 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
38 |
39 |
40 | //********** button handling
41 | //********** button handling
42 | //********** button handling
43 | //********** button handling
44 | //********** button handling
45 | /*
46 | Note: try changing shortPressAfterMiliseconds and longPressAfterMiliseconds to fit your needs
47 | In case you dont need long press set longPressAfterMiliseconds=999999; that should be enough.
48 |
49 | Then change what code soes on void on_button_short_click() and void on_button_long_click()
50 | to fit your needs
51 |
52 | To remove writing "+" when button is down remove lines marked with //REMOVE THIS LINE IF YOU DONT WANT TO SEE
53 |
54 | Use the similar logic to implement double click or very long button press.
55 |
56 | There is a bit of code. But it is non-blocking.
57 | Try moving the rotary encoder while the button is down. You will see that it works.
58 |
59 | rotary_loop() is actually calling handle_rotary_button();
60 | If you prefer you can move that logic somewhere else but dont forget to call both methods frequently.
61 | So it is important that you have nonblocking code.
62 |
63 | button functions
64 | on_button_short_click - change function body to fit your needs
65 | on_button_long_click - change function body to fit your needs
66 | handle_rotary_button() - it already ahs logic for short and long press, but you can add double click or extra long press...
67 | if no need than leave it as it is (and remove lines marked with REMOVE THIS LINE IF YOU DONT WANT TO SEE)
68 |
69 | in case your button is reversed you can uncomment line looking like this (but not here -> do it in a handle_rotary_button):
70 | isEncoderButtonDown = !isEncoderButtonDown;
71 | */
72 |
73 | //paramaters for button
74 | unsigned long shortPressAfterMiliseconds = 50; //how long short press shoud be. Do not set too low to avoid bouncing (false press events).
75 | unsigned long longPressAfterMiliseconds = 1000; //how long čong press shoud be.
76 |
77 |
78 | void on_button_short_click() {
79 | Serial.print("button SHORT press ");
80 | Serial.print(millis());
81 | Serial.println(" milliseconds after restart");
82 | }
83 |
84 | void on_button_long_click() {
85 | Serial.print("button LONG press ");
86 | Serial.print(millis());
87 | Serial.println(" milliseconds after restart");
88 | }
89 |
90 | void handle_rotary_button() {
91 | static unsigned long lastTimeButtonDown = 0;
92 | static bool wasButtonDown = false;
93 |
94 | bool isEncoderButtonDown = rotaryEncoder.isEncoderButtonDown();
95 | //isEncoderButtonDown = !isEncoderButtonDown; //uncomment this line if your button is reversed
96 |
97 | if (isEncoderButtonDown) {
98 | Serial.print("+"); //REMOVE THIS LINE IF YOU DONT WANT TO SEE
99 | if (!wasButtonDown) {
100 | //start measuring
101 | lastTimeButtonDown = millis();
102 | }
103 | //else we wait since button is still down
104 | wasButtonDown = true;
105 | return;
106 | }
107 |
108 | //button is up
109 | if (wasButtonDown) {
110 | Serial.println(""); //REMOVE THIS LINE IF YOU DONT WANT TO SEE
111 | //click happened, lets see if it was short click, long click or just too short
112 | if (millis() - lastTimeButtonDown >= longPressAfterMiliseconds) {
113 | on_button_long_click();
114 | } else if (millis() - lastTimeButtonDown >= shortPressAfterMiliseconds) {
115 | on_button_short_click();
116 | }
117 | }
118 | wasButtonDown = false;
119 | }
120 | //********** button handling ----
121 | //********** button handling ----
122 | //********** button handling ----
123 | //********** button handling ----
124 |
125 | void rotary_loop() {
126 | //dont print anything unless value changed
127 | if (rotaryEncoder.encoderChanged()) {
128 | Serial.print("Value: ");
129 | Serial.println(rotaryEncoder.readEncoder());
130 | }
131 | handle_rotary_button();
132 | }
133 |
134 | void IRAM_ATTR readEncoderISR() {
135 | rotaryEncoder.readEncoder_ISR();
136 | }
137 |
138 | void setup() {
139 | Serial.begin(115200);
140 |
141 | //we must initialize rotary encoder
142 | rotaryEncoder.begin();
143 | rotaryEncoder.setup(readEncoderISR);
144 | //set boundaries and if values should cycle or not
145 | //in this example we will set possible values between 0 and 1000;
146 | bool circleValues = false;
147 | rotaryEncoder.setBoundaries(0, 1000, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
148 |
149 | /*Rotary acceleration introduced 25.2.2021.
150 | * in case range to select is huge, for example - select a value between 0 and 1000 and we want 785
151 | * without accelerateion you need long time to get to that number
152 | * Using acceleration, faster you turn, faster will the value raise.
153 | * For fine tuning slow down.
154 | */
155 | //rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
156 | rotaryEncoder.setAcceleration(250); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
157 | }
158 |
159 | void loop() {
160 | //in loop call your custom function which will process rotary encoder values
161 | rotary_loop();
162 | delay(50); //or do whatever you need to do...
163 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestAcceleration/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "port": "COM10",
4 | "output": "b:/dummy/Esp32RotaryEncoderTestAcceleration",
5 | "sketch": "Esp32RotaryEncoderTestAcceleration.ino",
6 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600"
7 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestAcceleration/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "b:\\dummy\\Esp32RotaryEncoderTestAcceleration\\core",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
44 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
45 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
51 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
52 | ],
53 | "forcedInclude": [
54 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
55 | ],
56 | "cStandard": "c11",
57 | "cppStandard": "c++11",
58 | "defines": [
59 | "__ets__",
60 | "ICACHE_FLASH",
61 | "NONOSDK22x_190703=1",
62 | "F_CPU=80000000L",
63 | "LWIP_OPEN_SRC",
64 | "TCP_MSS=536",
65 | "LWIP_FEATURES=1",
66 | "LWIP_IPV6=0",
67 | "ARDUINO=10815",
68 | "ARDUINO_ESP8266_WEMOS_D1MINI",
69 | "ARDUINO_ARCH_ESP8266",
70 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
71 | "FLASHMODE_DIO",
72 | "ESP8266",
73 | "__DBL_MIN_EXP__=(-1021)",
74 | "__UINT_LEAST16_MAX__=65535",
75 | "__ATOMIC_ACQUIRE=2",
76 | "__FLT_MIN__=1.1754943508222875e-38F",
77 | "__UINT_LEAST8_TYPE__=unsigned char",
78 | "__INTMAX_C(c)=c ## LL",
79 | "__CHAR_BIT__=8",
80 | "__UINT8_MAX__=255",
81 | "__WINT_MAX__=4294967295U",
82 | "__ORDER_LITTLE_ENDIAN__=1234",
83 | "__SIZE_MAX__=4294967295U",
84 | "__WCHAR_MAX__=65535",
85 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
86 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
87 | "__FLT_EVAL_METHOD__=0",
88 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
89 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
90 | "__SIG_ATOMIC_TYPE__=int",
91 | "__DBL_MIN_10_EXP__=(-307)",
92 | "__FINITE_MATH_ONLY__=0",
93 | "__GNUC_PATCHLEVEL__=2",
94 | "__UINT_FAST8_MAX__=4294967295U",
95 | "__DEC64_MAX_EXP__=385",
96 | "__INT8_C(c)=c",
97 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
98 | "__SHRT_MAX__=32767",
99 | "__LDBL_MAX__=1.7976931348623157e+308L",
100 | "__UINT_LEAST8_MAX__=255",
101 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
102 | "__UINTMAX_TYPE__=long long unsigned int",
103 | "__DEC32_EPSILON__=1E-6DF",
104 | "__CHAR_UNSIGNED__=1",
105 | "__UINT32_MAX__=4294967295UL",
106 | "__LDBL_MAX_EXP__=1024",
107 | "__WINT_MIN__=0U",
108 | "__SCHAR_MAX__=127",
109 | "__WCHAR_MIN__=0",
110 | "__INT64_C(c)=c ## LL",
111 | "__DBL_DIG__=15",
112 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
113 | "__XTENSA_CALL0_ABI__=1",
114 | "__SIZEOF_INT__=4",
115 | "__SIZEOF_POINTER__=4",
116 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
117 | "__USER_LABEL_PREFIX__",
118 | "__STDC_HOSTED__=1",
119 | "__LDBL_HAS_INFINITY__=1",
120 | "__XTENSA_EL__=1",
121 | "__FLT_EPSILON__=1.1920928955078125e-7F",
122 | "__GXX_WEAK__=1",
123 | "__LDBL_MIN__=2.2250738585072014e-308L",
124 | "__DEC32_MAX__=9.999999E96DF",
125 | "__INT32_MAX__=2147483647L",
126 | "__SIZEOF_LONG__=4",
127 | "__UINT16_C(c)=c",
128 | "__DECIMAL_DIG__=17",
129 | "__LDBL_HAS_QUIET_NAN__=1",
130 | "__GNUC__=4",
131 | "__GXX_RTTI=1",
132 | "__FLT_HAS_DENORM__=1",
133 | "__SIZEOF_LONG_DOUBLE__=8",
134 | "__BIGGEST_ALIGNMENT__=16",
135 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
136 | "__INT_FAST32_MAX__=2147483647",
137 | "__DBL_HAS_INFINITY__=1",
138 | "__INT64_MAX__=9223372036854775807LL",
139 | "__DEC32_MIN_EXP__=(-94)",
140 | "__INT_FAST16_TYPE__=int",
141 | "__LDBL_HAS_DENORM__=1",
142 | "__cplusplus=199711L",
143 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
144 | "__INT_LEAST32_MAX__=2147483647L",
145 | "__DEC32_MIN__=1E-95DF",
146 | "__DEPRECATED=1",
147 | "__DBL_MAX_EXP__=1024",
148 | "__DEC128_EPSILON__=1E-33DL",
149 | "__PTRDIFF_MAX__=2147483647",
150 | "__GNUG__=4",
151 | "__LONG_LONG_MAX__=9223372036854775807LL",
152 | "__SIZEOF_SIZE_T__=4",
153 | "__SIZEOF_WINT_T__=4",
154 | "__GXX_ABI_VERSION=1002",
155 | "__FLT_MIN_EXP__=(-125)",
156 | "__INT_FAST64_TYPE__=long long int",
157 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
158 | "__FLT_MIN_10_EXP__=(-37)",
159 | "__DEC128_MIN__=1E-6143DL",
160 | "__REGISTER_PREFIX__",
161 | "__UINT16_MAX__=65535",
162 | "__DBL_HAS_DENORM__=1",
163 | "__UINT8_TYPE__=unsigned char",
164 | "__NO_INLINE__=1",
165 | "__FLT_MANT_DIG__=24",
166 | "__VERSION__=\"4.8.2\"",
167 | "__UINT64_C(c)=c ## ULL",
168 | "__XTENSA_SOFT_FLOAT__=1",
169 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
170 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
171 | "__INT32_C(c)=c ## L",
172 | "__DEC64_EPSILON__=1E-15DD",
173 | "__ORDER_PDP_ENDIAN__=3412",
174 | "__DEC128_MIN_EXP__=(-6142)",
175 | "__INT_FAST32_TYPE__=int",
176 | "__UINT_LEAST16_TYPE__=short unsigned int",
177 | "__INT16_MAX__=32767",
178 | "__SIZE_TYPE__=unsigned int",
179 | "__UINT64_MAX__=18446744073709551615ULL",
180 | "__INT8_TYPE__=signed char",
181 | "__ELF__=1",
182 | "__xtensa__=1",
183 | "__FLT_RADIX__=2",
184 | "__INT_LEAST16_TYPE__=short int",
185 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
186 | "__UINTMAX_C(c)=c ## ULL",
187 | "__SIG_ATOMIC_MAX__=2147483647",
188 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
189 | "__SIZEOF_PTRDIFF_T__=4",
190 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
191 | "__INT_FAST16_MAX__=2147483647",
192 | "__UINT_FAST32_MAX__=4294967295U",
193 | "__UINT_LEAST64_TYPE__=long long unsigned int",
194 | "__FLT_HAS_QUIET_NAN__=1",
195 | "__FLT_MAX_10_EXP__=38",
196 | "__LONG_MAX__=2147483647L",
197 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
198 | "__FLT_HAS_INFINITY__=1",
199 | "__UINT_FAST16_TYPE__=unsigned int",
200 | "__DEC64_MAX__=9.999999999999999E384DD",
201 | "__CHAR16_TYPE__=short unsigned int",
202 | "__PRAGMA_REDEFINE_EXTNAME=1",
203 | "__INT_LEAST16_MAX__=32767",
204 | "__DEC64_MANT_DIG__=16",
205 | "__UINT_LEAST32_MAX__=4294967295UL",
206 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
207 | "__INT_LEAST64_TYPE__=long long int",
208 | "__INT16_TYPE__=short int",
209 | "__INT_LEAST8_TYPE__=signed char",
210 | "__DEC32_MAX_EXP__=97",
211 | "__INT_FAST8_MAX__=2147483647",
212 | "__INTPTR_MAX__=2147483647",
213 | "__EXCEPTIONS=1",
214 | "__LDBL_MANT_DIG__=53",
215 | "__DBL_HAS_QUIET_NAN__=1",
216 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
217 | "__INTPTR_TYPE__=int",
218 | "__UINT16_TYPE__=short unsigned int",
219 | "__WCHAR_TYPE__=short unsigned int",
220 | "__SIZEOF_FLOAT__=4",
221 | "__UINTPTR_MAX__=4294967295U",
222 | "__DEC64_MIN_EXP__=(-382)",
223 | "__INT_FAST64_MAX__=9223372036854775807LL",
224 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
225 | "__FLT_DIG__=6",
226 | "__UINT_FAST64_TYPE__=long long unsigned int",
227 | "__INT_MAX__=2147483647",
228 | "__INT64_TYPE__=long long int",
229 | "__FLT_MAX_EXP__=128",
230 | "__DBL_MANT_DIG__=53",
231 | "__INT_LEAST64_MAX__=9223372036854775807LL",
232 | "__DEC64_MIN__=1E-383DD",
233 | "__WINT_TYPE__=unsigned int",
234 | "__UINT_LEAST32_TYPE__=long unsigned int",
235 | "__SIZEOF_SHORT__=2",
236 | "__LDBL_MIN_EXP__=(-1021)",
237 | "__INT_LEAST8_MAX__=127",
238 | "__WCHAR_UNSIGNED__=1",
239 | "__LDBL_MAX_10_EXP__=308",
240 | "__ATOMIC_RELAXED=0",
241 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
242 | "__UINT8_C(c)=c",
243 | "__INT_LEAST32_TYPE__=long int",
244 | "__SIZEOF_WCHAR_T__=2",
245 | "__UINT64_TYPE__=long long unsigned int",
246 | "__INT_FAST8_TYPE__=int",
247 | "__DBL_DECIMAL_DIG__=17",
248 | "__DEC_EVAL_METHOD__=2",
249 | "__XTENSA__=1",
250 | "__ORDER_BIG_ENDIAN__=4321",
251 | "__UINT32_C(c)=c ## UL",
252 | "__INTMAX_MAX__=9223372036854775807LL",
253 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
254 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
255 | "__INT8_MAX__=127",
256 | "__UINT_FAST32_TYPE__=unsigned int",
257 | "__CHAR32_TYPE__=long unsigned int",
258 | "__FLT_MAX__=3.4028234663852886e+38F",
259 | "__INT32_TYPE__=long int",
260 | "__SIZEOF_DOUBLE__=8",
261 | "__INTMAX_TYPE__=long long int",
262 | "__DEC128_MAX_EXP__=6145",
263 | "__ATOMIC_CONSUME=1",
264 | "__GNUC_MINOR__=8",
265 | "__UINTMAX_MAX__=18446744073709551615ULL",
266 | "__DEC32_MANT_DIG__=7",
267 | "__DBL_MAX_10_EXP__=308",
268 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
269 | "__INT16_C(c)=c",
270 | "__STDC__=1",
271 | "__PTRDIFF_TYPE__=int",
272 | "__ATOMIC_SEQ_CST=5",
273 | "__UINT32_TYPE__=long unsigned int",
274 | "__UINTPTR_TYPE__=unsigned int",
275 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
276 | "__DEC128_MANT_DIG__=34",
277 | "__LDBL_MIN_10_EXP__=(-307)",
278 | "__SIZEOF_LONG_LONG__=8",
279 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
280 | "__LDBL_DIG__=15",
281 | "__FLT_DECIMAL_DIG__=9",
282 | "__UINT_FAST16_MAX__=4294967295U",
283 | "__GNUC_GNU_INLINE__=1",
284 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
285 | "__UINT_FAST8_TYPE__=unsigned int",
286 | "__ATOMIC_ACQ_REL=4",
287 | "__ATOMIC_RELEASE=3",
288 | "USBCON"
289 | ]
290 | }
291 | ]
292 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestAcceleration/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestAcceleration/Esp32RotaryEncoderTestAcceleration.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 | #include "Arduino.h"
3 |
4 | /*
5 | connecting Rotary encoder
6 |
7 | Rotary encoder side MICROCONTROLLER side
8 | ------------------- ---------------------------------------------------------------------
9 | CLK (A pin) any microcontroler intput pin with interrupt -> in this example pin 32
10 | DT (B pin) any microcontroler intput pin with interrupt -> in this example pin 21
11 | SW (button pin) any microcontroler intput pin with interrupt -> in this example pin 25
12 | GND - to microcontroler GND
13 | VCC microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1)
14 |
15 | ***OR in case VCC pin is not free you can cheat and connect:***
16 | VCC any microcontroler output pin - but set also ROTARY_ENCODER_VCC_PIN 25
17 | in this example pin 25
18 |
19 | */
20 | #if defined(ESP8266)
21 | #define ROTARY_ENCODER_A_PIN D6
22 | #define ROTARY_ENCODER_B_PIN D5
23 | #define ROTARY_ENCODER_BUTTON_PIN D7
24 | #else
25 | #define ROTARY_ENCODER_A_PIN 32
26 | #define ROTARY_ENCODER_B_PIN 21
27 | #define ROTARY_ENCODER_BUTTON_PIN 25
28 | #endif
29 | #define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
30 |
31 | //depending on your encoder - try 1,2 or 4 to get expected behaviour
32 | //#define ROTARY_ENCODER_STEPS 1
33 | //#define ROTARY_ENCODER_STEPS 2
34 | #define ROTARY_ENCODER_STEPS 4
35 |
36 | //instead of changing here, rather change numbers above
37 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
38 |
39 | void rotary_onButtonClick()
40 | {
41 | static unsigned long lastTimePressed = 0;
42 | if (millis() - lastTimePressed < 500)
43 | return; //ignore multiple press in that time milliseconds
44 | lastTimePressed = millis();
45 |
46 | unsigned long acceletation = rotaryEncoder.getAcceleration() + 50;
47 | if (acceletation > 400)
48 | acceletation = 0;
49 | rotaryEncoder.setAcceleration(acceletation);
50 |
51 | Serial.print("new acceleration is ");
52 | Serial.println(acceletation);
53 | Serial.print("Try to set value: ");
54 | Serial.println(random(-999, 999));
55 | Serial.println("Set as fast as you can. If it is too hard or you suceeded, press the button again.");
56 | }
57 |
58 | void rotary_loop()
59 | {
60 | if (rotaryEncoder.encoderChanged())
61 | {
62 | Serial.print("Value: ");
63 | Serial.println(rotaryEncoder.readEncoder());
64 | }
65 | if (rotaryEncoder.isEncoderButtonClicked())
66 | {
67 | rotary_onButtonClick();
68 | }
69 | }
70 |
71 | void IRAM_ATTR readEncoderISR()
72 | {
73 | rotaryEncoder.readEncoder_ISR();
74 | }
75 |
76 | void setup()
77 | {
78 | Serial.begin(115200);
79 | rotaryEncoder.begin();
80 | rotaryEncoder.setup(readEncoderISR);
81 | bool circleValues = false;
82 | rotaryEncoder.setBoundaries(-1000, 1000, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
83 | rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
84 | Serial.println("Ready");
85 | Serial.print("Try to set value: ");
86 | Serial.println(752);
87 | Serial.println("If it is too hard press the button.");
88 | }
89 |
90 | void loop()
91 | {
92 | rotary_loop();
93 | delay(50);
94 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestBoundaries/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600",
4 | "sketch": "Esp32RotaryEncoderTestBoundaries.ino",
5 | "port": "COM10",
6 | "output": "b:/dummy/Esp32RotaryEncoderTestBoundaries"
7 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestBoundaries/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "b:\\dummy\\Esp32RotaryEncoderTestBoundaries\\core",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
44 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
45 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
51 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
52 | ],
53 | "forcedInclude": [
54 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
55 | ],
56 | "cStandard": "c11",
57 | "cppStandard": "c++11",
58 | "defines": [
59 | "__ets__",
60 | "ICACHE_FLASH",
61 | "NONOSDK22x_190703=1",
62 | "F_CPU=80000000L",
63 | "LWIP_OPEN_SRC",
64 | "TCP_MSS=536",
65 | "LWIP_FEATURES=1",
66 | "LWIP_IPV6=0",
67 | "ARDUINO=10815",
68 | "ARDUINO_ESP8266_WEMOS_D1MINI",
69 | "ARDUINO_ARCH_ESP8266",
70 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
71 | "FLASHMODE_DIO",
72 | "ESP8266",
73 | "__DBL_MIN_EXP__=(-1021)",
74 | "__UINT_LEAST16_MAX__=65535",
75 | "__ATOMIC_ACQUIRE=2",
76 | "__FLT_MIN__=1.1754943508222875e-38F",
77 | "__UINT_LEAST8_TYPE__=unsigned char",
78 | "__INTMAX_C(c)=c ## LL",
79 | "__CHAR_BIT__=8",
80 | "__UINT8_MAX__=255",
81 | "__WINT_MAX__=4294967295U",
82 | "__ORDER_LITTLE_ENDIAN__=1234",
83 | "__SIZE_MAX__=4294967295U",
84 | "__WCHAR_MAX__=65535",
85 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
86 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
87 | "__FLT_EVAL_METHOD__=0",
88 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
89 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
90 | "__SIG_ATOMIC_TYPE__=int",
91 | "__DBL_MIN_10_EXP__=(-307)",
92 | "__FINITE_MATH_ONLY__=0",
93 | "__GNUC_PATCHLEVEL__=2",
94 | "__UINT_FAST8_MAX__=4294967295U",
95 | "__DEC64_MAX_EXP__=385",
96 | "__INT8_C(c)=c",
97 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
98 | "__SHRT_MAX__=32767",
99 | "__LDBL_MAX__=1.7976931348623157e+308L",
100 | "__UINT_LEAST8_MAX__=255",
101 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
102 | "__UINTMAX_TYPE__=long long unsigned int",
103 | "__DEC32_EPSILON__=1E-6DF",
104 | "__CHAR_UNSIGNED__=1",
105 | "__UINT32_MAX__=4294967295UL",
106 | "__LDBL_MAX_EXP__=1024",
107 | "__WINT_MIN__=0U",
108 | "__SCHAR_MAX__=127",
109 | "__WCHAR_MIN__=0",
110 | "__INT64_C(c)=c ## LL",
111 | "__DBL_DIG__=15",
112 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
113 | "__XTENSA_CALL0_ABI__=1",
114 | "__SIZEOF_INT__=4",
115 | "__SIZEOF_POINTER__=4",
116 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
117 | "__USER_LABEL_PREFIX__",
118 | "__STDC_HOSTED__=1",
119 | "__LDBL_HAS_INFINITY__=1",
120 | "__XTENSA_EL__=1",
121 | "__FLT_EPSILON__=1.1920928955078125e-7F",
122 | "__GXX_WEAK__=1",
123 | "__LDBL_MIN__=2.2250738585072014e-308L",
124 | "__DEC32_MAX__=9.999999E96DF",
125 | "__INT32_MAX__=2147483647L",
126 | "__SIZEOF_LONG__=4",
127 | "__UINT16_C(c)=c",
128 | "__DECIMAL_DIG__=17",
129 | "__LDBL_HAS_QUIET_NAN__=1",
130 | "__GNUC__=4",
131 | "__GXX_RTTI=1",
132 | "__FLT_HAS_DENORM__=1",
133 | "__SIZEOF_LONG_DOUBLE__=8",
134 | "__BIGGEST_ALIGNMENT__=16",
135 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
136 | "__INT_FAST32_MAX__=2147483647",
137 | "__DBL_HAS_INFINITY__=1",
138 | "__INT64_MAX__=9223372036854775807LL",
139 | "__DEC32_MIN_EXP__=(-94)",
140 | "__INT_FAST16_TYPE__=int",
141 | "__LDBL_HAS_DENORM__=1",
142 | "__cplusplus=199711L",
143 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
144 | "__INT_LEAST32_MAX__=2147483647L",
145 | "__DEC32_MIN__=1E-95DF",
146 | "__DEPRECATED=1",
147 | "__DBL_MAX_EXP__=1024",
148 | "__DEC128_EPSILON__=1E-33DL",
149 | "__PTRDIFF_MAX__=2147483647",
150 | "__GNUG__=4",
151 | "__LONG_LONG_MAX__=9223372036854775807LL",
152 | "__SIZEOF_SIZE_T__=4",
153 | "__SIZEOF_WINT_T__=4",
154 | "__GXX_ABI_VERSION=1002",
155 | "__FLT_MIN_EXP__=(-125)",
156 | "__INT_FAST64_TYPE__=long long int",
157 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
158 | "__FLT_MIN_10_EXP__=(-37)",
159 | "__DEC128_MIN__=1E-6143DL",
160 | "__REGISTER_PREFIX__",
161 | "__UINT16_MAX__=65535",
162 | "__DBL_HAS_DENORM__=1",
163 | "__UINT8_TYPE__=unsigned char",
164 | "__NO_INLINE__=1",
165 | "__FLT_MANT_DIG__=24",
166 | "__VERSION__=\"4.8.2\"",
167 | "__UINT64_C(c)=c ## ULL",
168 | "__XTENSA_SOFT_FLOAT__=1",
169 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
170 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
171 | "__INT32_C(c)=c ## L",
172 | "__DEC64_EPSILON__=1E-15DD",
173 | "__ORDER_PDP_ENDIAN__=3412",
174 | "__DEC128_MIN_EXP__=(-6142)",
175 | "__INT_FAST32_TYPE__=int",
176 | "__UINT_LEAST16_TYPE__=short unsigned int",
177 | "__INT16_MAX__=32767",
178 | "__SIZE_TYPE__=unsigned int",
179 | "__UINT64_MAX__=18446744073709551615ULL",
180 | "__INT8_TYPE__=signed char",
181 | "__ELF__=1",
182 | "__xtensa__=1",
183 | "__FLT_RADIX__=2",
184 | "__INT_LEAST16_TYPE__=short int",
185 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
186 | "__UINTMAX_C(c)=c ## ULL",
187 | "__SIG_ATOMIC_MAX__=2147483647",
188 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
189 | "__SIZEOF_PTRDIFF_T__=4",
190 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
191 | "__INT_FAST16_MAX__=2147483647",
192 | "__UINT_FAST32_MAX__=4294967295U",
193 | "__UINT_LEAST64_TYPE__=long long unsigned int",
194 | "__FLT_HAS_QUIET_NAN__=1",
195 | "__FLT_MAX_10_EXP__=38",
196 | "__LONG_MAX__=2147483647L",
197 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
198 | "__FLT_HAS_INFINITY__=1",
199 | "__UINT_FAST16_TYPE__=unsigned int",
200 | "__DEC64_MAX__=9.999999999999999E384DD",
201 | "__CHAR16_TYPE__=short unsigned int",
202 | "__PRAGMA_REDEFINE_EXTNAME=1",
203 | "__INT_LEAST16_MAX__=32767",
204 | "__DEC64_MANT_DIG__=16",
205 | "__UINT_LEAST32_MAX__=4294967295UL",
206 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
207 | "__INT_LEAST64_TYPE__=long long int",
208 | "__INT16_TYPE__=short int",
209 | "__INT_LEAST8_TYPE__=signed char",
210 | "__DEC32_MAX_EXP__=97",
211 | "__INT_FAST8_MAX__=2147483647",
212 | "__INTPTR_MAX__=2147483647",
213 | "__EXCEPTIONS=1",
214 | "__LDBL_MANT_DIG__=53",
215 | "__DBL_HAS_QUIET_NAN__=1",
216 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
217 | "__INTPTR_TYPE__=int",
218 | "__UINT16_TYPE__=short unsigned int",
219 | "__WCHAR_TYPE__=short unsigned int",
220 | "__SIZEOF_FLOAT__=4",
221 | "__UINTPTR_MAX__=4294967295U",
222 | "__DEC64_MIN_EXP__=(-382)",
223 | "__INT_FAST64_MAX__=9223372036854775807LL",
224 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
225 | "__FLT_DIG__=6",
226 | "__UINT_FAST64_TYPE__=long long unsigned int",
227 | "__INT_MAX__=2147483647",
228 | "__INT64_TYPE__=long long int",
229 | "__FLT_MAX_EXP__=128",
230 | "__DBL_MANT_DIG__=53",
231 | "__INT_LEAST64_MAX__=9223372036854775807LL",
232 | "__DEC64_MIN__=1E-383DD",
233 | "__WINT_TYPE__=unsigned int",
234 | "__UINT_LEAST32_TYPE__=long unsigned int",
235 | "__SIZEOF_SHORT__=2",
236 | "__LDBL_MIN_EXP__=(-1021)",
237 | "__INT_LEAST8_MAX__=127",
238 | "__WCHAR_UNSIGNED__=1",
239 | "__LDBL_MAX_10_EXP__=308",
240 | "__ATOMIC_RELAXED=0",
241 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
242 | "__UINT8_C(c)=c",
243 | "__INT_LEAST32_TYPE__=long int",
244 | "__SIZEOF_WCHAR_T__=2",
245 | "__UINT64_TYPE__=long long unsigned int",
246 | "__INT_FAST8_TYPE__=int",
247 | "__DBL_DECIMAL_DIG__=17",
248 | "__DEC_EVAL_METHOD__=2",
249 | "__XTENSA__=1",
250 | "__ORDER_BIG_ENDIAN__=4321",
251 | "__UINT32_C(c)=c ## UL",
252 | "__INTMAX_MAX__=9223372036854775807LL",
253 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
254 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
255 | "__INT8_MAX__=127",
256 | "__UINT_FAST32_TYPE__=unsigned int",
257 | "__CHAR32_TYPE__=long unsigned int",
258 | "__FLT_MAX__=3.4028234663852886e+38F",
259 | "__INT32_TYPE__=long int",
260 | "__SIZEOF_DOUBLE__=8",
261 | "__INTMAX_TYPE__=long long int",
262 | "__DEC128_MAX_EXP__=6145",
263 | "__ATOMIC_CONSUME=1",
264 | "__GNUC_MINOR__=8",
265 | "__UINTMAX_MAX__=18446744073709551615ULL",
266 | "__DEC32_MANT_DIG__=7",
267 | "__DBL_MAX_10_EXP__=308",
268 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
269 | "__INT16_C(c)=c",
270 | "__STDC__=1",
271 | "__PTRDIFF_TYPE__=int",
272 | "__ATOMIC_SEQ_CST=5",
273 | "__UINT32_TYPE__=long unsigned int",
274 | "__UINTPTR_TYPE__=unsigned int",
275 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
276 | "__DEC128_MANT_DIG__=34",
277 | "__LDBL_MIN_10_EXP__=(-307)",
278 | "__SIZEOF_LONG_LONG__=8",
279 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
280 | "__LDBL_DIG__=15",
281 | "__FLT_DECIMAL_DIG__=9",
282 | "__UINT_FAST16_MAX__=4294967295U",
283 | "__GNUC_GNU_INLINE__=1",
284 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
285 | "__UINT_FAST8_TYPE__=unsigned int",
286 | "__ATOMIC_ACQ_REL=4",
287 | "__ATOMIC_RELEASE=3",
288 | "USBCON"
289 | ]
290 | }
291 | ]
292 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestBoundaries/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTestBoundaries/Esp32RotaryEncoderTestBoundaries.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 | #include "Arduino.h"
3 |
4 | /*
5 | connecting Rotary encoder
6 |
7 | Rotary encoder side MICROCONTROLLER side
8 | ------------------- ---------------------------------------------------------------------
9 | CLK (A pin) any microcontroler intput pin with interrupt -> in this example pin 32
10 | DT (B pin) any microcontroler intput pin with interrupt -> in this example pin 21
11 | SW (button pin) any microcontroler intput pin with interrupt -> in this example pin 25
12 | GND - to microcontroler GND
13 | VCC microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1)
14 |
15 | ***OR in case VCC pin is not free you can cheat and connect:***
16 | VCC any microcontroler output pin - but set also ROTARY_ENCODER_VCC_PIN 25
17 | in this example pin 25
18 |
19 | */
20 | #if defined(ESP8266)
21 | #define ROTARY_ENCODER_A_PIN D6
22 | #define ROTARY_ENCODER_B_PIN D5
23 | #define ROTARY_ENCODER_BUTTON_PIN D7
24 | #else
25 | #define ROTARY_ENCODER_A_PIN 32
26 | #define ROTARY_ENCODER_B_PIN 21
27 | #define ROTARY_ENCODER_BUTTON_PIN 25
28 | #endif
29 | #define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
30 |
31 | //depending on your encoder - try 1,2 or 4 to get expected behaviour
32 | //#define ROTARY_ENCODER_STEPS 1
33 | //#define ROTARY_ENCODER_STEPS 2
34 | #define ROTARY_ENCODER_STEPS 4
35 |
36 | //instead of changing here, rather change numbers above
37 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
38 |
39 | int16_t test_limits = 2;
40 |
41 | void rotary_onButtonClick()
42 | {
43 | static unsigned long lastTimePressed = 0;
44 | if (millis() - lastTimePressed < 500)
45 | return; //ignore multiple press in that time milliseconds
46 | lastTimePressed = millis();
47 | //rotaryEncoder.reset();
48 | //rotaryEncoder.disable();
49 | rotaryEncoder.setBoundaries(-test_limits, test_limits, false);
50 | Serial.print("new boundaries are between minimumn value ");
51 | Serial.print(-test_limits);
52 | Serial.print(" and maximum value ");
53 | Serial.println(test_limits);
54 | rotaryEncoder.reset();
55 |
56 | if (test_limits >= 2048)
57 | test_limits = 2;
58 | test_limits *= 2;
59 | }
60 |
61 | void rotary_loop()
62 | {
63 |
64 | if (rotaryEncoder.isEncoderButtonClicked())
65 | {
66 | rotary_onButtonClick();
67 | }
68 | //lets see if anything changed
69 | int16_t encoderDelta = rotaryEncoder.encoderChanged();
70 |
71 | //optionally we can ignore whenever there is no change
72 | if (encoderDelta == 0)
73 | return;
74 |
75 | //for some cases we only want to know if value is increased or decreased (typically for menu items)
76 | if (encoderDelta > 0)
77 | Serial.print("+");
78 | if (encoderDelta < 0)
79 | Serial.print("-");
80 |
81 | //for other cases we want to know what is current value. Additionally often we only want if something changed
82 | //example: when using rotary encoder to set termostat temperature, or sound volume etc
83 |
84 | //if value is changed compared to our last read
85 | if (encoderDelta != 0)
86 | {
87 | //now we need current value
88 | int16_t encoderValue = rotaryEncoder.readEncoder();
89 | //process new value. Here is simple output.
90 | Serial.print("Value: ");
91 | Serial.println(encoderValue);
92 | }
93 | }
94 |
95 | void IRAM_ATTR readEncoderISR()
96 | {
97 | rotaryEncoder.readEncoder_ISR();
98 | }
99 |
100 | void setup()
101 | {
102 |
103 | Serial.begin(115200);
104 |
105 | //we must initialize rotary encoder
106 | rotaryEncoder.begin();
107 | rotaryEncoder.setup(readEncoderISR);
108 | //optionally we can set boundaries and if values should cycle or not
109 | bool circleValues = false;
110 | rotaryEncoder.setBoundaries(0, 1000, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
111 |
112 | /*Rotary acceleration introduced 25.2.2021.
113 | * in case range to select is huge, for example - select a value between 0 and 1000 and we want 785
114 | * without accelerateion you need long time to get to that number
115 | * Using acceleration, faster you turn, faster will the value raise.
116 | * For fine tuning slow down.
117 | */
118 | //rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
119 | rotaryEncoder.setAcceleration(250); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
120 | Serial.print("\nPress rotary button to change boundaries ");
121 | }
122 |
123 | void loop()
124 | {
125 | //in loop call your custom function which will process rotary encoder values
126 | rotary_loop();
127 |
128 | delay(50);
129 | if (millis() > 20000)
130 | rotaryEncoder.enable();
131 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTheShortestExample/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600",
4 | "sketch": "Esp32RotaryEncoderTheShortestExample.ino",
5 | "port": "COM10",
6 | "output": "b:/dummy/Esp32RotaryEncoderTheShortestExample"
7 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTheShortestExample/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "b:\\dummy\\Esp32RotaryEncoderTheShortestExample\\core",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
44 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
45 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
51 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
52 | ],
53 | "forcedInclude": [
54 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
55 | ],
56 | "cStandard": "c11",
57 | "cppStandard": "c++11",
58 | "defines": [
59 | "__ets__",
60 | "ICACHE_FLASH",
61 | "NONOSDK22x_190703=1",
62 | "F_CPU=80000000L",
63 | "LWIP_OPEN_SRC",
64 | "TCP_MSS=536",
65 | "LWIP_FEATURES=1",
66 | "LWIP_IPV6=0",
67 | "ARDUINO=10815",
68 | "ARDUINO_ESP8266_WEMOS_D1MINI",
69 | "ARDUINO_ARCH_ESP8266",
70 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
71 | "FLASHMODE_DIO",
72 | "ESP8266",
73 | "__DBL_MIN_EXP__=(-1021)",
74 | "__UINT_LEAST16_MAX__=65535",
75 | "__ATOMIC_ACQUIRE=2",
76 | "__FLT_MIN__=1.1754943508222875e-38F",
77 | "__UINT_LEAST8_TYPE__=unsigned char",
78 | "__INTMAX_C(c)=c ## LL",
79 | "__CHAR_BIT__=8",
80 | "__UINT8_MAX__=255",
81 | "__WINT_MAX__=4294967295U",
82 | "__ORDER_LITTLE_ENDIAN__=1234",
83 | "__SIZE_MAX__=4294967295U",
84 | "__WCHAR_MAX__=65535",
85 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
86 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
87 | "__FLT_EVAL_METHOD__=0",
88 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
89 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
90 | "__SIG_ATOMIC_TYPE__=int",
91 | "__DBL_MIN_10_EXP__=(-307)",
92 | "__FINITE_MATH_ONLY__=0",
93 | "__GNUC_PATCHLEVEL__=2",
94 | "__UINT_FAST8_MAX__=4294967295U",
95 | "__DEC64_MAX_EXP__=385",
96 | "__INT8_C(c)=c",
97 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
98 | "__SHRT_MAX__=32767",
99 | "__LDBL_MAX__=1.7976931348623157e+308L",
100 | "__UINT_LEAST8_MAX__=255",
101 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
102 | "__UINTMAX_TYPE__=long long unsigned int",
103 | "__DEC32_EPSILON__=1E-6DF",
104 | "__CHAR_UNSIGNED__=1",
105 | "__UINT32_MAX__=4294967295UL",
106 | "__LDBL_MAX_EXP__=1024",
107 | "__WINT_MIN__=0U",
108 | "__SCHAR_MAX__=127",
109 | "__WCHAR_MIN__=0",
110 | "__INT64_C(c)=c ## LL",
111 | "__DBL_DIG__=15",
112 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
113 | "__XTENSA_CALL0_ABI__=1",
114 | "__SIZEOF_INT__=4",
115 | "__SIZEOF_POINTER__=4",
116 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
117 | "__USER_LABEL_PREFIX__",
118 | "__STDC_HOSTED__=1",
119 | "__LDBL_HAS_INFINITY__=1",
120 | "__XTENSA_EL__=1",
121 | "__FLT_EPSILON__=1.1920928955078125e-7F",
122 | "__GXX_WEAK__=1",
123 | "__LDBL_MIN__=2.2250738585072014e-308L",
124 | "__DEC32_MAX__=9.999999E96DF",
125 | "__INT32_MAX__=2147483647L",
126 | "__SIZEOF_LONG__=4",
127 | "__UINT16_C(c)=c",
128 | "__DECIMAL_DIG__=17",
129 | "__LDBL_HAS_QUIET_NAN__=1",
130 | "__GNUC__=4",
131 | "__GXX_RTTI=1",
132 | "__FLT_HAS_DENORM__=1",
133 | "__SIZEOF_LONG_DOUBLE__=8",
134 | "__BIGGEST_ALIGNMENT__=16",
135 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
136 | "__INT_FAST32_MAX__=2147483647",
137 | "__DBL_HAS_INFINITY__=1",
138 | "__INT64_MAX__=9223372036854775807LL",
139 | "__DEC32_MIN_EXP__=(-94)",
140 | "__INT_FAST16_TYPE__=int",
141 | "__LDBL_HAS_DENORM__=1",
142 | "__cplusplus=199711L",
143 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
144 | "__INT_LEAST32_MAX__=2147483647L",
145 | "__DEC32_MIN__=1E-95DF",
146 | "__DEPRECATED=1",
147 | "__DBL_MAX_EXP__=1024",
148 | "__DEC128_EPSILON__=1E-33DL",
149 | "__PTRDIFF_MAX__=2147483647",
150 | "__GNUG__=4",
151 | "__LONG_LONG_MAX__=9223372036854775807LL",
152 | "__SIZEOF_SIZE_T__=4",
153 | "__SIZEOF_WINT_T__=4",
154 | "__GXX_ABI_VERSION=1002",
155 | "__FLT_MIN_EXP__=(-125)",
156 | "__INT_FAST64_TYPE__=long long int",
157 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
158 | "__FLT_MIN_10_EXP__=(-37)",
159 | "__DEC128_MIN__=1E-6143DL",
160 | "__REGISTER_PREFIX__",
161 | "__UINT16_MAX__=65535",
162 | "__DBL_HAS_DENORM__=1",
163 | "__UINT8_TYPE__=unsigned char",
164 | "__NO_INLINE__=1",
165 | "__FLT_MANT_DIG__=24",
166 | "__VERSION__=\"4.8.2\"",
167 | "__UINT64_C(c)=c ## ULL",
168 | "__XTENSA_SOFT_FLOAT__=1",
169 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
170 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
171 | "__INT32_C(c)=c ## L",
172 | "__DEC64_EPSILON__=1E-15DD",
173 | "__ORDER_PDP_ENDIAN__=3412",
174 | "__DEC128_MIN_EXP__=(-6142)",
175 | "__INT_FAST32_TYPE__=int",
176 | "__UINT_LEAST16_TYPE__=short unsigned int",
177 | "__INT16_MAX__=32767",
178 | "__SIZE_TYPE__=unsigned int",
179 | "__UINT64_MAX__=18446744073709551615ULL",
180 | "__INT8_TYPE__=signed char",
181 | "__ELF__=1",
182 | "__xtensa__=1",
183 | "__FLT_RADIX__=2",
184 | "__INT_LEAST16_TYPE__=short int",
185 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
186 | "__UINTMAX_C(c)=c ## ULL",
187 | "__SIG_ATOMIC_MAX__=2147483647",
188 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
189 | "__SIZEOF_PTRDIFF_T__=4",
190 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
191 | "__INT_FAST16_MAX__=2147483647",
192 | "__UINT_FAST32_MAX__=4294967295U",
193 | "__UINT_LEAST64_TYPE__=long long unsigned int",
194 | "__FLT_HAS_QUIET_NAN__=1",
195 | "__FLT_MAX_10_EXP__=38",
196 | "__LONG_MAX__=2147483647L",
197 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
198 | "__FLT_HAS_INFINITY__=1",
199 | "__UINT_FAST16_TYPE__=unsigned int",
200 | "__DEC64_MAX__=9.999999999999999E384DD",
201 | "__CHAR16_TYPE__=short unsigned int",
202 | "__PRAGMA_REDEFINE_EXTNAME=1",
203 | "__INT_LEAST16_MAX__=32767",
204 | "__DEC64_MANT_DIG__=16",
205 | "__UINT_LEAST32_MAX__=4294967295UL",
206 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
207 | "__INT_LEAST64_TYPE__=long long int",
208 | "__INT16_TYPE__=short int",
209 | "__INT_LEAST8_TYPE__=signed char",
210 | "__DEC32_MAX_EXP__=97",
211 | "__INT_FAST8_MAX__=2147483647",
212 | "__INTPTR_MAX__=2147483647",
213 | "__EXCEPTIONS=1",
214 | "__LDBL_MANT_DIG__=53",
215 | "__DBL_HAS_QUIET_NAN__=1",
216 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
217 | "__INTPTR_TYPE__=int",
218 | "__UINT16_TYPE__=short unsigned int",
219 | "__WCHAR_TYPE__=short unsigned int",
220 | "__SIZEOF_FLOAT__=4",
221 | "__UINTPTR_MAX__=4294967295U",
222 | "__DEC64_MIN_EXP__=(-382)",
223 | "__INT_FAST64_MAX__=9223372036854775807LL",
224 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
225 | "__FLT_DIG__=6",
226 | "__UINT_FAST64_TYPE__=long long unsigned int",
227 | "__INT_MAX__=2147483647",
228 | "__INT64_TYPE__=long long int",
229 | "__FLT_MAX_EXP__=128",
230 | "__DBL_MANT_DIG__=53",
231 | "__INT_LEAST64_MAX__=9223372036854775807LL",
232 | "__DEC64_MIN__=1E-383DD",
233 | "__WINT_TYPE__=unsigned int",
234 | "__UINT_LEAST32_TYPE__=long unsigned int",
235 | "__SIZEOF_SHORT__=2",
236 | "__LDBL_MIN_EXP__=(-1021)",
237 | "__INT_LEAST8_MAX__=127",
238 | "__WCHAR_UNSIGNED__=1",
239 | "__LDBL_MAX_10_EXP__=308",
240 | "__ATOMIC_RELAXED=0",
241 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
242 | "__UINT8_C(c)=c",
243 | "__INT_LEAST32_TYPE__=long int",
244 | "__SIZEOF_WCHAR_T__=2",
245 | "__UINT64_TYPE__=long long unsigned int",
246 | "__INT_FAST8_TYPE__=int",
247 | "__DBL_DECIMAL_DIG__=17",
248 | "__DEC_EVAL_METHOD__=2",
249 | "__XTENSA__=1",
250 | "__ORDER_BIG_ENDIAN__=4321",
251 | "__UINT32_C(c)=c ## UL",
252 | "__INTMAX_MAX__=9223372036854775807LL",
253 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
254 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
255 | "__INT8_MAX__=127",
256 | "__UINT_FAST32_TYPE__=unsigned int",
257 | "__CHAR32_TYPE__=long unsigned int",
258 | "__FLT_MAX__=3.4028234663852886e+38F",
259 | "__INT32_TYPE__=long int",
260 | "__SIZEOF_DOUBLE__=8",
261 | "__INTMAX_TYPE__=long long int",
262 | "__DEC128_MAX_EXP__=6145",
263 | "__ATOMIC_CONSUME=1",
264 | "__GNUC_MINOR__=8",
265 | "__UINTMAX_MAX__=18446744073709551615ULL",
266 | "__DEC32_MANT_DIG__=7",
267 | "__DBL_MAX_10_EXP__=308",
268 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
269 | "__INT16_C(c)=c",
270 | "__STDC__=1",
271 | "__PTRDIFF_TYPE__=int",
272 | "__ATOMIC_SEQ_CST=5",
273 | "__UINT32_TYPE__=long unsigned int",
274 | "__UINTPTR_TYPE__=unsigned int",
275 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
276 | "__DEC128_MANT_DIG__=34",
277 | "__LDBL_MIN_10_EXP__=(-307)",
278 | "__SIZEOF_LONG_LONG__=8",
279 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
280 | "__LDBL_DIG__=15",
281 | "__FLT_DECIMAL_DIG__=9",
282 | "__UINT_FAST16_MAX__=4294967295U",
283 | "__GNUC_GNU_INLINE__=1",
284 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
285 | "__UINT_FAST8_TYPE__=unsigned int",
286 | "__ATOMIC_ACQ_REL=4",
287 | "__ATOMIC_RELEASE=3",
288 | "USBCON"
289 | ]
290 | }
291 | ]
292 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTheShortestExample/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp",
18 | "xlocale": "cpp"
19 | }
20 | }
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTheShortestExample/Esp32RotaryEncoderTheShortestExample.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 |
3 | #if defined(ESP8266)
4 | #define ROTARY_ENCODER_A_PIN D6
5 | #define ROTARY_ENCODER_B_PIN D5
6 | #define ROTARY_ENCODER_BUTTON_PIN D7
7 | #else
8 | #define ROTARY_ENCODER_A_PIN 32
9 | #define ROTARY_ENCODER_B_PIN 21
10 | #define ROTARY_ENCODER_BUTTON_PIN 25
11 | #endif
12 | #define ROTARY_ENCODER_STEPS 4
13 |
14 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
15 |
16 | void IRAM_ATTR readEncoderISR()
17 | {
18 | rotaryEncoder.readEncoder_ISR();
19 | }
20 |
21 | void setup()
22 | {
23 | Serial.begin(115200);
24 | rotaryEncoder.begin();
25 | rotaryEncoder.setup(readEncoderISR);
26 | rotaryEncoder.setBoundaries(0, 1000, false); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
27 | rotaryEncoder.setAcceleration(250);
28 | }
29 |
30 | void loop()
31 | {
32 | if (rotaryEncoder.encoderChanged())
33 | {
34 | Serial.println(rotaryEncoder.readEncoder());
35 | }
36 | if (rotaryEncoder.isEncoderButtonClicked())
37 | {
38 | Serial.println("button pressed");
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/Esp32RotaryEncoderTheShortestExampleNoResistors/Esp32RotaryEncoderTheShortestExampleNoResistors.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 |
3 | #if defined(ESP8266)
4 | #define ROTARY_ENCODER_A_PIN D6
5 | #define ROTARY_ENCODER_B_PIN D5
6 | #define ROTARY_ENCODER_BUTTON_PIN D7
7 | #else
8 | #define ROTARY_ENCODER_A_PIN 32
9 | #define ROTARY_ENCODER_B_PIN 21
10 | #define ROTARY_ENCODER_BUTTON_PIN 25
11 | #endif
12 | #define ROTARY_ENCODER_STEPS 4
13 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
14 |
15 | void IRAM_ATTR readEncoderISR()
16 | {
17 | rotaryEncoder.readEncoder_ISR();
18 | }
19 |
20 | void setup()
21 | {
22 | // pinMode(ROTARY_ENCODER_A_PIN, INPUT_PULLUP);
23 | // pinMode(ROTARY_ENCODER_B_PIN, INPUT_PULLUP);
24 | Serial.begin(115200);
25 | rotaryEncoder.areEncoderPinsPulldownforEsp32=false;
26 | rotaryEncoder.begin();
27 | rotaryEncoder.setup(readEncoderISR);
28 | rotaryEncoder.setBoundaries(0, 1000, false); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
29 | rotaryEncoder.setAcceleration(250);
30 | }
31 |
32 | void loop()
33 | {
34 | if (rotaryEncoder.encoderChanged())
35 | {
36 | Serial.println(rotaryEncoder.readEncoder());
37 | }
38 | if (rotaryEncoder.isEncoderButtonClicked())
39 | {
40 | Serial.println("button pressed");
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/examples/FM-radio-tuner/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "port": "COM10",
4 | "sketch": "FM-radio-tuner.ino",
5 | "output": "b:/dummy/FM-radio-tuner8266",
6 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200"
7 | }
--------------------------------------------------------------------------------
/examples/FM-radio-tuner/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "b:\\dummy\\FM-radio-tuner8266\\core",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
44 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
45 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
51 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
52 | ],
53 | "forcedInclude": [
54 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
55 | ],
56 | "cStandard": "c11",
57 | "cppStandard": "c++11",
58 | "defines": [
59 | "__ets__",
60 | "ICACHE_FLASH",
61 | "NONOSDK22x_190703=1",
62 | "F_CPU=80000000L",
63 | "LWIP_OPEN_SRC",
64 | "TCP_MSS=536",
65 | "LWIP_FEATURES=1",
66 | "LWIP_IPV6=0",
67 | "ARDUINO=10815",
68 | "ARDUINO_ESP8266_WEMOS_D1MINI",
69 | "ARDUINO_ARCH_ESP8266",
70 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
71 | "FLASHMODE_DIO",
72 | "ESP8266",
73 | "__DBL_MIN_EXP__=(-1021)",
74 | "__UINT_LEAST16_MAX__=65535",
75 | "__ATOMIC_ACQUIRE=2",
76 | "__FLT_MIN__=1.1754943508222875e-38F",
77 | "__UINT_LEAST8_TYPE__=unsigned char",
78 | "__INTMAX_C(c)=c ## LL",
79 | "__CHAR_BIT__=8",
80 | "__UINT8_MAX__=255",
81 | "__WINT_MAX__=4294967295U",
82 | "__ORDER_LITTLE_ENDIAN__=1234",
83 | "__SIZE_MAX__=4294967295U",
84 | "__WCHAR_MAX__=65535",
85 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
86 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
87 | "__FLT_EVAL_METHOD__=0",
88 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
89 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
90 | "__SIG_ATOMIC_TYPE__=int",
91 | "__DBL_MIN_10_EXP__=(-307)",
92 | "__FINITE_MATH_ONLY__=0",
93 | "__GNUC_PATCHLEVEL__=2",
94 | "__UINT_FAST8_MAX__=4294967295U",
95 | "__DEC64_MAX_EXP__=385",
96 | "__INT8_C(c)=c",
97 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
98 | "__SHRT_MAX__=32767",
99 | "__LDBL_MAX__=1.7976931348623157e+308L",
100 | "__UINT_LEAST8_MAX__=255",
101 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
102 | "__UINTMAX_TYPE__=long long unsigned int",
103 | "__DEC32_EPSILON__=1E-6DF",
104 | "__CHAR_UNSIGNED__=1",
105 | "__UINT32_MAX__=4294967295UL",
106 | "__LDBL_MAX_EXP__=1024",
107 | "__WINT_MIN__=0U",
108 | "__SCHAR_MAX__=127",
109 | "__WCHAR_MIN__=0",
110 | "__INT64_C(c)=c ## LL",
111 | "__DBL_DIG__=15",
112 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
113 | "__XTENSA_CALL0_ABI__=1",
114 | "__SIZEOF_INT__=4",
115 | "__SIZEOF_POINTER__=4",
116 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
117 | "__USER_LABEL_PREFIX__",
118 | "__STDC_HOSTED__=1",
119 | "__LDBL_HAS_INFINITY__=1",
120 | "__XTENSA_EL__=1",
121 | "__FLT_EPSILON__=1.1920928955078125e-7F",
122 | "__GXX_WEAK__=1",
123 | "__LDBL_MIN__=2.2250738585072014e-308L",
124 | "__DEC32_MAX__=9.999999E96DF",
125 | "__INT32_MAX__=2147483647L",
126 | "__SIZEOF_LONG__=4",
127 | "__UINT16_C(c)=c",
128 | "__DECIMAL_DIG__=17",
129 | "__LDBL_HAS_QUIET_NAN__=1",
130 | "__GNUC__=4",
131 | "__GXX_RTTI=1",
132 | "__FLT_HAS_DENORM__=1",
133 | "__SIZEOF_LONG_DOUBLE__=8",
134 | "__BIGGEST_ALIGNMENT__=16",
135 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
136 | "__INT_FAST32_MAX__=2147483647",
137 | "__DBL_HAS_INFINITY__=1",
138 | "__INT64_MAX__=9223372036854775807LL",
139 | "__DEC32_MIN_EXP__=(-94)",
140 | "__INT_FAST16_TYPE__=int",
141 | "__LDBL_HAS_DENORM__=1",
142 | "__cplusplus=199711L",
143 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
144 | "__INT_LEAST32_MAX__=2147483647L",
145 | "__DEC32_MIN__=1E-95DF",
146 | "__DEPRECATED=1",
147 | "__DBL_MAX_EXP__=1024",
148 | "__DEC128_EPSILON__=1E-33DL",
149 | "__PTRDIFF_MAX__=2147483647",
150 | "__GNUG__=4",
151 | "__LONG_LONG_MAX__=9223372036854775807LL",
152 | "__SIZEOF_SIZE_T__=4",
153 | "__SIZEOF_WINT_T__=4",
154 | "__GXX_ABI_VERSION=1002",
155 | "__FLT_MIN_EXP__=(-125)",
156 | "__INT_FAST64_TYPE__=long long int",
157 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
158 | "__FLT_MIN_10_EXP__=(-37)",
159 | "__DEC128_MIN__=1E-6143DL",
160 | "__REGISTER_PREFIX__",
161 | "__UINT16_MAX__=65535",
162 | "__DBL_HAS_DENORM__=1",
163 | "__UINT8_TYPE__=unsigned char",
164 | "__NO_INLINE__=1",
165 | "__FLT_MANT_DIG__=24",
166 | "__VERSION__=\"4.8.2\"",
167 | "__UINT64_C(c)=c ## ULL",
168 | "__XTENSA_SOFT_FLOAT__=1",
169 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
170 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
171 | "__INT32_C(c)=c ## L",
172 | "__DEC64_EPSILON__=1E-15DD",
173 | "__ORDER_PDP_ENDIAN__=3412",
174 | "__DEC128_MIN_EXP__=(-6142)",
175 | "__INT_FAST32_TYPE__=int",
176 | "__UINT_LEAST16_TYPE__=short unsigned int",
177 | "__INT16_MAX__=32767",
178 | "__SIZE_TYPE__=unsigned int",
179 | "__UINT64_MAX__=18446744073709551615ULL",
180 | "__INT8_TYPE__=signed char",
181 | "__ELF__=1",
182 | "__xtensa__=1",
183 | "__FLT_RADIX__=2",
184 | "__INT_LEAST16_TYPE__=short int",
185 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
186 | "__UINTMAX_C(c)=c ## ULL",
187 | "__SIG_ATOMIC_MAX__=2147483647",
188 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
189 | "__SIZEOF_PTRDIFF_T__=4",
190 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
191 | "__INT_FAST16_MAX__=2147483647",
192 | "__UINT_FAST32_MAX__=4294967295U",
193 | "__UINT_LEAST64_TYPE__=long long unsigned int",
194 | "__FLT_HAS_QUIET_NAN__=1",
195 | "__FLT_MAX_10_EXP__=38",
196 | "__LONG_MAX__=2147483647L",
197 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
198 | "__FLT_HAS_INFINITY__=1",
199 | "__UINT_FAST16_TYPE__=unsigned int",
200 | "__DEC64_MAX__=9.999999999999999E384DD",
201 | "__CHAR16_TYPE__=short unsigned int",
202 | "__PRAGMA_REDEFINE_EXTNAME=1",
203 | "__INT_LEAST16_MAX__=32767",
204 | "__DEC64_MANT_DIG__=16",
205 | "__UINT_LEAST32_MAX__=4294967295UL",
206 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
207 | "__INT_LEAST64_TYPE__=long long int",
208 | "__INT16_TYPE__=short int",
209 | "__INT_LEAST8_TYPE__=signed char",
210 | "__DEC32_MAX_EXP__=97",
211 | "__INT_FAST8_MAX__=2147483647",
212 | "__INTPTR_MAX__=2147483647",
213 | "__EXCEPTIONS=1",
214 | "__LDBL_MANT_DIG__=53",
215 | "__DBL_HAS_QUIET_NAN__=1",
216 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
217 | "__INTPTR_TYPE__=int",
218 | "__UINT16_TYPE__=short unsigned int",
219 | "__WCHAR_TYPE__=short unsigned int",
220 | "__SIZEOF_FLOAT__=4",
221 | "__UINTPTR_MAX__=4294967295U",
222 | "__DEC64_MIN_EXP__=(-382)",
223 | "__INT_FAST64_MAX__=9223372036854775807LL",
224 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
225 | "__FLT_DIG__=6",
226 | "__UINT_FAST64_TYPE__=long long unsigned int",
227 | "__INT_MAX__=2147483647",
228 | "__INT64_TYPE__=long long int",
229 | "__FLT_MAX_EXP__=128",
230 | "__DBL_MANT_DIG__=53",
231 | "__INT_LEAST64_MAX__=9223372036854775807LL",
232 | "__DEC64_MIN__=1E-383DD",
233 | "__WINT_TYPE__=unsigned int",
234 | "__UINT_LEAST32_TYPE__=long unsigned int",
235 | "__SIZEOF_SHORT__=2",
236 | "__LDBL_MIN_EXP__=(-1021)",
237 | "__INT_LEAST8_MAX__=127",
238 | "__WCHAR_UNSIGNED__=1",
239 | "__LDBL_MAX_10_EXP__=308",
240 | "__ATOMIC_RELAXED=0",
241 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
242 | "__UINT8_C(c)=c",
243 | "__INT_LEAST32_TYPE__=long int",
244 | "__SIZEOF_WCHAR_T__=2",
245 | "__UINT64_TYPE__=long long unsigned int",
246 | "__INT_FAST8_TYPE__=int",
247 | "__DBL_DECIMAL_DIG__=17",
248 | "__DEC_EVAL_METHOD__=2",
249 | "__XTENSA__=1",
250 | "__ORDER_BIG_ENDIAN__=4321",
251 | "__UINT32_C(c)=c ## UL",
252 | "__INTMAX_MAX__=9223372036854775807LL",
253 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
254 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
255 | "__INT8_MAX__=127",
256 | "__UINT_FAST32_TYPE__=unsigned int",
257 | "__CHAR32_TYPE__=long unsigned int",
258 | "__FLT_MAX__=3.4028234663852886e+38F",
259 | "__INT32_TYPE__=long int",
260 | "__SIZEOF_DOUBLE__=8",
261 | "__INTMAX_TYPE__=long long int",
262 | "__DEC128_MAX_EXP__=6145",
263 | "__ATOMIC_CONSUME=1",
264 | "__GNUC_MINOR__=8",
265 | "__UINTMAX_MAX__=18446744073709551615ULL",
266 | "__DEC32_MANT_DIG__=7",
267 | "__DBL_MAX_10_EXP__=308",
268 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
269 | "__INT16_C(c)=c",
270 | "__STDC__=1",
271 | "__PTRDIFF_TYPE__=int",
272 | "__ATOMIC_SEQ_CST=5",
273 | "__UINT32_TYPE__=long unsigned int",
274 | "__UINTPTR_TYPE__=unsigned int",
275 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
276 | "__DEC128_MANT_DIG__=34",
277 | "__LDBL_MIN_10_EXP__=(-307)",
278 | "__SIZEOF_LONG_LONG__=8",
279 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
280 | "__LDBL_DIG__=15",
281 | "__FLT_DECIMAL_DIG__=9",
282 | "__UINT_FAST16_MAX__=4294967295U",
283 | "__GNUC_GNU_INLINE__=1",
284 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
285 | "__UINT_FAST8_TYPE__=unsigned int",
286 | "__ATOMIC_ACQ_REL=4",
287 | "__ATOMIC_RELEASE=3",
288 | "USBCON"
289 | ]
290 | }
291 | ]
292 | }
--------------------------------------------------------------------------------
/examples/FM-radio-tuner/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/examples/FM-radio-tuner/FM-radio-tuner.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 |
3 | #if defined(ESP8266)
4 | #define ROTARY_ENCODER_A_PIN D6
5 | #define ROTARY_ENCODER_B_PIN D5
6 | #define ROTARY_ENCODER_BUTTON_PIN D7
7 | #else
8 | #define ROTARY_ENCODER_A_PIN 32
9 | #define ROTARY_ENCODER_B_PIN 21
10 | #define ROTARY_ENCODER_BUTTON_PIN 25
11 | #endif
12 |
13 | #define ROTARY_ENCODER_STEPS 4
14 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
15 |
16 | /*
17 | FM radio tunner is suposed to set frequency between 88.0 MHz and 104.0 MHz by 0.1MHz steps
18 | Rotary encoder works with integers so we will map 88.0 to 166 and then divide by 10 to get 0.1 steps
19 | frequency = rotaryValue / 2;
20 | */
21 |
22 | float getFrequency()
23 | {
24 | return (float)rotaryEncoder.readEncoder() / 10.0;
25 | }
26 |
27 | void rotary_onButtonClick()
28 | {
29 | static unsigned long lastTimePressed = 0;
30 | if (millis() - lastTimePressed < 200)
31 | return;
32 | lastTimePressed = millis();
33 |
34 | Serial.print("Radio station set to ");
35 | Serial.print(getFrequency());
36 | Serial.println(" MHz ");
37 | }
38 |
39 | void IRAM_ATTR readEncoderISR()
40 | {
41 | rotaryEncoder.readEncoder_ISR();
42 | }
43 |
44 | void setup()
45 | {
46 | Serial.begin(115200);
47 | rotaryEncoder.begin();
48 | rotaryEncoder.setup(readEncoderISR);
49 | rotaryEncoder.setBoundaries(88 * 10, 104 * 10, true); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
50 | rotaryEncoder.setAcceleration(50);
51 | rotaryEncoder.setEncoderValue(92.1 * 10); //set default to 92.1 MHz
52 | Serial.println("FM Radio");
53 | Serial.print("Radio station initially set to ");
54 | Serial.print(getFrequency());
55 | Serial.println(" MHz. Tune to some other station like 103.2... and press button ");
56 | }
57 |
58 | void loop()
59 | {
60 | if (rotaryEncoder.encoderChanged())
61 | {
62 | Serial.print(getFrequency(), 1);
63 | Serial.println(" MHz ");
64 | }
65 | if (rotaryEncoder.isEncoderButtonClicked())
66 | {
67 | rotary_onButtonClick();
68 | }
69 | }
--------------------------------------------------------------------------------
/examples/Multi-select/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "port": "COM10",
4 | "sketch": "Multi-select.ino",
5 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600"
6 | }
--------------------------------------------------------------------------------
/examples/Multi-select/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
44 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
45 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
51 | ],
52 | "forcedInclude": [
53 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
54 | ],
55 | "cStandard": "c11",
56 | "cppStandard": "c++11",
57 | "defines": [
58 | "__ets__",
59 | "ICACHE_FLASH",
60 | "NONOSDK22x_190703=1",
61 | "F_CPU=80000000L",
62 | "LWIP_OPEN_SRC",
63 | "TCP_MSS=536",
64 | "LWIP_FEATURES=1",
65 | "LWIP_IPV6=0",
66 | "ARDUINO=10815",
67 | "ARDUINO_ESP8266_WEMOS_D1MINI",
68 | "ARDUINO_ARCH_ESP8266",
69 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
70 | "FLASHMODE_DIO",
71 | "ESP8266",
72 | "__DBL_MIN_EXP__=(-1021)",
73 | "__UINT_LEAST16_MAX__=65535",
74 | "__ATOMIC_ACQUIRE=2",
75 | "__FLT_MIN__=1.1754943508222875e-38F",
76 | "__UINT_LEAST8_TYPE__=unsigned char",
77 | "__INTMAX_C(c)=c ## LL",
78 | "__CHAR_BIT__=8",
79 | "__UINT8_MAX__=255",
80 | "__WINT_MAX__=4294967295U",
81 | "__ORDER_LITTLE_ENDIAN__=1234",
82 | "__SIZE_MAX__=4294967295U",
83 | "__WCHAR_MAX__=65535",
84 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
85 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
86 | "__FLT_EVAL_METHOD__=0",
87 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
88 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
89 | "__SIG_ATOMIC_TYPE__=int",
90 | "__DBL_MIN_10_EXP__=(-307)",
91 | "__FINITE_MATH_ONLY__=0",
92 | "__GNUC_PATCHLEVEL__=2",
93 | "__UINT_FAST8_MAX__=4294967295U",
94 | "__DEC64_MAX_EXP__=385",
95 | "__INT8_C(c)=c",
96 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
97 | "__SHRT_MAX__=32767",
98 | "__LDBL_MAX__=1.7976931348623157e+308L",
99 | "__UINT_LEAST8_MAX__=255",
100 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
101 | "__UINTMAX_TYPE__=long long unsigned int",
102 | "__DEC32_EPSILON__=1E-6DF",
103 | "__CHAR_UNSIGNED__=1",
104 | "__UINT32_MAX__=4294967295UL",
105 | "__LDBL_MAX_EXP__=1024",
106 | "__WINT_MIN__=0U",
107 | "__SCHAR_MAX__=127",
108 | "__WCHAR_MIN__=0",
109 | "__INT64_C(c)=c ## LL",
110 | "__DBL_DIG__=15",
111 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
112 | "__XTENSA_CALL0_ABI__=1",
113 | "__SIZEOF_INT__=4",
114 | "__SIZEOF_POINTER__=4",
115 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
116 | "__USER_LABEL_PREFIX__",
117 | "__STDC_HOSTED__=1",
118 | "__LDBL_HAS_INFINITY__=1",
119 | "__XTENSA_EL__=1",
120 | "__FLT_EPSILON__=1.1920928955078125e-7F",
121 | "__GXX_WEAK__=1",
122 | "__LDBL_MIN__=2.2250738585072014e-308L",
123 | "__DEC32_MAX__=9.999999E96DF",
124 | "__INT32_MAX__=2147483647L",
125 | "__SIZEOF_LONG__=4",
126 | "__UINT16_C(c)=c",
127 | "__DECIMAL_DIG__=17",
128 | "__LDBL_HAS_QUIET_NAN__=1",
129 | "__GNUC__=4",
130 | "__GXX_RTTI=1",
131 | "__FLT_HAS_DENORM__=1",
132 | "__SIZEOF_LONG_DOUBLE__=8",
133 | "__BIGGEST_ALIGNMENT__=16",
134 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
135 | "__INT_FAST32_MAX__=2147483647",
136 | "__DBL_HAS_INFINITY__=1",
137 | "__INT64_MAX__=9223372036854775807LL",
138 | "__DEC32_MIN_EXP__=(-94)",
139 | "__INT_FAST16_TYPE__=int",
140 | "__LDBL_HAS_DENORM__=1",
141 | "__cplusplus=199711L",
142 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
143 | "__INT_LEAST32_MAX__=2147483647L",
144 | "__DEC32_MIN__=1E-95DF",
145 | "__DEPRECATED=1",
146 | "__DBL_MAX_EXP__=1024",
147 | "__DEC128_EPSILON__=1E-33DL",
148 | "__PTRDIFF_MAX__=2147483647",
149 | "__GNUG__=4",
150 | "__LONG_LONG_MAX__=9223372036854775807LL",
151 | "__SIZEOF_SIZE_T__=4",
152 | "__SIZEOF_WINT_T__=4",
153 | "__GXX_ABI_VERSION=1002",
154 | "__FLT_MIN_EXP__=(-125)",
155 | "__INT_FAST64_TYPE__=long long int",
156 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
157 | "__FLT_MIN_10_EXP__=(-37)",
158 | "__DEC128_MIN__=1E-6143DL",
159 | "__REGISTER_PREFIX__",
160 | "__UINT16_MAX__=65535",
161 | "__DBL_HAS_DENORM__=1",
162 | "__UINT8_TYPE__=unsigned char",
163 | "__NO_INLINE__=1",
164 | "__FLT_MANT_DIG__=24",
165 | "__VERSION__=\"4.8.2\"",
166 | "__UINT64_C(c)=c ## ULL",
167 | "__XTENSA_SOFT_FLOAT__=1",
168 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
169 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
170 | "__INT32_C(c)=c ## L",
171 | "__DEC64_EPSILON__=1E-15DD",
172 | "__ORDER_PDP_ENDIAN__=3412",
173 | "__DEC128_MIN_EXP__=(-6142)",
174 | "__INT_FAST32_TYPE__=int",
175 | "__UINT_LEAST16_TYPE__=short unsigned int",
176 | "__INT16_MAX__=32767",
177 | "__SIZE_TYPE__=unsigned int",
178 | "__UINT64_MAX__=18446744073709551615ULL",
179 | "__INT8_TYPE__=signed char",
180 | "__ELF__=1",
181 | "__xtensa__=1",
182 | "__FLT_RADIX__=2",
183 | "__INT_LEAST16_TYPE__=short int",
184 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
185 | "__UINTMAX_C(c)=c ## ULL",
186 | "__SIG_ATOMIC_MAX__=2147483647",
187 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
188 | "__SIZEOF_PTRDIFF_T__=4",
189 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
190 | "__INT_FAST16_MAX__=2147483647",
191 | "__UINT_FAST32_MAX__=4294967295U",
192 | "__UINT_LEAST64_TYPE__=long long unsigned int",
193 | "__FLT_HAS_QUIET_NAN__=1",
194 | "__FLT_MAX_10_EXP__=38",
195 | "__LONG_MAX__=2147483647L",
196 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
197 | "__FLT_HAS_INFINITY__=1",
198 | "__UINT_FAST16_TYPE__=unsigned int",
199 | "__DEC64_MAX__=9.999999999999999E384DD",
200 | "__CHAR16_TYPE__=short unsigned int",
201 | "__PRAGMA_REDEFINE_EXTNAME=1",
202 | "__INT_LEAST16_MAX__=32767",
203 | "__DEC64_MANT_DIG__=16",
204 | "__UINT_LEAST32_MAX__=4294967295UL",
205 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
206 | "__INT_LEAST64_TYPE__=long long int",
207 | "__INT16_TYPE__=short int",
208 | "__INT_LEAST8_TYPE__=signed char",
209 | "__DEC32_MAX_EXP__=97",
210 | "__INT_FAST8_MAX__=2147483647",
211 | "__INTPTR_MAX__=2147483647",
212 | "__EXCEPTIONS=1",
213 | "__LDBL_MANT_DIG__=53",
214 | "__DBL_HAS_QUIET_NAN__=1",
215 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
216 | "__INTPTR_TYPE__=int",
217 | "__UINT16_TYPE__=short unsigned int",
218 | "__WCHAR_TYPE__=short unsigned int",
219 | "__SIZEOF_FLOAT__=4",
220 | "__UINTPTR_MAX__=4294967295U",
221 | "__DEC64_MIN_EXP__=(-382)",
222 | "__INT_FAST64_MAX__=9223372036854775807LL",
223 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
224 | "__FLT_DIG__=6",
225 | "__UINT_FAST64_TYPE__=long long unsigned int",
226 | "__INT_MAX__=2147483647",
227 | "__INT64_TYPE__=long long int",
228 | "__FLT_MAX_EXP__=128",
229 | "__DBL_MANT_DIG__=53",
230 | "__INT_LEAST64_MAX__=9223372036854775807LL",
231 | "__DEC64_MIN__=1E-383DD",
232 | "__WINT_TYPE__=unsigned int",
233 | "__UINT_LEAST32_TYPE__=long unsigned int",
234 | "__SIZEOF_SHORT__=2",
235 | "__LDBL_MIN_EXP__=(-1021)",
236 | "__INT_LEAST8_MAX__=127",
237 | "__WCHAR_UNSIGNED__=1",
238 | "__LDBL_MAX_10_EXP__=308",
239 | "__ATOMIC_RELAXED=0",
240 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
241 | "__UINT8_C(c)=c",
242 | "__INT_LEAST32_TYPE__=long int",
243 | "__SIZEOF_WCHAR_T__=2",
244 | "__UINT64_TYPE__=long long unsigned int",
245 | "__INT_FAST8_TYPE__=int",
246 | "__DBL_DECIMAL_DIG__=17",
247 | "__DEC_EVAL_METHOD__=2",
248 | "__XTENSA__=1",
249 | "__ORDER_BIG_ENDIAN__=4321",
250 | "__UINT32_C(c)=c ## UL",
251 | "__INTMAX_MAX__=9223372036854775807LL",
252 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
253 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
254 | "__INT8_MAX__=127",
255 | "__UINT_FAST32_TYPE__=unsigned int",
256 | "__CHAR32_TYPE__=long unsigned int",
257 | "__FLT_MAX__=3.4028234663852886e+38F",
258 | "__INT32_TYPE__=long int",
259 | "__SIZEOF_DOUBLE__=8",
260 | "__INTMAX_TYPE__=long long int",
261 | "__DEC128_MAX_EXP__=6145",
262 | "__ATOMIC_CONSUME=1",
263 | "__GNUC_MINOR__=8",
264 | "__UINTMAX_MAX__=18446744073709551615ULL",
265 | "__DEC32_MANT_DIG__=7",
266 | "__DBL_MAX_10_EXP__=308",
267 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
268 | "__INT16_C(c)=c",
269 | "__STDC__=1",
270 | "__PTRDIFF_TYPE__=int",
271 | "__ATOMIC_SEQ_CST=5",
272 | "__UINT32_TYPE__=long unsigned int",
273 | "__UINTPTR_TYPE__=unsigned int",
274 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
275 | "__DEC128_MANT_DIG__=34",
276 | "__LDBL_MIN_10_EXP__=(-307)",
277 | "__SIZEOF_LONG_LONG__=8",
278 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
279 | "__LDBL_DIG__=15",
280 | "__FLT_DECIMAL_DIG__=9",
281 | "__UINT_FAST16_MAX__=4294967295U",
282 | "__GNUC_GNU_INLINE__=1",
283 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
284 | "__UINT_FAST8_TYPE__=unsigned int",
285 | "__ATOMIC_ACQ_REL=4",
286 | "__ATOMIC_RELEASE=3",
287 | "USBCON"
288 | ]
289 | }
290 | ]
291 | }
--------------------------------------------------------------------------------
/examples/Multi-select/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/examples/Multi-select/Multi-select.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 | #if defined(ESP8266)
3 | #define ROTARY_ENCODER_A_PIN D6
4 | #define ROTARY_ENCODER_B_PIN D5
5 | #define ROTARY_ENCODER_BUTTON_PIN D7
6 | #else
7 | #define ROTARY_ENCODER_A_PIN 32
8 | #define ROTARY_ENCODER_B_PIN 21
9 | #define ROTARY_ENCODER_BUTTON_PIN 25
10 | #endif
11 | #define ROTARY_ENCODER_STEPS 4
12 | AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
13 |
14 | /*
15 | Select fast food - Hot dog, Pizza, Hamburger, Cheeseburger
16 | Then select how many pieces 1 to 10
17 | At the end select if you want fast delivery for extra 2$
18 | */
19 | String options[] = {"Select fast food", "How many (1...10)", "Do you want fast delicery for 2$?"};
20 |
21 | String foods[] = {"Hot dog", "Pizza", "Hamburger", "Cheeseburger"};
22 | //String foods[] = {" 1", " 2", " 3", " 4"};
23 | String selectedFood = "";
24 |
25 | String delivery[] = {"Normal", "Fast for extra 2$"};
26 | String selectedDelivery = "";
27 |
28 | int selectedQuantity = 1;
29 |
30 | int currentOption = 0;
31 |
32 | void setForOption(int newOption)
33 | {
34 | currentOption = newOption;
35 |
36 | switch (newOption)
37 | {
38 | case 0:
39 | rotaryEncoder.setBoundaries(0, 3, true); //food type 0..3
40 | rotaryEncoder.setEncoderValue(0);
41 | break;
42 | case 1:
43 | rotaryEncoder.setBoundaries(1, 10, false); //how many pieces 1 to 10; do not go from 10 to 1
44 | rotaryEncoder.setEncoderValue(1);
45 | break;
46 | case 2:
47 | rotaryEncoder.setBoundaries(0, 1, false); //select delivery
48 | rotaryEncoder.setEncoderValue(0);
49 | break;
50 |
51 | default:
52 | break;
53 | }
54 |
55 | Serial.println(options[currentOption]);
56 | showSelection();
57 | }
58 |
59 | void rotary_onButtonClick()
60 | {
61 | static unsigned long lastTimePressed = 0;
62 | if (millis() - lastTimePressed < 200)
63 | return;
64 | lastTimePressed = millis();
65 |
66 | int selecedValue = rotaryEncoder.readEncoder();
67 |
68 | switch (currentOption)
69 | {
70 | case 0: //"Select fast food"
71 | selectedFood = foods[selecedValue];
72 | setForOption(1);
73 | break;
74 | case 1: //"Select quantity"
75 | selectedQuantity = selecedValue;
76 | setForOption(2);
77 | break;
78 | case 2: //"Select delivery"
79 | selectedDelivery = delivery[selecedValue];
80 | showOrder();
81 | setForOption(0);
82 | break;
83 |
84 | default:
85 | break;
86 | }
87 | }
88 |
89 | void showOrder()
90 | {
91 | Serial.println("++++++++++++++++++++++++ ORDER DETAILS ++++++++++++++++++++++++++++++++++++++++++");
92 | Serial.print("You ordered ");
93 | Serial.print(selectedFood);
94 | Serial.print(", quantity: ");
95 | Serial.print(selectedQuantity);
96 | Serial.print(". Delivery: ");
97 | Serial.println(selectedDelivery);
98 | Serial.println("---------------------------------------------------------------------------------");
99 | Serial.println("");
100 |
101 | Serial.print("NEW ORDER ");
102 | }
103 |
104 | void IRAM_ATTR readEncoderISR()
105 | {
106 | rotaryEncoder.readEncoder_ISR();
107 | }
108 |
109 | void setup()
110 | {
111 | Serial.begin(115200);
112 | rotaryEncoder.begin();
113 | rotaryEncoder.setup(readEncoderISR);
114 | rotaryEncoder.setAcceleration(0);
115 |
116 | rotaryEncoder.correctionOffset=2; //try with zero or ROTARY_ENCODER_STEPS/2
117 | rotaryEncoder.isButtonPulldown = false;
118 | rotaryEncoder.areEncoderPinsPulldownforEsp32 = true;
119 |
120 | setForOption(0);
121 | }
122 |
123 | void showSelection()
124 | {
125 | int selecedValue = rotaryEncoder.readEncoder();
126 |
127 | switch (currentOption)
128 | {
129 | case 0: //"Select fast food"
130 | Serial.println(foods[selecedValue]);
131 | break;
132 | case 1: //"Select quantity"
133 | Serial.print("Quantity: ");
134 | Serial.println(selecedValue);
135 | break;
136 | case 2: //"Select delivery"
137 | Serial.println(delivery[selecedValue]);
138 | break;
139 | default:
140 | break;
141 | }
142 | }
143 |
144 | void loop()
145 | {
146 | if (rotaryEncoder.encoderChanged())
147 | {
148 | showSelection();
149 | }
150 | if (rotaryEncoder.isEncoderButtonClicked())
151 | {
152 | rotary_onButtonClick();
153 | }
154 | }
--------------------------------------------------------------------------------
/examples/Number-select/.vscode/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "board": "esp8266:esp8266:d1_mini",
3 | "configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600",
4 | "sketch": "Number-select.ino",
5 | "output": "b:/dummy/Number-select",
6 | "port": "COM10"
7 | }
--------------------------------------------------------------------------------
/examples/Number-select/.vscode/c_cpp_properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 4,
3 | "configurations": [
4 | {
5 | "name": "Win32",
6 | "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe",
7 | "compilerArgs": [],
8 | "intelliSenseMode": "windows-msvc-x64",
9 | "includePath": [
10 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\**",
11 | "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0\\**",
12 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\**",
13 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
14 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp32\\hardware\\esp32\\**",
15 | "${workspaceFolder}/**"
16 | ],
17 | "forcedInclude": [],
18 | "cStandard": "c17",
19 | "cppStandard": "c++17",
20 | "defines": [
21 | "_DEBUG",
22 | "UNICODE",
23 | "_UNICODE"
24 | ]
25 | },
26 | {
27 | "name": "Arduino",
28 | "compilerPath": "C:\\Users\\Igor\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\bin\\xtensa-lx106-elf-g++",
29 | "compilerArgs": [
30 | "-U__STRICT_ANSI__",
31 | "-mlongcalls",
32 | "-mtext-section-literals",
33 | "-fno-rtti",
34 | "-falign-functions=4",
35 | "-std=gnu++11"
36 | ],
37 | "intelliSenseMode": "gcc-x64",
38 | "includePath": [
39 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\include",
40 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\lwip2\\include",
41 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\tools\\sdk\\libc\\xtensa-lx106-elf\\include",
42 | "b:\\dummy\\Number-select\\core",
43 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266",
44 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\variants\\d1_mini",
45 | "C:\\Users\\Igor\\Documents\\Arduino\\libraries\\ai-esp32-rotary-encoder\\src",
46 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2",
47 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\xtensa-lx106-elf",
48 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include\\c++\\4.8.2\\backward",
49 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include",
50 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\lib\\gcc\\xtensa-lx106-elf\\4.8.2\\include-fixed",
51 | "c:\\users\\igor\\appdata\\local\\arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506\\xtensa-lx106-elf\\include"
52 | ],
53 | "forcedInclude": [
54 | "C:\\Users\\Igor\\AppData\\Local\\arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.4\\cores\\esp8266\\Arduino.h"
55 | ],
56 | "cStandard": "c11",
57 | "cppStandard": "c++11",
58 | "defines": [
59 | "__ets__",
60 | "ICACHE_FLASH",
61 | "NONOSDK22x_190703=1",
62 | "F_CPU=80000000L",
63 | "LWIP_OPEN_SRC",
64 | "TCP_MSS=536",
65 | "LWIP_FEATURES=1",
66 | "LWIP_IPV6=0",
67 | "ARDUINO=10815",
68 | "ARDUINO_ESP8266_WEMOS_D1MINI",
69 | "ARDUINO_ARCH_ESP8266",
70 | "ARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"",
71 | "FLASHMODE_DIO",
72 | "ESP8266",
73 | "__DBL_MIN_EXP__=(-1021)",
74 | "__UINT_LEAST16_MAX__=65535",
75 | "__ATOMIC_ACQUIRE=2",
76 | "__FLT_MIN__=1.1754943508222875e-38F",
77 | "__UINT_LEAST8_TYPE__=unsigned char",
78 | "__INTMAX_C(c)=c ## LL",
79 | "__CHAR_BIT__=8",
80 | "__UINT8_MAX__=255",
81 | "__WINT_MAX__=4294967295U",
82 | "__ORDER_LITTLE_ENDIAN__=1234",
83 | "__SIZE_MAX__=4294967295U",
84 | "__WCHAR_MAX__=65535",
85 | "__DBL_DENORM_MIN__=double(4.9406564584124654e-324L)",
86 | "__GCC_ATOMIC_CHAR_LOCK_FREE=1",
87 | "__FLT_EVAL_METHOD__=0",
88 | "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
89 | "__UINT_FAST64_MAX__=18446744073709551615ULL",
90 | "__SIG_ATOMIC_TYPE__=int",
91 | "__DBL_MIN_10_EXP__=(-307)",
92 | "__FINITE_MATH_ONLY__=0",
93 | "__GNUC_PATCHLEVEL__=2",
94 | "__UINT_FAST8_MAX__=4294967295U",
95 | "__DEC64_MAX_EXP__=385",
96 | "__INT8_C(c)=c",
97 | "__UINT_LEAST64_MAX__=18446744073709551615ULL",
98 | "__SHRT_MAX__=32767",
99 | "__LDBL_MAX__=1.7976931348623157e+308L",
100 | "__UINT_LEAST8_MAX__=255",
101 | "__GCC_ATOMIC_BOOL_LOCK_FREE=1",
102 | "__UINTMAX_TYPE__=long long unsigned int",
103 | "__DEC32_EPSILON__=1E-6DF",
104 | "__CHAR_UNSIGNED__=1",
105 | "__UINT32_MAX__=4294967295UL",
106 | "__LDBL_MAX_EXP__=1024",
107 | "__WINT_MIN__=0U",
108 | "__SCHAR_MAX__=127",
109 | "__WCHAR_MIN__=0",
110 | "__INT64_C(c)=c ## LL",
111 | "__DBL_DIG__=15",
112 | "__GCC_ATOMIC_POINTER_LOCK_FREE=1",
113 | "__XTENSA_CALL0_ABI__=1",
114 | "__SIZEOF_INT__=4",
115 | "__SIZEOF_POINTER__=4",
116 | "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
117 | "__USER_LABEL_PREFIX__",
118 | "__STDC_HOSTED__=1",
119 | "__LDBL_HAS_INFINITY__=1",
120 | "__XTENSA_EL__=1",
121 | "__FLT_EPSILON__=1.1920928955078125e-7F",
122 | "__GXX_WEAK__=1",
123 | "__LDBL_MIN__=2.2250738585072014e-308L",
124 | "__DEC32_MAX__=9.999999E96DF",
125 | "__INT32_MAX__=2147483647L",
126 | "__SIZEOF_LONG__=4",
127 | "__UINT16_C(c)=c",
128 | "__DECIMAL_DIG__=17",
129 | "__LDBL_HAS_QUIET_NAN__=1",
130 | "__GNUC__=4",
131 | "__GXX_RTTI=1",
132 | "__FLT_HAS_DENORM__=1",
133 | "__SIZEOF_LONG_DOUBLE__=8",
134 | "__BIGGEST_ALIGNMENT__=16",
135 | "__DBL_MAX__=double(1.7976931348623157e+308L)",
136 | "__INT_FAST32_MAX__=2147483647",
137 | "__DBL_HAS_INFINITY__=1",
138 | "__INT64_MAX__=9223372036854775807LL",
139 | "__DEC32_MIN_EXP__=(-94)",
140 | "__INT_FAST16_TYPE__=int",
141 | "__LDBL_HAS_DENORM__=1",
142 | "__cplusplus=199711L",
143 | "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
144 | "__INT_LEAST32_MAX__=2147483647L",
145 | "__DEC32_MIN__=1E-95DF",
146 | "__DEPRECATED=1",
147 | "__DBL_MAX_EXP__=1024",
148 | "__DEC128_EPSILON__=1E-33DL",
149 | "__PTRDIFF_MAX__=2147483647",
150 | "__GNUG__=4",
151 | "__LONG_LONG_MAX__=9223372036854775807LL",
152 | "__SIZEOF_SIZE_T__=4",
153 | "__SIZEOF_WINT_T__=4",
154 | "__GXX_ABI_VERSION=1002",
155 | "__FLT_MIN_EXP__=(-125)",
156 | "__INT_FAST64_TYPE__=long long int",
157 | "__DBL_MIN__=double(2.2250738585072014e-308L)",
158 | "__FLT_MIN_10_EXP__=(-37)",
159 | "__DEC128_MIN__=1E-6143DL",
160 | "__REGISTER_PREFIX__",
161 | "__UINT16_MAX__=65535",
162 | "__DBL_HAS_DENORM__=1",
163 | "__UINT8_TYPE__=unsigned char",
164 | "__NO_INLINE__=1",
165 | "__FLT_MANT_DIG__=24",
166 | "__VERSION__=\"4.8.2\"",
167 | "__UINT64_C(c)=c ## ULL",
168 | "__XTENSA_SOFT_FLOAT__=1",
169 | "__GCC_ATOMIC_INT_LOCK_FREE=1",
170 | "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
171 | "__INT32_C(c)=c ## L",
172 | "__DEC64_EPSILON__=1E-15DD",
173 | "__ORDER_PDP_ENDIAN__=3412",
174 | "__DEC128_MIN_EXP__=(-6142)",
175 | "__INT_FAST32_TYPE__=int",
176 | "__UINT_LEAST16_TYPE__=short unsigned int",
177 | "__INT16_MAX__=32767",
178 | "__SIZE_TYPE__=unsigned int",
179 | "__UINT64_MAX__=18446744073709551615ULL",
180 | "__INT8_TYPE__=signed char",
181 | "__ELF__=1",
182 | "__xtensa__=1",
183 | "__FLT_RADIX__=2",
184 | "__INT_LEAST16_TYPE__=short int",
185 | "__LDBL_EPSILON__=2.2204460492503131e-16L",
186 | "__UINTMAX_C(c)=c ## ULL",
187 | "__SIG_ATOMIC_MAX__=2147483647",
188 | "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
189 | "__SIZEOF_PTRDIFF_T__=4",
190 | "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
191 | "__INT_FAST16_MAX__=2147483647",
192 | "__UINT_FAST32_MAX__=4294967295U",
193 | "__UINT_LEAST64_TYPE__=long long unsigned int",
194 | "__FLT_HAS_QUIET_NAN__=1",
195 | "__FLT_MAX_10_EXP__=38",
196 | "__LONG_MAX__=2147483647L",
197 | "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
198 | "__FLT_HAS_INFINITY__=1",
199 | "__UINT_FAST16_TYPE__=unsigned int",
200 | "__DEC64_MAX__=9.999999999999999E384DD",
201 | "__CHAR16_TYPE__=short unsigned int",
202 | "__PRAGMA_REDEFINE_EXTNAME=1",
203 | "__INT_LEAST16_MAX__=32767",
204 | "__DEC64_MANT_DIG__=16",
205 | "__UINT_LEAST32_MAX__=4294967295UL",
206 | "__GCC_ATOMIC_LONG_LOCK_FREE=1",
207 | "__INT_LEAST64_TYPE__=long long int",
208 | "__INT16_TYPE__=short int",
209 | "__INT_LEAST8_TYPE__=signed char",
210 | "__DEC32_MAX_EXP__=97",
211 | "__INT_FAST8_MAX__=2147483647",
212 | "__INTPTR_MAX__=2147483647",
213 | "__EXCEPTIONS=1",
214 | "__LDBL_MANT_DIG__=53",
215 | "__DBL_HAS_QUIET_NAN__=1",
216 | "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
217 | "__INTPTR_TYPE__=int",
218 | "__UINT16_TYPE__=short unsigned int",
219 | "__WCHAR_TYPE__=short unsigned int",
220 | "__SIZEOF_FLOAT__=4",
221 | "__UINTPTR_MAX__=4294967295U",
222 | "__DEC64_MIN_EXP__=(-382)",
223 | "__INT_FAST64_MAX__=9223372036854775807LL",
224 | "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
225 | "__FLT_DIG__=6",
226 | "__UINT_FAST64_TYPE__=long long unsigned int",
227 | "__INT_MAX__=2147483647",
228 | "__INT64_TYPE__=long long int",
229 | "__FLT_MAX_EXP__=128",
230 | "__DBL_MANT_DIG__=53",
231 | "__INT_LEAST64_MAX__=9223372036854775807LL",
232 | "__DEC64_MIN__=1E-383DD",
233 | "__WINT_TYPE__=unsigned int",
234 | "__UINT_LEAST32_TYPE__=long unsigned int",
235 | "__SIZEOF_SHORT__=2",
236 | "__LDBL_MIN_EXP__=(-1021)",
237 | "__INT_LEAST8_MAX__=127",
238 | "__WCHAR_UNSIGNED__=1",
239 | "__LDBL_MAX_10_EXP__=308",
240 | "__ATOMIC_RELAXED=0",
241 | "__DBL_EPSILON__=double(2.2204460492503131e-16L)",
242 | "__UINT8_C(c)=c",
243 | "__INT_LEAST32_TYPE__=long int",
244 | "__SIZEOF_WCHAR_T__=2",
245 | "__UINT64_TYPE__=long long unsigned int",
246 | "__INT_FAST8_TYPE__=int",
247 | "__DBL_DECIMAL_DIG__=17",
248 | "__DEC_EVAL_METHOD__=2",
249 | "__XTENSA__=1",
250 | "__ORDER_BIG_ENDIAN__=4321",
251 | "__UINT32_C(c)=c ## UL",
252 | "__INTMAX_MAX__=9223372036854775807LL",
253 | "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
254 | "__FLT_DENORM_MIN__=1.4012984643248171e-45F",
255 | "__INT8_MAX__=127",
256 | "__UINT_FAST32_TYPE__=unsigned int",
257 | "__CHAR32_TYPE__=long unsigned int",
258 | "__FLT_MAX__=3.4028234663852886e+38F",
259 | "__INT32_TYPE__=long int",
260 | "__SIZEOF_DOUBLE__=8",
261 | "__INTMAX_TYPE__=long long int",
262 | "__DEC128_MAX_EXP__=6145",
263 | "__ATOMIC_CONSUME=1",
264 | "__GNUC_MINOR__=8",
265 | "__UINTMAX_MAX__=18446744073709551615ULL",
266 | "__DEC32_MANT_DIG__=7",
267 | "__DBL_MAX_10_EXP__=308",
268 | "__LDBL_DENORM_MIN__=4.9406564584124654e-324L",
269 | "__INT16_C(c)=c",
270 | "__STDC__=1",
271 | "__PTRDIFF_TYPE__=int",
272 | "__ATOMIC_SEQ_CST=5",
273 | "__UINT32_TYPE__=long unsigned int",
274 | "__UINTPTR_TYPE__=unsigned int",
275 | "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
276 | "__DEC128_MANT_DIG__=34",
277 | "__LDBL_MIN_10_EXP__=(-307)",
278 | "__SIZEOF_LONG_LONG__=8",
279 | "__GCC_ATOMIC_LLONG_LOCK_FREE=1",
280 | "__LDBL_DIG__=15",
281 | "__FLT_DECIMAL_DIG__=9",
282 | "__UINT_FAST16_MAX__=4294967295U",
283 | "__GNUC_GNU_INLINE__=1",
284 | "__GCC_ATOMIC_SHORT_LOCK_FREE=1",
285 | "__UINT_FAST8_TYPE__=unsigned int",
286 | "__ATOMIC_ACQ_REL=4",
287 | "__ATOMIC_RELEASE=3",
288 | "USBCON"
289 | ]
290 | }
291 | ]
292 | }
--------------------------------------------------------------------------------
/examples/Number-select/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_Cpp.errorSquiggles": "Enabled",
3 | "files.associations": {
4 | "memory": "cpp",
5 | "array": "cpp",
6 | "deque": "cpp",
7 | "initializer_list": "cpp",
8 | "list": "cpp",
9 | "vector": "cpp",
10 | "xhash": "cpp",
11 | "xstring": "cpp",
12 | "xtree": "cpp",
13 | "xutility": "cpp",
14 | "string": "cpp",
15 | "unordered_map": "cpp",
16 | "unordered_set": "cpp",
17 | "string_view": "cpp"
18 | }
19 | }
--------------------------------------------------------------------------------
/examples/Number-select/Number-select.ino:
--------------------------------------------------------------------------------
1 | #include "AiEsp32RotaryEncoder.h"
2 | #include "AiEsp32RotaryEncoderNumberSelector.h"
3 | #if defined(ESP8266)
4 | #define ROTARY_ENCODER_A_PIN D6
5 | #define ROTARY_ENCODER_B_PIN D5
6 | #define ROTARY_ENCODER_BUTTON_PIN D7
7 | #else
8 | #define ROTARY_ENCODER_A_PIN 32
9 | #define ROTARY_ENCODER_B_PIN 21
10 | #define ROTARY_ENCODER_BUTTON_PIN 25
11 | #endif
12 | #define ROTARY_ENCODER_STEPS 4
13 | AiEsp32RotaryEncoder *rotaryEncoder = new AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, -1, ROTARY_ENCODER_STEPS);
14 | AiEsp32RotaryEncoderNumberSelector numberSelector = AiEsp32RotaryEncoderNumberSelector();
15 | /*
16 | In this example an additional functionality is used.
17 |
18 | AiEsp32RotaryEncoderNumberSelector is that additional helper which will hide calculation for a rotary encoder.
19 |
20 | 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
21 | In example 2 - you can select some frequency between 6999000 and 7000000 Hz in steps by 10 Hz; using precision of 0 decimal (integer)
22 |
23 | Internally AiEsp32RotaryEncoderNumberSelector will do the math and set the most apropriate acceleration, min and max values for you
24 |
25 | use setRange to set parameters
26 | use setValue for a default/initial value
27 | and finally read the value with getValue
28 |
29 | So, this value is actually value you need
30 |
31 | In code bellow comment / uncomment example 1 or 2
32 | */
33 |
34 | void IRAM_ATTR readEncoderISR()
35 | {
36 | rotaryEncoder->readEncoder_ISR();
37 | }
38 |
39 | void setup()
40 | {
41 | Serial.begin(115200);
42 | rotaryEncoder->begin();
43 | rotaryEncoder->setup(readEncoderISR);
44 | numberSelector.attachEncoder(rotaryEncoder);
45 |
46 | /*
47 | numberSelector.setRange parameters:
48 | float minValue, set minimum value for example -12.0
49 | float maxValue, set maximum value for example 31.5
50 | float step, set step increment, default 1, can be smaller steps like 0.5 or 10
51 | bool cycleValues, set true only if you want going to miminum value after maximum
52 | unsigned int decimals = 0 precision - how many decimal places you want, default is 0
53 |
54 | numberSelector.setValue - sets initial value
55 | */
56 |
57 | //example 1
58 | //numberSelector.setRange(-12.0, 31.5, 0.5, false, 1);
59 | //numberSelector.setValue(24.3);
60 | //example 2
61 | numberSelector.setRange(6999000.0, 7000000.0, 10, false, 0);
62 | numberSelector.setValue(6999500.0);
63 | }
64 |
65 | void loop()
66 | {
67 | if (rotaryEncoder->encoderChanged())
68 | {
69 | Serial.print(numberSelector.getValue());
70 | Serial.println(" ");
71 | }
72 |
73 | if (rotaryEncoder->isEncoderButtonClicked())
74 | {
75 | Serial.print("Selected value is ");
76 | Serial.print(numberSelector.getValue(), 1);
77 | Serial.println(" ***********************");
78 | }
79 | }
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=Ai Esp32 Rotary Encoder
2 | version=1.7
3 | author=Igor Antolic (adapted code from github.com/marcmerlin/IoTuz)
4 | maintainer=Igor Antolic
5 | sentence=Easy implement rotary encoder to your application for ESP32 and ESP8266
6 | paragraph=Supports acceleration, setting boundaries. Works with ESP32 and ESP8266. Use version 1.3 for better button handling and updated examples. AiEsp32RotaryEncoderNumberSelector helps select numbers in range. Example: -12 do 31.5 in steps of 0.5.
7 | category=Device Control
8 | url=https://github.com/igorantolic/ai-esp32-rotary-encoder.git
9 | architectures=esp32,esp8266
10 |
--------------------------------------------------------------------------------
/src/AiEsp32RotaryEncoder.cpp:
--------------------------------------------------------------------------------
1 | // based on https://github.com/marcmerlin/IoTuz code - extracted and modified Encoder code
2 | //
3 | //
4 |
5 | #if defined(ESP8266)
6 | #else
7 | #include "esp_log.h"
8 | #define LOG_TAG "AiEsp32RotaryEncoder"
9 | #endif
10 |
11 | #include "AiEsp32RotaryEncoder.h"
12 |
13 | #if defined(ESP8266)
14 | ICACHE_RAM_ATTR void AiEsp32RotaryEncoder::readEncoder_ISR()
15 | #else
16 | void IRAM_ATTR AiEsp32RotaryEncoder::readEncoder_ISR()
17 | #endif
18 | {
19 |
20 | unsigned long now = millis();
21 | #if defined(ESP8266)
22 | #else
23 | portENTER_CRITICAL_ISR(&(this->mux));
24 | #endif
25 | if (this->isEnabled)
26 | {
27 | // code from https://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino/
28 | /**/
29 | this->old_AB <<= 2; // remember previous state
30 |
31 | int8_t ENC_PORT = ((digitalRead(this->encoderBPin)) ? (1 << 1) : 0) | ((digitalRead(this->encoderAPin)) ? (1 << 0) : 0);
32 |
33 | this->old_AB |= (ENC_PORT & 0x03); // add current state
34 |
35 | // this->encoder0Pos += ( this->enc_states[( this->old_AB & 0x0f )]);
36 | int8_t currentDirection = (this->enc_states[(this->old_AB & 0x0f)]); //-1,0 or 1
37 |
38 | if (currentDirection != 0)
39 | {
40 | // bool ignoreCorrection = false;
41 | // if (this->encoder0Pos > this->_maxEncoderValue) ignoreCorrection = true;
42 | // if (this->encoder0Pos < this->_minEncoderValue) ignoreCorrection = true;
43 | long prevRotaryPosition = this->encoder0Pos / this->encoderSteps;
44 | this->encoder0Pos += currentDirection;
45 | long newRotaryPosition = this->encoder0Pos / this->encoderSteps;
46 |
47 | if (newRotaryPosition != prevRotaryPosition && rotaryAccelerationCoef > 1)
48 | {
49 | // additional movements cause acceleration?
50 | // at X ms, there should be no acceleration.
51 | unsigned long accelerationLongCutoffMillis = 200;
52 | // at Y ms, we want to have maximum acceleration
53 | unsigned long accelerationShortCutffMillis = 4;
54 |
55 | // compute linear acceleration
56 | if (currentDirection == lastMovementDirection &&
57 | currentDirection != 0 &&
58 | lastMovementDirection != 0)
59 | {
60 | // ... but only of the direction of rotation matched and there
61 | // actually was a previous rotation.
62 | unsigned long millisAfterLastMotion = now - lastMovementAt;
63 |
64 | if (millisAfterLastMotion < accelerationLongCutoffMillis)
65 | {
66 | if (millisAfterLastMotion < accelerationShortCutffMillis)
67 | {
68 | millisAfterLastMotion = accelerationShortCutffMillis; // limit to maximum acceleration
69 | }
70 | if (currentDirection > 0)
71 | {
72 | this->encoder0Pos += rotaryAccelerationCoef / millisAfterLastMotion;
73 | }
74 | else
75 | {
76 | this->encoder0Pos -= rotaryAccelerationCoef / millisAfterLastMotion;
77 | }
78 | }
79 | }
80 | this->lastMovementAt = now;
81 | this->lastMovementDirection = currentDirection;
82 | }
83 |
84 | // https://github.com/igorantolic/ai-esp32-rotary-encoder/issues/40
85 | /*
86 | when circling there is an issue since encoderSteps is tipically 4
87 | that means 4 changes for a single roary movement (step)
88 | so if maximum is 4 that means _maxEncoderValue is 4*4=16
89 | when we detact 18 we cannot go to zero since next 2 will make it wild
90 | Here we changed to 18 set not to 0 but to -2; 17 to -3...
91 | Now it seems better however that -3 divided with 4 will give -1 which is not regular -> also readEncoder() is changed to give allowed values
92 | It is not yet perfect for cycling options but it is much better than before
93 |
94 | optimistic view was that most of the time encoder0Pos values will be near to N*encodersteps
95 | */
96 | // respect limits
97 | if ((this->encoder0Pos / this->encoderSteps) > (this->_maxEncoderValue / this->encoderSteps))
98 | {
99 | // Serial.print("circle values limit HIGH");
100 | // Serial.print(this->encoder0Pos);
101 | // this->encoder0Pos = this->_circleValues ? this->_minEncoderValue : this->_maxEncoderValue;
102 | if (_circleValues)
103 | {
104 | // if (!ignoreCorrection){
105 | int delta = this->_maxEncoderValue + this->encoderSteps - this->encoder0Pos;
106 | this->encoder0Pos = this->_minEncoderValue - delta;
107 | //}
108 | }
109 | else
110 | {
111 | this->encoder0Pos = this->_maxEncoderValue;
112 | }
113 | // this->encoder0Pos = this->_circleValues ? (this->_minEncoderValue this->encoder0Pos-this->encoderSteps) : this->_maxEncoderValue;
114 | // Serial.print(" -> ");
115 | // Serial.println(this->encoder0Pos);
116 | }
117 | else if ((this->encoder0Pos / this->encoderSteps) < (this->_minEncoderValue / this->encoderSteps))
118 | {
119 | // Serial.print("circle values limit LOW");
120 | // Serial.print(this->encoder0Pos);
121 | // this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue;
122 | this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue;
123 | if (_circleValues)
124 | {
125 | // if (!ignoreCorrection){
126 | int delta = this->_minEncoderValue + this->encoderSteps + this->encoder0Pos;
127 | this->encoder0Pos = this->_maxEncoderValue + delta;
128 | //}
129 | }
130 | else
131 | {
132 | this->encoder0Pos = this->_minEncoderValue;
133 | }
134 |
135 | // Serial.print(" -> ");
136 | // Serial.println(this->encoder0Pos);
137 | }
138 | else
139 | {
140 | // Serial.print("no circle values limit ");
141 | // Serial.println(this->encoder0Pos);
142 | }
143 | // Serial.println(this->encoder0Pos);
144 | }
145 | }
146 | #if defined(ESP8266)
147 | #else
148 | portEXIT_CRITICAL_ISR(&(this->mux));
149 | #endif
150 | }
151 |
152 | #if defined(ESP8266)
153 | ICACHE_RAM_ATTR void AiEsp32RotaryEncoder::readButton_ISR()
154 | #else
155 | void IRAM_ATTR AiEsp32RotaryEncoder::readButton_ISR()
156 | #endif
157 | {
158 | #if defined(ESP8266)
159 | #else
160 | portENTER_CRITICAL_ISR(&(this->buttonMux));
161 | #endif
162 |
163 | uint8_t butt_state = !digitalRead(this->encoderButtonPin);
164 |
165 | if (!this->isEnabled)
166 | {
167 | buttonState = BUT_DISABLED;
168 | }
169 | else if (butt_state && !this->previous_butt_state)
170 | {
171 | this->previous_butt_state = true;
172 | Serial.println("Button Pushed");
173 | buttonState = BUT_PUSHED;
174 | }
175 | else if (!butt_state && this->previous_butt_state)
176 | {
177 | this->previous_butt_state = false;
178 | Serial.println("Button Released");
179 | buttonState = BUT_RELEASED;
180 | }
181 | else
182 | {
183 | buttonState = (butt_state ? BUT_DOWN : BUT_UP);
184 | Serial.println(butt_state ? "BUT_DOWN" : "BUT_UP");
185 | }
186 |
187 | #if defined(ESP8266)
188 | #else
189 | portEXIT_CRITICAL_ISR(&(this->buttonMux));
190 | #endif
191 | }
192 |
193 | AiEsp32RotaryEncoder::AiEsp32RotaryEncoder(uint8_t encoder_APin, uint8_t encoder_BPin, int encoder_ButtonPin, int encoder_VccPin, uint8_t encoderSteps, bool areEncoderPinsPulldown_forEsp32)
194 | {
195 | this->old_AB = 0;
196 |
197 | this->encoderAPin = encoder_APin;
198 | this->encoderBPin = encoder_BPin;
199 | this->encoderButtonPin = encoder_ButtonPin;
200 | this->encoderVccPin = encoder_VccPin;
201 | this->encoderSteps = encoderSteps;
202 | areEncoderPinsPulldownforEsp32 = areEncoderPinsPulldown_forEsp32;
203 | #if defined(ESP8266)
204 | pinMode(this->encoderAPin, INPUT_PULLUP);
205 | pinMode(this->encoderBPin, INPUT_PULLUP);
206 | #else
207 | pinMode(this->encoderAPin, (areEncoderPinsPulldownforEsp32 ? INPUT_PULLDOWN : INPUT_PULLUP));
208 | pinMode(this->encoderBPin, (areEncoderPinsPulldownforEsp32 ? INPUT_PULLDOWN : INPUT_PULLUP));
209 | #endif
210 | }
211 |
212 | void AiEsp32RotaryEncoder::setBoundaries(long minEncoderValue, long maxEncoderValue, bool circleValues)
213 | {
214 | this->_minEncoderValue = minEncoderValue * this->encoderSteps;
215 | this->_maxEncoderValue = maxEncoderValue * this->encoderSteps;
216 |
217 | this->_circleValues = circleValues;
218 | }
219 |
220 | long AiEsp32RotaryEncoder::readEncoder()
221 | {
222 | // return (this->encoder0Pos / this->encoderSteps);
223 | if ((this->encoder0Pos / this->encoderSteps) > (this->_maxEncoderValue / this->encoderSteps))
224 | return this->_maxEncoderValue / this->encoderSteps;
225 | if ((this->encoder0Pos / this->encoderSteps) < (this->_minEncoderValue / this->encoderSteps))
226 | return this->_minEncoderValue / this->encoderSteps;
227 | return (this->encoder0Pos / this->encoderSteps);
228 | }
229 |
230 | void AiEsp32RotaryEncoder::setEncoderValue(long newValue)
231 | {
232 | reset(newValue);
233 | }
234 |
235 | long AiEsp32RotaryEncoder::encoderChanged()
236 | {
237 | long _encoder0Pos = readEncoder();
238 | long encoder0Diff = _encoder0Pos - this->lastReadEncoder0Pos;
239 |
240 | this->lastReadEncoder0Pos = _encoder0Pos;
241 |
242 | return encoder0Diff;
243 | }
244 |
245 | void AiEsp32RotaryEncoder::setup(void (*ISR_callback)(void), void (*ISR_button)(void))
246 | {
247 | attachInterrupt(digitalPinToInterrupt(this->encoderAPin), ISR_callback, CHANGE);
248 | attachInterrupt(digitalPinToInterrupt(this->encoderBPin), ISR_callback, CHANGE);
249 | if (this->encoderButtonPin >= 0)
250 | attachInterrupt(digitalPinToInterrupt(this->encoderButtonPin), ISR_button, RISING);
251 | // attachInterrupt(digitalPinToInterrupt(this->encoderButtonPin), ISR_button, CHANGE);
252 | }
253 |
254 | void AiEsp32RotaryEncoder::setup(void (*ISR_callback)(void))
255 | {
256 | attachInterrupt(digitalPinToInterrupt(this->encoderAPin), ISR_callback, CHANGE);
257 | attachInterrupt(digitalPinToInterrupt(this->encoderBPin), ISR_callback, CHANGE);
258 | }
259 |
260 | void AiEsp32RotaryEncoder::begin()
261 | {
262 | this->lastReadEncoder0Pos = 0;
263 | if (this->encoderVccPin >= 0)
264 | {
265 | pinMode(this->encoderVccPin, OUTPUT);
266 | digitalWrite(this->encoderVccPin, 1); // Vcc for encoder
267 | }
268 |
269 | // Initialize rotary encoder reading and decoding
270 | this->previous_butt_state = 0;
271 | if (this->encoderButtonPin >= 0)
272 | {
273 |
274 | #if defined(ESP8266)
275 | pinMode(this->encoderButtonPin, INPUT_PULLUP);
276 | #else
277 | pinMode(this->encoderButtonPin, isButtonPulldown ? INPUT_PULLDOWN : INPUT_PULLUP);
278 | #endif
279 | }
280 | }
281 |
282 | ButtonState AiEsp32RotaryEncoder::currentButtonState()
283 | {
284 | return buttonState;
285 | }
286 |
287 | ButtonState AiEsp32RotaryEncoder::readButtonState()
288 | {
289 | return buttonState;
290 | }
291 |
292 | void AiEsp32RotaryEncoder::reset(long newValue_)
293 | {
294 | newValue_ = newValue_ * this->encoderSteps;
295 | this->encoder0Pos = newValue_ + this->correctionOffset;
296 | this->lastReadEncoder0Pos = this->encoder0Pos;
297 | if (this->encoder0Pos > this->_maxEncoderValue)
298 | this->encoder0Pos = this->_circleValues ? this->_minEncoderValue : this->_maxEncoderValue;
299 | if (this->encoder0Pos < this->_minEncoderValue)
300 | this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue;
301 |
302 | this->lastReadEncoder0Pos = this->readEncoder();
303 | }
304 |
305 | void AiEsp32RotaryEncoder::enable()
306 | {
307 | this->isEnabled = true;
308 | }
309 | void AiEsp32RotaryEncoder::disable()
310 | {
311 | this->isEnabled = false;
312 | }
313 |
314 | bool AiEsp32RotaryEncoder::isEncoderButtonClicked(unsigned long maximumWaitMilliseconds)
315 | {
316 | static bool wasTimeouted = false;
317 | int button = 1 - digitalRead(encoderButtonPin);
318 | if (!button)
319 | {
320 | if (wasTimeouted)
321 | {
322 | wasTimeouted = false;
323 | return true;
324 | }
325 | return false;
326 | }
327 | delay(30); // debounce
328 | button = 1 - digitalRead(encoderButtonPin);
329 | if (!button)
330 | {
331 | return false;
332 | }
333 |
334 | // wait release of button but only maximumWaitMilliseconds
335 | wasTimeouted = false;
336 | unsigned long waitUntil = millis() + maximumWaitMilliseconds;
337 | while (1 - digitalRead(encoderButtonPin))
338 | {
339 | if (millis() > waitUntil)
340 | {
341 | // button not released until timeout
342 | wasTimeouted = true;
343 | return false;
344 | }
345 | }
346 |
347 | return true;
348 | }
349 |
350 | bool AiEsp32RotaryEncoder::isEncoderButtonDown()
351 | {
352 | return digitalRead(encoderButtonPin) ? false : true;
353 | }
354 |
--------------------------------------------------------------------------------
/src/AiEsp32RotaryEncoder.h:
--------------------------------------------------------------------------------
1 | // AiEsp32RotaryEncoder.h
2 | // based on https://github.com/marcmerlin/IoTuz code - extracted and modified Encoder code
3 |
4 | #ifndef _AIESP32ROTARYENCODER_h
5 | #define _AIESP32ROTARYENCODER_h
6 |
7 | #if defined(ARDUINO) && ARDUINO >= 100
8 | #include "Arduino.h"
9 | #else
10 | #include "WProgram.h"
11 | #endif
12 |
13 | // Rotary Encocer
14 | #define AIESP32ROTARYENCODER_DEFAULT_A_PIN 25
15 | #define AIESP32ROTARYENCODER_DEFAULT_B_PIN 26
16 | #define AIESP32ROTARYENCODER_DEFAULT_BUT_PIN 15
17 | #define AIESP32ROTARYENCODER_DEFAULT_VCC_PIN -1
18 | #define AIESP32ROTARYENCODER_DEFAULT_STEPS 2
19 |
20 | typedef enum
21 | {
22 | BUT_DOWN = 0,
23 | BUT_PUSHED = 1,
24 | BUT_UP = 2,
25 | BUT_RELEASED = 3,
26 | BUT_DISABLED = 99,
27 | } ButtonState;
28 |
29 | class AiEsp32RotaryEncoder
30 | {
31 |
32 | private:
33 | #if defined(ESP8266)
34 | #else
35 | portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
36 | portMUX_TYPE buttonMux = portMUX_INITIALIZER_UNLOCKED;
37 | #endif
38 | volatile long encoder0Pos = 0;
39 |
40 | volatile int8_t lastMovementDirection = 0; // 1 right; -1 left
41 | volatile unsigned long lastMovementAt = 0;
42 | unsigned long rotaryAccelerationCoef = 150;
43 |
44 | bool _circleValues = false;
45 | bool isEnabled = true;
46 |
47 | uint8_t encoderAPin = AIESP32ROTARYENCODER_DEFAULT_A_PIN;
48 | uint8_t encoderBPin = AIESP32ROTARYENCODER_DEFAULT_B_PIN;
49 | int encoderButtonPin = AIESP32ROTARYENCODER_DEFAULT_BUT_PIN;
50 | int encoderVccPin = AIESP32ROTARYENCODER_DEFAULT_VCC_PIN;
51 | long encoderSteps = AIESP32ROTARYENCODER_DEFAULT_STEPS;
52 |
53 | long _minEncoderValue = -2147483648; // -1 << 15;
54 | long _maxEncoderValue = 2147483647; // 1 << 15;
55 |
56 | int8_t old_AB;
57 | long lastReadEncoder0Pos;
58 | bool previous_butt_state;
59 |
60 | ButtonState buttonState;
61 |
62 | int8_t enc_states[16] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
63 | void (*ISR_callback)();
64 | void (*ISR_button)();
65 |
66 | public:
67 | AiEsp32RotaryEncoder(
68 | uint8_t encoderAPin = AIESP32ROTARYENCODER_DEFAULT_A_PIN,
69 | uint8_t encoderBPin = AIESP32ROTARYENCODER_DEFAULT_B_PIN,
70 | int encoderButtonPin = AIESP32ROTARYENCODER_DEFAULT_BUT_PIN,
71 | int encoderVccPin = AIESP32ROTARYENCODER_DEFAULT_VCC_PIN,
72 | uint8_t encoderSteps = AIESP32ROTARYENCODER_DEFAULT_STEPS,
73 | bool areEncoderPinsPulldown_forEsp32 = true);
74 | void setBoundaries(long minValue = -100, long maxValue = 100, bool circleValues = false);
75 | int correctionOffset = 2;
76 | bool isButtonPulldown = false;
77 | bool areEncoderPinsPulldownforEsp32 = true;
78 | #if defined(ESP8266)
79 | ICACHE_RAM_ATTR void readEncoder_ISR();
80 | ICACHE_RAM_ATTR void readButton_ISR();
81 | #else
82 | void IRAM_ATTR readEncoder_ISR();
83 | void IRAM_ATTR readButton_ISR();
84 |
85 | #endif
86 |
87 | void setup(void (*ISR_callback)(void));
88 | void setup(void (*ISR_callback)(void), void (*ISR_button)(void));
89 | void begin();
90 | void reset(long newValue = 0);
91 | void enable();
92 | void disable();
93 | long readEncoder();
94 | void setEncoderValue(long newValue);
95 | long encoderChanged();
96 | ButtonState currentButtonState();
97 | ButtonState readButtonState();
98 | unsigned long getAcceleration() { return this->rotaryAccelerationCoef; }
99 | void setAcceleration(unsigned long acceleration) { this->rotaryAccelerationCoef = acceleration; }
100 | void disableAcceleration() { setAcceleration(0); }
101 |
102 | bool isEncoderButtonClicked(unsigned long maximumWaitMilliseconds = 300);
103 | bool isEncoderButtonDown();
104 | };
105 | #endif
106 |
--------------------------------------------------------------------------------
/src/AiEsp32RotaryEncoderNumberSelector.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/igorantolic/ai-esp32-rotary-encoder/6f7f6cc446424cccc4f58a39220550f2d438a86f/src/AiEsp32RotaryEncoderNumberSelector.cpp
--------------------------------------------------------------------------------
/src/AiEsp32RotaryEncoderNumberSelector.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
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 | };
92 |
--------------------------------------------------------------------------------