<br />
<b>Deprecated</b>:  YoastSEO_Vendor\Symfony\Component\DependencyInjection\Container::__construct(): Implicitly marking parameter $parameterBag as nullable is deprecated, the explicit nullable type must be used instead in <b>/home/nubelus/sharedove/adisjugo/wp-content/plugins/wordpress-seo/vendor_prefixed/symfony/dependency-injection/Container.php</b> on line <b>60</b><br />
<br />
<b>Deprecated</b>:  YoastSEO_Vendor\League\OAuth2\Client\Provider\AbstractProvider::authorize(): Implicitly marking parameter $redirectHandler as nullable is deprecated, the explicit nullable type must be used instead in <b>/home/nubelus/sharedove/adisjugo/wp-content/plugins/wordpress-seo/vendor_prefixed/league/oauth2-client/src/Provider/AbstractProvider.php</b> on line <b>416</b><br />
<br />
<b>Deprecated</b>:  YoastSEO_Vendor\GuzzleHttp\Client::getConfig(): Implicitly marking parameter $option as nullable is deprecated, the explicit nullable type must be used instead in <b>/home/nubelus/sharedove/adisjugo/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/guzzle/src/Client.php</b> on line <b>181</b><br />
<br />
<b>Deprecated</b>:  YoastSEO_Vendor\GuzzleHttp\ClientInterface::getConfig(): Implicitly marking parameter $option as nullable is deprecated, the explicit nullable type must be used instead in <b>/home/nubelus/sharedove/adisjugo/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/guzzle/src/ClientInterface.php</b> on line <b>77</b><br />
{"id":4184,"date":"2020-05-10T19:50:35","date_gmt":"2020-05-10T17:50:35","guid":{"rendered":"https:\/\/blog.sharedove.com\/adisjugo\/?p=4184"},"modified":"2020-05-11T08:43:36","modified_gmt":"2020-05-11T06:43:36","slug":"using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume","status":"publish","type":"post","link":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/","title":{"rendered":"Using KY-040 rotary encoder on Raspberry Pi to control volume"},"content":{"rendered":"\n<p>The last week I have been posting about <a href=\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/03\/saving-grundig-mandello-e-st-the-next-generation-going-fully-digital-with-hifiberry-beocreate\/\">using Raspberry Pi, HiFiBerry BEOCREATE and Moode Audio to revive my vintage Grundig Mandello e\/St<\/a> music cabinet. It is all working just fine, one last thing that had to be done is to put back to function a rotary controller. In the original box from 1969, it has been of course connected to the potentiometer. Well, that potentiometer was unfortunately the very first thing to die from the original equipment. <\/p>\n\n\n\n<p>Why did I want a knob in the first place? I can control the volume through the app? First of all, there was already a hole drilled where rotary knob should come. I couldn&#8217;t just leave it there. Sure, I could cover it with a non-functional dummy knob, but that would be just lame. Plus, I really <em>wanted<\/em> to do it \ud83d\ude42<\/p>\n\n\n\n<p>I&#8217;ve got a Frei KY\u2011040 rotary encoder, which works well with the Raspberry Pi. A nice small piece of tech, well documented, and relatively easy to wire with the Pi.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/files2.elv.com\/\/public\/25\/2504\/250447\/Internet\/250447_w01_drehschalter.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>It has got five pins &#8211; ground (GND), power (+), SW (push button switch), CLK (clock) and DT (direction). In theory, you need to connect those pins to the corresponding GPIO pins of the Raspberry PI, write a small Python script (or a C program) to fetch the input signals and control the volume, and the thing would work.<\/p>\n\n\n\n<p>Well, of course things wouldn&#8217;t be that simple.<\/p>\n\n\n\n<p>The main issue was that I did not want to send the vol+ and vol- signals directly to the BEOCREATE amplifier, since MoodeAudio software (which I am using as a media player) wouldn&#8217;t know anything about it, and those two would be out of sync. If someone would, for example, first change the volume with the knob (directly on the amplifier), and then through the app on Moode, the results would be very &#8220;interesting&#8221;, to say at least. No, I wanted my rotary knob to be sending instructions to the software, not to the amp. &#8220;All&#8221; what I wanted to do, is to send GET requests to the MoodeAudio APIs. <\/p>\n\n\n\n<p>But wait &#8211; in that case, my rotary encoder did not even have to be connected to that Raspberry Pi, which was connected to the BEOCREATE! That way I didn&#8217;t have to fiddle with the &#8220;production&#8221; machine, fight for the processor time, or solder anything on the bottom side of the GPIO pins. So, another Raspberry Pi device was needed to join the setup!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"766\" src=\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200503_181145_2-1024x766.jpg\" alt=\"\" class=\"wp-image-4187\" srcset=\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200503_181145_2-980x733.jpg 980w, https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200503_181145_2-480x359.jpg 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p>In essence, an ultra cheap Raspberry Pi Zero would be more than enough for that, but, since I already had an old Pi 3 laying unused somewhere in a drawer, it was the time to power it up again. I have started with a fresh installation of Raspbian Lite (no need for a GUI here). Once that has been set up, it was a time to connect the rotary encoder to that Pi. This is the schema I was using:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"498\" src=\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/schema-1024x498.png\" alt=\"\" class=\"wp-image-4186\" srcset=\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/schema-1024x498.png 1024w, https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/schema-980x477.png 980w, https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/schema-480x233.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>GND <\/td><td>&#8220;GND&#8221; (physical PIN 6)<\/td><td>Ground<\/td><\/tr><tr><td>+<\/td><td>3v3 Power (physical PIN 1)<\/td><td>Power supply<\/td><\/tr><tr><td>SW<\/td><td>Pin 27 (physical PIN 13)<\/td><td>Push button switch control<\/td><\/tr><tr><td>CLK<\/td><td>Pin 18 (physical PIN 12)<\/td><td>Clock<\/td><\/tr><tr><td>DT<\/td><td>Pin 17 (physical PIN 11)<\/td><td>Direction<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>The vast majority of schemas that you will find on internet does not include the &#8220;purple&#8221; line, which connecting the SW pin on the rotary control to the GPIO Pin 27. I have no idea why &#8211; the &#8220;switch push&#8221; gesture, when you &#8220;press&#8221; the knob can be used for a lot of interesting functions, such as mute\/unmute, pause\/resume, etc.<\/p><\/blockquote>\n\n\n\n<p>The next step was to write a Python script for fetching those signals, and doing some work. First, I wrote a very basic script to test how the rotary encoder was working:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: Code sample:; notranslate\" title=\"Code sample:\">\nimport os\nfrom RPi import GPIO\n\nos.system(&#039;clear&#039;) #clear screen, this is just for the OCD purposes\n\nstep = 5 #linear steps for increasing\/decreasing volume\npaused = False #paused state\n\n#tell to GPIO library to use logical PIN names\/numbers, instead of the physical PIN numbers\nGPIO.setmode(GPIO.BCM) \n\n#set up the pins we have been using\nclk = 17\ndt = 18\nsw = 27\n\n#set up the GPIO events on those pins\nGPIO.setup(clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)\nGPIO.setup(dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)\nGPIO.setup(sw, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)\n\n#get the initial states\ncounter = 0\nclkLastState = GPIO.input(clk)\ndtLastState = GPIO.input(dt)\nswLastState = GPIO.input(sw)\n\n#define functions which will be triggered on pin state changes\ndef clkClicked(channel):\n        global counter\n        global step\n\n        clkState = GPIO.input(clk)\n        dtState = GPIO.input(dt)\n\n        if clkState == 0 and dtState == 1:\n                counter = counter + step\n                print (&quot;Counter &quot;, counter)\n\ndef dtClicked(channel):\n        global counter\n        global step\n\n        clkState = GPIO.input(clk)\n        dtState = GPIO.input(dt)\n        \n        if clkState == 1 and dtState == 0:\n                counter = counter - step\n                print (&quot;Counter &quot;, counter)\n\ndef swClicked(channel):\n        global paused\n        paused = not paused\n        print (&quot;Paused &quot;, paused)             \n                \nprint (&quot;Initial clk:&quot;, clkLastState)\nprint (&quot;Initial dt:&quot;, dtLastState)\nprint (&quot;Initial sw:&quot;, swLastState)\nprint (&quot;=========================================&quot;)\n\n#set up the interrupts\nGPIO.add_event_detect(clk, GPIO.FALLING, callback=clkClicked, bouncetime=300)\nGPIO.add_event_detect(dt, GPIO.FALLING, callback=dtClicked, bouncetime=300)\nGPIO.add_event_detect(sw, GPIO.FALLING, callback=swClicked, bouncetime=300)\n\nraw_input(&quot;Start monitoring input&quot;)\n\nGPIO.cleanup()\n<\/pre><\/div>\n\n\n<p>The Python script above &#8220;fetches&#8221; the impulses coming to the GPIO pins, and then increases or decreases the &#8220;counter&#8221; variable value, depending if the rotary encoder has been turned clockwise or counterclockwise. <\/p>\n\n\n\n<p>But how do we know, when has it been turned clockwise, and when counterclockwise? It is important to know, that the &#8220;natural&#8221;, &#8220;default&#8221; state of all pins (CLK, DT, SW) is &#8220;1&#8221;. So we are checking when this value will change. <\/p>\n\n\n\n<p>For a clockwise rotation, you will get two consecutive &#8220;signals&#8221;. After the first signal, CLK will be 0 (CLK has changed), whereas DT remains 1. After the second signal, both CLK and DT will be set to 0. <\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Clockwise rotation<\/td><td>CLK State<\/td><td>DT State<\/td><\/tr><tr><td>1st signal<\/td><td>0<\/td><td>1<\/td><\/tr><tr><td>2nd signal<\/td><td>0<\/td><td>0<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>For a counterclockwise rotation, you will also get two consecutive signals. After the first signal, DT will be 0, whereas CLK remains 1. After the second signal, both CLK and DT will be set to 0.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Counterclockwise rotation<\/td><td>CLK State<\/td><td>DT State<\/td><\/tr><tr><td>1st signal<\/td><td>1<\/td><td>0<\/td><\/tr><tr><td>2nd signal<\/td><td>0<\/td><td>0<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>In essence, we will catch the CLK and DT interrupts, and check for these combinations. As you are turning the knob clockwise or counterclockwise, you will see the Counter being increased or decreased by the step you have declared (5 in my case). <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>You can of course get very playful here, and measure the time intervals between interrupts, and increase\/decrease step based on the time difference. So, for example, when someone is turning the knob fast, you can use exponential volume increase\/decrease, whereas if the knob is being turned slower, you can keep it linear. This way, you are making the feeling of the &#8220;fast&#8221; but also &#8220;fine&#8221; volume control change. <\/p><\/blockquote>\n\n\n\n<p>Catching the push switch button event is easy. It has got its own interrupt, and you don&#8217;t need to check for the combination of the values, like with the knob turning gestures. In my scenario, I will be using it to pause\/resume the music play. The source code for that interrupt is a very simple one. <\/p>\n\n\n\n<p>But, we do not want just to increase\/decrease the value of a &#8220;counter&#8221; variable, we actually want to turn the volume up or down. For Moode Audio, a media player which is based on the MPD server, those are the GET requests that you need to call in order to preform the volume and music control operations:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Play<\/td><td>http:\/\/moode\/command?cmd=play<\/td><\/tr><tr><td>Skip to next song<\/td><td>http:\/\/moode\/command?cmd=next<\/td><\/tr><tr><td>Stop<\/td><td>http:\/\/moode\/command?cmd=stop<\/td><\/tr><tr><td>Pause \/ Resume<\/td><td>http:\/\/moode\/command?cmd=pause<\/td><\/tr><tr><td>Volume up by 5%<\/td><td>http:\/\/moode\/command?cmd=vol.sh up 5<\/td><\/tr><tr><td>Volume down by 5%<\/td><td>http:\/\/moode\/command?cmd=vol.sh dn 5<\/td><\/tr><tr><td>Mute \/ Unmute<\/td><td>http:\/\/moode\/command?cmd=vol.sh mute<\/td><\/tr><tr><td>Set volume to 25%<\/td><td>http:\/\/moode\/command?cmd=vol.sh 25<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>You will of course want to change the URL to the host name of your media player.<\/p><\/blockquote>\n\n\n\n<p>The code then looks something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: Code sample:; notranslate\" title=\"Code sample:\">\nimport requests\n\n#here we define the commands we want to send to the player\nurlmoode = &quot;http:\/\/moode-studio\/command&quot;\nparamVolUp = {&#039;cmd&#039; : &#039;vol.sh up 5&#039;}\nparamVolDn = {&#039;cmd&#039; : &#039;vol.sh dn 5&#039;}\nparamMute = {&#039;cmd&#039; : &#039;vol.sh mute&#039;}\nparamStop = {&#039;cmd&#039; : &#039;stop&#039;}\nparamPlay = {&#039;cmd&#039; : &#039;play&#039;}\nparamPause = {&#039;cmd&#039; : &#039;pause&#039;}\n\n#get request for volume down\nr = requests.get(url = urlmoode, params = paramVolDn)\n\n#get request for volume up\nr = requests.get(url = urlmoode, params = paramVolUp)\n\n#get request for pause\/play\nr = requests.get(url = urlmoode, params = paramPause)\n\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Now, one thing to consider here is, if you make those GET requests synchronously, they will necessarily slow down your code, because they need time to execute, and some of the interrupts from the rotary encoder might be skipped. That is not a pleasant user experience. This is why I am suggesting you either use multithreading, or async patterns here. That way, your script will remain &#8220;responsive&#8221;, even if another thread, or an async block of code is executing that GET request somewhere.<\/p><\/blockquote>\n\n\n\n<p>These &#8220;delays&#8221;, caused by the web service calls, are in the same time the only reason why I would possibly think of sending the vol+ or vol- signals directly to the amplifier, instead of sending them to the software. In that case, the whole pause\/resume use case would not be supported, the real volume would not be in sync to that what your player thinks it is, but it WOULD perform faster. I have still decided against it. But, if you are considering going down that path, please keep in mind that the GPIO pins 17, 18 and 27 are reserved by many amplifiers and DACs, for example BEOCREATE. In that case, think of using GPIO pins 5, 6, 12, 13 and 16 instead of the abovementioned ones &#8211; they are usually free. BEOCREATE, for example, exposes them through the own set of pins. <\/p>\n\n\n\n<p>That would be all about rotary encoder and Pi. Once you grasp the concepts of clock and direction within the encoder, and once you understand the function of the GPIO pins on the raspberry board, it is a very simple procedure. The code itself can be made fancy (with exponential increase etc.), but the starter code here can get you going.<\/p>\n<div class=\"fb-background-color\">\n\t\t\t  <div \n\t\t\t  \tclass = \"fb-comments\" \n\t\t\t  \tdata-href = \"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/\"\n\t\t\t  \tdata-numposts = \"59\"\n\t\t\t  \tdata-lazy = \"true\"\n\t\t\t\tdata-colorscheme = \"light\"\n\t\t\t\tdata-order-by = \"time\"\n\t\t\t\tdata-mobile=true>\n\t\t\t  <\/div><\/div>\n\t\t  <style>\n\t\t    .fb-background-color {\n\t\t\t\tbackground:  !important;\n\t\t\t}\n\t\t\t.fb_iframe_widget_fluid_desktop iframe {\n\t\t\t    width: 100% !important;\n\t\t\t}\n\t\t  <\/style>\n\t\t  ","protected":false},"excerpt":{"rendered":"<p>Understanding and setting up the rotary encoder with Raspberry Pi<\/p>\n","protected":false},"author":1,"featured_media":4121,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[11,15],"tags":[],"class_list":["post-4184","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","category-random-thoughts"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using KY-040 rotary encoder on Raspberry Pi to control volume - Adis Jugo blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using KY-040 rotary encoder on Raspberry Pi to control volume - Adis Jugo blog\" \/>\n<meta property=\"og:description\" content=\"Understanding and setting up the rotary encoder with Raspberry Pi\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/\" \/>\n<meta property=\"og:site_name\" content=\"Adis Jugo blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-10T17:50:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-05-11T06:43:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1915\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"adis.jugo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"adis.jugo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/\",\"url\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/\",\"name\":\"Using KY-040 rotary encoder on Raspberry Pi to control volume - Adis Jugo blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg\",\"datePublished\":\"2020-05-10T17:50:35+00:00\",\"dateModified\":\"2020-05-11T06:43:36+00:00\",\"author\":{\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/#\/schema\/person\/a5ca63552094ce9d5a0440f3a1ac9a4c\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#primaryimage\",\"url\":\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg\",\"contentUrl\":\"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg\",\"width\":2560,\"height\":1915},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.sharedove.com\/adisjugo\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using KY-040 rotary encoder on Raspberry Pi to control volume\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/#website\",\"url\":\"https:\/\/blog.sharedove.com\/adisjugo\/\",\"name\":\"Adis Jugo blog\",\"description\":\"The Southern Side\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.sharedove.com\/adisjugo\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/#\/schema\/person\/a5ca63552094ce9d5a0440f3a1ac9a4c\",\"name\":\"adis.jugo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.sharedove.com\/adisjugo\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cc5a23cf1bd0b9d8401c9dd65c6c141041ec0c6e37eedbb511779e4a40a198fd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cc5a23cf1bd0b9d8401c9dd65c6c141041ec0c6e37eedbb511779e4a40a198fd?s=96&d=mm&r=g\",\"caption\":\"adis.jugo\"},\"url\":\"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/author\/adisjugo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using KY-040 rotary encoder on Raspberry Pi to control volume - Adis Jugo blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/","og_locale":"en_US","og_type":"article","og_title":"Using KY-040 rotary encoder on Raspberry Pi to control volume - Adis Jugo blog","og_description":"Understanding and setting up the rotary encoder with Raspberry Pi","og_url":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/","og_site_name":"Adis Jugo blog","article_published_time":"2020-05-10T17:50:35+00:00","article_modified_time":"2020-05-11T06:43:36+00:00","og_image":[{"width":2560,"height":1915,"url":"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg","type":"image\/jpeg"}],"author":"adis.jugo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"adis.jugo","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/","url":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/","name":"Using KY-040 rotary encoder on Raspberry Pi to control volume - Adis Jugo blog","isPartOf":{"@id":"https:\/\/blog.sharedove.com\/adisjugo\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#primaryimage"},"image":{"@id":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg","datePublished":"2020-05-10T17:50:35+00:00","dateModified":"2020-05-11T06:43:36+00:00","author":{"@id":"https:\/\/blog.sharedove.com\/adisjugo\/#\/schema\/person\/a5ca63552094ce9d5a0440f3a1ac9a4c"},"breadcrumb":{"@id":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#primaryimage","url":"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg","contentUrl":"https:\/\/blog.sharedove.com\/adisjugo\/wp-content\/uploads\/2020\/05\/IMG_20200501_190244-scaled.jpg","width":2560,"height":1915},{"@type":"BreadcrumbList","@id":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/2020\/05\/10\/using-ky-040-rotary-encoder-on-raspberry-pi-to-control-volume\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.sharedove.com\/adisjugo\/"},{"@type":"ListItem","position":2,"name":"Using KY-040 rotary encoder on Raspberry Pi to control volume"}]},{"@type":"WebSite","@id":"https:\/\/blog.sharedove.com\/adisjugo\/#website","url":"https:\/\/blog.sharedove.com\/adisjugo\/","name":"Adis Jugo blog","description":"The Southern Side","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.sharedove.com\/adisjugo\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.sharedove.com\/adisjugo\/#\/schema\/person\/a5ca63552094ce9d5a0440f3a1ac9a4c","name":"adis.jugo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.sharedove.com\/adisjugo\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cc5a23cf1bd0b9d8401c9dd65c6c141041ec0c6e37eedbb511779e4a40a198fd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cc5a23cf1bd0b9d8401c9dd65c6c141041ec0c6e37eedbb511779e4a40a198fd?s=96&d=mm&r=g","caption":"adis.jugo"},"url":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/author\/adisjugo\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/posts\/4184","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/comments?post=4184"}],"version-history":[{"count":3,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/posts\/4184\/revisions"}],"predecessor-version":[{"id":4191,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/posts\/4184\/revisions\/4191"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/media\/4121"}],"wp:attachment":[{"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/media?parent=4184"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/categories?post=4184"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.sharedove.com\/adisjugo\/index.php\/wp-json\/wp\/v2\/tags?post=4184"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}