{"id":2127,"date":"2019-10-03T16:08:42","date_gmt":"2019-10-03T14:08:42","guid":{"rendered":"https:\/\/willem.aandewiel.nl\/?p=2127"},"modified":"2020-10-12T12:00:17","modified_gmt":"2020-10-12T10:00:17","slug":"i2c-rotary-encoder","status":"publish","type":"post","link":"https:\/\/willem.aandewiel.nl\/index.php\/2019\/10\/03\/i2c-rotary-encoder\/","title":{"rendered":"I2C Rotary Encoder"},"content":{"rendered":"\n<p>15,152 keer bekeken \/ views<\/p>\n\n\n\n<p>I will address two topics in this post.<\/p>\n\n\n\n<p>The first one is about Rotary Encoders and what you can do with them. The second is about the Inter-Integrated Circuit protocol (I\u00b2C), developed by Philips.<\/p>\n\n\n\n<p>Een in het Nederlands vertaalde versie van deze post kunt je <a rel=\"noreferrer noopener\" aria-label=\"hier (opens in a new tab)\" href=\"https:\/\/opencircuit.nl\/Blog\/I2C-Rotary-Encoder\" target=\"_blank\">hier<\/a> vinden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rotary Encoders<\/h2>\n\n\n\n<p>A Rotary Encoder is a device that looks (physically) like a potentiometer but it does not vary the resistance between two\/three connectors. Instead it gives pulses when the axle is rotated. Another difference with the potentiometer is that you can rotate the axle over 360\u00b0 (in fact, there is no limit in how many degrees you can rotate the axle).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/RGB_Rotary_Encoder.png\" alt=\"\" class=\"wp-image-2128\" width=\"189\" height=\"267\"\/><\/figure><\/div>\n\n\n\n<p>Most Rotary Encoders have a switch that is activated when you press the axle. And then there are Rotary Encoders that also have a three colour LED inside (<em>RGB Rotary Encoder<\/em>) which give you the option to feedback to the user a pallet of colours. <\/p>\n\n\n\n<p>The Rotary Encoder generate pulses when the axle is rotated. Most Rotary Encoders generate 24 pulses at every 360\u00b0 rotation. In your program you can count these pulses and let the program act on it (for instance: de- or in-crease the voltage of a bench power supply or step through a menu-list).<\/p>\n\n\n\n<p>You may ask: \u201c<em>why use a Rotary Encoder and not just use a potentiometer?<\/em>\u201d. Well of course there is no \u201c<em>this is better than that<\/em>\u201d answer. It depends on the project at hand. If you build an analogue HiFi amplifier the potentiometer is probably the better choice. If you have a project with a microprocessor the (digital) Rotary Encoder gives you a lot of options to create a nice user interface (with maybe a fine\/coarse change depending on the axle pushed short or long and a coloured feedback to show which mode is active).<\/p>\n\n\n\n<p>This is an example Sketch to \u201cread\u201d a Rotary Encoder. You need hardware bounce control circuitry on pin A and B of the rotary Encoder to make it work reliably:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define outputA 6\n#define outputB 7\n\nint rotVal = 0; \nint rotState;\nint rotLastState;  \n\nvoid setup() { \n    pinMode (outputA,INPUT);\n    pinMode (outputB,INPUT);\n    Serial.begin (115200);\n    \/\/ Reads the initial state of the outputA\n    rotLastState = digitalRead(outputA);   \n} \/\/ setup()\n\nvoid loop() \n{ \n    rotState = digitalRead(outputA);\n    \/\/ If the previous and the current state of \n    \/\/ the outputA are different, that means a\n    \/\/ Pulse has occured\n    if (rotState != rotLastState){     \n      \/\/ If the outputB state is different to the outputA state, \n      \/\/ the encoder is rotating clockwise\n      if (digitalRead(outputB) != rotState) { \n        rotVal ++;\n      } else {\n        rotVal --;\n      }\n      Serial.print(F(\"Position: \"));\n      Serial.println(rotVal);\n    } \n    rotLastState = rotState; \/\/ Update the previous state to \n                             \/\/ the current state\n}  \/\/ loop()<\/pre>\n\n\n\n<p>There is a drawback on using a Rotary Encoder in your project: <em>You need a lot of pins<\/em>!<br>One RGB Rotary Encoder needs two GPIO pins for the Encoder itself (plus GND), then you need one GPIO pin for the push switch and three GPIO pins for the RGB LED. Thats a total of six GPIO pins! On, for instance an ESP8266 that leaves only three free GPIO pins to control the rest of your project! On an Arduino UNO you have more free GPIO pins so one Rotary Encoder will not be a problem. But what if you want to connect two or even three Rotary Encoders. On an ESP8266 that\u2019s impossible, but on an Arduino UNO you will also run out of free GPIO pins.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Luckily, there is a solution!<\/h3>\n\n\n\n<h2 class=\"wp-block-heading\">The Inter-Integrated Circuit bus (I\u00b2C)<\/h2>\n\n\n\n<p>This is called a (data) \u201c<em>bus<\/em>\u201d because you can connect a lot of devices at it. The \u201cbus\u201d exists of two lines. A clock line (<em>SCL<\/em>) and a data line (<em>SDA<\/em>). There is always (at least) one \u201c<em>master<\/em>\u201d device and all the other devices are \u201c<em>slave<\/em>\u201d devices. Every device has a unique address to differentiate between each other. I will not go into the depths of the I\u00b2C protocol, but normally the master will claim control over the bus and sends a request to a slave with a specific address. The slave in turn will take action on the request either by performing a specific action in the slave itself, by sending data back to the master or simply by sending an acknowledge back to the master to let him know he received the request. <a href=\"https:\/\/www.gibbard.me\/?s=beginners+guide+to+i2c&amp;submit=Search\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Here<\/a>  you can read more about the I\u00b2C protocol.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The I\u00b2C Rotary Encoder<\/h2>\n\n\n\n<p>Wouldn\u2019t it be nice to connect a Rotary Encoder using only the two wires of the I\u00b2C bus!?<\/p>\n\n\n\n<p>And that is what this post really is about: A Rotary Encoder that you connect via the I\u00b2C bus and control with the I\u00b2C protocol.<\/p>\n\n\n\n<p>I developed the firmware and a small PCB with an ATtiny841 micro processor. I chose&nbsp; the ATtiny841 because it has <em>Wire<\/em> hardware (the layer underneath  I\u00b2C) for a Slave builtin.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RotaryEncoder_v22-PCB_top-1024x848.png\" alt=\"\" class=\"wp-image-2129\" width=\"512\" height=\"424\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RotaryEncoder_v22-PCB_top-1024x848.png 1024w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RotaryEncoder_v22-PCB_top-300x248.png 300w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RotaryEncoder_v22-PCB_top-768x636.png 768w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RotaryEncoder_v22-PCB_top.png 1123w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/figure>\n\n\n\n<p>The firmware makes the ATtiny841 act like a \u2018<em>normal<\/em>\u2019 I\u00b2C Slave at one end and <em>interface with a RGB Rotary Encoder<\/em> at the other end. For ease of use I wrote an <a href=\"https:\/\/github.com\/mrWheel\/I2C_RotaryEncoder\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Arduino\/ESP8266 Library<\/a> to interface with the I\u00b2C RotaryEncoder.<\/p>\n\n\n\n<p>With this setup it is possible to connect as many (<em>literally!<\/em>) I\u00b2C RotaryEncoders to your microprocessor as you like and still only use two GPIO pins. You can even connect other I\u00b2C devices (display\u2019s, sensors etc.) to the same two GPIO pins leaving a lot of GPIO pins free for other purposes. <\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C.svg_-1024x362.png\" alt=\"\" class=\"wp-image-2134\" width=\"768\" height=\"272\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C.svg_-1024x362.png 1024w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C.svg_-300x106.png 300w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C.svg_-768x271.png 768w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C.svg_.png 1200w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p>If you want, you can use the Interrupt pin of the I\u00b2C RotaryEncoder. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RE_bus.png\" alt=\"\" class=\"wp-image-2130\" width=\"600\" height=\"277\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RE_bus.png 1200w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RE_bus-300x139.png 300w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RE_bus-768x355.png 768w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2019\/10\/I2C_RE_bus-1024x473.png 1024w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/figure>\n\n\n\n<p>This pin generates an interrupt for every change in the position of the rotary axle or push button. All I\u00b2C RotaryEncoders share the same Interrupt line.<\/p>\n\n\n\n<p class=\"has-blue-color has-text-color has-medium-font-size\"><a href=\"https:\/\/opencircuit.nl\/Product\/15457\/I2C-Rotary-Encoder-module-zonder-encoder\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Here (opens in a new tab)\">Here<\/a> you can buy this I2C Rotary Encoder.<\/p>\n\n\n\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/_yOXAgfKwmo\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\"><\/iframe>\n\n\n\n<h2 class=\"wp-block-heading\">How to use the I\u00b2C RotaryEncoder in your project<\/h2>\n\n\n\n<p>The below code is an example Sketch to interface with the I\u00b2C RotaryEncoder (using the Interrupt line):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* Sketch to show the use of the I2C_RotaryEncoder *\/\n\n#define I2C_DEFAULT_ADDRESS   0x28  \/\/ the 7-bit address \n\n#include &lt;i2c_rotaryencoder.h>\n\nI2CRE     Encoder;     \/\/ Create instance of the I2CRE object\n\nint16_t   rotVal;\nvolatile bool interruptPending = false;\n \n\/\/=======================================================\nISR_PREFIX void handleInterrupt()\n{\n  interruptPending = true;\n}\n \n\/\/=======================================================\nvoid handleRotaryEncoder()\n{\n  byte statusReg = Encoder.getStatus();\n  if (statusReg == 0) return;\n\n  if (Encoder.isRotValChanged() ) {\n    Serial.print(F(\"Request Value of ROTARY .......... \"));\n    rotVal = Encoder.getRotVal();\n    Serial.print(F(\"[\"));\n    Serial.print(rotVal);\n    Serial.println(F(\"]\"));\n  }\n\n  if (Encoder.isButtonPressed() ) {\n    Serial.println(F(\"-------> Button Pressed\"));\n  }\n  if (Encoder.isButtonQuickReleased() ) {\n    Serial.println(F(\"-------> Quick Release\"));\n    Encoder.setRotVal(0);            \/\/ or do something else\n    Encoder.setRGBcolor(200, 0, 0);  \/\/ Red\n  }\n  if (Encoder.isButtonMidReleased() ) {\n    Serial.println(F(\"-------> Mid Release\"));\n    Encoder.setRotVal(255);          \/\/ or do something else\n    Encoder.setRGBcolor(0, 200, 0);  \/\/ Green\n  }\n  if (Encoder.isButtonLongReleased() ) {\n    Serial.println(F(\"-------> Long Release\"));\n    Encoder.setRotVal(128);            \/\/ or do something else\n     Encoder.setRGBcolor(0, 0, 200);   \/\/ Blue\n  }\n\n} \/\/ handleRotaryEncoder();\n\n\/\/=======================================================\nvoid setup()\n{\n  Serial.begin(115200);\n  Serial.println(F(\"Start I2C-Rotary-Encoder Basic ...\"));\n  Serial.print(F(\"Setup Wire ..\"));\n  Wire.begin();\n  Serial.println(F(\".. done\"));\n\n  pinMode(_INTERRUPTPIN, INPUT_PULLUP);\n  attachInterrupt(digitalPinToInterrupt(_INTERRUPTPIN)\n                                        , handleInterrupt\n                                        , FALLING);\n\n  if (!Encoder.begin(Wire, I2C_DEFAULT_ADDRESS)) {\n     Serial.println(F(\".. Error connecting to I2C slave ..\"));\n     delay(1000);\n     return; \/\/ restart the micro processor\n }\n \n  Encoder.setLedGreen(128); \/\/ turn green led on half intensity\n \n  interruptPending  = false;\n\n  Serial.println(F(\"setup() done .. \\n\"));\n\n} \/\/ setup()\n\n\n\/\/============================================================\nvoid loop()\n{\n  if (interruptPending) {\n     interruptPending = false;\n     handleRotaryEncoder();\n  } \/\/ handle interrupt ..\n\n  \/\/\n  \/\/ do other stuff ..\n  \/\/\n\n} \/\/ loop() &lt;\/i2c_rotaryencoder.h><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">I2C Rotary Library<\/h2>\n\n\n\n<p>The I\u00b2C_RotaryLibrary has the following methods:<\/p>\n\n\n\n<p> The library gives you the following setters:<br><\/p>\n\n\n\n<table cellspacing=\"0\" cellpadding=\"0\">\n  <tbody>\n    <tr>\n      <td valign=\"middle\">\n        <p><b>Setter<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Returns<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Parms<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Description<\/b><\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRotVal()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the value of the Rotary Encoder (-5000 .. + 5000)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRotStep()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the rotary Step (1 .. 50)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRotMin()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Minimum rotary value (-5000 .. +5000)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRotMax()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Maximum rotary value (-5000 .. +5000)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRotSpinTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Rotary Spin thime value (2 .. 100 milli seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRGBcolor()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t, uint8_t, uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the color of all 3 leds Red, Green, Blue (0 .. 255, 0 .. 255, 0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setRGBcolor()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint32_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the RGB color of all 3 leds (0x000000 .. 0xFFFFFF)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setLedRed()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the PWM value of the Red led (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setLedGreen()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the PWM value of the Green led (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setLedBlue()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the PWM value of the Blue led (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setDebounceTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Debounce Time of the switch (5 .. 250 micro seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setMidPressTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Mid Press Time of the switch (100 .. 5000 milli seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setLongPressTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Long Press Time of the switch (300 .. 10000 milli seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setModeSetBit()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set the Mode Bit (STNG_HWROTDIR | STNG_FLIPMODE | STNG_TURNMODE)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setModeClearBit()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>clears the Mode Bit (STNG_HWROTDIR | STNG_FLIPMODE | STNG_TURNMODE)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>setI\u00b2Caddress()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>set a new I\u00b2C address for this Slave (1 .. 127)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>writeCommand()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>write a command to the Slave (CMD_READCONF | CMD_WRITECONF | CMD_REBOOT)<\/p>\n      <\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n<p>The library gives you the following getters:<\/p>\n<table cellspacing=\"0\" cellpadding=\"0\">\n  <tbody>\n    <tr>\n      <td valign=\"middle\">\n        <p><b>Getter<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Returns<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Parms<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Description<\/b><\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getStatus()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>reads the status byte<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getRotVal()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the value of the rotary (-5000 .. +5000)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getRotStep()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the rotary Step (1 .. 50)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getRotMin()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the minimum rotary value (-5000 .. +5000)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getRotMax()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the maximum rotary value (-5000 .. +5000)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getRotSpinTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the rotary spin time (2 .. 100 milli seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getWhoAmI()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>int8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Address Register<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getLedRed()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the current Red led PWM value (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getLedGreen()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the current Green led PWM value (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getLedBlue()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the current Blue led PWM value (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getDebounceTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Debounce Time of the switch (5 .. 250 micro seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getMidPressTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Mid Press Time of the switch (100 .. 5000 milli seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getLongPressTime()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint16_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Long Press Time of the switch (300 .. 10000 milli seconds)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getMajorRelease()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Major Firmware Release byte (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getMinorRelease()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Minor Firmware Release byte (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getModeSettings()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Mode register byte (0 .. 255)<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>getModeSettings()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>uint8_t<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>read the Mode register byte and test against (STNG_HWROTDIR | STNG_FLIPMODE | STNG_TURNMODE)<\/p>\n      <\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n<p>And the library gives you the following helpers:<\/p>\n<table cellspacing=\"0\" cellpadding=\"0\">\n  <tbody>\n    <tr>\n      <td valign=\"middle\">\n        <p><b>Helper<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Returns<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Parms<\/b><\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p><b>Description<\/b><\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isRotValChanged()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Rotary Value has changed<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isRotValChangedUp()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Rotary Value &gt; previous value<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isRotValChangedDown()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Rotary Value &lt; previous value<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isButtonPressed()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Button is pressed<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isButtonQuickReleased()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Button is released before midPressTime<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isButtonMidReleased()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Button is released between midPressTime and longPressTime<\/p>\n      <\/td>\n    <\/tr>\n    <tr>\n      <td valign=\"middle\">\n        <p>isButtonLongReleased()<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>bool<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>none<\/p>\n      <\/td>\n      <td valign=\"middle\">\n        <p>true if the Button is released after longPressTime<\/p>\n      <\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>15,152 keer bekeken \/ views I will address two topics in this post. The first one is about Rotary Encoders and what you can do with them. The second is about the Inter-Integrated Circuit protocol (I\u00b2C), developed by Philips. Een &hellip; <a href=\"https:\/\/willem.aandewiel.nl\/index.php\/2019\/10\/03\/i2c-rotary-encoder\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3,6,10,115],"tags":[27,59,123],"class_list":["post-2127","post","type-post","status-publish","format-standard","hentry","category-arduino","category-computer","category-esp8266","category-hardware","category-kicad","tag-attiny84","tag-i2c","tag-rotary-encoder"],"views":15152,"_links":{"self":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts\/2127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/comments?post=2127"}],"version-history":[{"count":28,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts\/2127\/revisions"}],"predecessor-version":[{"id":6176,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts\/2127\/revisions\/6176"}],"wp:attachment":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/media?parent=2127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/categories?post=2127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/tags?post=2127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}