{"id":5577,"date":"2017-04-20T12:50:53","date_gmt":"2017-04-20T03:50:53","guid":{"rendered":"http:\/\/jumbleat.com\/?p=5577"},"modified":"2017-10-22T20:02:58","modified_gmt":"2017-10-22T11:02:58","slug":"encoder_2","status":"publish","type":"post","link":"https:\/\/jumbleat.com\/en\/2017\/04\/20\/encoder_2\/","title":{"rendered":"Using rotary encoder <span class=\"sub_title\">part 2 : High-Res with &#8220;non-click&#8221;<\/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-69de3d563020a\" 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-69de3d563020a\"  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\/2017\/04\/20\/encoder_2\/#Wiring\" >Wiring<\/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\/2017\/04\/20\/encoder_2\/#Rotary_Encoder\" >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-3\" href=\"https:\/\/jumbleat.com\/en\/2017\/04\/20\/encoder_2\/#Remodeling_Rotary_Encoder\" >Remodeling Rotary Encoder<\/a><\/li><\/ul><\/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\/2017\/04\/20\/encoder_2\/#Sketch\" >Sketch<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/jumbleat.com\/en\/2017\/04\/20\/encoder_2\/#On_my_theory\" >On my theory<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/jumbleat.com\/en\/2017\/04\/20\/encoder_2\/#Watch_the_%E2%80%9CChattering%E2%80%9D\" >Watch the &#8220;Chattering&#8221;<\/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\/2017\/04\/20\/encoder_2\/#Counterplan\" >Counterplan<\/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\/2017\/04\/20\/encoder_2\/#Process_and_Constant\" >Process and Constant<\/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\/2017\/04\/20\/encoder_2\/#Adjustment\" >Adjustment<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<p><\/p>\n<div id=\"prog\">\n<p>Previously, I wrote about <a href=\"https:\/\/jumbleat.com\/2016\/12\/17\/encoder_1\/\" target=\"_blank\" rel=\"noopener\">efficient Sketch how to use click type Rotary encoder<\/a>. But, it wasn&#8217;t for non-click type encoder.<\/p>\n<p>So I will try write new Sketch for it, and more, it makes worth to High-Resolution. No need extra electronic parts, just a Sketch.<!--more--><\/p>\n<p>Of course, it is not a perfect method. If you want it, you should get more expensive parts like &#8220;absolute-type&#8221; encoder. But I think my Sketch will works pretty well.<\/p>\n<p style=\"font-size: 85%; color: #777;\">New sketch is available on <a href=\"https:\/\/jumbleat.com\/2017\/10\/22\/encoder_3\/\" target=\"_blank\" rel=\"noopener noreferrer\">Part 3<\/a>\u00a0\uff082017\/10\/22\uff09<\/p>\n<\/div>\n<div id=\"chap1\">\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<p>Necessary electric parts is non-click Rotary Encoder, and LED if you have. Digital pins for Rotary Encoder is pull up by inside Arduino.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/rotary_encoder2_schematic_breadboard.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5671\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/rotary_encoder2_schematic_breadboard.png\" alt=\"\" width=\"1024\" height=\"501\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/rotary_encoder2_schematic_breadboard.png 1024w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/rotary_encoder2_schematic_breadboard-300x147.png 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/rotary_encoder2_schematic_breadboard-768x376.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Rotary_Encoder\"><\/span>Rotary Encoder<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Generally, rotary encoder judges &#8220;forward&#8221; or &#8220;backward&#8221; by comparing 2 digital pins of the current combination and the last. And &#8220;click-type&#8221; is consist of 4 different combination as one &#8220;click&#8221;. So if you have &#8220;20 click&#8221; encoder, there are 80 tangent point for each rotation on it.<\/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\" alt=\"\" width=\"500\" height=\"230\" \/><\/p>\n<p>If we can pick up all the change, we could get more high-resolution control by the encoder. That&#8217;s the what I want.<\/p>\n<p class=\"mtm\">You can buy &#8220;non-click-type&#8221; rotary encoder on shops.<\/p>\n<p><iframe loading=\"lazy\" width=\"300\" height=\"150\" style=\"width: 120px; height: 240px;\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\" frameborder=\"0\" src=\"\/\/rcm-fe.amazon-adsystem.com\/e\/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=jumbler02-22&amp;o=9&amp;p=8&amp;l=as4&amp;m=amazon&amp;f=ifr&amp;ref=as_ss_li_til&amp;asins=B016W82H9A&amp;linkId=d10013123b3d26ed30cc36de62db548d\"><\/iframe><\/p>\n<p>But most of those are fewer tangent point, and it hard to find one which have many tangent point. So I find &#8220;click-type&#8221; encoder which has more tangent point, and remodel to &#8220;non-click-type&#8221; physically.<\/p>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Remodeling_Rotary_Encoder\"><\/span>Remodeling Rotary Encoder<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><small>Do take your responsibility for your own if you will try this. I will never take for yours.<\/small><\/p>\n<p>This idea was coming from <a href=\"http:\/\/www.mi-take.biz\/mitake_techHouse\/rotaryRemodeling.html\" target=\"_blank\" rel=\"noopener\">this article<\/a>.(Sorry, this page is in Japanese only.)<\/p>\n<p>The mechanism of &#8220;click&#8221; is generated by protulutions meshing with the rotating table inside. And it becomes &#8220;non-click&#8221; if you remove it.<\/p>\n<p>In this article, I use <a href=\"http:\/\/akizukidenshi.com\/catalog\/g\/gP-05762\/\" target=\"_blank\" rel=\"noopener\">this Rotary Encoder<\/a> which has 24 clicks.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-5659\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins01-300x200.jpg\" alt=\"\" width=\"300\" height=\"200\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins01-300x200.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins01-768x512.jpg 768w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins01.jpg 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>It will have 96 resolution, in my theory.<\/p>\n<p><figure id=\"attachment_5662\" aria-describedby=\"caption-attachment-5662\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-5662 size-medium\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins02-300x200.jpg\" alt=\"\" width=\"300\" height=\"200\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins02-300x200.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins02-768x512.jpg 768w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins02.jpg 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-5662\" class=\"wp-caption-text\">Remove caulking that connects the foundation.<\/figcaption><\/figure> <figure id=\"attachment_5663\" aria-describedby=\"caption-attachment-5663\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins03.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-5663 size-medium\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins03-300x200.jpg\" alt=\"\" width=\"300\" height=\"200\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins03-300x200.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins03-768x512.jpg 768w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins03.jpg 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-5663\" class=\"wp-caption-text\">You can see mechanism of tangent point.<\/figcaption><\/figure> <figure id=\"attachment_5664\" aria-describedby=\"caption-attachment-5664\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-5664 size-medium\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins04-300x200.jpg\" alt=\"\" width=\"300\" height=\"200\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins04-300x200.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins04-768x512.jpg 768w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins04.jpg 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-5664\" class=\"wp-caption-text\">When further separated from the knob, you can see what makes &#8220;click&#8221; mechanism. So bend the protrusion not to touch ditch.<\/figcaption><\/figure><\/p>\n<p>Mechanism for &#8220;click&#8221; differs from each type. So this way is reference.<\/p>\n<\/div>\n<div id=\"chap2\">\n<h2 class=\"h2_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Sketch\"><\/span>Sketch<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"mbm\" style=\"font-size: 85%; color: #f00;\">I noticed a miss in the Sketch and modified it.\uff08Ver1.1\uff09 So it may improved encoder-read. (16\/10\/2017)<br \/>\n New sketch is available on <a href=\"https:\/\/jumbleat.com\/2017\/10\/22\/encoder_3\/\" target=\"_blank\" rel=\"noopener\">Part 3<\/a>. (22\/10\/2017)<\/p>\n<p>This method uses &#8220;MsTimer2&#8221; library. So if you haven&#8217;t installed it yet, get from &#8220;Library Manager&#8221;.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5666 size-medium\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_1-300x271.jpg\" alt=\"\" width=\"300\" height=\"271\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_1-300x271.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_1-768x693.jpg 768w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_1.jpg 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p class=\"mtm\">Download this project file,<\/p>\n<p style=\"padding-left: 30px;\"><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/download\/Arduino_Sketches\/ppj\/High_res_enc_v1.zip\">Sketch:High Res Rotary Encoder<\/a><\/p>\n<p>or copy code of down below.<\/p>\n<p><small>If you fail to compile, <a href=\"https:\/\/jumbleat.com\/2017\/02\/15\/error_on_arduino_ide\/\" target=\"_blank\" rel=\"noopener\">read here<\/a>.<\/small><\/p>\n<pre class=\"minimize:true lang:default mark:1 decode:true\" title=\"Click to Expand Sketch\">\/\/ Rotary Encoder Reading with watch dog timer and Dual Gauge\r\n\/\/ HighResEnc Version 1.1 by jumbler\r\n\r\n#include &lt;MsTimer2.h&gt;\r\n#define TIM MsTimer2\r\n\r\n\/\/pins\r\n#define ENCA 2\r\n#define ENCB 3\r\n#define LED  4\r\n\r\n\/\/encoder constants\r\n#define ENC_JUDGE 30\r\n#define ECUR B00000011  \/\/ enc current position\r\n#define EPRE B00001100  \/\/ enc previous position\r\n#define EHOM B00110000  \/\/ enc home position\r\n#define ETRG B01000000  \/\/ enc has been triggered\r\n#define ECHG B10000000  \/\/ encoder count has been charged\r\n\r\nconst    byte  enc_pins[2] = {ENCA, ENCB};\r\nvolatile byte  enc_status;\r\nvolatile short enc_count = 0;\r\n\r\n\r\nvoid setup() {\r\n  pinMode(LED, OUTPUT);\r\n  Serial.begin(38400);\r\n\r\n  for (byte i = 0 ; i &lt; 2 ; i++)\r\n  {\r\n    pinMode(enc_pins[i], INPUT_PULLUP);\r\n    digitalWrite(LED, 1 - i);\r\n    delay(1000);\r\n  }\r\n\r\n  TIM::set(1, ENC_GAUGE);\r\n  TIM::start();\r\n  enc_status = ENC_PIN_READ() &lt;&lt; SBIT(EHOM);\r\n}\r\n\r\n\r\nvoid loop() {\r\n  static int val;\r\n  static unsigned long time_led;\r\n\r\n  if (SBVAL(enc_status, ECHG))\r\n  {\r\n    digitalWrite(LED, HIGH);\r\n    val = ENC_COUNT(val);\r\n    Serial.println(val);\r\n    time_led = millis() + 10;\r\n  } else {\r\n    if (millis() &gt; time_led) digitalWrite(LED, LOW);\r\n  }\r\n}\r\n\r\n\r\n\r\nshort ENC_COUNT(int val) {\r\n  static int enc_old;\r\n  if (enc_old != enc_count)\r\n  {\r\n    val += enc_count - enc_old;\r\n    enc_old = enc_count;\r\n    enc_status = enc_status &amp; ~ECHG;\r\n  }\r\n  return val;\r\n}\r\n\r\n\r\n\r\nbyte SBIT(byte layer) {\r\n  for (byte i = 0 ; i &lt; 8; i++) if ((layer &gt;&gt; i)&amp;B00000001) return i;\r\n}\r\nbyte SBVAL(byte val, byte layer) {\r\n  byte tmp = (val &amp; layer) &gt;&gt; SBIT(layer);\r\n  return tmp;\r\n}\r\n\r\n\r\n\r\nbyte ENC_PIN_READ() {\r\n  \/\/ Read encoder pins status\r\n  byte enc_cur = (digitalRead(ENCB) &lt;&lt; 1) + digitalRead(ENCA);\r\n  \/\/ Modify position order\r\n  if (enc_cur &lt; 2) enc_cur = 1 + (enc_cur * -1);\r\n\r\n  if (!SBVAL(enc_status, ETRG))\r\n  {\r\n    if (SBVAL(enc_status, EHOM) != enc_cur) enc_status = enc_status | ETRG;\r\n  }\r\n\r\n  \/\/ apply update to enc_status\r\n  enc_status = (enc_status &amp; B11110000) + ((enc_status &amp; ECUR) &lt;&lt; 2) + enc_cur;\r\n\r\n  return enc_cur;\r\n}\r\n\r\n\r\n\r\nvoid ENC_GAUGE() {\r\n  static unsigned short gauge[2];\r\n  byte curr = ENC_PIN_READ();\r\n\r\n  \/\/ if encoder change has been triggerd\r\n  if (SBVAL(enc_status, ETRG))\r\n  {\r\n    byte prev, dist;\r\n    dist = SBVAL(enc_status, EHOM);\r\n\r\n    for (byte i = 0 ; i &lt; (ENC_JUDGE * 1.5) ; i++)\r\n    {\r\n      curr = ENC_PIN_READ();\r\n      prev = SBVAL(enc_status, EPRE);\r\n\r\n      \/\/ each gauge for \"moved\" or \"not moved\"\r\n      bool bias = (curr != dist) ? 1 : 0;\r\n      gauge [bias]++;\r\n      int goal = gauge[1] - gauge[0];\r\n\r\n      if (abs(gauge[1] - gauge[0]) &gt; ENC_JUDGE)\r\n      {\r\n        \/\/ encoder moved!\r\n        if (goal &gt; 0)\r\n        {\r\n          \/\/ increase or decrease\r\n          bool dir = ((curr - dist) &gt; 0) ? 1 : 0;\r\n          if (curr == 0 &amp;&amp; dist == 3) dir = 1;\r\n          else if (curr == 3 &amp;&amp; dist == 0) dir = 0;\r\n\r\n          \/\/ add count by the direction\r\n          if (dir) enc_count++;\r\n          else enc_count--;\r\n\r\n          \/\/ update home position\r\n          enc_status = (enc_status &amp; ~EHOM) + (curr &lt;&lt; SBIT(EHOM));\r\n          enc_status = enc_status | ECHG;\r\n        }\r\n\r\n        for (byte ii = 0 ; ii &lt; 2 ; ii++) gauge[ii] = 0;\r\n        enc_status = enc_status &amp; ~ETRG;\r\n        break;\r\n      }\r\n    }\r\n  }\r\n}<\/pre>\n<p class=\"mtm\">I recommend you to use &#8220;project file&#8221;. Because it is tabbed.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5667 size-full\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_2.jpg\" alt=\"\" width=\"398\" height=\"176\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_2.jpg 398w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_2-300x133.jpg 300w\" sizes=\"auto, (max-width: 398px) 100vw, 398px\" \/><\/p>\n<p class=\"mtm\">How to use is very simple. Set value to &#8220;ENC_COUNT()&#8221;. And it returns applied value.<\/p>\n<pre class=\"toolbar-hide:false nums:false copy:false popup:false expand-toggle:false lang:default decode:true\" title=\"Sample for using ENC_COUNT()\" enc_count=\"\">static int val;\r\n\r\nval = ENC_COUNT(val);\r\nSerial.println(val);<\/pre>\n<p>In sample code, you can see &#8216;val&#8217; is printed to &#8220;serial monitor&#8221;.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5668 size-medium\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_3-300x257.jpg\" alt=\"\" width=\"300\" height=\"257\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_3-300x257.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_3.jpg 655w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p class=\"mtm\">Also, you can check the behavior by Arduino &#8220;serial plotter&#8221;.\uff08Ctrl+Shift+M\uff09<\/p>\n<p>Although it can&#8217;t catch fast change, it won&#8217;t be extreme bullshit value.<\/p>\n<figure id=\"attachment_5670\" aria-describedby=\"caption-attachment-5670\" style=\"width: 1024px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_4re.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-5670 size-full\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_4re.jpg\" alt=\"\" width=\"1024\" height=\"679\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_4re.jpg 1024w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_4re-300x199.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_4re-768x509.jpg 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption id=\"caption-attachment-5670\" class=\"wp-caption-text\">It becomes jagged if it failed.<\/figcaption><\/figure>\n<p>I haven&#8217;t used this code with other routine so far. If you like this sketch, let me know your comment.<\/p>\n<p class=\"mtl\">Incidentally, I explain about how it works as reference.<\/p>\n<\/div>\n<div id=\"chap3\">\n<h2 class=\"h2_HLine mts mbs\"><span class=\"ez-toc-section\" id=\"On_my_theory\"><\/span>On my theory<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>First of all, we have to recognize how many &#8220;chattering&#8221; occurred.<\/p>\n<h3 class=\"h3_HLine mts mbs\"><span class=\"ez-toc-section\" id=\"Watch_the_%E2%80%9CChattering%E2%80%9D\"><\/span>Watch the &#8220;Chattering&#8221;<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>By using attachinterrupt to record and display pin changes. There is a problem <a href=\"https:\/\/jumbleat.com\/2016\/10\/19\/loss_time_of_serial-print\/\" target=\"_blank\" rel=\"noopener\">use attachinterrupt and Serial.print use same time<\/a> in a function. So it keeps the changes in arrays and prints all after intervals. (Because this sketch function slightly wrong, data of first and last goes wrong. Never minds)<\/p>\n<pre class=\"lang:default decode:true\" title=\"Sketch 'Pick up all change'\">\/\/ watch chattering\r\n\r\n#define ENCA 2\r\n#define ENCB 3\r\n#define LED  4\r\nconst    byte  enc_pins[2] = {ENCA, ENCB};\r\n\r\nvoid setup() {\r\n  pinMode(LED, OUTPUT);\r\n  Serial.begin(38400);\r\n  \r\n  for (byte i = 0 ; i &lt; 2 ; i++)\r\n  {\r\n    pinMode(enc_pins[i], INPUT_PULLUP);\r\n    attachInterrupt(i, ENC_HIT, CHANGE);\r\n    digitalWrite(LED, 1 - i);\r\n    delay(1000);\r\n  }\r\n}\r\n\r\n#define MEM 200\r\n\r\nvolatile unsigned long time_enc_read[MEM];\r\nvolatile byte          enc_stat[MEM];\r\nvolatile unsigned int  read_count;\r\n\r\n\r\nvoid loop() {\r\n  if (read_count &gt; 0 &amp;&amp; (micros() - time_enc_read[read_count]) &gt; 1000000)\r\n  {\r\n    for (byte i = 0 ; i &lt;= read_count ; i++)\r\n    {\r\n      if (i &lt; 100) Serial.print(\"0\");\r\n      if (i &lt; 10) Serial.print(\"0\");\r\n      Serial.print(i);\r\n      Serial.print(\" \");\r\n      Serial.print((char)('A' + enc_stat[i]));\r\n      Serial.print(\" \");\r\n      Serial.print(time_enc_read[i] - time_enc_read[max(0, i - 1)]);\r\n      Serial.println();\r\n    }\r\n    Serial.println();\r\n    read_count = 0;\r\n  }\r\n}\r\n\r\n\r\nbyte ENC_PIN_READ() {\r\n  \/\/ Read encoder pins\r\n  byte enc_cur = (digitalRead(ENCB) &lt;&lt; 1) + digitalRead(ENCA);\r\n  \/\/ Modify position order\r\n  if (enc_cur &lt; 2) enc_cur = 1 + (enc_cur * -1);\r\n  return enc_cur;\r\n}\r\n\r\nvoid ENC_HIT() {\r\n  digitalWrite(LED, HIGH);\r\n  enc_stat[read_count] = ENC_PIN_READ();\r\n  time_enc_read[read_count] = micros();\r\n  read_count++;\r\n  digitalWrite(LED, LOW);\r\n}<\/pre>\n<p class=\"mtm\">There are so many &#8220;chattering&#8221; on. &#8220;A&#8221; to &#8220;D&#8221; means pattern of encoders 2 pin. So you can see the patterns go back and forth repeatedly.<\/p>\n<p><a href=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_5.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5674\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_5.jpg\" alt=\"\" width=\"657\" height=\"563\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_5.jpg 657w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_sc_5-300x257.jpg 300w\" sizes=\"auto, (max-width: 657px) 100vw, 657px\" \/><\/a><\/p>\n<p>Sometimes it repeats over 100 time, on the other hands, it never appears. On the fast move of encoder, you can&#8217;t tell which pattern is correct.<\/p>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Counterplan\"><\/span>Counterplan<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>On this situation, attachinterrupt may not helps counting.<\/p>\n<p>So I thought to use <a href=\"https:\/\/jumbleat.com\/2016\/08\/19\/switch_without_chatter\/\" target=\"_blank\" rel=\"noopener\">&#8220;gauging&#8221;<\/a> which I invented and &#8220;timer&#8221; as flash update.<\/p>\n<ul class=\"ls_algn\">\n<li>confirmed position is \u201cHome\u201d<\/li>\n<li>latest position is \u201cCurrent\u201d<\/li>\n<\/ul>\n<p>I judge a position by comparing those two elements.<\/p>\n<p class=\"mtm mbl\"><em>I wrote <a href=\"https:\/\/jumbleat.com\/2017\/06\/26\/bye-bye_chattering_seriously_library\/\" target=\"_blank\" rel=\"noopener\">a chattering-less switch library<\/a> with &#8220;gauging&#8221; method.<br \/>\n (26.6.2017)<\/em><\/p>\n<p>If &#8220;Home&#8221; and &#8220;Curr&#8221; is different, &#8220;Trigger&#8221; goes on. But it isn&#8217;t confirmed yet. By triggered, digital pins is read repeatedly.<\/p>\n<p>And it watches changes of pins by two gauge. If one of them reaches value of &#8220;ENC_JUDGE&#8221;, it is comfirmed &#8220;moved&#8221; or &#8220;not moved&#8221; by the gauge&#8217;s value. If it moves, update &#8220;Home&#8221; position and count. Or abort if it is &#8220;not move&#8221;.<\/p>\n<p>This is the basic task for reading pins.<\/p>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Process_and_Constant\"><\/span>Process and Constant<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Patterns for 2 pins can be expressed by 2 bits. So, I set several encoder&#8217;s status to a byte in variable &#8220;edc_status&#8221;.<\/p>\n<pre class=\"toolbar-hide:false nums:false copy:false popup:false expand-toggle:false lang:default decode:true\" title=\"enc_status value\">#define ECUR B00000011  \/\/ enc current position\r\n#define EPRE B00001100  \/\/ enc previous position\r\n#define EHOM B00110000  \/\/ enc home position\r\n#define ETRG B01000000  \/\/ enc has been triggered\r\n#define ECHG B10000000  \/\/ encoder count has been charged<\/pre>\n<p class=\"mtm\">Those values is manipulated by &#8220;bit-shift&#8221;. So I made some functions.<\/p>\n<pre class=\"toolbar-hide:false nums:false copy:false popup:false expand-toggle:false lang:default decode:true\" title=\"Functions to make bit operation easier\">\/\/ Determine and return the number of bits\r\nbyte SBIT(byte layer) {\r\n  for (byte i = 0 ; i &lt; 8; i++) if ((layer &gt;&gt; i)&amp;B00000001) return i;\r\n}\r\n\r\n\/\/ Masks only on the specified bits and returns the numeric value right-shifted to the minimum bit\r\nbyte SBVAL(byte val, byte layer) {\r\n  byte tmp = (val &amp; layer) &gt;&gt; SBIT(layer);\r\n  return tmp;\r\n}<\/pre>\n<p class=\"mtm\">Then, I create a function to read the pin state.<\/p>\n<pre class=\"toolbar-hide:false nums:false copy:false popup:false expand-toggle:false lang:default decode:true\" title=\"Read encoder's pins\">byte ENC_PIN_READ() {\r\n  \/\/ Acquire current pin state with 2 bits\r\n  byte enc_cur = (digitalRead(ENCB) &lt;&lt; 1) + digitalRead(ENCA);\r\n  \/\/ Since in decimal notation, the order of the pattern is 1023, I forced it to 0123.\r\n  if (enc_cur &lt; 2) enc_cur = 1 + (enc_cur * -1);\r\n\r\n  \/\/ Trigger is on, if \"Curr\" and \"Home\" is different.\r\n  if (!SBVAL(enc_status, ETRG))\r\n  {\r\n    if (SBVAL(enc_status, EHOM) != enc_cur) enc_status = enc_status | ETRG;\r\n  }\r\n\r\n  \/\/ Update \"enc_Status\"\r\n  enc_status = (enc_status &amp; B11110000) + ((enc_status &amp; ECUR) &lt;&lt; 2) + enc_cur;\r\n\r\n  return enc_cur;\r\n}<\/pre>\n<p class=\"mtm\">Timer works to this &#8220;ENC_GAUGE&#8221;.<\/p>\n<pre class=\"toolbar-hide:false nums:false copy:false popup:false expand-toggle:false lang:default decode:true  \" title=\"Timer works\">void ENC_GAUGE() {\r\n  static unsigned short gauge[2];\r\n  \/\/ Read pins at first\r\n  byte curr = ENC_PIN_READ();\r\n\r\n  \/\/ Excute repeat read if it were triggered\r\n  if (SBVAL(enc_status, ETRG))\r\n  {\r\n    byte prev, dist;\r\n    dist = SBVAL(enc_status, EHOM);\r\n\r\n    \/\/ repeat digital pins and update\r\n    for (byte i = 0 ; i &lt; (ENC_JUDGE * 1.5) ; i++)\r\n    {\r\n      curr = ENC_PIN_READ();\r\n      prev = SBVAL(enc_status, EPRE);\r\n\r\n      \/\/ gauging for \"move\" and \"not move\"\r\n      bool bias = (curr != dist) ? 1 : 0;\r\n      gauge [bias]++;\r\n      int goal = gauge[1] - gauge[0];\r\n\r\n      \/\/ confirmation of filled gauge\r\n      if (abs(gauge[1] - gauge[0]) &gt; ENC_JUDGE)\r\n      {\r\n        \/\/ it moved !\r\n        if (goal &gt; 0)\r\n        {\r\n          \/\/ find direction of encoder\r\n          bool dir = ((curr - dist) &gt; 0) ? 1 : 0;\r\n          if (curr == 0 &amp;&amp; dist == 3) dir = 1;\r\n          else if (curr == 3 &amp;&amp; dist == 0) dir = 0;\r\n\r\n          \/\/ refect to variable \"enc_count\"\r\n          if (dir) enc_count++;\r\n          else enc_count--;\r\n\r\n          \/\/ update \"Home\" position\r\n          enc_status = (enc_status &amp; ~EHOM) + (curr &lt;&lt; SBIT(EHOM));\r\n          enc_status = enc_status | ECHG;\r\n        }\r\n\r\n        \/\/ Reset gauge and Trigger\r\n        for (byte ii = 0 ; ii &lt; 2 ; ii++) gauge[ii] = 0;\r\n        enc_status = enc_status &amp; ~ETRG;\r\n        break;  \/\/ escape repeat\r\n      }\r\n    }\r\n  }\r\n}<\/pre>\n<p class=\"mtm\">By not to update encoder change immediately, but charge to function &#8220;ENC_COUNT()&#8221;, prevent mistakes and it makes easy access to counter value.<\/p>\n<pre class=\"toolbar-hide:false nums:false copy:false popup:false expand-toggle:false lang:default decode:true\" title=\"counting bank\">short ENC_COUNT(int val) {\r\n  \/\/ Previous counter value\r\n  static int enc_old;\r\n  \/\/ If values of counter and previous is different, add and update.\r\n  if (enc_old != enc_count)\r\n  {\r\n    val += enc_count - enc_old;\r\n    enc_old = enc_count;\r\n    \/\/ Reset\r\n    enc_status = enc_status &amp; ~ECHG;\r\n  }\r\n  return val;\r\n}<\/pre>\n<h3 class=\"h3_HLine mtm mbs\"><span class=\"ez-toc-section\" id=\"Adjustment\"><\/span>Adjustment<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This sketch is optimized for Arduino Uno. So it may not works as well if you use another type Arduino. Several changes of constant may helps for your trouble shooting.<\/p>\n<ul class=\"ls_algn\">\n<li>ENC_JUDGE<\/li>\n<li>TIM::set(1, ENC_GAUGE);<\/li>\n<\/ul>\n<p>ENC_JUDGE value is for &#8220;repeating times&#8221; and &#8220;judging gauge&#8221;. If wobble is terrible, changing here may resolves it.<\/p>\n<p>&#8220;Timer&#8221; is set to 1ms. This is minimum value. But if you use faster one than Arduino Uno, it may not necessary to be 1ms.<\/p>\n<\/div>\n<div id=\"epilog\">\n<p class=\"mtl\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5689\" src=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins2_1re.jpg\" alt=\"\" width=\"825\" height=\"300\" srcset=\"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins2_1re.jpg 825w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins2_1re-300x109.jpg 300w, https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/encoder2_ins2_1re-768x279.jpg 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><\/p>\n<p>By this explain, I realized some code are irrelevant. Those were abandoned on my try and error. But as it are. Sorry. Modify it yourself if you care about.<\/p>\n<ul class=\"mtl 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=\"http:\/\/www.mi-take.biz\/mitake_techHouse\/\" target=\"_blank\" rel=\"noopener\">\u7f8e\u6b66\u30af\u30ea\u30a8\u30a4\u30c8<\/a> &#8211; <a href=\"http:\/\/www.mi-take.biz\/mitake_techHouse\/rotaryRemodeling.html\" target=\"_blank\" rel=\"noopener\">\u30ed\u30fc\u30bf\u30ea\u30a8\u30f3\u30b3\u30fc\u30c0\u306e\u30af\u30ea\u30c3\u30af\u7121\u3057\u3078\u306e\u6539\u9020<\/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\/2017\/04\/20\/encoder_2\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Using rotary encoder <span class=\"sub_title\">part 2 : High-Res with &#8220;non-click&#8221;<\/span><\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":5685,"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":false,"_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,378,28,31,359,360,275,278],"class_list":["post-5577","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-378","tag-28","tag-31","tag-359","tag-360","tag-275","tag-278"],"jetpack_featured_media_url":"https:\/\/jumbleat.com\/wp-content\/uploads\/2017\/04\/e_catch_encoder2.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p7JALB-1rX","jetpack_likes_enabled":false,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts\/5577","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=5577"}],"version-history":[{"count":4,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts\/5577\/revisions"}],"predecessor-version":[{"id":8649,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/posts\/5577\/revisions\/8649"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/media\/5685"}],"wp:attachment":[{"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/media?parent=5577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/categories?post=5577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jumbleat.com\/en\/wp-json\/wp\/v2\/tags?post=5577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}