User Tools

Site Tools


arduino:rotary-encoder

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
arduino:rotary-encoder [2023/01/10 15:18]
Ilias Iliopoulos [Theory of operation]
arduino:rotary-encoder [2024/02/02 21:48] (current)
Ilias Iliopoulos
Line 23: Line 23:
   * [[https://​en.wikipedia.org/​wiki/​Gray_code | Gray code]]  ​   * [[https://​en.wikipedia.org/​wiki/​Gray_code | Gray code]]  ​
  
-In this article, we will explore a simple form of Rotary Encoder which provides as outputs two signals, A and B. Most encoders labeled as EC11 or KY-40, are based on this principle. Please note that not all rotary encoders behave exactly the same, especially during transition from one state to another, depending on their construction. I will try to implement a universal solution, applicable to most rotary encoders variants. It is understood that this approach may have implications which may or may not affect a specific implementation and should be considered thoroughly at the design phase of each project. ​   ​+In this article, we will explore a simple form of Rotary Encoder which provides as outputs two signals, A and B. Most encoders labeled as EC11 or KY-040, are based on this principle. Please note that not all rotary encoders behave exactly the same, especially during transition from one state to another, depending on their construction. I will try to implement a universal solution, applicable to most rotary encoders variants. It is understood that this approach may have implications which may or may not affect a specific implementation and should be considered thoroughly at the design phase of each project. ​   ​
  
 In theory, we learn that signals A and B __"are in quadrature"​__ or __"are 90 degrees out of phase"​__. In theory, we learn that signals A and B __"are in quadrature"​__ or __"are 90 degrees out of phase"​__.
Line 42: Line 42:
 Going back to Diagram 1, at the end of time instance C, signal B goes ''​LOW'',​ while signal A remains ''​LOW''​. Most rotary encoders designed to be operated by humans (in contrast to other encoders which are moved and controlled by machines), employ a mechanism to temporarily "​lock"​ the shaft in this resting position, which is the **"​detent"​**. Turning the shaft right or left of this position, you feel a distinctive "​click"​ when you move to the next stable position. These positions are shown as **"​stable zones"​** in the diagram. Therefore, in the types of encoders that we examine, we will consider the change from one detent to the immediately neighbouring detent, either on the right side or the left side, as one identified change in our position indication. ​     ​ Going back to Diagram 1, at the end of time instance C, signal B goes ''​LOW'',​ while signal A remains ''​LOW''​. Most rotary encoders designed to be operated by humans (in contrast to other encoders which are moved and controlled by machines), employ a mechanism to temporarily "​lock"​ the shaft in this resting position, which is the **"​detent"​**. Turning the shaft right or left of this position, you feel a distinctive "​click"​ when you move to the next stable position. These positions are shown as **"​stable zones"​** in the diagram. Therefore, in the types of encoders that we examine, we will consider the change from one detent to the immediately neighbouring detent, either on the right side or the left side, as one identified change in our position indication. ​     ​
  
 +** NOTE: The stable zones had been a source of controversy since I have received several emails regarding implementations of other encoder manufacturers where the signal transition from one step to another and the detents did not follow the above principle. For example, one detent might correspond to a change of a single signal, either A or B, according to the Gray encoding. The reason that I have not covered this case in this section relates: **
 +
 +** a) to the fact that the common EC11, KY-040 variants produce two Gray code transitions per detent. As per the {{arduino:​ky-040-datasheet.pdf|KY-040 datasheet}}:​ **
 +
 +//
 + A rotary encoder has a fixed number of positions. These positions are easily felt as small clicks when you turn the encoder. The KY-040 module has thirty of these positions....... In each encoder position, both switches are either opened or closed. Each click causes these switches to change states as follows:
 +
 +  * If both switches are closed, turning the encoder either clockwise or counterclockwise,​ one position will cause both switches to open.
 +
 +  * If both switches are open, turning the encoder either clockwise or counterclockwise,​ one position will cause both switches to close.
 +// 
 +
 +** 
 +b) to the principle of the debouncing algorithm [[arduino:​rotary-encoder#​2. A transition is considered valid when both signals (A and B) change value]] presented below. Therefore, I considered that even in the case where one detent corresponds to a change in only one signal, the user should make two shaft movements, or in the generic case, as many movements as necessary so that both signals are changed. This obviously has the effect that the Gray code will move two positions instead of one. This is a side-effect of this debouncing algorithm and the price to pay if we do not debounce with hardware. ​
 ** **
-NOTE: The stable zones had been a source of controversy since I have received several emails regarding implementations of other encoder manufacturers where the signal transition from one step to another and the detents did not follow the above principle. For example, one detent might correspond to a change of a single signal, either A or B, according to the Gray encoding. The reason that I have not covered this case in this section relates a) to the fact that the common EC11, KY-40 variants produce two Gray code transitions per detent and b) to the principle of the debouncing algorithm [[arduino:​rotary-encoder#​2. A transition is considered valid when both signals (A and B) change value]] presented below. Therefore, I considered that even in the case where one detent corresponds to a change in only one signal, the user should make two shaft movements, or in the generic case, as many movements as necessary so that both signals are changed. This obviously has the effect that the Gray code will move two positions instead of one. This is a side-effect of this debouncing algorithm and the price to pay if we do not debounce with hardware. ** 
  
 If we consider signal A the most significant bit (MSB) and B the least significant bit (LSB) of a binary number composed of A and B, we can see that when the shaft is not rotating, it rests at state **00** (which is decimal **0**), or at state ** binary 11** (which is **decimal 3**).  If we consider signal A the most significant bit (MSB) and B the least significant bit (LSB) of a binary number composed of A and B, we can see that when the shaft is not rotating, it rests at state **00** (which is decimal **0**), or at state ** binary 11** (which is **decimal 3**). 
Line 68: Line 81:
 Most algorithms try to eliminate the bouncing problem by examining whether the rotation creates strictly the known patterns (**0-2-3, 3-1-0, 0-1-3, 3-2-0**). Anything different will be considered illegal and will not be identified as a known rotation. The problem with this method, is that although we have moved the shaft of the encoder, in the case of illegal patterns the system does not respond. If for example we use a knob to change the value at a display, sometimes we may need one "​click"​ to change the value from e.g. number 7 to 8, and other times two or three clicks. This behaviour is certainly not acceptable. We definitely want each and every click of the encoder to produce one response from the system. ​ Most algorithms try to eliminate the bouncing problem by examining whether the rotation creates strictly the known patterns (**0-2-3, 3-1-0, 0-1-3, 3-2-0**). Anything different will be considered illegal and will not be identified as a known rotation. The problem with this method, is that although we have moved the shaft of the encoder, in the case of illegal patterns the system does not respond. If for example we use a knob to change the value at a display, sometimes we may need one "​click"​ to change the value from e.g. number 7 to 8, and other times two or three clicks. This behaviour is certainly not acceptable. We definitely want each and every click of the encoder to produce one response from the system. ​
  
-Yet, //bouncing is a fact of life (and not only of electro-mechanical contacts :-) ) and we must learn to live with it//. Even with more expensive electro-mechanical switches that do not present a problem ​in the current time, when just purchased, they may exhibit bouncing problems after several months or years of use, because of the wear of the metallic parts due to oxidization,​ electrolysis etc, as well as other mechanical issues.  ​+Yet, //bouncing is a fact of life (and not only of electro-mechanical contacts :-) ) and we must learn to live with it//. Even with more expensive electro-mechanical switches that do not present a problem when just purchased, they may exhibit bouncing problems after several months or years of use, because of the wear of the metallic parts due to oxidization,​ electrolysis etc, as well as other mechanical issues.  ​
  
 ===== Explanation of the de-bouncing method ===== ===== Explanation of the de-bouncing method =====
Line 208: Line 221:
 For example, consider that our implementation has a counter displaying only positive values (e.g. from 1 to 10) and the value is increased with a clockwise rotation. We can setup the system so that the first "​lost"​ detent will occur at the same clockwise rotation. Starting from the initial point of counter = 1, the first right click will be lost and the second right click will set counter = 2. If the user changes direction and turns left, the first left click will be lost, but the second left click will return the shaft to the starting position of 1.  For example, consider that our implementation has a counter displaying only positive values (e.g. from 1 to 10) and the value is increased with a clockwise rotation. We can setup the system so that the first "​lost"​ detent will occur at the same clockwise rotation. Starting from the initial point of counter = 1, the first right click will be lost and the second right click will set counter = 2. If the user changes direction and turns left, the first left click will be lost, but the second left click will return the shaft to the starting position of 1. 
  
-Another workaround to make the operation of the encoder to be consistent in each and every step, instead of "​fixing"​ the problem, we can "​expand"​ the problem to all transitions. If for example, after each transition, we set the previous state to a wrong value, the encoder will not recognize the direction of the next step. This way, each position change, regardless of the direction, will require two clicks. This feature is implemented in the library.+Another workaround to make the operation of the encoder to be consistent in each and every step, instead of "​fixing"​ the problem, we can "​expand"​ the problem to all transitions. If for example, after each transition, we set the previous state to a wrong value, the encoder will not recognize the direction of the next step. This way, each position change ​will require two clicks, regardless of the direction. This feature is implemented in the library.
  
 Finally, it seems that to deal completely with the bouncing problem, a hardware solution (monostable multivibrator,​ flip-flop, RC filter followed by Schmitt trigger etc.) is the proper thing to do. If no such resource is available, or such a level of accuracy is not mandatory, such as for hobby projects, the next best thing is the algorithm described above.  ​ Finally, it seems that to deal completely with the bouncing problem, a hardware solution (monostable multivibrator,​ flip-flop, RC filter followed by Schmitt trigger etc.) is the proper thing to do. If no such resource is available, or such a level of accuracy is not mandatory, such as for hobby projects, the next best thing is the algorithm described above.  ​
Line 221: Line 234:
 Please check [[https://​github.com/​fryktoria/​FR_RotaryEncoder | the Github page]] for a description of the functionality available and to download the library. Several examples which demonstrate the library features are included. ​   Please check [[https://​github.com/​fryktoria/​FR_RotaryEncoder | the Github page]] for a description of the functionality available and to download the library. Several examples which demonstrate the library features are included. ​  
  
 +~~DISQUS~~
arduino/rotary-encoder.1673356681.txt.gz ยท Last modified: 2023/01/10 15:18 by Ilias Iliopoulos