-
Notifications
You must be signed in to change notification settings - Fork 405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Description and example code for KY-040 encoder does not reflect operation of actual device #168
Comments
Thanks for the feedback! The intent is to have the simulation match as closely at it make sense (i.e. requires a reasonable level of effort and is not computationally heavy). For parts that can't be accurately simulated, we should at least point out any significant differences in the documentation. I'd love to read what you think is inaccurate so we can address it. |
Here's a summary of the changes required to bring the operational description and the example code into agreement with the behavior that I see with real-world KY-040 parts, and consistent with your own timing diagram (which is correct as shown). If you agree with what is below, I'll be happy to provide a pull request that corrects the errors. However, if you dispute my analysis, I'll also be happy to go down to the next level of detail and make the case with some carefully-drawn timing diagrams and results obtained using an actual part, just to avoid the time spent in submitting a pull request that you may not agree with. (But I think you should be able to verify all of the corrections below by simply examining the behavior of an actual KY-040 part using a scope or multimeter. Your timing diagram shows the real-world behavior correctly.) ===========================================================================
That statement does not agree with the behavior of any quadrature encoder that I have ever worked with, and in particular, does not agree with the behavior of the Taiss KY-040, which is a pretty common Chinese part. All quadrature encoders I've come across toggle the state of both CK and DT pins on every detent movement (i.e. on every "click" of the encoder shaft); but the direction (and final state) alternates: It "produces a LOW signal" (per your statement above) only on every other detent movement, not on every detent movement. Concrete example that you can check easily yourself with just a power supply and a multimeter or scope: Set the initial detent position such that the state of both CLK and DT happens to be HIGH: In this case, rotating the shaft by one detent position (in either direction) will indeed change the final state of both CLK and DT to LOW, as your document states above. But if the initial detent position happens to be such that CLK at DT are both LOW, then rotating the shaft by one position in either direction will change the state of both CLK and DT to HIGH, contradicting the word "every" in the above statement from your document. In other words, with the real-world part, every detent click, in either direction, results in a transition of both CLK and DT, but the direction of that transition (hence the final state in the new detent position) depends on the steady-state value of the initial position. It does not always "produce a LOW signal", as stated in your doc. ===========================================================================
which correctly assesses the direction on every CLK transition, not just transitions from HIGH to LOW. Unfortunately, the example code also introduces a new mistake in determining the direction of rotation by assessing the direction like this:
But that is not correct: The correct clauses should be:
The above corrected version is consistent with both the observed behavior of an actual Taiss part and with the timing diagram shown in your document. (And of course the above corrected clauses could be improved efficiency-wise by preceding the second clause with "else".) =========================================================================== Again, if you're not convinced of the above analysis after fiddling around with an actual KY-040 part in view of the manufacturer's datasheet, just let me know, and I'll be glad to provide additional detail and actual test results using a Taiss KY-040. |
Thanks for the detailed explanation! I did a quick experiment with my logic analyzer and a rotary encoder that I have here (from Ender-3 S1 printer). This is what I'm seeing I make a single detent movement clockwise: And when I make a single detent movement counterclockwise: Each channel has a pull-up resistor (otherwise, the signal is always low, and does not change when I move the knob). From what I see, it looks like there are two transitions on each channel for every detent movement: first, it goes LOW, then HIGH. However, if I make what I perceive as partial movement (carefully applying force to the knob so that is hangs between two clicks), it does make a single transition (either goes to HIGH or to LOW). When the encoder is connected to the printer, however, it doesn't register this as a movement - it requires two transitions (so HIGH to LOW and then back HIGH), before the UI responds (e.g. moves to the next item in the menu). I guess either different people may have different definitions of what a detent movement is, or different rotary encoders give different kind of feedback. I don't have a Taiss KY-040 at hand to tell whether this is a matter of definition or difference between rotary encoder, but I will try to obtain a unit. In any case, we should probably adapt the docs to reflect that. |
Interesting. Couple of questions:
As to the definition of "detent movement": I can't speak for anyone but myself, but what I mean by a "detent movement" is a monotonic angular rotation of the shaft, starting from one stable shaft position and ending at an adjacent stable shaft position, in either direction, with no attempt to retard the movement during the transition. For example, define three stable adjacent shaft positions A, B, and C, located respectively at (say) 12-o'clock, 1-o-clock, and 2-o'clock positions. Then what I mean by a single "detent movement" is a monotonic rotation from A to B or from B to C or from C to B or from B to A. I've not come across any mechanical shaft encoders that behave as you are showing, but that certainly doesn't mean there aren't any. (One precision optical encoder I worked with many years ago may have possibly behaved as you show, but I am not sure of that and may simply be mis-recalling.) In any case, your document explicitly claims to describe the behavior of the KY-040, and I can say for sure that the Taiss KY-040's that I have do behave as stated in my previous post. I just checked carefully again, to be sure I was not mis-interpreting or mis-reporting, but there is no ambiguity: Each detent movement (as defined above) toggles the state of both CLK and DT. There is no "return to HIGH" or "return to LOW" at the final detent position: It's just a straightforward toggle, nothing more. And that toggle behavior is fully constent with the attached document, which appears to be excerpted from the datasheet for a KY-040 manufactured by Keyes. Annoyingly, I could not quickly put my hands a datasheet claiming to be published by Taiss, but in any case, I buzzed out my Taiss unit and the schematic is exactly as shown for the Keyes KY-040, including the two on-board 10k pullups. The Taiss units appear to be physically identical to the photos shown of the Keyes part. Anyway... it will be interesting to hear what you find if you are able to put your hands on a part that is definitely represented as being a KY-040. P.S. Btw, as an amusing aside from issue we're discussing: Both the Keyes and Taiss KY-040's have 30 detent positions, despite the fact that they are both routinely mis-advertised (e.g. Amazon, eBay, AliExpress, etc.) as having 20 positions. (Your document also mentions 20 positions up at the top.) |
Nope, I didn't take apart the LCD assembly, and the only thing I could find online was this photo: It does seem similar in appearance of the encoder inside the KY-040.
I tested by connecting to the connector at the back of the LCD assembly, while it was disconnected from the printer. In any case, I just ordered an KY-040 compatible encoder (it says LB-Link instead of Keyes), to remove another bit of uncertainty. I will update once it arrives. |
That actually looks like it may be an EC-11 rather than a KY-040, but it's hard to tell, they do look similar. The EC-11's I've got operate like the KY-040's as well. Here's a datasheet for the Alps line of EC-11s:
See the timing diagram at the top of p. 7. That diagram explicitly defines what they mean by "stable detent position", and it makes clear that the operation I refer to above as "detent movement" (i.e. moving from one stable detent position to an adjacent stable detent position) results in a toggle of both lines, not a "return to HIGH" or "return to LOW". |
Update: still waiting for the KY-040 compatible board. Should be shipped this week, according to store. |
Ok, will be interesting to see exactly how it behaves. Can you post the URL of the site that you ordered it from? Btw, here is another explanatory blurb which seems to indicate that the encoding operation is as I described in the original post, i.e. that movement from one detent to an adjacent detent (in either direction) toggles both CK and DT, rather than "return to HIGH" at each detent position:
Unfortunately, the document does not state that explicitly, but if the vertical dotted lines in the timing diagram are interpreted as stable detent positions, then the encoding operation accords with my earlier description. Anyway... that still doesn't mean that there might not be other parts which are (accurately or inaccurately) being marketed and sold as "KY-040", and which use a "return to HIGH" encoding scheme. |
URL: https://brk.co.il/product/ky-040-%D7%9E%D7%A7%D7%95%D7%93%D7%93-%D7%A1%D7%99%D7%91%D7%95%D7%91%D7%99 Should arrive today |
Just got the part, and it seems like it does toggle twice (high → low → high) for each detent movement: ky-040-s.mp4I guess you are getting different results with your encoder? |
Interesting. The part you show in your video does not appear to be the same part as shown in the advertisement URL that you posted. The board is clearly different (there is no "LB-link" notation) and the encoder itself also does not appear to be the same as the one shown in the ad photo. See attached annotated photo of the ad. I've also attached the tag from the Taiss KY-040 parts that I got via Amazon. (I also have some from eBay, but there was no original packaging.) All of those parts behave as I described earlier, and verified in a very simple way using a multimeter to verify the contact resistances to GND and + for adjacent detent positions. If you insist, I will be glad to supply a video showing those measurements, but the test is so straightforward that it hardly seems worth the effort. And in any case, the behavior seen and described in my earlier posts is in full agreement with all the other documentation that I have come across for the KY-040, and provided in the links in the above postings. And my many projects using those parts would not work if the encoding behavior were other than what I described. The shaft encoding used in the parts that I have in my lab is unambiguously toggle-type behavior, not the return-to-HIGH that you show above. Here's the Amazon ad for at least some of the KY-040's in my collection: https://www.amazon.com/dp/B07F26CT6B?psc=1&ref=ppx_yo2ov_dt_b_product_details The parts from eBay did not come in original packaging, but externally at least, they do appear to be mechanically identical to the ones from Amazon. |
Btw, how many detent positions does your part have? |
Yes, the part indeed seems different from the one in the picture. It has 20 detent positions. It may be the part from this tutorial, as the plastic color matches and also the number of detents: It seems to me like there as if are two different models out there - one with 30 detent positions, which does not return-to-high, and another one with 20 detent positions which returns to high. |
There's no question or debate that various manufacturers produce various mechanical encoders of similar appearance, having differing encoding schemes and resolutions, and certainly not limited to 20 or 30 detents. But I seriously doubt that a manufacturer would designate a part as "KY-040" yet having two different encoding schemes for different resolutions. It's my belief that the device you tested -- which may well be the blue encoder in the tutorial as you say -- is probably not a KY-040. |
I like the full-quadrature-cycle-per-detent behavior in Wokwi: It matches the behavior of my bare no-breakout board blue encoder with its open circuits at the detents, and the encoders I have on breakout boards with VCC pullup resistors on the signal lines making HIGH at the detents. However, this datasheet says their KY-040 alternates between both signals resting at HIGH and LOW with alternate detents:
I don't think you can rely on drop-in compatibility of the cheap and popular KY-040 encoder switches. There's probably more than two models, and based on Urish's disassembly photo, they only need differ by the pattern of tabs on the disk in the RHS. Here's a datasheet for ALPS EC11 encoders that the KY-040 module is likely built from: |
Imo, the confusion here probably results from various secondary market parts-sellers uncritically using the designation "KY-040" to describe any of these small inexpensive mechanical encoders. It is still my belief that the "real" KY-040, as originally produced by Keyes electronics, has only one encoding mode, which is the half-quadrature mode, regardless of the number of detent positions. (They made several models having different numbers of detent positions.) My guess is that the full-quadrature-per-detent encoders are not really KY-040 parts, even though they are frequently marketed as such on Amazon, eBay, etc. |
Re this page:
Is it your intent that the simulation of the KY-040 exactly match the behavior of the actual device? If that is the intent, then both the description (in the Operation section) and the associated example code (first example under Reading the rotation) are incorrect: The stated description does not reflect the behavior of the actual device, and the associated example code will not work correctly on the actual device.
I would be happy to provide a pull request with corrections that bring the description and the code into agreement with actual device behavior, but first wanted to ask whether it is even your intent that the simulation match the actual device behavior. Perhaps your intent is only that the simulation behave in a functionally similar way, but not mimic the device exactly....?
The text was updated successfully, but these errors were encountered: