{"id":8275,"date":"2018-02-18T21:33:48","date_gmt":"2018-02-18T21:33:48","guid":{"rendered":"http:\/\/localhost:8105\/?p=8275"},"modified":"2022-12-10T04:49:32","modified_gmt":"2022-12-10T04:49:32","slug":"diy-dual-concentric-rotary-encoders-with-push-button","status":"publish","type":"post","link":"https:\/\/blog.shahada.abubakar.net\/?p=8275","title":{"rendered":"DIY Dual Concentric Rotary Encoders with Push Button"},"content":{"rendered":"<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9084\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350.jpg\" alt=\"\" width=\"2111\" height=\"2419\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350.jpg 2111w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350-262x300.jpg 262w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350-894x1024.jpg 894w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350-768x880.jpg 768w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350-1340x1536.jpg 1340w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_052350-1787x2048.jpg 1787w\" sizes=\"auto, (max-width: 2111px) 100vw, 2111px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>This is my fully 3D printed design for a Dual Concentric Rotary Encoder with Push Button. It&#8217;s useful for making the knobs for flight-sim radio panels, where there is an outer knob to set the smaller digits, and an inner knob to set the larger digits.<\/div>\n<div>\u00a0<\/div>\n<div>It&#8217;s inspired by a design I found on <a href=\"https:\/\/www.youtube.com\/watch?v=iWVXWxhSfjo\">Youtube<\/a>, where the designer, Theo Deckers, CNC&#8217;d a bracket to hold two regular rotary encoders together. I don&#8217;t have access to a CNC machine or the parts that Theo uses, so I decided to design one purely using 3D-Printed plastic.<\/div>\n<div>\u00a0<\/div>\n<div>You can buy a ready made part, but they are either <a href=\"https:\/\/geremy.co.uk\/epages\/364c2b81-e826-48ea-aded-582ceaf6e41c.sf\/en_GB\/?ObjectPath=\/Shops\/364c2b81-e826-48ea-aded-582ceaf6e41c\/Products\/GLB16%23164\">expensive<\/a> or have a<a href=\"https:\/\/www.alibaba.com\/product-detail\/Dongguan-LJV-Dual-Metal-Shaft-08mm_60507431389.html?spm=a2700.7724838.2017115.235.65083eccXFO7LX\"> large minimum order quantity<\/a> (MOQ).<\/div>\n<div>\u00a0<\/div>\n<div>This design makes use of common cheap rotary encoders. Rotary encoders allow you to rotate the shaft infinitely clockwise or anticlockwise. For each click, it will report the direction the shaft was rotated in. Most also feature a push-button switch, where pressing down on the shaft closes a switch.<\/div>\n<div>\u00a0<\/div>\n<div>You can buy these rotary encoders in most electronics parts shops, or on eBay (search for &#8220;Rotary Encoder Push Button 12mm D-Shaft&#8221;. Here&#8217;s a <a href=\"https:\/\/www.ebay.com\/itm\/10pcs-Rotary-Encoder-Push-Button-Switch-Keyswitch-Electronic-Components-12mm\/282211130638\">link<\/a> that&#8217;s valid right now, USD4.17 for a pack of 10 with free shipping). You&#8217;ll need two for each part.<\/div>\n<div>\u00a0<\/div>\n<div><b><span style=\"font-size: 18px;\">Printing The Components<\/span><\/b><\/div>\n<div>\u00a0<\/div>\n<div>The components of the part can be donwloaded from my TinkerCAD project page at\u00a0 <span style=\"color: #333333; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 200; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #eeeeee; text-decoration-style: initial; text-decoration-color: initial; float: none; display: inline !important;\"><a href=\"https:\/\/www.tinkercad.com\/things\/dwthDbal5YY\">https:\/\/www.tinkercad.com\/things\/dwthDbal5YY<\/a><\/span>.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9568\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/Screenshot-from-2018-02-19-04-43-29.png\" alt=\"\" width=\"1024\" height=\"665\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/Screenshot-from-2018-02-19-04-43-29.png 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/Screenshot-from-2018-02-19-04-43-29-300x195.png 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/Screenshot-from-2018-02-19-04-43-29-768x499.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>There are a number of components that need to be printed:<\/div>\n<div>\u00a0<\/div>\n<ul>\n<li>Outer Knob<\/li>\n<li>Inner Knob<\/li>\n<li>Outer Shaft<\/li>\n<li>Inner Shaft<\/li>\n<li>Outer Encoder Cog<\/li>\n<li>Upper Plate<\/li>\n<li>Lower Plate<\/li>\n<li>Mounting Nut<\/li>\n<\/ul>\n<div>\u00a0<\/div>\n<div>I printed my parts on a Prusa Mk2 at 0.2mm layer height and 20% infill, with the exception of the mounting nut which I printed at 0.05mm layer height and 100% infill.<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div><span style=\"font-size: 18px;\"><b>Assembly<\/b><\/span><\/div>\n<div>\u00a0<\/div>\n<div>You will also need the following items:<\/div>\n<div>\u00a0<\/div>\n<ul>\n<li>4pcs M3x24 bolts, or longer<\/li>\n<li>12pcs M3 nuts<\/li>\n<li>a M3x12 bot<\/li>\n<\/ul>\n<div>\u00a0<\/div>\n<div>Start by attaching the rotary encoders to the lower plate.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9569\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_044827.jpg\" alt=\"\" width=\"1280\" height=\"720\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_044827.jpg 1280w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_044827-300x169.jpg 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_044827-1024x576.jpg 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_044827-768x432.jpg 768w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>Then attach the inner shaft and the Outer Encoder Cog to the D-shafts.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9570\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045034.jpg\" alt=\"\" width=\"1024\" height=\"576\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045034.jpg 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045034-300x169.jpg 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045034-768x432.jpg 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>Next attach the four M3 bolts to the upper plate. Secure them tightly with four M3 bolts. Thread another four bolts till they are roughly 7mm from the upper plate.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9571\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045517.jpg\" alt=\"\" width=\"1280\" height=\"720\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045517.jpg 1280w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045517-300x169.jpg 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045517-1024x576.jpg 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045517-768x432.jpg 768w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>The outer shaft should then be inserted to through the upper plate. Align the tabs through the holes in the plate so that it may slide through.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9572\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045554.jpg\" alt=\"\" width=\"1280\" height=\"720\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045554.jpg 1280w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045554-300x169.jpg 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045554-1024x576.jpg 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045554-768x432.jpg 768w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>Connect the upper and lower plates together, making sure the two cogs align properly. Once the upper and lower plates are aligned, adjust the middle nuts so they touch the lower plate. Insert four more nuts to secure the lower plate. You should be able to feel a click when you press down on the inner shaft. If not, increase the spacing between the plates.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9573\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045856.jpg\" alt=\"\" width=\"1280\" height=\"720\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045856.jpg 1280w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045856-300x169.jpg 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045856-1024x576.jpg 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_045856-768x432.jpg 768w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/div>\n<div><b><span style=\"font-size: 18px;\">\u00a0<\/span><\/b><\/div>\n<div><b><span style=\"font-size: 18px;\">Panel Mounting<\/span><\/b><\/div>\n<div>\u00a0<\/div>\n<div>The part is designed to be mounted onto a 3mm thick panel. For this method, you will need a 16mm hole drilled into your panel. I used a <a href=\"https:\/\/www.ebay.com\/itm\/12-14-16-18mm-Hole-Saw-Tooth-HSS-Drill-Bit-Coated-Hole-Cutter-Woodworking-SteelF\/362153223886\">16mm hole saw<\/a> to create this. The part is simply placed through the hole and tightened using the mounting nut. In my case, it was sufficiently tight to hold the part in place, however you may wish to use hot glue to further secure the part in place.<\/div>\n<div>\u00a0<\/div>\n<div>If the mounting nut doesn&#8217;t work for you, or if you have a thicker panel, you can also mount the part using two m3 bolts. Use the lower plate as a template and drill additional holes on your panel where the &#8220;tabs&#8221; are. Then use these two holes to mount the part in place. By using longer bolts, you can also place the part further away to the back of the the panel, which is useful of you have other clearance issues with other components on the panel. When extending the part further behind the panel, you may need to extend the Outer shaft and inner shaft lengths. Just ungroup the part in tinkerCAD, extend them accordingly, and regroup the parts together.<\/div>\n<div>\u00a0<\/div>\n<div>Once mounted to your panel, align the groves in the outer knob with the tabs on the outer shaft, and slide the knob down.<\/div>\n<div>\u00a0<\/div>\n<div>The inner knob is secured into place using a M3x12 bolt. You will first need to tap a M3 thread into the hole on the inner shaft, using a <a href=\"https:\/\/www.banggood.com\/HSS-14-Inch-Hex-Shank-Combination-Metric-Drill-Tap-Bit-M3M4M5M6M8M10-p-1010687.html?cur_warehouse=CN\">M3 Tapping Bit<\/a>. When fixing the M3x12 bolt in place, do not overtighten or you will damage the thread.<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9574\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_051819.jpg\" alt=\"\" width=\"1280\" height=\"836\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_051819.jpg 1280w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_051819-300x196.jpg 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_051819-1024x669.jpg 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/20180219_051819-768x502.jpg 768w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div><b><span style=\"font-size: 18px;\">Wiring<\/span><\/b><\/div>\n<div><b><span style=\"font-size: 18px;\">\u00a0<\/span><\/b><\/div>\n<div>The pins on the part are as follows:<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9575\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z.png\" alt=\"\" width=\"1024\" height=\"616\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z.png 1024w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-300x180.png 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-768x462.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/div>\n<ul>\n<li><b>GND<\/b> &#8211; Signal Ground<\/li>\n<li><b>IA<\/b>\/<b>IB<\/b> &#8211; Rotation Signals for Inner Encoder<\/li>\n<li><b>OA<\/b>\/<b>OB<\/b> &#8211; Rotation Signals for Outer Encoder<\/li>\n<li><b>IS<\/b> &#8211; Push button Switch for Inner Encoder<\/li>\n<\/ul>\n<div>\u00a0<\/div>\n<div>We don&#8217;t need to use the push button Switch for the Outer Encoder since it&#8217;s not possible to press it mechanically. The other two tabs at the sides are for mounting the rotary encoders to a PCB and not used in this design.<\/div>\n<div>\u00a0<\/div>\n<div>Start by soldering wires and bridging the four GND points together. You can then either solder wires to attach to attach the signal wires directly to your controller, or solder wires to attach a <a href=\"https:\/\/www.ebay.com\/itm\/100pcs-2-54mm-6P-Pitch-Dupont-Jumper-Wire-Cable-Housing-Female-Pin-Connector\/252485629780\">DuPont<\/a> 6-way connector (see my post on crimping <a href=\"http:\/\/blog.shahada.abubakar.net\/post\/how-to-crimp-dupont-connector-pins\">DuPont pins<\/a>). If you\u00a0 use a\u00a0 connector, I suggest the following pin layout:<\/div>\n<div>\u00a0<\/div>\n<div style=\"text-align: center;\">\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9576\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-1-1.png\" alt=\"\" width=\"731\" height=\"1024\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-1-1.png 731w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-1-1-214x300.png 214w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/div>\n<div>\u00a0<\/div>\n<div><b><span style=\"font-size: 18px;\">Decoding A Rotary Encoder<\/span><\/b><\/div>\n<div>\u00a0<\/div>\n<div>To demonstrate the part, I connected it to a Raspberry Pi, and wrote a test program using the <a href=\"http:\/\/wiringpi.com\/\">WiringPi<\/a> library. I connected the wires to my Pi Model B&#8217;s GPIO Pins as follows:<\/div>\n<div>\u00a0<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9577\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-2-1.png\" alt=\"\" width=\"800\" height=\"470\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-2-1.png 800w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-2-1-300x176.png 300w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-2-1-768x451.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>Notes:<\/div>\n<ul>\n<li>This my original Model B with 26 GPIO pins. On a newer Pi Model B+, 2, or 3, with 40-pin GPIO, the pin connections are the same, except that there are extra pins (27-40) on the left.<\/li>\n<li>Pins #8 and #10 are shared for use with the TTL Serial Port. Make sure this is disabled (using &#8220;sudo raspi-config&#8221;).<\/li>\n<\/ul>\n<div>\u00a0<\/div>\n<div>In our program, after calling wiringPiSetup(), the pins in use are configured as inputs, using the pinMode() command.<\/div>\n<div>\u00a0<\/div>\n<div>The rotary encoder signals by transitioning between a &#8220;not connected&#8221; state to &#8220;connected to ground&#8221; state. To read this using our GPIO inputs, we need to enable the built-in pull up resistor on the raspberry pi. This will cause the GPIO to return &#8220;1&#8221; (high) when the line is not connected to ground, and &#8220;0&#8221; (low) when the line is connected to ground.<\/div>\n<div>\u00a0<\/div>\n<div>Next let us look at the signalling mechanism of this rotary encoder. Not all rotary encoders work the same way, but almost all of the cheap &#8220;no-name&#8221; ones do.<\/div>\n<div>\u00a0<\/div>\n<div>In these rotary encoders, whenever the knob is &#8220;idle&#8221; in a detent, both signal lines A and B will report 1.<\/div>\n<div>\u00a0<\/div>\n<div>When the encoder is rotated to clockwise a single &#8220;click&#8221;, the following transition is observed:<\/div>\n<div>\u00a0<\/div>\n<table style=\"-evernote-table: true; border-collapse: collapse; width: 100%; table-layout: fixed; margin-left: 0px;\">\n<tbody>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">\u00a0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">A<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">B<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>(Idle)<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>Start<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>\u00a0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>\u00a0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>Finish (Idle)<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div style=\"text-align: center;\"><i>A single Clockwise <\/i><i style=\"font-family: gotham, helvetica, arial, sans-serif; font-size: 14px;\">&#8220;click&#8221; <\/i><\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>And when the encoder is rotated anti-clockwise a single &#8220;click&#8221;, the following transition is observed:<\/div>\n<div>\u00a0<\/div>\n<div style=\"font-family: gotham, helvetica, arial, sans-serif; font-size: 14px;\">\u00a0<\/div>\n<table style=\"-evernote-table: true; border-collapse: collapse; width: 100%; table-layout: fixed; margin-left: 0px; font-family: 'Helvetica Neue', Arial, sans; font-size: 16px;\">\n<tbody>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">\u00a0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">A<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">B<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>(Idle)<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>Start<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>\u00a0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>\u00a0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">0<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div>Finish (Idle)<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<td style=\"padding: 10px; margin: 0px; width: 33.33%; border: 1px solid #d3d3d3;\">\n<div style=\"text-align: center;\">1<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div style=\"text-align: center;\"><span style=\"font-size: 16px;\"><span style=\"font-family: 'Helvetica Neue', Arial, sans;\"><i>A single <\/i><\/span><\/span><i style=\"font-family: 'Helvetica Neue', Arial, sans; font-size: 16px;\">Anti-clockwise\u00c2\u00a0<\/i><span style=\"font-size: 16px;\"><span style=\"font-family: 'Helvetica Neue', Arial, sans;\"><i>&#8220;click&#8221;<\/i><\/span><\/span><\/div>\n<div style=\"font-family: gotham, helvetica, arial, sans-serif; font-size: 14px;\">\u00a0<\/div>\n<div>A few observations can be made from these two tables:<\/div>\n<div>\u00a0<\/div>\n<ul>\n<li>For each click in either direction, four transitions occur.<\/li>\n<li>We can tell when an encoder is idle, because at that point A = 1 and B = 1<\/li>\n<li>When the first transition that brings the encoder out of idle occurs, we can identify the direction the knob is being rotated in by looking at which signal changed first to 0 (A = 0 means clockwise, B = 0 means anti-clockwise).<\/li>\n<li>Everything else can be ignored until we are idle again (A = 1 and B = 1).<\/li>\n<\/ul>\n<div>\u00a0<\/div>\n<div>Because the exact sequence of transitions is critical, it is critical that our program is aware of every change in transition as it occurs. Fortunately, the wiringPi library allows us to use <i>interrupts<\/i>\u00c2\u00a0to call our code when a transition occurs on a GPIO line.<\/div>\n<div>\u00a0<\/div>\n<div>Using interrupts is superior to frequently checking the status of A and B, which may result in reading the situation wrongly if a signal changes state when we are not looking. Using interrupts also has the advantage of not using the CPU unnecessarily.<\/div>\n<div>\u00a0<\/div>\n<div>To tell wiringPi to call our code when an interrupt occurs, we need to declare an Interrupt Service Routine (ISR). The <i>WiringPiISR()<\/i> command takes a pin number, a transition mode, and a pointer to the ISR function. The transition mode can be INT_MODE_FALLING, INT_MODE_RISING, or INT_MODE_BOTH, and determines whether the ISR should be called when the signal transitions from 1 to 0 (falling) or 0 to 1 (rising) or both. Since we are interested in both rising and falling transitions, we use INT_EDGE_BOTH.<\/div>\n<div>\u00a0<\/div>\n<div>Because we have two encoders, and wiringPi&#8217;s <i>wiringPiISR<\/i>() command doesn&#8217;t allow us to pass parameters to the ISR, we need two separate ISRs for each encoder.<\/div>\n<div>\u00a0<\/div>\n<div>Each ISR maintains a boolean variable called encoder_I_idle, which tracks the whether the encoder is in an idle position or not. When the ISR is called, the current value of pin A and B are read. If the encoder was idle before this, it means that this is the first transition within the click, and we can check whether pin A or pin B is 0, to determine the direction. Otherwise, it means we are somewhere in the middle of a click and therefore the current transitions are of no interest. The ISR finally checks if both A and B are 1 (which signifies the end of a click) and sets the encoder_I_idle variable accordingly, to prepare us for the next transition.<\/div>\n<div>\u00a0<\/div>\n<div>The above logic is all we need to handle the rotary encoders.<\/div>\n<div>\u00a0<\/div>\n<div>For the push button switch, it is a simpler situation, as there is only one signal. We just need to wait for a FALLING transition to determine when the button has been pressed (we don&#8217;t really care when the button is released). A separate ISR is used to service the push button.<\/div>\n<div>\u00a0<\/div>\n<div>At this point, our test program to read both rotary encoders and the push button looks like this:<\/div>\n<div style=\"text-align: center;\">\u00a0<\/div>\n<div style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9578\" src=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-4.png\" alt=\"\" width=\"590\" height=\"2420\" srcset=\"https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-4.png 590w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-4-73x300.png 73w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-4-250x1024.png 250w, https:\/\/blog.shahada.abubakar.net\/wp-content\/uploads\/2018\/02\/z-4-499x2048.png 499w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div><b><span style=\"font-size: 18px;\">And Now for Some In-Flight Entertainment<\/span><\/b><\/div>\n<div>A practical use of the Dual Concentric Rotary Encoder with Push Button is to act as a radio tuner within a flight simulator.<\/div>\n<div>\u00a0<\/div>\n<div>I&#8217;ve expanded the test program above and added in some code that opens a connection to an X-Plane simulator with the ExtPlane plugin installed. If you open any aircraft with the Laminar X1000 avionics suite (for example, the Cessna 172 with G1000 or the Cirrus), the Dual Cocentric Rotary Encoder can be used to tune the COM1 and COM2 radios. The outer encoder tunes the integer portion of the frequency, and the inner encoder tunes the decimals. Pressing the push-button toggles between COM1 and COM2.<\/div>\n<div>\u00a0<\/div>\n<div>The way this works is that within the ISR routine, I&#8217;ve added calls that submit commands to the ExtPlane service. These commands can be used to control many aspects of the flight simulator.<\/div>\n<div>\u00a0<\/div>\n<div>Here&#8217;s the demo in action:<\/div>\n<div>\u00a0<\/div>\n<div>https:\/\/youtu.be\/mXS_wEJCNN8<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>\u00a0<\/div>\n<div>The source code for the demo is available here: <a href=\"https:\/\/github.com\/dotsha747\/TestRotaryEncoder\">https:\/\/github.com\/dotsha747\/TestRotaryEncoder<\/a>. To run it, clone the repository and type &#8220;make&#8221;. You will need to have my libXPlane-ExtPlane-Client libraries installed (see here for instructions). To start the demo, just execute &#8220;.\/testRotaryEncoder &lt;IP&gt;&#8221;, where &lt;IP&gt; is the IP address of your X-Plane PC.<\/div>\n<div>\u00a0<\/div>\n<p>#X-Plane <a href=\"https:\/\/blog.shahada.abubakar.net\/?tag=g1000\">#g1000<\/a><\/p>\n<p><i>Originally created with EverNote at 20180218T213348Z<\/i><\/p>\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"video-container\"><iframe loading=\"lazy\" title=\"Testing Dual Concentric Rotary Encoder with Push Button\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/mXS_wEJCNN8?feature=oembed&#038;wmode=opaque\" 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<\/div><\/figure>\n\n\n\n<div class=\"wp-block-media-text alignwide is-stacked-on-mobile\"><figure class=\"wp-block-media-text__media\"><\/figure><div class=\"wp-block-media-text__content\">\n<p><\/p>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0 This is my fully 3D printed design for a Dual Concentric Rotary Encoder with Push Button. It&#8217;s useful for making the knobs for flight-sim radio panels, where there is an outer knob to&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":9084,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[152],"tags":[178],"class_list":["post-8275","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-evernote","tag-g1000"],"_links":{"self":[{"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/posts\/8275","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8275"}],"version-history":[{"count":5,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/posts\/8275\/revisions"}],"predecessor-version":[{"id":9581,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/posts\/8275\/revisions\/9581"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=\/wp\/v2\/media\/9084"}],"wp:attachment":[{"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.shahada.abubakar.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}