├── .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 | --------------------------------------------------------------------------------