{"id":2234,"date":"2016-12-17T11:47:03","date_gmt":"2016-12-17T02:47:03","guid":{"rendered":"http:\/\/jumbleat.com\/?p=2234"},"modified":"2017-10-22T19:28:17","modified_gmt":"2017-10-22T10:28:17","slug":"encoder_1","status":"publish","type":"post","link":"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/","title":{"rendered":"Using rotary encoder <span class=\"sub_title\">part 1 : attachInterrupt<\/span>"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_80 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">\u76ee\u6b21 [ Contents ]<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69d6308e43035\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #757575;color:#757575\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #757575;color:#757575\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69d6308e43035\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#What_is_a_rotary_encoder\" >What is a rotary encoder?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#Wiring\" >Wiring<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#AttachInterrupt\" >AttachInterrupt<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#Reading_the_rotary_encoder\" >Reading the rotary encoder<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#1_Check_the_state\" >1. Check the state<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#2_Dividing_into_patterns\" >2.\u00a0Dividing into patterns<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#3_To_detect_the_direction\" >3. To detect\u00a0the direction<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#4_Counting_by_encoder\" >4.\u00a0Counting by encoder<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#5_Separating_interrupt_and_count_addition_processing\" >5. Separating interrupt and count addition processing<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#Summary_Sketch\" >Summary Sketch<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/#Sketch_Brightness_adjustment_of_LED_by_rotary_encoder\" >Sketch : Brightness adjustment of LED by rotary encoder<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<p><\/p>\n<div id=\"prolog\">\n<p>If you want to control the value step by step with Arduino, it is a quick way to &#8216;analogRead&#8217; using a variable resistor. \u3001But,<!--more--> there are another way to use <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rotary_encoder\" target=\"_blank\" rel=\"noopener\">rotary encoder<\/a>. However, if you try to implement it, there are practically difficult aspects. It is a so-called\u00a0<a href=\"https:\/\/jumbleat.com\/2016\/08\/19\/switch_without_chatter\/\" target=\"_blank\" rel=\"noopener\">chattering problem<\/a>.<\/p>\n<p>I would like to write a method that can be avoiding problems encountered in using rotary encoders on this article.<\/p>\n<p style=\"font-size: 85%; color: #777;\">If you want to use &#8220;non-click&#8221; type Rotary Encoder, check <a href=\"https:\/\/jumbleat.com\/2017\/04\/20\/encoder_2\/\" target=\"_blank\" rel=\"noopener noreferrer\">Part 2<\/a>. (21\/4\/2017)<br \/>\n If you want use without &#8220;attachinterrupt&#8221;, check <a href=\"https:\/\/jumbleat.com\/2017\/10\/22\/encoder_3\/\" target=\"_blank\" rel=\"noopener\">Part 3<\/a>.\u00a0(22\/10\/2017)<\/p>\n<p class=\"mtm\"><small>The explanation in this article is a method that I thought during make my own &#8216;follow focus&#8217;.<\/small><\/p>\n<p><div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"\u300cAR-FOCUS\u300d Arduino\u3067\u4f5c\u308b\u81ea\u4f5c\u30d5\u30a9\u30ed\u30fc\u30d5\u30a9\u30fc\u30ab\u30b9\" width=\"660\" height=\"371\" src=\"https:\/\/www.youtube.com\/embed\/XnipKRHAZ5U?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/p>\n<\/div>\n<div id=\"chap_1\">\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"What_is_a_rotary_encoder\"><\/span>What is a rotary encoder?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"caution\">There are two types of rotary encoder, but in this article I will only deal with incremental type.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2425\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_1.jpg\" alt=\"\" width=\"825\" height=\"300\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_1.jpg 825w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_1-300x109.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_1-768x279.jpg 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><\/p>\n<p>The rotary encoder is a knob that rotates just like a variable resistor. But, the structure is completely different. Its structure is a continuous switch, so it turns on and off depending on the turning angle.\u00a0You can see whether this knob moved or not, by this mechanism.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2311 size-full alignnone\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/1step_gear_enc_anim.gif\" width=\"400\" height=\"200\" \/><\/p>\n<p>However, with this, it can not tell its direction. Therefore, there are two contact points in rotary encoder, and which is slightly misaligned.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2312 size-full\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/2step_gear_anim.gif\" width=\"500\" height=\"230\" \/><\/p>\n<p>Considering the two contact states collectively, it can tell the direction by patterns.\u00a0This is how a rotary encoder works.<\/p>\n<table style=\"width: 95%;\">\n<tbody>\n<tr>\n<td style=\"background-color: #fcfcfc;\">A<\/td>\n<td style=\"width: 15%; background-color: #0000ff;\"><span style=\"color: #ffffff;\">0<\/span><\/td>\n<td style=\"width: 15%; background-color: #b0b0ff;\">1<\/td>\n<td style=\"width: 15%; background-color: #b0b0ff;\">1<\/td>\n<td style=\"width: 15%; background-color: #0000ff;\"><span style=\"color: #ffffff;\">0<\/span><\/td>\n<td style=\"width: 15%;\">\uff5e<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc;\">B<\/td>\n<td style=\"width: 15%; background-color: #b0b000;\">0<\/td>\n<td style=\"width: 15%; background-color: #b0b000;\">0<\/td>\n<td style=\"width: 15%; background-color: #f0f000;\">1<\/td>\n<td style=\"width: 15%; background-color: #f0f000;\">1<\/td>\n<td style=\"width: 15%;\">\uff5e<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div id=\"chap_2\">\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Wiring\"><\/span>Wiring<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul class=\"ls_algn\">\n<li>Rotary encoder with click function<\/li>\n<li>Tact switch<\/li>\n<li>LED &amp; resistor\u3000* 2<\/li>\n<\/ul>\n<p class=\"mtm\"><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/Rotary_encoder_normal_breadboard.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2339\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/Rotary_encoder_normal_breadboard.png\" alt=\"\" width=\"1749\" height=\"945\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/Rotary_encoder_normal_breadboard.png 1749w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/Rotary_encoder_normal_breadboard-300x162.png 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/Rotary_encoder_normal_breadboard-768x415.png 768w\" sizes=\"auto, (max-width: 1749px) 100vw, 1749px\" \/><\/a><\/p>\n<p>Rotary encoders have two types of click and unclick. Click type have a clicking feel when it&#8217;s rotated. In this article, I will use it.<\/p>\n<p class=\"mtm\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2426\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_2.jpg\" alt=\"\" width=\"825\" height=\"280\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_2.jpg 825w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_2-300x102.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_2-768x261.jpg 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><\/p>\n<p><iframe loading=\"lazy\" width=\"468\" height=\"336\" style=\"border: none;\" src=\"https:\/\/rcm-fe.amazon-adsystem.com\/e\/cm?t=jumbleat-22&amp;o=9&amp;p=16&amp;l=st1&amp;mode=hi-jp&amp;search=\u30ed\u30fc\u30bf\u30ea\u30fc\u30a8\u30f3\u30b3\u30fc\u30c0&amp;fc1=000000&amp;lt1=_blank&amp;lc1=3366FF&amp;bg1=FFFFFF&amp;f=ifr\" marginwidth=\"0\" marginheight=\"0\" border=\"0\" frameborder=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<\/div>\n<div id=\"chap_3\">\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"AttachInterrupt\"><\/span>AttachInterrupt<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Generally, &#8220;attachinterrupt&#8221; is used when you use rotary encoder. &#8220;attachinterrupt&#8221; is a function that monitors the state of the digital pin at all times and executes the specified function preferentially when detecting a specific change.<\/p>\n<pre class=\"lang:default mark:9-10,19 decode:true\" title=\"sample 0:attachinterrupt\">#define ENC_A 2\r\n#define ENC_B 3\r\n\r\n\r\nvoid setup() {\r\n  pinMode(ENC_A, INPUT_PULLUP);\r\n  pinMode(ENC_B, INPUT_PULLUP);\r\n\r\n  attachInterrupt(0, ENC_READ, CHANGE);\r\n  attachInterrupt(1, ENC_READ, CHANGE);\r\n\r\n  Serial.begin(38400);\r\n}\r\n\r\n\r\nvoid loop() {}\r\n\r\n\r\nvoid ENC_READ() {}<\/pre>\n<p class=\"spacer\">As mentioned above, it is usual to specify &#8220;attachinterrupt&#8221; in the &#8216;setup&#8217; function. Although Pins that can be used for &#8216;attachinterrupt&#8217; depend on the type of Arduino, but in this case, Arduino UNO has D2 and D3 pins.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false toolbar-delay:false marking:false ranges:false wrap-toggle:false start-line:9 copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"attach interrupt setting\">attachInterrupt(0, ENC_READ, CHANGE);\r\nattachInterrupt(1, ENC_READ, CHANGE);<\/pre>\n<p class=\"mtm\">In the attachInterrupt function (argument of pin number, function to be executed, condition to be executed) is specified.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2427\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_3.jpg\" alt=\"\" width=\"500\" height=\"200\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_3.jpg 500w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_3-300x120.jpg 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<h4 class=\"uLLine mtn mbs\">Pin number<\/h4>\n<p>Be careful that it&#8217;s not pin numbers in Arduino but it&#8217;s number for pins which is correspond to external interrupts. For ArduinoUNO, the D2 pin is 0 and the D3 pin is 1.<\/p>\n<h4 class=\"uLLine mtn mbs\">Function to be executed<\/h4>\n<p>This is the function name to be executed when a change is detected. In this article it is set to &#8220;ENC_READ&#8221;. But like general function rule, it is OK with arbitrary name unless you use reserved function name.<\/p>\n<h4 class=\"uLLine mtn mbs\">Conditions to be executed<\/h4>\n<p class=\"mbm\">Specify what kind of state the designated pin will respond. There are several conditions, and specify it with the following character strings.<\/p>\n<table style=\"width: 100%;\">\n<tbody>\n<tr style=\"background-color: #eee;\">\n<td style=\"width: 30%;\">strings<\/td>\n<td>explanation<\/td>\n<\/tr>\n<tr>\n<td>LOW<\/td>\n<td style=\"font-size: 85%;\">When the pin goes LOW<\/td>\n<\/tr>\n<tr>\n<td>CHANGE<\/td>\n<td style=\"font-size: 85%;\">When the pin goes changed<\/td>\n<\/tr>\n<tr>\n<td>RISING<\/td>\n<td style=\"font-size: 85%;\">When the pin goes\u00a0HIGH<\/td>\n<\/tr>\n<tr>\n<td>FALLING<\/td>\n<td style=\"font-size: 85%;\">When the pin turns to LOW from HIGH<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div id=\"chap_4\">\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Reading_the_rotary_encoder\"><\/span>Reading the rotary encoder<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3 class=\"h3_HLine mts mbs\"><span class=\"ez-toc-section\" id=\"1_Check_the_state\"><\/span>1. Check the state<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>First, I will write a sketch that can always check the encoder&#8217;s status. The result is displayed on &#8216;serial monitor&#8217;.<\/p>\n<pre class=\"lang:default range:19-34 decode:true\" title=\"sample 1-1\uff1aConfirm pin status\">#define ENC_A 2\r\n#define ENC_B 3\r\n\r\n\r\nvoid setup() {\r\n  pinMode(ENC_A, INPUT_PULLUP);\r\n  pinMode(ENC_B, INPUT_PULLUP);\r\n\r\n  attachInterrupt(0, ENC_READ, CHANGE);\r\n  attachInterrupt(1, ENC_READ, CHANGE);\r\n\r\n  Serial.begin(38400);\r\n}\r\n\r\n\r\nvoid loop() {}\r\n\r\n\r\nvoid ENC_READ() {\r\n  bool cur[2];\r\n\r\n  cur[0] = !digitalRead(ENC_A);\r\n  cur[1] = !digitalRead(ENC_B);\r\n\r\n  Serial.print(\"A:\");\r\n  Serial.print(cur[0]);\r\n  Serial.print(\" \");\r\n\r\n  Serial.print(\"B:\");\r\n  Serial.print(cur[1]);\r\n\r\n  Serial.println();\r\n}<\/pre>\n<p class=\"mtm\">If it detect a pin change, repeat simply reading both pin states (cur [0], cur [1]) and returning the result in &#8216;Serial monitor&#8217;.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2344 size-full\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon1.jpg\" width=\"752\" height=\"377\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon1.jpg 752w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon1-300x150.jpg 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/a><\/p>\n<p><small>It supposed to be displayed only four times per a click, but it is displayed extra due to chattering. This problem will be resolved later, so let it be for now.<\/small><\/p>\n<p class=\"mtm\">Assuming that the basic place is &#8216;W&#8217;, the pattern of both pins will change continuously \u00a0to the next &#8216;W&#8217; during one click.\u00a0Check the summary down below.<\/p>\n<table style=\"width: 95%;\">\n<tbody>\n<tr>\n<td style=\"width: 30%; background-color: #ffff00; font-size: 85%;\">Pattern<\/td>\n<td style=\"background-color: #ffff5a;\">X<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<td style=\"background-color: #f5f55a;\">W<\/td>\n<td style=\"background-color: #ffff5a;\">X<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<td style=\"background-color: #ffff5a;\">\uff5e<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 30%; background-color: #fcfcfc;\">D2 pin(A)<\/td>\n<td>1<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>\uff5e<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 30%; background-color: #fcfcfc;\">D3 pin(B)<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>1<\/td>\n<td>\uff5e<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"2_Dividing_into_patterns\"><\/span>2.\u00a0Dividing into patterns<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Next, rewrite the sketch so that two pin states can be handled as a set. In this case, it will be simple by combine two bit into one byte with &#8216;bit shift&#8217;.<\/p>\n<pre class=\"start-line:19 lang:default decode:true\" title=\"sample 2-1\uff1aBit shift\">void ENC_READ() {\r\n  byte cur;\r\n\r\n  cur  = !digitalRead(ENC_B) &lt;&lt; 1;\r\n  cur += !digitalRead(ENC_A);\r\n\r\n  Serial.println(cur, BIN);\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>For example,<\/p>\n<p style=\"padding-left: 30px;\">B00000001\u3000\u2192\u3000B00000010<\/p>\n<p class=\"spacer_tail\">And adding &#8216;A&#8217; pin status to this, you can see both status in one value &#8216;cur&#8217;.\u00a0<a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2348\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon2.jpg\" alt=\"\" width=\"436\" height=\"321\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon2.jpg 436w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon2-300x221.jpg 300w\" sizes=\"auto, (max-width: 436px) 100vw, 436px\" \/><\/a><\/p>\n<p>&#8220;Serial.println(cur, BIN);&#8221;, means output &#8216;cur&#8217; value as binary. So by changing it to &#8220;Serial.println(cur)\uff1b&#8221;, you can see it in the decimal value.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2349\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon3.jpg\" alt=\"\" width=\"436\" height=\"321\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon3.jpg 436w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample1_serial_mon3-300x221.jpg 300w\" sizes=\"auto, (max-width: 436px) 100vw, 436px\" \/><\/a><\/p>\n<p>The relationship between binary numbers and decimal numbers can be summarized as follows.<\/p>\n<table style=\"width: 95%;\">\n<tbody>\n<tr>\n<td style=\"width: 30%; background-color: #ffff00; font-size: 85%;\">Pattern<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<td style=\"background-color: #ffff5a;\">W<\/td>\n<td style=\"background-color: #ffff5a;\">X<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">binary<\/td>\n<td>11<\/td>\n<td>10<\/td>\n<td>00<\/td>\n<td>01<\/td>\n<td>11<\/td>\n<td>10<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">decimal<\/td>\n<td>3<\/td>\n<td>2<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>3<\/td>\n<td>2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"line_middle\">\u00a0<\/p>\n<p>Now, the encoder pattern can now be expressed with 2 bits. However, as array of decimal numbers are 0 &#8211; 1 &#8211; 3 &#8211; 2, it confusing. So I will rewrite it so that it is aligned in order for convenience.<\/p>\n<pre class=\"start-line:19 lang:default mark:6-7 decode:true\" title=\"sample 2-2\uff1aDecimal number combination\">void ENC_READ() {\r\n  byte cur;\r\n\r\n  cur = (!digitalRead(ENC_B) &lt;&lt; 1) + !digitalRead(ENC_A);\r\n\r\n  if (cur == 3) cur = 2;\r\n  else if (cur == 2) cur = 3;\r\n\r\n  Serial.println(cur);\r\n}<\/pre>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 30%; background-color: #ffff00; font-size: 85%;\">Pattern<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<td style=\"background-color: #ffff5a;\">W<\/td>\n<td style=\"background-color: #ffff5a;\">X<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">decimal<\/td>\n<td>2<\/td>\n<td>3<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>2<\/td>\n<td>3<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"3_To_detect_the_direction\"><\/span>3. To detect\u00a0the direction<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The next step is detect the direction identification. To know the direction, you need to match with the previous pattern.<\/p>\n<pre class=\"lang:default decode:true\" title=\"sample 3-1\uff1aDirection indication\">#define ENC_A 2\r\n#define ENC_B 3\r\n\r\nvolatile byte pos;\r\n\r\n\r\nvoid setup() {\r\n  pinMode(ENC_A, INPUT_PULLUP);\r\n  pinMode(ENC_B, INPUT_PULLUP);\r\n\r\n  attachInterrupt(0, ENC_READ, CHANGE);\r\n  attachInterrupt(1, ENC_READ, CHANGE);\r\n\r\n  Serial.begin(38400);\r\n}\r\n\r\n\r\nvoid loop() {}\r\n\r\n\r\nvoid ENC_READ() {\r\n  byte cur = (!digitalRead(ENC_B) &lt;&lt; 1) + !digitalRead(ENC_A);\r\n  byte old = pos &amp; B00000011;\r\n\r\n  if (cur == 3) cur = 2;\r\n  else if (cur == 2) cur = 3;\r\n\r\n  bool rote = 0;\r\n  if (cur == 3 &amp;&amp; old == 0) rote = 0;\r\n  else if (cur == 0 &amp;&amp; old == 3) rote = 1;\r\n  else if (cur &gt; old) rote = 1;\r\n\r\n  pos = (old &lt;&lt; 2) + cur;\r\n\r\n  const char vector[2] = {'&lt;', '&gt;'};\r\n  Serial.print(vector[rote]);\r\n  Serial.println(pos + 128, BIN);\r\n\r\n}<\/pre>\n<p>First, we create a byte type global variable &#8220;pos&#8221;.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false toolbar-delay:false show-title:false striped:false marking:false ranges:false wrap-toggle:false start-line:4 copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"Declaration of variables for pattern information\">volatile byte pos;<\/pre>\n<p>On interrupt value, you must put &#8220;volatile&#8221; on declaring.\u00a0<\/p>\n<p>Since 2 patterns can be stored with 2 bits, we will combine this time and last time into &#8216;pos&#8217;.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false toolbar-delay:false show-title:false marking:false ranges:false wrap-toggle:false start-line:33 copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"Combline current &amp; previous location in one value\">pos = (old &lt;&lt; 2) + cur;<\/pre>\n<p class=\"mts\" style=\"padding-left: 30px;\">B0000<span style=\"background-color: #99ccff;\">00<\/span><span style=\"background-color: #ffff99;\">00<\/span>\u3000\u2190\u3000Blue<span style=\"background-color: #99ccff;\">\uff1aold<\/span>\u3000Yellow<span style=\"background-color: #ffff99;\">\uff1acur<\/span><\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false toolbar-delay:false show-title:false marking:false ranges:false wrap-toggle:false start-line:23 copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"Substitute previous pattern as old variable\">byte old = pos &amp; B00000011;<\/pre>\n<p class=\"mts\">I have changed the pattern to normal number. So I can easily see it rotates forward if it increased except &#8220;0 to 3&#8221; or &#8220;0 to 3&#8221;.\u00a0Now, apply it.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false toolbar-delay:false show-title:false marking:false ranges:false start-line:28 copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"judge the direction of rotation by current and previous value\">  bool rote = 0;\r\n  if (cur == 3 &amp;&amp; old == 0) rote = 0;\r\n  else if (cur == 0 &amp;&amp; old == 3) rote = 1;\r\n  else if (cur &gt; old) rote = 1;<\/pre>\n<p class=\"mtm\">In this way, we can get direction, get into &#8220;rote&#8221;. And &#8220;Serial monitor&#8221; displays result. By the way, a highest bit is set to HIGH (128) to prevent the number of digits of the binary display from changing on &#8220;Serial monitor&#8221;.<\/p>\n<pre class=\"toolbar-overlay:false toolbar-hide:false toolbar-delay:false show-title:false marking:false ranges:false wrap-toggle:false start-line:37 copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"For convenience of display, being enabled the most significant bit.\">Serial.println(pos + 128, BIN);<\/pre>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2360\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon1.jpg\" alt=\"\" width=\"421\" height=\"301\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon1.jpg 421w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon1-300x214.jpg 300w\" sizes=\"auto, (max-width: 421px) 100vw, 421px\" \/><\/a><\/p>\n<p>Here, we add chattering countermeasures by refer the previous pattern. You can see there may be duplication between the previous time and this time on serial monitor. I change sketch so that if it is not together, it will be updated the pattern memory.<\/p>\n<pre class=\"start-line:21 lang:default mark:8 decode:true\" title=\"sample 3-2\uff1aMeasures against chattering\">void ENC_READ() {\r\n  byte cur = (!digitalRead(ENC_B) &lt;&lt; 1) + !digitalRead(ENC_A);\r\n  byte old = pos &amp; B00000011;\r\n\r\n  if (cur == 3) cur = 2;\r\n  else if (cur == 2) cur = 3;\r\n\r\n  if (cur != old)\r\n  {\r\n    bool rote = 0;\r\n    if (cur == 3 &amp;&amp; old == 0) rote = 0;\r\n    else if (cur == 0 &amp;&amp; old == 3) rote = 1;\r\n    else if (cur &gt; old) rote = 1;\r\n\r\n    pos = (old &lt;&lt; 2) + cur;\r\n\r\n    const char vector[2] = {'&lt;', '&gt;'};\r\n    Serial.print(vector[rote]);\r\n    Serial.println(pos + (1 &lt;&lt; 7), BIN);\r\n    if (cur == 0) Serial.println();\r\n  }\r\n}<\/pre>\n<p>Although the response was improved, it is still not possible to prevent erroneous operation by chattering perfectly.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2362\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon2.jpg\" alt=\"\" width=\"421\" height=\"342\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon2.jpg 421w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample2_serial_mon2-300x244.jpg 300w\" sizes=\"auto, (max-width: 421px) 100vw, 421px\" \/><\/a><\/p>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"4_Counting_by_encoder\"><\/span>4.\u00a0Counting by encoder<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Based on what we have done so far, I try to count with encoder rotation. But, chattering problem is still remains. In order to avoid this, we need to change our way of thinking.<\/p>\n<p>At the time, this problem was terribly annoying me, but one conclusion came out. As the one click becomes one movement with four patterns, you do not have to follow all patterns on rotary encoder. Important things are &#8220;start moving&#8221; and &#8220;end of moving&#8221;. If it is captured properly, it will be work as a count.<\/p>\n<table style=\"width: 95%;\">\n<tbody>\n<tr>\n<td style=\"width: 20%; background-color: #ffff00; font-size: 85%;\">Pattern<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<td style=\"background-color: #ffff5a;\">W<\/td>\n<td style=\"background-color: #ffff5a;\">X<\/td>\n<td style=\"background-color: #ffff5a;\">Y<\/td>\n<td style=\"background-color: #ffff5a;\">Z<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">decimal<\/td>\n<td>2<\/td>\n<td>3<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>2<\/td>\n<td>3<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">Forward<\/td>\n<td>&nbsp;<\/td>\n<td>\u2192<\/td>\n<td style=\"font-size: 85%;\">END<\/td>\n<td style=\"font-size: 85%;\">START<\/td>\n<td>\u2192<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">Backward<\/td>\n<td>\u2190<\/td>\n<td style=\"font-size: 85%;\">START<\/td>\n<td style=\"font-size: 85%;\">END<\/td>\n<td>\u2190<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"mtm\">So I make &#8216;dir&#8217; variable to tell it whether or not you move. Then write the pattern of the starting point when you start moving, and reset to 0 when the movement is over.<\/p>\n<pre class=\"marking:false ranges:false nums:false wrap-toggle:false copy:false popup:false scroll:false expand-toggle:false decode-attributes:false trim-whitespace:false trim-code-tag:false mixed:false lang:default decode:true\" title=\"Rotation start and end, direction judgment\">if (dir == 0)\r\n{\r\n  if (cur == 1 || cur == 3) dir = cur;\r\n} else {\r\n  if (cur == 0)\r\n{\r\n  dir = 0;\r\n}<\/pre>\n<p class=\"mtm\">There is nothing to do with patterns and chattering in the middle, if it can catches proper starting and ending.<\/p>\n<table style=\"width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 20%; background-color: #ffffc8;\">\u00a0<\/td>\n<td style=\"background-color: #ffffc8; font-size: 85%;\">direction<\/td>\n<td style=\"background-color: #ffffc8; font-size: 85%;\">finished judgment<\/td>\n<td style=\"background-color: #ffffc8; font-size: 85%;\">achievement of rotation<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">Forward<\/td>\n<td>dir = 1<\/td>\n<td>cur = 0<\/td>\n<td>old = 3<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fcfcfc; font-size: 85%;\">Backward<\/td>\n<td>dir = 3<\/td>\n<td>cur = 0<\/td>\n<td>old = 1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Finally, put the &#8216;dir&#8217; bit into the &#8216;pos&#8217; variable.<\/p>\n<p style=\"padding-left: 30px;\">pos = (dir &lt;&lt; 4) + (old &lt;&lt; 2) + cur;<\/p>\n<p class=\"line_middle\">\u00a0<\/p>\n<p class=\"mtm\">Summarizing, it will be the sketch below. For counting, &#8220;enc_count&#8221; is newly prepared.<\/p>\n<pre class=\"lang:default decode:true\" title=\"sample 4-1\uff1aCount display\">#define ENC_A 2\r\n#define ENC_B 3\r\n\r\nvolatile byte pos;\r\nvolatile int  enc_count;\r\n\r\n\r\nvoid setup() {\r\n  pinMode(ENC_A, INPUT_PULLUP);\r\n  pinMode(ENC_B, INPUT_PULLUP);\r\n\r\n  attachInterrupt(0, ENC_READ, CHANGE);\r\n  attachInterrupt(1, ENC_READ, CHANGE);\r\n\r\n  Serial.begin(38400);\r\n}\r\n\r\n\r\nvoid loop() {}\r\n\r\n\r\nvoid ENC_READ() {\r\n  byte cur = (!digitalRead(ENC_B) &lt;&lt; 1) + !digitalRead(ENC_A);\r\n  byte old = pos &amp; B00000011;\r\n  byte dir = (pos &amp; B00110000) &gt;&gt; 4;\r\n\r\n  if (cur == 3) cur = 2;\r\n  else if (cur == 2) cur = 3;\r\n\r\n  if (cur != old)\r\n  {\r\n    if (dir == 0)\r\n    {\r\n      if (cur == 1 || cur == 3) dir = cur;\r\n    } else {\r\n      if (cur == 0)\r\n      {\r\n        if (dir == 1 &amp;&amp; old == 3) enc_count++;\r\n        else if (dir == 3 &amp;&amp; old == 1) enc_count--;\r\n        dir = 0;\r\n      }\r\n    }\r\n\r\n    bool rote = 0;\r\n    if (cur == 3 &amp;&amp; old == 0) rote = 0;\r\n    else if (cur == 0 &amp;&amp; old == 3) rote = 1;\r\n    else if (cur &gt; old) rote = 1;\r\n\r\n    pos = (dir &lt;&lt; 4) + (old &lt;&lt; 2) + cur;\r\n\r\n    const char vector[2] = {'&lt;', '&gt;'};\r\n    Serial.print(vector[rote]);\r\n    Serial.print(\" \");\r\n    Serial.print(enc_count);\r\n    Serial.print(\" \");\r\n    Serial.println(pos + (1 &lt;&lt; 7), BIN);\r\n    if (cur == 0) Serial.println();\r\n  }\r\n}<\/pre>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample4_serial_mon.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2375\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample4_serial_mon.jpg\" alt=\"\" width=\"752\" height=\"521\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample4_serial_mon.jpg 752w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/R_Encoder1_sample4_serial_mon-300x208.jpg 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/a><\/p>\n<p>How about that? I think that it works quite accurately. If you have a complaint about response, comment out &#8220;Serial.print&#8221; in attachinterrupt. This cause to delay of precise counting.<\/p>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"5_Separating_interrupt_and_count_addition_processing\"><\/span>5. Separating interrupt and count addition processing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Interrupt processing always executes immediately when there is a change. So if you try to use &#8220;enc_count&#8221; value in the main loop, it makes discrepancy. Therefore, we separate function of counting from total count value.<\/p>\n<pre class=\"nums:false copy:false popup:false scroll:false expand-toggle:false lang:default decode:true\">int ENC_COUNT(int incoming) {\r\n  static int enc_old = enc_count;\r\n  int val_change = enc_count - enc_old;\r\n\r\n  if (val_change != 0)\r\n  {\r\n    incoming += val_change;\r\n    enc_old   = enc_count;\r\n  }\r\n  return incoming;\r\n}<\/pre>\n<p>By making &#8220;ENC_COUNT&#8221; function, we can get bridged value.<\/p>\n<\/div>\n<div id=\"chap_5\">\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Summary_Sketch\"><\/span>Summary Sketch<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2428\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_4.jpg\" alt=\"\" width=\"825\" height=\"350\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_4.jpg 825w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_4-300x127.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1_insert_4-768x326.jpg 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><\/p>\n<p>In the end, draw a sketch that you can individually adjust the brightness of the two LEDs with a rotary encoder. You can toggle the LED by the switch.\u00a0Also you can see the values of LED on the &#8220;Serial Monitor&#8221;.<\/p>\n<p>In addition, you can also add LED pins by increasing the pin numbers on &#8220;LED_SIZE&#8221; and &#8220;led_pin&#8221;.\u00a0<\/p>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Sketch_Brightness_adjustment_of_LED_by_rotary_encoder\"><\/span>Sketch : Brightness adjustment of LED by rotary encoder<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<pre class=\"lang:default mark:1-5,15-19,45,71-107 decode:true\" title=\"Samle Sketch : Rotary Encoder contorl LED\">#define ENC_A  2\r\n#define ENC_B  3\r\n\r\nvolatile byte pos;\r\nvolatile int  enc_count;\r\n\r\n#define LED_SW   7\r\n#define LED_SIZE 2\r\nconst byte led_pin[LED_SIZE]  = {10, 11};   \/\/ digital pins for LED\r\nbyte       led_luma[LED_SIZE] = {255, 255}; \/\/ luma for each LED\r\nboolean    sw = false;\r\n\r\n\r\nvoid setup() {\r\n  pinMode(ENC_A, INPUT_PULLUP);\r\n  pinMode(ENC_B, INPUT_PULLUP);\r\n\r\n  attachInterrupt(0, ENC_READ, CHANGE);\r\n  attachInterrupt(1, ENC_READ, CHANGE);\r\n\r\n  Serial.begin(38400);\r\n\r\n  for (byte i = 0 ; i &lt; LED_SIZE ; i++)\r\n  {\r\n    pinMode(led_pin[i], OUTPUT);\r\n    analogWrite(led_pin[i], led_luma[i]);\r\n  }\r\n  pinMode(LED_SW, INPUT_PULLUP);\r\n  SERIAL_MON();\r\n}\r\n\r\n\r\nvoid loop() {\r\n\r\n  \/\/ LED switch change\r\n  unsigned long gauge;\r\n  while (!digitalRead(LED_SW)) gauge++;\r\n  if (gauge &gt; 700)\r\n  {\r\n    sw = !sw;\r\n    SERIAL_MON();\r\n  }\r\n\r\n  \/\/ set led_luma of active LED\r\n  short led_ref = ENC_COUNT(led_luma[sw]);\r\n  led_ref = constrain(led_ref, 0, 255);\r\n\r\n  \/\/ excute luma change\r\n  if (led_luma[sw] != led_ref)\r\n  {\r\n    led_luma[sw] = led_ref;\r\n    analogWrite(led_pin[sw], led_luma[sw]);\r\n    SERIAL_MON();\r\n  }\r\n}\r\n\r\n\r\nvoid SERIAL_MON() {\r\n  for (byte i = 0 ; i &lt; LED_SIZE ; i++)\r\n  {\r\n    Serial.print((char)(i + 'A'));\r\n    Serial.print(\":\");\r\n    Serial.print(led_luma[i]);\r\n    if (sw == i) Serial.print(\"&lt; \");\r\n    else Serial.print(\"  \");\r\n  }\r\n  Serial.println();\r\n}\r\n\r\n\r\nint ENC_COUNT(int incoming) {\r\n  static int enc_old = enc_count;\r\n  int val_change = enc_count - enc_old;\r\n\r\n  if (val_change != 0)\r\n  {\r\n    incoming += val_change;\r\n    enc_old   = enc_count;\r\n  }\r\n  return incoming;\r\n}\r\n\r\n\r\nvoid ENC_READ() {\r\n  byte cur = (!digitalRead(ENC_B) &lt;&lt; 1) + !digitalRead(ENC_A);\r\n  byte old = pos &amp; B00000011;\r\n  byte dir = (pos &amp; B00110000) &gt;&gt; 4;\r\n\r\n  if (cur == 3) cur = 2;\r\n  else if (cur == 2) cur = 3;\r\n\r\n  if (cur != old)\r\n  {\r\n    if (dir == 0)\r\n    {\r\n      if (cur == 1 || cur == 3) dir = cur;\r\n    } else {\r\n      if (cur == 0)\r\n      {\r\n        if (dir == 1 &amp;&amp; old == 3) enc_count++;\r\n        else if (dir == 3 &amp;&amp; old == 1) enc_count--;\r\n        dir = 0;\r\n      }\r\n    }\r\n    pos = (dir &lt;&lt; 4) + (old &lt;&lt; 2) + cur;\r\n  }\r\n}<\/pre>\n<\/div>\n<div id=\"epilog\">\n<ul class=\"mbl\" style=\"font-size: 85%; list-style: none;\">\n<li><a href=\"https:\/\/jumbleat.com\/2016\/12\/17\/encoder_1\/\">Using rotary encoder Part 1 : AttachInterrupt<\/a><\/li>\n<li><a href=\"https:\/\/jumbleat.com\/2017\/04\/20\/encoder_2\/\">Using rotary encoder Part 2 : Non-Click type<\/a><\/li>\n<li><a href=\"https:\/\/jumbleat.com\/2017\/10\/22\/encoder_3\/\">Using rotary encoder Part 3 : Dual Encoder<\/a><\/li>\n<\/ul>\n<p class=\"ref_site\">Reference Site<\/p>\n<ul class=\"ls_algn reference_links\">\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Main_Page\" target=\"_blank\" rel=\"noopener\">wikipedia<\/a> &#8211; <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rotary_encoder\" target=\"_blank\" rel=\"noopener\">Rotary Encoder<\/a><\/li>\n<\/ul>\n<\/div>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Sorry, this entry is only available in \u65e5\u672c\u8a9e. For the sake of viewer convenience, the content is shown below in  &hellip; <a href=\"https:\/\/jumbleat.com\/en\/2016\/12\/17\/encoder_1\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Using rotary encoder <span class=\"sub_title\">part 1 : attachInterrupt<\/span><\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":2424,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5,8],"tags":[11,30,280,277,276,279,28,31,359,360,275,278],"class_list":["post-2234","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-electric","tag-arduino","tag-chattering","tag-read-rotary-encoder","tag-rotary-encoder","tag-276","tag-279","tag-28","tag-31","tag-359","tag-360","tag-275","tag-278"],"jetpack_featured_media_url":"https:\/\/jumbleat.com\/wp-content\/uploads\/2016\/12\/e_catch_R_encoder_part1.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p7JALB-A2","jetpack_likes_enabled":false,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts\/2234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/comments?post=2234"}],"version-history":[{"count":4,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts\/2234\/revisions"}],"predecessor-version":[{"id":8648,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts\/2234\/revisions\/8648"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/media\/2424"}],"wp:attachment":[{"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/media?parent=2234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/categories?post=2234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/tags?post=2234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}